Commit d91cbbfa by Karl Schimpf

Change ARM calls into indirect calls.

This is done by putting far pointers (for calls) into a register and then do an indirect call. This was done to guarantee that we aren't putting a size limit on ARM32 executables. BUG= https://bugs.chromium.org/p/nativeclient/issues/detail?id=4076 R=jpp@chromium.org Review URL: https://codereview.chromium.org/1687553002 .
parent f084a571
...@@ -3354,7 +3354,10 @@ void TargetARM32::lowerBr(const InstBr *Instr) { ...@@ -3354,7 +3354,10 @@ void TargetARM32::lowerBr(const InstBr *Instr) {
} }
void TargetARM32::lowerCall(const InstCall *Instr) { void TargetARM32::lowerCall(const InstCall *Instr) {
Operand *CallTarget = Instr->getCallTarget(); // Note: Keep original call target. This allows us to call the correct
// postamble helper, even if the CallTarget gets modified during lowering.
Operand *OrigCallTarget = Instr->getCallTarget();
Operand *CallTarget = OrigCallTarget;
if (Instr->isTargetHelperCall()) { if (Instr->isTargetHelperCall()) {
auto TargetHelperPreamble = ARM32HelpersPreamble.find(CallTarget); auto TargetHelperPreamble = ARM32HelpersPreamble.find(CallTarget);
if (TargetHelperPreamble != ARM32HelpersPreamble.end()) { if (TargetHelperPreamble != ARM32HelpersPreamble.end()) {
...@@ -3479,12 +3482,9 @@ void TargetARM32::lowerCall(const InstCall *Instr) { ...@@ -3479,12 +3482,9 @@ void TargetARM32::lowerCall(const InstCall *Instr) {
} }
} }
// Allow ConstantRelocatable to be left alone as a direct call, but force // Note: To allow far calls, even for constant relocatables, we force
// other constants like ConstantInteger32 to be in a register and make it an // the call target into a register, and make an indirect call.
// indirect call. CallTarget = legalizeToReg(CallTarget);
if (!llvm::isa<ConstantRelocatable>(CallTarget)) {
CallTarget = legalize(CallTarget, Legal_Reg);
}
// Copy arguments to be passed in registers to the appropriate registers. // Copy arguments to be passed in registers to the appropriate registers.
for (auto &FPArg : FPArgs) { for (auto &FPArg : FPArgs) {
...@@ -3535,7 +3535,7 @@ void TargetARM32::lowerCall(const InstCall *Instr) { ...@@ -3535,7 +3535,7 @@ void TargetARM32::lowerCall(const InstCall *Instr) {
} }
if (Instr->isTargetHelperCall()) { if (Instr->isTargetHelperCall()) {
auto TargetHelpersPostamble = ARM32HelpersPostamble.find(CallTarget); auto TargetHelpersPostamble = ARM32HelpersPostamble.find(OrigCallTarget);
if (TargetHelpersPostamble != ARM32HelpersPostamble.end()) { if (TargetHelpersPostamble != ARM32HelpersPostamble.end()) {
(this->*TargetHelpersPostamble->second)(Instr); (this->*TargetHelpersPostamble->second)(Instr);
} }
......
; Show that we convert direct calls, into indirect calls (to handle far
; branches).
; NOTE: We use -O2 to get rid of memory stores.
; REQUIRES: allow_dump
; Compile using standalone assembler.
; RUN: %p2i --filetype=asm -i %s --target=arm32 --args -O2 -allow-extern \
; RUN: -reg-use r5 | FileCheck %s --check-prefix=ASM
; Show bytes in assembled standalone code.
; RUN: %p2i --filetype=asm -i %s --target=arm32 --assemble --disassemble \
; RUN: --args -O2 -allow-extern -reg-use r5 | FileCheck %s --check-prefix=DIS
; Compile using integrated assembler.
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --args -O2 \
; RUN: -allow-extern -reg-use r5 | FileCheck %s --check-prefix=IASM
; Show bytes in assembled integrated code.
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --assemble --disassemble \
; RUN: --args -O2 -allow-extern -reg-use r5 | FileCheck %s --check-prefix=DIS
declare external void @doSomething()
define internal void @callSomething() {
; ASM-LABEL:callSomething:
; DIS-LABEL:{{.+}} <callSomething>:
; IASM-LABEL:callSomething:
call void @doSomething();
; ASM: movw r5, #:lower16:doSomething
; DIS: {{.+}}: e3005000
; ASM-NOT: movw
; ASM-NEXT: movt r5, #:upper16:doSomething
; DIS-NEXT: {{.+}}: e3405000
; ASM-NOT: movt
; ASM-NEXT: blx r5
; DIS-NEXT: {{.+}}: e12fff35
; ASM-NOT: blx
ret void
}
...@@ -40,9 +40,9 @@ define internal float @test2SPops(float %p1, float %p2) { ...@@ -40,9 +40,9 @@ define internal float @test2SPops(float %p1, float %p2) {
; ASM-NEXT: vpush {s22, s23} ; ASM-NEXT: vpush {s22, s23}
; ASM-NEXT: push {lr} ; ASM-NEXT: push {lr}
; DIS: 0: ed2daa01 ; DIS: {{.+}}: ed2daa01
; DIS-NEXT: 4: ed2dba02 ; DIS-NEXT: {{.+}}: ed2dba02
; DIS-NEXT: 8: e52de004 ; DIS-NEXT: {{.+}}: e52de004
; IASM-NOT: vpush ; IASM-NOT: vpush
; IASM-NOT: push ; IASM-NOT: push
...@@ -59,9 +59,9 @@ define internal float @test2SPops(float %p1, float %p2) { ...@@ -59,9 +59,9 @@ define internal float @test2SPops(float %p1, float %p2) {
; ASM-NEXT: vpop {s22, s23} ; ASM-NEXT: vpop {s22, s23}
; ASM-NEXT: vpop {s20} ; ASM-NEXT: vpop {s20}
; DIS: 40: e49de004 ; DIS: {{.+}}: e49de004
; DIS-NEXT: 44: ecbdba02 ; DIS-NEXT: {{.+}}: ecbdba02
; DIS-NEXT: 48: ecbdaa01 ; DIS-NEXT: {{.+}}: ecbdaa01
; IASM-NOT: pop ; IASM-NOT: pop
; IASM-NOT: vpop ; IASM-NOT: vpop
......
...@@ -7,71 +7,42 @@ ...@@ -7,71 +7,42 @@
; Compile using standalone assembler. ; Compile using standalone assembler.
; RUN: %p2i --filetype=asm -i %s --target=arm32 --args -O2 -allow-extern \ ; RUN: %p2i --filetype=asm -i %s --target=arm32 --args -O2 -allow-extern \
; RUN: | FileCheck %s --check-prefix=ASM ; RUN: -reg-use r0,r1,r2,r3,r4,r5 | FileCheck %s --check-prefix=ASM
; Show bytes in assembled standalone code. ; Show bytes in assembled standalone code.
; RUN: %p2i --filetype=asm -i %s --target=arm32 --assemble --disassemble \ ; RUN: %p2i --filetype=asm -i %s --target=arm32 --assemble --disassemble \
; RUN: --args -O2 -allow-extern | FileCheck %s --check-prefix=DIS ; RUN: --args -O2 -allow-extern -reg-use r0,r1,r2,r3,r4,r5 \
; RUN: | FileCheck %s --check-prefix=DIS
; Compile using integrated assembler. ; Compile using integrated assembler.
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --args -O2 \ ; RUN: %p2i --filetype=iasm -i %s --target=arm32 --args -O2 \
; RUN: -allow-extern | FileCheck %s --check-prefix=IASM ; RUN: -allow-extern -reg-use r0,r1,r2,r3,r4,r5 \
; RUN: | FileCheck %s --check-prefix=IASM
; Show bytes in assembled integrated code. ; Show bytes in assembled integrated code.
; RUN: %p2i --filetype=iasm -i %s --target=arm32 --assemble --disassemble \ ; RUN: %p2i --filetype=iasm -i %s --target=arm32 --assemble --disassemble \
; RUN: --args -O2 -allow-extern | FileCheck %s --check-prefix=DIS ; RUN: --args -O2 -allow-extern -reg-use r0,r1,r2,r3,r4,r5 \
; RUN: | FileCheck %s --check-prefix=DIS
declare external void @DoSomething() declare external void @DoSomething()
define internal void @SinglePushPop() { define internal void @SinglePushPop() {
; ASM-LABEL:SinglePushPop:
; DIS-LABEL:{{.+}} <SinglePushPop>:
; IASM-LABEL:SinglePushPop:
; ASM: push {lr}
; DIS: {{.+}} e52de004
; IASM-NOT: push
call void @DoSomething(); call void @DoSomething();
ret void ret void
}
; ASM-LABEL:SinglePushPop: ; ASM: pop {lr}
; ASM-NEXT:.LSinglePushPop$__0: ; DIS: {{.+}} e49de004
; ASM-NEXT: push {lr} ; IASM-NOT: pop
; ASM-NEXT: sub sp, sp, #12
; ASM-NEXT: bl DoSomething
; ASM-NEXT: add sp, sp, #12
; ASM-NEXT: pop {lr}
; ASM-NEXT: # lr = def.pseudo
; ASM-NEXT: bx lr
; DIS-LABEL:00000000 <SinglePushPop>:
; DIS-NEXT: 0: e52de004
; DIS-NEXT: 4: e24dd00c
; DIS-NEXT: 8: ebfffffe
; DIS-NEXT: c: e28dd00c
; DIS-NEXT: 10: e49de004
; DIS-NEXT: 14: e12fff1e
; IASM-LABEL:SinglePushPop: }
; IASM-NEXT:.LSinglePushPop$__0:
; IASM-NEXT: .byte 0x4
; IASM-NEXT: .byte 0xe0
; IASM-NEXT: .byte 0x2d
; IASM-NEXT: .byte 0xe5
; IASM-NEXT: .byte 0xc
; IASM-NEXT: .byte 0xd0
; IASM-NEXT: .byte 0x4d
; IASM-NEXT: .byte 0xe2
; IASM-NEXT: bl DoSomething @ .word ebfffffe
; IASM-NEXT: .byte 0xc
; IASM-NEXT: .byte 0xd0
; IASM-NEXT: .byte 0x8d
; IASM-NEXT: .byte 0xe2
; IASM-NEXT: .byte 0x4
; IASM-NEXT: .byte 0xe0
; IASM-NEXT: .byte 0x9d
; IASM-NEXT: .byte 0xe4
; IASM: .byte 0x1e
; IASM-NEXT: .byte 0xff
; IASM-NEXT: .byte 0x2f
; IASM-NEXT: .byte 0xe1
; This test is based on taking advantage of the over-eager -O2 ; This test is based on taking advantage of the over-eager -O2
; register allocator that puts V1 and V2 into callee-save registers, ; register allocator that puts V1 and V2 into callee-save registers,
...@@ -79,83 +50,21 @@ define internal void @SinglePushPop() { ...@@ -79,83 +50,21 @@ define internal void @SinglePushPop() {
; requires the callee-save registers to be pushed/popped in the ; requires the callee-save registers to be pushed/popped in the
; prolog/epilog. ; prolog/epilog.
define internal i32 @MultPushPop(i32 %v1, i32 %v2) { define internal i32 @MultPushPop(i32 %v1, i32 %v2) {
; ASM-LABEL:MultPushPop:
; DIS_LABEL: {{.+}} <MultPushPop>:
; IASM-LABEL:MultPushPop:
; ASM: push {r4, r5, lr}
; DIS: {{.+}}: e92d4030
; IASM-NOT: push
call void @DoSomething(); call void @DoSomething();
%v3 = add i32 %v1, %v2 %v3 = add i32 %v1, %v2
ret i32 %v3 ret i32 %v3
}
; ASM-LABEL:MultPushPop: ; ASM: pop {r4, r5, lr}
; ASM-NEXT:.LMultPushPop$__0: ; DIS: {{.+}} e8bd4030
; ASM-NEXT: push {r4, r5, lr} ; IASM-NOT: pop
; ASM-NEXT: sub sp, sp, #4
; ASM-NEXT: mov r4, r0
; ASM-NEXT: mov r5, r1
; ASM-NEXT: bl DoSomething
; ASM-NEXT: add r4, r4, r5
; ASM-NEXT: mov r0, r4
; ASM-NEXT: add sp, sp, #4
; ASM-NEXT: pop {r4, r5, lr}
; ASM-NEXT: # r4 = def.pseudo
; ASM-NEXT: # r5 = def.pseudo
; ASM-NEXT: # lr = def.pseudo
; ASM-NEXT: bx lr
; DIS-LABEL:00000020 <MultPushPop>:
; DIS-NEXT: 20: e92d4030
; DIS-NEXT: 24: e24dd004
; DIS-NEXT: 28: e1a04000
; DIS-NEXT: 2c: e1a05001
; DIS-NEXT: 30: ebfffffe
; DIS-NEXT: 34: e0844005
; DIS-NEXT: 38: e1a00004
; DIS-NEXT: 3c: e28dd004
; DIS-NEXT: 40: e8bd4030
; DIS-NEXT: 44: e12fff1e
; IASM-LABEL:MultPushPop: }
; IASM-NEXT:.LMultPushPop$__0:
; IASM-NEXT: .byte 0x30
; IASM-NEXT: .byte 0x40
; IASM-NEXT: .byte 0x2d
; IASM-NEXT: .byte 0xe9
; IASM-NEXT: .byte 0x4
; IASM-NEXT: .byte 0xd0
; IASM-NEXT: .byte 0x4d
; IASM-NEXT: .byte 0xe2
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x40
; IASM-NEXT: .byte 0xa0
; IASM-NEXT: .byte 0xe1
; IASM-NEXT: .byte 0x1
; IASM-NEXT: .byte 0x50
; IASM-NEXT: .byte 0xa0
; IASM-NEXT: .byte 0xe1
; IASM-NEXT: bl DoSomething @ .word ebfffffe
; IASM-NEXT: .byte 0x5
; IASM-NEXT: .byte 0x40
; IASM-NEXT: .byte 0x84
; IASM-NEXT: .byte 0xe0
; IASM-NEXT: .byte 0x4
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0xa0
; IASM-NEXT: .byte 0xe1
; IASM-NEXT: .byte 0x4
; IASM-NEXT: .byte 0xd0
; IASM-NEXT: .byte 0x8d
; IASM-NEXT: .byte 0xe2
; IASM-NEXT: .byte 0x30
; IASM-NEXT: .byte 0x40
; IASM-NEXT: .byte 0xbd
; IASM-NEXT: .byte 0xe8
; IASM: .byte 0x1e
; IASM-NEXT: .byte 0xff
; IASM-NEXT: .byte 0x2f
; IASM-NEXT: .byte 0xe1
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
; REQUIRES: allow_dump, target_ARM32 ; REQUIRES: allow_dump, target_ARM32
; RUN: %p2i -i %s --sandbox --filetype=asm --target=arm32 --assemble \ ; RUN: %p2i -i %s --sandbox --filetype=asm --target=arm32 --assemble \
; RUN: --disassemble --args -Om1 -allow-externally-defined-symbols \ ; RUN: --disassemble --args -Om1 -allow-externally-defined-symbols \
; RUN: -ffunction-sections | FileCheck %s ; RUN: -ffunction-sections -reg-use r0,r1,r3 | FileCheck %s
declare void @call_target() declare void @call_target()
declare void @call_target1(i32 %arg0) declare void @call_target1(i32 %arg0)
...@@ -18,125 +18,315 @@ declare void @call_target3(i32 %arg0, i32 %arg1, i32 %arg2) ...@@ -18,125 +18,315 @@ declare void @call_target3(i32 %arg0, i32 %arg1, i32 %arg2)
define internal void @test_direct_call() { define internal void @test_direct_call() {
entry: entry:
call void @call_target() call void @call_target()
; bundle aigned.
call void @call_target()
ret void ret void
} }
; CHECK-LABEL: test_direct_call
; CHECK: sub sp, ; CHECK-LABEL:<test_direct_call>:
; CHECK-NEXT: bic sp, sp, {{.*}} ; 0xc0000000 ; Search for bundle alignment of first call.
; CHECK: {{[0-9]*}}c: {{.*}} bl {{.*}} call_target ; CHECK: {{[0-9a-f]*}}c: {{.+}} blx
; CHECK-NEXT: {{[0-9]*}}0: ; CHECK-NEXT: movw [[REG:r[0-9]]], {{.+}} call_target
; CHECK-NEXT: movt [[REG]], {{.+}} call_target
; CHECK-NEXT: bic [[REG]], [[REG]], {{.+}} ; 0xc000000f
; CHECK-NEXT: blx [[REG]]
; CHECK-NEXT: {{[0-9a-f]*}}0:
; Same as above, but force bundle padding by adding three (branch) instruction
; before the tested call.
define internal void @test_direct_call_with_padding_1() {
entry:
call void @call_target()
; bundle aigned.
br label %next1 ; add 1 inst.
next1:
br label %next2 ; add 1 inst.
next2:
br label %next3 ; add 1 inst.
next3:
call void @call_target()
ret void
}
; CHECK-LABEL:<test_direct_call_with_padding_1>:
; Search for bundle alignment of first call.
; CHECK: {{[0-9a-f]*}}c: {{.+}} blx
; CHECK-NEXT: b
; CHECK-NEXT: b
; CHECK-NEXT: b
; CHECK-NEXT: movw [[REG:r[0-9]]], {{.+}} call_target
; CHECK-NEXT: movt [[REG]], {{.+}} call_target
; CHECK-NEXT: nop
; CHECK-NEXT: bic [[REG]], [[REG]], {{.+}} ; 0xc000000f
; CHECK-NEXT: blx r0
; CHECk-NEXT: {{[0-9a-f]*}}0:
; Same as above, but force bundle padding by adding two (branch) instruction
; before the tested call.
define internal void @test_direct_call_with_padding_2() {
entry:
call void @call_target()
; bundle aigned.
br label %next1 ; add 1 inst.
next1:
br label %next2 ; add 1 inst.
next2:
call void @call_target()
ret void
}
; CHECK-LABEL:<test_direct_call_with_padding_2>:
; Search for bundle alignment of first call.
; CHECK: {{[0-9a-f]*}}c: {{.+}} blx
; CHECK-NEXT: b
; CHECK-NEXT: b
; CHECK-NEXT: movw [[REG:r[0-9]]], {{.+}} call_target
; CHECK-NEXT: movt [[REG]], {{.+}} call_target
; CHECK-NEXT: nop
; CHECK-NEXT: nop
; CHECK-NEXT: bic [[REG]], [[REG]], {{.+}} ; 0xc000000f
; CHECK-NEXT: blx r0
; CHECk-NEXT: {{[0-9a-f]*}}0:
; Same as above, but force bundle padding by adding single (branch) instruction
; before the tested call.
define internal void @test_direct_call_with_padding_3() {
entry:
call void @call_target()
; bundle aigned.
br label %next ; add 1 inst.
next:
call void @call_target()
ret void
}
; CHECK-LABEL:<test_direct_call_with_padding_3>:
; Search for bundle alignment of first call.
; CHECK: {{[0-9a-f]*}}c: {{.+}} blx
; CHECK-NEXT: b
; CHECK-NEXT: movw [[REG:r[0-9]]], {{.+}} call_target
; CHECK-NEXT: movt [[REG]], {{.+}} call_target
; CHECK-NEXT: nop
; CHECK-NEXT: nop
; CHECK-NEXT: nop
; CHECK-NEXT: bic [[REG]], [[REG]], {{.+}} ; 0xc000000f
; CHECK-NEXT: blx r0
; CHECk-NEXT: {{[0-9a-f]*}}0:
; An indirect call sequence uses the right mask and register-call sequence. ; An indirect call sequence uses the right mask and register-call sequence.
define internal void @test_indirect_call(i32 %target) { define internal void @test_indirect_call(i32 %target) {
entry: entry:
%__1 = inttoptr i32 %target to void ()* %__1 = inttoptr i32 %target to void ()*
call void %__1() call void @call_target();
; bundle aigned.
br label %next ; add 1 inst.
next:
call void %__1() ; requires 3 insts.
ret void
}
; CHECK-LABEL:<test_indirect_call>:
; Search for bundle alignment of first call.
; CHECK: {{[0-9a-f]*}}c: {{.+}} blx
; CHECK-NEXT: b
; CHECK-NEXT: ldr
; CHECK-NEXT: bic [[REG:r[0-3]]], [[REG]], {{.*}} 0xc000000f
; CHECK-NEXT: blx [[REG]]
; CHECk-NEXT: {{[0-9]+}}0:
; An indirect call sequence uses the right mask and register-call sequence.
; Forces bundling before the tested call.
define internal void @test_indirect_call_with_padding_1(i32 %target) {
entry:
%__1 = inttoptr i32 %target to void ()*
call void @call_target();
; bundle aigned.
call void %__1() ; requires 3 insts.
ret void ret void
} }
; CHECK-LABEL: test_indirect_call
; CHECK: sub sp, ; CHECK-LABEL: <test_indirect_call_with_padding_1>:
; CHECK: bic sp, sp, {{.*}} ; 0xc0000000 ; Search for bundle alignment of first call.
; CHECK-NOT: bic sp, sp, {{.*}} ; 0xc0000000 ; CHECK: {{[0-9a-f]*}}c: {{.+}} blx
; CHECK: ldr [[REG:r[0-9]+]], [sp, ; CHECK-NEXT: ldr
; CHECK-NEXT: nop ; CHECK-NEXT: nop
; CHECK: {{[0-9]+}}8: {{.*}} bic [[REG:r[0-9]+]], [[REG]], {{.*}} 0xc000000f ; CHECK-NEXT: bic [[REG:r[0-3]]], [[REG]], {{.*}} 0xc000000f
; CHECK-NEXT: blx [[REG]] ; CHECK-NEXT: blx [[REG]]
; CHECk-NEXT: {{[0-9]+}}0: ; CHECk-NEXT: {{[0-9]+}}0:
; A return sequences uses the right pop / mask / jmp sequence. ; An indirect call sequence uses the right mask and register-call sequence.
define internal void @test_ret() { ; Forces bundling by adding three (branch) instructions befor the tested call.
define internal void @test_indirect_call_with_padding_2(i32 %target) {
entry: entry:
%__1 = inttoptr i32 %target to void ()*
call void @call_target();
; bundle aigned.
br label %next1 ; add 1 inst.
next1:
br label %next2 ; add 1 inst.
next2:
br label %next3 ; add 1 inst.
next3:
call void %__1() ; requires 3 insts.
ret void ret void
} }
; CHECK-LABEL: test_ret
; CHECK: 0: {{.*}} bic lr, lr, {{.*}} 0xc000000f
; CHECK-NEXT: bx lr
; Bundle lock without padding. ; CHECK-LABEL: <test_indirect_call_with_padding_2>:
define internal void @bundle_lock_without_padding() { ; Search for bundle alignment of first call.
; CHECK: {{[0-9a-f]*}}c: {{.+}} blx
; CHECK-NEXT: b
; CHECK-NEXT: b
; CHECK-NEXT: b
; CHECK-NEXT: ldr
; CHECK-NEXT: nop
; CHECK-NEXT: nop
; CHECK-NEXT: bic [[REG:r[0-3]]], [[REG]], {{.*}} 0xc000000f
; CHECK-NEXT: blx [[REG]]
; CHECk-NEXT: {{[0-9]+}}0:
; An indirect call sequence uses the right mask and register-call sequence.
; Forces bundling by adding two (branch) instructions befor the tested call.
define internal void @test_indirect_call_with_padding_3(i32 %target) {
entry: entry:
%addr_short = bitcast [2 x i8]* @global_short to i16* %__1 = inttoptr i32 %target to void ()*
store i16 0, i16* %addr_short, align 1 call void @call_target();
; bundle aigned.
br label %next1 ; add 1 inst
next1:
br label %next2 ; add 1 inst
next2:
call void %__1() ; requires 3 insts.
ret void ret void
} }
; CHECK-LABEL: bundle_lock_without_padding ; CHECK-LABEL: <test_indirect_call_with_padding_3>:
; CHECK: 0: {{.*}} movw ; Search for bundle alignment of first call.
; CHECK-NEXT: movt ; CHECK: {{[0-9a-f]*}}c: {{.+}} blx
; CHECK-NEXT: mov ; CHECK-NEXT: b
; CHECK-NEXT: b
; CHECK-NEXT: ldr
; CHECK-NEXT: nop ; CHECK-NEXT: nop
; CHECK-NEXT: bic [[REG:r[0-9]+]], {{.*}} 0xc0000000 ; CHECK-NEXT: nop
; CHECK-NEXT: strh {{.*}}, {{[[]}}[[REG]] ; CHECK-NEXT: nop
; CHECK-NEXT: bic lr, lr, {{.*}} ; 0xc000000f ; CHECK-NEXT: bic [[REG:r[0-3]]], [[REG]], {{.*}} 0xc000000f
; CHECK-NEXT: {{.*}} bx lr ; CHECK-NEXT: blx [[REG]]
; CHECk-NEXT: {{[0-9]+}}0:
; Bundle lock with padding. ; A return sequences uses the right pop / mask / jmp sequence.
define internal void @bundle_lock_with_padding() { define internal void @test_ret() {
entry: entry:
call void @call_target() call void @call_target()
; bundle boundary ; Bundle boundary.
store i16 0, i16* undef, align 1 ; 3 insts br label %next ; add 1 inst.
store i16 0, i16* undef, align 1 ; 3 insts next:
store i16 0, i16* undef, align 1 ; 3 insts
; SP adjustment + pop
; nop
; bundle boundary
ret void ret void
} }
; CHECK-LABEL: bundle_lock_with_padding ; CHECK-LABEL:<test_ret>:
; CHECK: 48: {{.*}} pop ; Search for bundle alignment of first call.
; CHECK: {{[0-9a-f]*}}c: {{.+}} blx
; CHECK-NEXT: b
; CHECK-NEXT: add sp, sp
; CHECK-NEXT: bic sp, sp, {{.+}} ; 0xc0000000
; CHECK-NEXT: pop {lr}
; CHECK-NEXT: {{[0-9a-f]*}}0: {{.+}} bic lr, lr, {{.+}} ; 0xc000000f
; CHECK-NEXT: bx lr
; A return sequence with padding for bundle lock.
define internal void @test_ret_with_padding() {
call void @call_target()
; Bundle boundary.
ret void
}
; CHECK-LABEL:<test_ret_with_padding>:
; Search for bundle alignment of first call.
; CHECK: {{[0-9a-f]*}}c: {{.+}} blx
; CHECK-NEXT: add sp, sp
; CHECK-NEXT: bic sp, sp, {{.+}} ; 0xc0000000
; CHECK-NEXT: pop {lr}
; CHECK-NEXT: nop ; CHECK-NEXT: nop
; CHECK-NEXT: bic lr, {{.*}} 0xc000000f ; CHECK-NEXT: {{[0-9a-f]*}}0: {{.+}} bic lr, lr, {{.+}} ; 0xc000000f
; CHECK-NEXT: {{.*}} bx lr ; CHECK-NEXT: bx lr
; Bundle lock align_to_end without any padding. ; Store without bundle padding.
define internal void @bundle_lock_align_to_end_padding_0() { define internal void @test_store() {
entry: entry:
call void @call_target() call void @call_target()
; bundle boundary ; Bundle boundary
call void @call_target3(i32 1, i32 2, i32 3) store i16 1, i16* undef, align 1 ; 3 insts + bic.
; bundle boundary
ret void ret void
} }
; CHECK-LABEL: bundle_lock_align_to_end_padding_0
; CHECK: c: {{.*}} bl {{.*}} call_target ; CHECK-LABEL: test_store
; CHECK-NEXT: mov ; Search for call at end of bundle.
; CHECK-NEXT: mov ; CHECK: {{[0-9a-f]*}}c: {{.+}} blx
; CHECK-NEXT: mov [[REG:r[0-9]]], #0
; CHECK-NEXT: mov ; CHECK-NEXT: mov
; CHECK-NEXT: {{[0-9]+}}c: {{.*}} bl {{.*}} call_target3 ; CHECK-NEXT: bic [[REG]], [[REG]], {{.+}} ; 0xc0000000
; CHECK-NEXT: add sp ; CHECK-NEXT: strh r{{.+}}[[REG]]
; CHECK-NEXT: bic sp, {{.*}} 0xc0000000
; CHECK-NEXT: pop ; Store with bundle padding. Force padding by adding a single branch
; CHECK: {{[0-9]+}}0: {{.*}} bic lr, lr, {{.*}} 0xc000000f ; instruction.
; CHECK-NEXT: {{.*}} bx lr define internal void @test_store_with_padding() {
; Bundle lock align_to_end with one bunch of padding.
define internal void @bundle_lock_align_to_end_padding_1() {
entry: entry:
call void @call_target() call void @call_target()
; bundle boundary ; bundle boundary
call void @call_target2(i32 1, i32 2) br label %next ; add 1 inst.
; bundle boundary next:
store i16 0, i16* undef, align 1 ; 3 insts
ret void ret void
} }
; CHECK-LABEL: bundle_lock_align_to_end_padding_1 ; CHECK-LABEL: test_store_with_padding
; CHECK: {{[0-9]*}}c: {{.*}} bl {{.*}} call_target ; Search for call at end of bundle.
; CHECK-NEXT: mov ; CHECK: {{[0-9a-f]*}}c: {{.+}} blx
; CHECK-NEXT: b
; CHECK-NEXT: mov [[REG:r[0-9]]], #0
; CHECK-NEXT: mov ; CHECK-NEXT: mov
; CHECK-NEXT: nop ; CHECK-NEXT: nop
; CHECK-NEXT: bl {{.*}} call_target2 ; CHECK-NEXT: bic [[REG]], [[REG]], {{.+}} ; 0xc0000000
; CHECK: {{[0-9]+}}0: {{.*}} bic lr, lr, {{.*}} 0xc000000f ; CHECK-NEXT: strh r{{.+}}[[REG]]
; CHECK-NEXT: {{.*}} bx lr
; Bundle lock align_to_end with two bunches of padding.
define internal void @bundle_lock_align_to_end_padding_2() { ; Store without bundle padding.
define internal i32 @test_load() {
entry: entry:
call void @call_target2(i32 1, i32 2) call void @call_target()
; bundle boundary ; Bundle boundary
ret void %v = load i32, i32* undef, align 1 ; 4 insts, bundling middle 2.
ret i32 %v
} }
; CHECK-LABEL: bundle_lock_align_to_end_padding_2
; CHECK: mov ; CHECK-LABEL: test_load
; CHECK-NEXT: mov ; Search for call at end of bundle.
; CHECK-NEXT: nop ; CHECK: {{[0-9a-f]*}}c: {{.+}} blx
; CHECK-NEXT: mov [[REG:r[0-9]]], #0
; CHECK-NEXT: bic [[REG]], [[REG]], {{.+}} ; 0xc0000000
; CHECK-NEXT: ldr r{{.+}}[[REG]]
; Store with bundle padding.
define internal i32 @test_load_with_padding() {
entry:
call void @call_target()
; Bundle boundary
br label %next1 ; add 1 inst.
next1:
br label %next2 ; add 1 inst.
next2:
%v = load i32, i32* undef, align 1 ; 4 insts, bundling middle 2.
ret i32 %v
}
; CHECK-LABEL: test_load_with_padding
; Search for call at end of bundle.
; CHECK: {{[0-9a-f]*}}c: {{.+}} blx
; CHECK-NEXT: b
; CHECK-NEXT: b
; CHECK-NEXT: mov [[REG:r[0-9]]], #0
; CHECK-NEXT: nop ; CHECK-NEXT: nop
; CHECK-NEXT: bl {{.*}} call_target2 ; CHECK-NEXT: bic [[REG]], [[REG]], {{.+}} ; 0xc0000000
; CHECK-NEXT: ldr r{{.+}}[[REG]]
...@@ -26,10 +26,10 @@ ...@@ -26,10 +26,10 @@
define internal double @testVpushVpop(double %v1, double %v2) { define internal double @testVpushVpop(double %v1, double %v2) {
; ASM-LABEL: testVpushVpop: ; ASM-LABEL: testVpushVpop:
; DIS-LABEL: 00000000 <testVpushVpop>: ; DIS-LABEL: {{.+}} <testVpushVpop>:
; ASM: vpush {s18, s19, s20, s21} ; ASM: vpush {s18, s19, s20, s21}
; DIS: 0: ed2d9a04 ; DIS: {{.+}}: ed2d9a04
; IASM-NOT: vpush ; IASM-NOT: vpush
call void @foo() call void @foo()
...@@ -37,7 +37,7 @@ define internal double @testVpushVpop(double %v1, double %v2) { ...@@ -37,7 +37,7 @@ define internal double @testVpushVpop(double %v1, double %v2) {
ret double %res ret double %res
; ASM: vpop {s18, s19, s20, s21} ; ASM: vpop {s18, s19, s20, s21}
; DIS: 28: ecbd9a04 ; DIS: {{.+}}: ecbd9a04
; IASM-NOT: vpopd ; IASM-NOT: vpopd
} }
......
...@@ -10,18 +10,15 @@ ...@@ -10,18 +10,15 @@
; RUN: --target x8632 -i %s --args -Om1 -allow-externally-defined-symbols \ ; RUN: --target x8632 -i %s --args -Om1 -allow-externally-defined-symbols \
; RUN: | %if --need=target_X8632 --command FileCheck --check-prefix=OPTM1 %s ; RUN: | %if --need=target_X8632 --command FileCheck --check-prefix=OPTM1 %s
; TODO(jvoung): Stop skipping unimplemented parts (via --skip-unimplemented)
; once enough infrastructure is in. Also, switch to --filetype=obj
; when possible.
; RUN: %if --need=target_ARM32 --need=allow_dump \ ; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble \ ; RUN: --command %p2i --filetype=obj --assemble \
; RUN: --disassemble --target arm32 -i %s --args -O2 --skip-unimplemented \ ; RUN: --disassemble --target arm32 -i %s --args -O2 \
; RUN: -allow-externally-defined-symbols \ ; RUN: -allow-externally-defined-symbols \
; RUN: | %if --need=target_ARM32 --need=allow_dump \ ; RUN: | %if --need=target_ARM32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix ARM32 --check-prefix ARM32-O2 %s ; RUN: --command FileCheck --check-prefix ARM32 --check-prefix ARM32-O2 %s
; RUN: %if --need=target_ARM32 --need=allow_dump \ ; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble --disassemble --target arm32 \ ; RUN: --command %p2i --filetype=obj --assemble --disassemble --target arm32 \
; RUN: -i %s --args -Om1 --skip-unimplemented \ ; RUN: -i %s --args -Om1 \
; RUN: -allow-externally-defined-symbols \ ; RUN: -allow-externally-defined-symbols \
; RUN: | %if --need=target_ARM32 --need=allow_dump \ ; RUN: | %if --need=target_ARM32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix ARM32 --check-prefix ARM32-OM1 %s ; RUN: --command FileCheck --check-prefix ARM32 --check-prefix ARM32-OM1 %s
...@@ -102,18 +99,24 @@ entry: ...@@ -102,18 +99,24 @@ entry:
; ARM32-LABEL: pass64BitArg ; ARM32-LABEL: pass64BitArg
; ARM32: str {{.*}}, [sp] ; ARM32: str {{.*}}, [sp]
; ARM32: movw [[CALL:r[0-9]]], {{.+}} ignore64BitArgNoInline
; ARM32: movt [[CALL]], {{.+}} ignore64BitArgNoInline
; ARM32: mov r2, #123 ; ARM32: mov r2, #123
; ARM32: bl {{.*}} ignore64BitArgNoInline ; ARM32: blx [[CALL]]
; ARM32: str {{.*}}, [sp] ; ARM32: str {{.*}}, [sp]
; ARM32: movw [[CALL:r[0-9]]], {{.+}} ignore64BitArgNoInline
; ARM32: movt [[CALL]], {{.+}} ignore64BitArgNoInline
; ARM32: {{mov|ldr}} r0 ; ARM32: {{mov|ldr}} r0
; ARM32: {{mov|ldr}} r1 ; ARM32: {{mov|ldr}} r1
; ARM32: mov r2, #123 ; ARM32: mov r2, #123
; ARM32: bl {{.*}} ignore64BitArgNoInline ; ARM32: blx [[CALL]]
; ARM32: str {{.*}}, [sp] ; ARM32: str {{.*}}, [sp]
; ARM32: movw [[CALL:r[0-9]]], {{.+}} ignore64BitArgNoInline
; ARM32: movt [[CALL]], {{.+}} ignore64BitArgNoInline
; ARM32: {{mov|ldr}} r0 ; ARM32: {{mov|ldr}} r0
; ARM32: {{mov|ldr}} r1 ; ARM32: {{mov|ldr}} r1
; ARM32: mov r2, #123 ; ARM32: mov r2, #123
; ARM32: bl {{.*}} ignore64BitArgNoInline ; ARM32: blx [[CALL]]
; MIPS32-LABEL: pass64BitArg ; MIPS32-LABEL: pass64BitArg
...@@ -155,10 +158,13 @@ entry: ...@@ -155,10 +158,13 @@ entry:
; ARM32: movt [[REG2]], {{.*}} ; 0x1234 ; ARM32: movt [[REG2]], {{.*}} ; 0x1234
; ARM32: str [[REG1]], [sp, #4] ; ARM32: str [[REG1]], [sp, #4]
; ARM32: str [[REG2]], [sp] ; ARM32: str [[REG2]], [sp]
; ARM32: movw [[CALL:r[0-9]]], {{.+}} ignore64BitArgNoInline
; ARM32: movt [[CALL]], {{.+}} ignore64BitArgNoInline
; ARM32: {{mov|ldr}} r0 ; ARM32: {{mov|ldr}} r0
; ARM32: {{mov|ldr}} r1 ; ARM32: {{mov|ldr}} r1
; ARM32: mov r2, #123 ; ARM32: mov r2, #123
; ARM32: bl {{.*}} ignore64BitArgNoInline ; ARM32: blx [[CALL]]
define internal i32 @pass64BitUndefArg() { define internal i32 @pass64BitUndefArg() {
entry: entry:
...@@ -179,8 +185,10 @@ entry: ...@@ -179,8 +185,10 @@ entry:
; ARM32: sub sp ; ARM32: sub sp
; ARM32: mov {{.*}}, #0 ; ARM32: mov {{.*}}, #0
; ARM32: str ; ARM32: str
; ARM32: movw [[CALL:r[0-9]]], {{.+}} ignore64BitArgNoInline
; ARM32: movt [[CALL]], {{.+}} ignore64BitArgNoInline
; ARM32: mov {{.*}}, #123 ; ARM32: mov {{.*}}, #123
; ARM32: bl {{.*}} ignore64BitArgNoInline ; ARM32: blx [[CALL]]
; MIPS32-LABEL: pass64BitUndefArg ; MIPS32-LABEL: pass64BitUndefArg
; MIPS32: jr ra ; MIPS32: jr ra
...@@ -388,7 +396,9 @@ entry: ...@@ -388,7 +396,9 @@ entry:
; ARM32-LABEL: div64BitSigned ; ARM32-LABEL: div64BitSigned
; ARM32: orrs {{r.*}}, {{r.*}} ; ARM32: orrs {{r.*}}, {{r.*}}
; ARM32: bne ; ARM32: bne
; ARM32: bl {{.*}} __divdi3 ; ARM32: movw [[CALL:r[0-9]]], {{.+}} __divdi3
; ARM32: movt [[CALL]], {{.+}} __divdi3
; ARM32: blx [[CALL]]
define internal i64 @div64BitSignedConst(i64 %a) { define internal i64 @div64BitSignedConst(i64 %a) {
entry: entry:
...@@ -408,10 +418,12 @@ entry: ...@@ -408,10 +418,12 @@ entry:
; ARM32-LABEL: div64BitSignedConst ; ARM32-LABEL: div64BitSignedConst
; For a constant, we should be able to optimize-out the divide by zero check. ; For a constant, we should be able to optimize-out the divide by zero check.
; ARM32-NOT: orrs ; ARM32-NOT: orrs
; ARM32: movw [[CALL:r[0-9]]], {{.+}} __divdi3
; ARM32: movt [[CALL]], {{.+}} __divdi3
; ARM32: movw {{.*}} ; 0x2ff2 ; ARM32: movw {{.*}} ; 0x2ff2
; ARM32: movt {{.*}} ; 0x73ce ; ARM32: movt {{.*}} ; 0x73ce
; ARM32: movw {{.*}} ; 0xb3a ; ARM32: movw {{.*}} ; 0xb3a
; ARM32: bl {{.*}} __divdi3 ; ARM32: blx [[CALL]]
define internal i64 @div64BitUnsigned(i64 %a, i64 %b) { define internal i64 @div64BitUnsigned(i64 %a, i64 %b) {
entry: entry:
...@@ -427,7 +439,9 @@ entry: ...@@ -427,7 +439,9 @@ entry:
; ARM32-LABEL: div64BitUnsigned ; ARM32-LABEL: div64BitUnsigned
; ARM32: orrs {{r.*}}, {{r.*}} ; ARM32: orrs {{r.*}}, {{r.*}}
; ARM32: bne ; ARM32: bne
; ARM32: bl {{.*}} __udivdi3 ; ARM32: movw [[CALL:r[0-9]]], {{.+}} __udivdi3
; ARM32: movt [[CALL]], {{.+}} __udivdi3
; ARM32: blx [[CALL]]
define internal i64 @rem64BitSigned(i64 %a, i64 %b) { define internal i64 @rem64BitSigned(i64 %a, i64 %b) {
entry: entry:
...@@ -443,7 +457,9 @@ entry: ...@@ -443,7 +457,9 @@ entry:
; ARM32-LABEL: rem64BitSigned ; ARM32-LABEL: rem64BitSigned
; ARM32: orrs {{r.*}}, {{r.*}} ; ARM32: orrs {{r.*}}, {{r.*}}
; ARM32: bne ; ARM32: bne
; ARM32: bl {{.*}} __moddi3 ; ARM32: movw [[CALL:r[0-9]]], {{.+}} __moddi3
; ARM32: movt [[CALL]], {{.+}} __moddi3
; ARM32: blx [[CALL]]
define internal i64 @rem64BitUnsigned(i64 %a, i64 %b) { define internal i64 @rem64BitUnsigned(i64 %a, i64 %b) {
entry: entry:
...@@ -459,7 +475,9 @@ entry: ...@@ -459,7 +475,9 @@ entry:
; ARM32-LABEL: rem64BitUnsigned ; ARM32-LABEL: rem64BitUnsigned
; ARM32: orrs {{r.*}}, {{r.*}} ; ARM32: orrs {{r.*}}, {{r.*}}
; ARM32: bne ; ARM32: bne
; ARM32: bl {{.*}} __umoddi3 ; ARM32: movw [[CALL:r[0-9]]], {{.+}} __umoddi3
; ARM32: movt [[CALL]], {{.+}} __umoddi3
; ARM32: blx [[CALL]]
define internal i64 @shl64BitSigned(i64 %a, i64 %b) { define internal i64 @shl64BitSigned(i64 %a, i64 %b) {
entry: entry:
...@@ -1122,12 +1140,16 @@ if.end3: ; preds = %if.then2, %if.end ...@@ -1122,12 +1140,16 @@ if.end3: ; preds = %if.then2, %if.end
; ARM32: cmpeq ; ARM32: cmpeq
; ARM32-OM1: tst ; ARM32-OM1: tst
; ARM32: bne ; ARM32: bne
; ARM32: bl {{.*}} <func> ; ARM32: movw [[CALL:r[0-9]]], {{.+}} func
; ARM32: movt [[CALL]], {{.+}} func
; ARM32: blx [[CALL]]
; ARM32: cmp ; ARM32: cmp
; ARM32: cmpeq ; ARM32: cmpeq
; ARM32-OM1: tst ; ARM32-OM1: tst
; ARM32: bne ; ARM32: bne
; ARM32: bl {{.*}} <func> ; ARM32: movw [[CALL:r[0-9]]], {{.+}} func
; ARM32: movt [[CALL]], {{.+}} func
; ARM32: blx [[CALL]]
; ARM32: bx ; ARM32: bx
declare void @func() declare void @func()
...@@ -1192,7 +1214,9 @@ if.end3: ; preds = %if.end, %if.then2 ...@@ -1192,7 +1214,9 @@ if.end3: ; preds = %if.end, %if.then2
; ARM32-OM1: tst ; ARM32-OM1: tst
; ARM32-OM1: bne ; ARM32-OM1: bne
; ARM32-O2: beq ; ARM32-O2: beq
; ARM32: bl {{.*}} <func> ; ARM32: movw [[CALL:r[0-9]]], {{.+}} func
; ARM32: movt [[CALL]], {{.+}} func
; ARM32: blx [[CALL]]
; ARM32: cmp ; ARM32: cmp
; ARM32: cmpeq ; ARM32: cmpeq
; ARM32-OM1: tst ; ARM32-OM1: tst
......
...@@ -9,19 +9,16 @@ ...@@ -9,19 +9,16 @@
; RUN: | %if --need=target_X8632 --command FileCheck \ ; RUN: | %if --need=target_X8632 --command FileCheck \
; RUN: --check-prefix CHECK-OPTM1 %s ; RUN: --check-prefix CHECK-OPTM1 %s
; TODO(jvoung): Stop skipping unimplemented parts (via --skip-unimplemented)
; once enough infrastructure is in. Also, switch to --filetype=obj
; when possible.
; RUN: %if --need=target_ARM32 --need=allow_dump \ ; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble \ ; RUN: --command %p2i --filetype=obj --assemble \
; RUN: --disassemble --target arm32 -i %s --args -O2 --skip-unimplemented \ ; RUN: --disassemble --target arm32 -i %s --args -O2 \
; RUN: -allow-externally-defined-symbols \ ; RUN: -allow-externally-defined-symbols \
; RUN: | %if --need=target_ARM32 --need=allow_dump \ ; RUN: | %if --need=target_ARM32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix ARM32 --check-prefix=ARM-OPT2 %s ; RUN: --command FileCheck --check-prefix ARM32 --check-prefix=ARM-OPT2 %s
; RUN: %if --need=target_ARM32 --need=allow_dump \ ; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble \ ; RUN: --command %p2i --filetype=obj --assemble \
; RUN: --disassemble --target arm32 -i %s --args -Om1 --skip-unimplemented \ ; RUN: --disassemble --target arm32 -i %s --args -Om1 \
; RUN: -allow-externally-defined-symbols \ ; RUN: -allow-externally-defined-symbols \
; RUN: | %if --need=target_ARM32 --need=allow_dump \ ; RUN: | %if --need=target_ARM32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix ARM32 --check-prefix=ARM-OPTM1 %s ; RUN: --command FileCheck --check-prefix ARM32 --check-prefix=ARM-OPTM1 %s
...@@ -48,7 +45,9 @@ entry: ...@@ -48,7 +45,9 @@ entry:
; ARM32-LABEL: fixed_416_align_16 ; ARM32-LABEL: fixed_416_align_16
; ARM32-OPT2: sub sp, sp, #428 ; ARM32-OPT2: sub sp, sp, #428
; ARM32-OPTM1: sub sp, sp, #416 ; ARM32-OPTM1: sub sp, sp, #416
; ARM32: bl {{.*}} R_{{.*}} f1 ; ARM32: movw [[CALL:r[0-9]]], {{.+}} f1
; ARM32: movt [[CALL]], {{.+}} f1
; ARM32: blx [[CALL]]
define internal void @fixed_416_align_32(i32 %n) { define internal void @fixed_416_align_32(i32 %n) {
entry: entry:
...@@ -70,7 +69,9 @@ entry: ...@@ -70,7 +69,9 @@ entry:
; ARM32-OPT2: sub sp, sp, #424 ; ARM32-OPT2: sub sp, sp, #424
; ARM32-OPTM1: sub sp, sp, #416 ; ARM32-OPTM1: sub sp, sp, #416
; ARM32: bic sp, sp, #31 ; ARM32: bic sp, sp, #31
; ARM32: bl {{.*}} R_{{.*}} f1 ; ARM32: movw [[CALL:r[0-9]]], {{.+}} f1
; ARM32: movt [[CALL]], {{.+}} f1
; ARM32: blx [[CALL]]
; Show that the amount to allocate will be rounded up. ; Show that the amount to allocate will be rounded up.
define internal void @fixed_351_align_16(i32 %n) { define internal void @fixed_351_align_16(i32 %n) {
...@@ -95,7 +96,9 @@ entry: ...@@ -95,7 +96,9 @@ entry:
; ARM32-LABEL: fixed_351_align_16 ; ARM32-LABEL: fixed_351_align_16
; ARM32-OPT2: sub sp, sp, #364 ; ARM32-OPT2: sub sp, sp, #364
; ARM32-OPTM1: sub sp, sp, #352 ; ARM32-OPTM1: sub sp, sp, #352
; ARM32: bl {{.*}} R_{{.*}} f1 ; ARM32: movw [[CALL:r[0-9]]], {{.+}} f1
; ARM32: movt [[CALL]], {{.+}} f1
; ARM32: blx [[CALL]]
define internal void @fixed_351_align_32(i32 %n) { define internal void @fixed_351_align_32(i32 %n) {
entry: entry:
...@@ -117,7 +120,9 @@ entry: ...@@ -117,7 +120,9 @@ entry:
; ARM32-OPT2: sub sp, sp, #360 ; ARM32-OPT2: sub sp, sp, #360
; ARM32-OPTM1: sub sp, sp, #352 ; ARM32-OPTM1: sub sp, sp, #352
; ARM32: bic sp, sp, #31 ; ARM32: bic sp, sp, #31
; ARM32: bl {{.*}} R_{{.*}} f1 ; ARM32: movw [[CALL:r[0-9]]], {{.+}} f1
; ARM32: movt [[CALL]], {{.+}} f1
; ARM32: blx [[CALL]]
declare void @f1(i32 %ignored) declare void @f1(i32 %ignored)
...@@ -144,7 +149,9 @@ entry: ...@@ -144,7 +149,9 @@ entry:
; ARM32: add r0, r0, #15 ; ARM32: add r0, r0, #15
; ARM32: bic r0, r0, #15 ; ARM32: bic r0, r0, #15
; ARM32: sub sp, sp, r0 ; ARM32: sub sp, sp, r0
; ARM32: bl {{.*}} R_{{.*}} f2 ; ARM32: movw [[CALL:r[0-9]]], {{.+}} f2
; ARM32: movt [[CALL]], {{.+}} f2
; ARM32: blx [[CALL]]
define internal void @variable_n_align_32(i32 %n) { define internal void @variable_n_align_32(i32 %n) {
entry: entry:
...@@ -176,7 +183,9 @@ entry: ...@@ -176,7 +183,9 @@ entry:
; ARM32: add r0, r0, #31 ; ARM32: add r0, r0, #31
; ARM32: bic r0, r0, #31 ; ARM32: bic r0, r0, #31
; ARM32: sub sp, sp, r0 ; ARM32: sub sp, sp, r0
; ARM32: bl {{.*}} R_{{.*}} f2 ; ARM32: movw [[CALL:r[0-9]]], {{.+}} f2
; ARM32: movt [[CALL]], {{.+}} f2
; ARM32: blx [[CALL]]
; ARM32: mov sp, fp ; ARM32: mov sp, fp
; ARM32: pop {fp, lr} ; ARM32: pop {fp, lr}
......
...@@ -4,28 +4,28 @@ ...@@ -4,28 +4,28 @@
; RUN: --target x8632 -i %s --args -O2 \ ; RUN: --target x8632 -i %s --args -O2 \
; RUN: | %if --need=target_X8632 --command FileCheck %s ; RUN: | %if --need=target_X8632 --command FileCheck %s
; TODO(jvoung): Stop skipping unimplemented parts (via --skip-unimplemented)
; once enough infrastructure is in. Also, switch to --filetype=obj
; when possible.
; RUN: %if --need=target_ARM32 --need=allow_dump \ ; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble --disassemble --target arm32 \ ; RUN: --command %p2i --filetype=obj --assemble --disassemble --target arm32 \
; RUN: -i %s --args -O2 --skip-unimplemented \ ; RUN: -i %s --args -O2 \
; RUN: | %if --need=target_ARM32 --need=allow_dump \ ; RUN: | %if --need=target_ARM32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix ARM32 --check-prefix ARM-OPT2 %s ; RUN: --command FileCheck --check-prefix ARM32 --check-prefix ARM-OPT2 %s
; RUN: %if --need=target_ARM32 --need=allow_dump \ ; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble --disassemble --target arm32 \ ; RUN: --command %p2i --filetype=obj --assemble --disassemble --target arm32 \
; RUN: -i %s --args -O2 --mattr=hwdiv-arm --skip-unimplemented \ ; RUN: -i %s --args -O2 --mattr=hwdiv-arm \
; RUN: | %if --need=target_ARM32 --need=allow_dump \ ; RUN: | %if --need=target_ARM32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix ARM32HWDIV %s ; RUN: --command FileCheck --check-prefix ARM32HWDIV %s
; RUN: %if --need=target_ARM32 --need=allow_dump \ ; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble --disassemble --target arm32 \ ; RUN: --command %p2i --filetype=obj --assemble --disassemble --target arm32 \
; RUN: -i %s --args -Om1 --skip-unimplemented \ ; RUN: -i %s --args -Om1 \
; RUN: | %if --need=target_ARM32 --need=allow_dump \ ; RUN: | %if --need=target_ARM32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix ARM32 --check-prefix ARM32-OPTM1 %s ; RUN: --command FileCheck --check-prefix ARM32 --check-prefix ARM32-OPTM1 %s
; ;
; TODO(kschimpf): Stop skipping unimplemented parts (via --skip-unimplemented)
; once enough infrastructure is in. Also, switch to --filetype=obj
; when possible.
; RUN: %if --need=target_MIPS32 --need=allow_dump \ ; RUN: %if --need=target_MIPS32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble --disassemble --target mips32\ ; RUN: --command %p2i --filetype=asm --assemble --disassemble --target mips32\
; RUN: -i %s --args -O2 --skip-unimplemented \ ; RUN: -i %s --args -O2 -skip-unimplemented \
; RUN: | %if --need=target_MIPS32 --need=allow_dump \ ; RUN: | %if --need=target_MIPS32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix MIPS32 %s ; RUN: --command FileCheck --check-prefix MIPS32 %s
...@@ -162,8 +162,11 @@ entry: ...@@ -162,8 +162,11 @@ entry:
; ARM32-LABEL: Sdiv ; ARM32-LABEL: Sdiv
; ARM32: tst [[DENOM:r.*]], [[DENOM]] ; ARM32: tst [[DENOM:r.*]], [[DENOM]]
; ARM32: bne ; ARM32: bne
; ARM32: .word 0xe7fedef0 ; AARM32: .word 0xe7fedef0
; ARM32: {{.*}} bl {{.*}} __divsi3 ; ARM32: udf #60896 ; 0xede0
; ARM32: movw [[CALL:r[0-9]]], {{.+}} __divsi3
; ARM32: movt [[CALL]], {{.+}} __divsi3
; ARM32: blx [[CALL]]
; ARM32HWDIV-LABEL: Sdiv ; ARM32HWDIV-LABEL: Sdiv
; ARM32HWDIV: tst ; ARM32HWDIV: tst
; ARM32HWDIV: bne ; ARM32HWDIV: bne
...@@ -182,7 +185,9 @@ entry: ...@@ -182,7 +185,9 @@ entry:
; ;
; ARM32-LABEL: SdivConst ; ARM32-LABEL: SdivConst
; ARM32-NOT: tst ; ARM32-NOT: tst
; ARM32: bl {{.*}} __divsi3 ; ARM32: movw [[CALL:r[0-9]]], {{.+}} __divsi3
; ARM32: movt [[CALL]], {{.+}} __divsi3
; ARM32: blx [[CALL]]
; ARM32HWDIV-LABEL: SdivConst ; ARM32HWDIV-LABEL: SdivConst
; ARM32HWDIV-NOT: tst ; ARM32HWDIV-NOT: tst
; ARM32HWDIV: sdiv ; ARM32HWDIV: sdiv
...@@ -201,7 +206,9 @@ entry: ...@@ -201,7 +206,9 @@ entry:
; ARM32-LABEL: Srem ; ARM32-LABEL: Srem
; ARM32: tst [[DENOM:r.*]], [[DENOM]] ; ARM32: tst [[DENOM:r.*]], [[DENOM]]
; ARM32: bne ; ARM32: bne
; ARM32: bl {{.*}} __modsi3 ; ARM32: movw [[CALL:r[0-9]]], {{.+}} __modsi3
; ARM32: movt [[CALL]], {{.+}} __modsi3
; ARM32: blx [[CALL]]
; ARM32HWDIV-LABEL: Srem ; ARM32HWDIV-LABEL: Srem
; ARM32HWDIV: tst ; ARM32HWDIV: tst
; ARM32HWDIV: bne ; ARM32HWDIV: bne
...@@ -221,7 +228,9 @@ entry: ...@@ -221,7 +228,9 @@ entry:
; ARM32-LABEL: Udiv ; ARM32-LABEL: Udiv
; ARM32: tst [[DENOM:r.*]], [[DENOM]] ; ARM32: tst [[DENOM:r.*]], [[DENOM]]
; ARM32: bne ; ARM32: bne
; ARM32: bl {{.*}} __udivsi3 ; ARM32: movw [[CALL:r[0-9]]], {{.+}} __udivsi3
; ARM32: movt [[CALL]], {{.+}} __udivsi3
; ARM32: blx [[CALL]]
; ARM32HWDIV-LABEL: Udiv ; ARM32HWDIV-LABEL: Udiv
; ARM32HWDIV: tst ; ARM32HWDIV: tst
; ARM32HWDIV: bne ; ARM32HWDIV: bne
...@@ -240,7 +249,9 @@ entry: ...@@ -240,7 +249,9 @@ entry:
; ARM32-LABEL: Urem ; ARM32-LABEL: Urem
; ARM32: tst [[DENOM:r.*]], [[DENOM]] ; ARM32: tst [[DENOM:r.*]], [[DENOM]]
; ARM32: bne ; ARM32: bne
; ARM32: bl {{.*}} __umodsi3 ; ARM32: movw [[CALL:r[0-9]]], {{.+}} __umodsi3
; ARM32: movt [[CALL]], {{.+}} __umodsi3
; ARM32: blx [[CALL]]
; ARM32HWDIV-LABEL: Urem ; ARM32HWDIV-LABEL: Urem
; ARM32HWDIV: tst ; ARM32HWDIV: tst
; ARM32HWDIV: bne ; ARM32HWDIV: bne
......
...@@ -55,7 +55,9 @@ branch2: ...@@ -55,7 +55,9 @@ branch2:
; CHECK: jge ; CHECK: jge
; ARM32-LABEL: fold_cmp_br_intervening_insts ; ARM32-LABEL: fold_cmp_br_intervening_insts
; ARM32: push {{[{].*[}]}} ; ARM32: push {{[{].*[}]}}
; ARM32: bl use_value ; ARM32: movw [[CALL:r[0-9]]], #:lower16:use_value
; ARM32: movt [[CALL]], #:upper16:use_value
; ARM32: blx [[CALL]]
; ARM32: cmp {{r[0-9]+}}, {{r[0-9]+}} ; ARM32: cmp {{r[0-9]+}}, {{r[0-9]+}}
; ARM32: bge ; ARM32: bge
; ARM32: mov r0, #1 ; ARM32: mov r0, #1
...@@ -190,7 +192,9 @@ entry: ...@@ -190,7 +192,9 @@ entry:
; CHECK: cmp ; CHECK: cmp
; CHECK: cmovl ; CHECK: cmovl
; ARM32-LABEL: fold_cmp_select_intervening_insts ; ARM32-LABEL: fold_cmp_select_intervening_insts
; ARM32: bl use_value ; ARM32: movw [[CALL:r[0-9]]], #:lower16:use_value
; ARM32: movt [[CALL]], #:upper16:use_value
; ARM32: blx [[CALL]]
; ARM32: cmp r{{[0-9]+}}, r{{[0-9]+}} ; ARM32: cmp r{{[0-9]+}}, r{{[0-9]+}}
; ARM32: movlt ; ARM32: movlt
; ARM32: bx lr ; ARM32: bx lr
......
...@@ -9,18 +9,15 @@ ...@@ -9,18 +9,15 @@
; RUN: --target x8632 -i %s --args -Om1 -allow-externally-defined-symbols \ ; RUN: --target x8632 -i %s --args -Om1 -allow-externally-defined-symbols \
; RUN: | %if --need=target_X8632 --command FileCheck --check-prefix=OM1 %s ; RUN: | %if --need=target_X8632 --command FileCheck --check-prefix=OM1 %s
; TODO(jvoung): Stop skipping unimplemented parts (via --skip-unimplemented)
; once enough infrastructure is in. Also, switch to --filetype=obj
; when possible.
; RUN: %if --need=target_ARM32 --need=allow_dump \ ; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble \ ; RUN: --command %p2i --filetype=obj --assemble \
; RUN: --disassemble --target arm32 -i %s --args -O2 \ ; RUN: --disassemble --target arm32 -i %s --args -O2 \
; RUN: -allow-externally-defined-symbols \ ; RUN: -allow-externally-defined-symbols \
; RUN: | %if --need=target_ARM32 --need=allow_dump \ ; RUN: | %if --need=target_ARM32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix ARM32O2 %s ; RUN: --command FileCheck --check-prefix ARM32O2 %s
; RUN: %if --need=target_ARM32 --need=allow_dump \ ; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble \ ; RUN: --command %p2i --filetype=obj --assemble \
; RUN: --disassemble --target arm32 -i %s --args -Om1 \ ; RUN: --disassemble --target arm32 -i %s --args -Om1 \
; RUN: -allow-externally-defined-symbols \ ; RUN: -allow-externally-defined-symbols \
; RUN: | %if --need=target_ARM32 --need=allow_dump \ ; RUN: | %if --need=target_ARM32 --need=allow_dump \
...@@ -51,13 +48,22 @@ next: ...@@ -51,13 +48,22 @@ next:
; OM1: call ; OM1: call
; ARM32O2-LABEL: testUncondToNextBlock ; ARM32O2-LABEL: testUncondToNextBlock
; ARM32O2: bl {{.*}} dummy ; ARM32O2: movw {{.+}} dummy
; ARM32O2-NEXT: bl {{.*}} dummy ; ARM32O2-NEXT: movt
; ARM32O2-NEXT: blx
; ARM32O2-NEXT: movw {{.+}} dummy
; ARM32O2-NEXT: movt
; ARM32O2-NEXT: blx
; ARM32OM1-LABEL: testUncondToNextBlock ; ARM32OM1-LABEL: testUncondToNextBlock
; ARM32OM1: bl {{.*}} dummy ; ARM32OM1: movw {{.+}} dummy
; ARM32OM1-NEXT: movt
; ARM32OM1-NEXT: blx
; ARM32OM1-NEXT: b ; ARM32OM1-NEXT: b
; ARM32OM1-NEXT: bl {{.*}} dummy ; ARM32OM1-NEXT: movw {{.+}} dummy
; ARM32OM1-NEXT: movt
; ARM32OM1-NEXT: blx
; For a conditional branch with a fallthrough to the next block, the ; For a conditional branch with a fallthrough to the next block, the
; fallthrough branch should be removed. ; fallthrough branch should be removed.
...@@ -95,9 +101,13 @@ target: ...@@ -95,9 +101,13 @@ target:
; ARM32O2-LABEL: testCondFallthroughToNextBlock ; ARM32O2-LABEL: testCondFallthroughToNextBlock
; ARM32O2: cmp {{.*}}, #123 ; ARM32O2: cmp {{.*}}, #123
; ARM32O2-NEXT: bge ; ARM32O2-NEXT: bge
; ARM32O2-NEXT: bl ; ARM32O2-NEXT: movw {{.+}} dummy
; ARM32O2-NEXT: movt
; ARM32O2-NEXT: blx
; ARM32O2: bx lr ; ARM32O2: bx lr
; ARM32O2: bl ; ARM32O2-NEXT: movw {{.+}} dummy
; ARM32O2-NEXT: movt
; ARM32O2-NEXT: blx
; ARM32O2: bx lr ; ARM32O2: bx lr
; ARM32OM1-LABEL: testCondFallthroughToNextBlock ; ARM32OM1-LABEL: testCondFallthroughToNextBlock
...@@ -107,9 +117,13 @@ target: ...@@ -107,9 +117,13 @@ target:
; ARM32OM1: tst {{.*}}, #1 ; ARM32OM1: tst {{.*}}, #1
; ARM32OM1: bne ; ARM32OM1: bne
; ARM32OM1: b ; ARM32OM1: b
; ARM32OM1: bl ; ARM32OM1: movw
; ARM32OM1: movt
; ARM32OM1: blx
; ARM32OM1: bx lr ; ARM32OM1: bx lr
; ARM32OM1: bl ; ARM32OM1: movw
; ARM32OM1: movt
; ARM32OM1: blx
; ARM32OM1: bx lr ; ARM32OM1: bx lr
; For a conditional branch with the next block as the target and a ; For a conditional branch with the next block as the target and a
...@@ -152,9 +166,13 @@ target: ...@@ -152,9 +166,13 @@ target:
; ARM32O2-LABEL: testCondTargetNextBlock ; ARM32O2-LABEL: testCondTargetNextBlock
; ARM32O2: cmp {{.*}}, #123 ; ARM32O2: cmp {{.*}}, #123
; ARM32O2-NEXT: blt ; ARM32O2-NEXT: blt
; ARM32O2-NEXT: bl ; ARM32O2-NEXT: movw
; ARM32O2-NEXT: movt
; ARM32O2-NEXT: blx
; ARM32O2: bx lr ; ARM32O2: bx lr
; ARM32O2: bl ; ARM32O2-NEXT: movw
; ARM32O2-NEXT: movt
; ARM32O2-NEXT: blx
; ARM32O2: bx lr ; ARM32O2: bx lr
; ARM32OM1-LABEL: testCondTargetNextBlock ; ARM32OM1-LABEL: testCondTargetNextBlock
...@@ -163,9 +181,9 @@ target: ...@@ -163,9 +181,9 @@ target:
; ARM32OM1: tst {{.*}}, #1 ; ARM32OM1: tst {{.*}}, #1
; ARM32OM1: bne ; ARM32OM1: bne
; ARM32OM1: b ; ARM32OM1: b
; ARM32OM1: bl ; ARM32OM1: blx
; ARM32OM1: bx lr ; ARM32OM1: bx lr
; ARM32OM1: bl ; ARM32OM1: blx
; ARM32OM1: bx lr ; ARM32OM1: bx lr
; Unconditional branches to the block after a contracted block should be ; Unconditional branches to the block after a contracted block should be
...@@ -194,10 +212,18 @@ target: ...@@ -194,10 +212,18 @@ target:
; OM1: call ; OM1: call
; ARM32O2-LABEL: testUncondToBlockAfterContract ; ARM32O2-LABEL: testUncondToBlockAfterContract
; ARM32O2: bl {{.*}} dummy ; ARM32O2: movw {{.+}} dummy
; ARM32O2-NEXT: bl {{.*}} dummy ; ARM32O2-NEXT: movt
; ARM32O2-NEXT: blx
; ARM32O2-NEXT: movw {{.+}} dummy
; ARM32O2-NEXT: movt
; ARM32O2-NEXT: blx
; ARM32OM1-LABEL: testUncondToBlockAfterContract ; ARM32OM1-LABEL: testUncondToBlockAfterContract
; ARM32OM1: bl {{.*}} dummy ; ARM32OM1: movw {{.+}} dummy
; ARM32OM1-NEXT: movt
; ARM32OM1-NEXT: blx
; ARM32OM1-NEXT: b ; ARM32OM1-NEXT: b
; ARM32OM1-NEXT: bl {{.*}} dummy ; ARM32OM1-NEXT: movw {{.+}} dummy
; ARM32OM1-NEXT: movt
; ARM32OM1-NEXT: blx
...@@ -117,7 +117,9 @@ entry: ...@@ -117,7 +117,9 @@ entry:
; CHECK-LABEL: remFloat ; CHECK-LABEL: remFloat
; CHECK: call {{.*}} R_{{.*}} fmodf ; CHECK: call {{.*}} R_{{.*}} fmodf
; ARM32-LABEL: remFloat ; ARM32-LABEL: remFloat
; ARM32: bl {{.*}} fmodf ; ARM32: movw {{.+}} fmodf
; ARM32: movt
; ARM32: blx
define internal double @remDouble(double %a, double %b) { define internal double @remDouble(double %a, double %b) {
entry: entry:
...@@ -127,4 +129,6 @@ entry: ...@@ -127,4 +129,6 @@ entry:
; CHECK-LABEL: remDouble ; CHECK-LABEL: remDouble
; CHECK: call {{.*}} R_{{.*}} fmod ; CHECK: call {{.*}} R_{{.*}} fmod
; ARM32-LABEL: remDouble ; ARM32-LABEL: remDouble
; ARM32: bl {{.*}} fmod ; ARM32: movw {{.+}} fmod
; ARM32: movt
; ARM32: blx
...@@ -63,29 +63,39 @@ define internal void @floatHarness() nounwind { ...@@ -63,29 +63,39 @@ define internal void @floatHarness() nounwind {
; CHECK-LABEL: floatHarness ; CHECK-LABEL: floatHarness
call void @float1(float 1.0) call void @float1(float 1.0)
; CHECK-DAG: vmov.f32 s0 ; CHECK-DAG: vmov.f32 s0
; CHECK: bl {{.*}} float1 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} float1
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @float2(float 1.0, float 2.0) call void @float2(float 1.0, float 2.0)
; CHECK-DAG: vmov.f32 s0 ; CHECK-DAG: vmov.f32 s0
; CHECK-DAG: vmov.f32 s1 ; CHECK-DAG: vmov.f32 s1
; CHECK: bl {{.*}} float2 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} float2
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @float3(float 1.0, float 2.0, float 3.0) call void @float3(float 1.0, float 2.0, float 3.0)
; CHECK-DAG: vmov.f32 s0 ; CHECK-DAG: vmov.f32 s0
; CHECK-DAG: vmov.f32 s1 ; CHECK-DAG: vmov.f32 s1
; CHECK-DAG: vmov.f32 s2 ; CHECK-DAG: vmov.f32 s2
; CHECK: bl {{.*}} float3 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} float3
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @float4(float 1.0, float 2.0, float 3.0, float 4.0) call void @float4(float 1.0, float 2.0, float 3.0, float 4.0)
; CHECK-DAG: vmov.f32 s0 ; CHECK-DAG: vmov.f32 s0
; CHECK-DAG: vmov.f32 s1 ; CHECK-DAG: vmov.f32 s1
; CHECK-DAG: vmov.f32 s2 ; CHECK-DAG: vmov.f32 s2
; CHECK-DAG: vmov.f32 s3 ; CHECK-DAG: vmov.f32 s3
; CHECK: bl {{.*}} float4 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} float4
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @float5(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0) call void @float5(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0)
; CHECK-DAG: vmov.f32 s0 ; CHECK-DAG: vmov.f32 s0
; CHECK-DAG: vmov.f32 s1 ; CHECK-DAG: vmov.f32 s1
; CHECK-DAG: vmov.f32 s2 ; CHECK-DAG: vmov.f32 s2
; CHECK-DAG: vmov.f32 s3 ; CHECK-DAG: vmov.f32 s3
; CHECK-DAG: vmov.f32 s4 ; CHECK-DAG: vmov.f32 s4
; CHECK: bl {{.*}} float5 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} float5
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @float6(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0, call void @float6(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0,
float 6.0) float 6.0)
; CHECK-DAG: vmov.f32 s0 ; CHECK-DAG: vmov.f32 s0
...@@ -94,7 +104,9 @@ define internal void @floatHarness() nounwind { ...@@ -94,7 +104,9 @@ define internal void @floatHarness() nounwind {
; CHECK-DAG: vmov.f32 s3 ; CHECK-DAG: vmov.f32 s3
; CHECK-DAG: vmov.f32 s4 ; CHECK-DAG: vmov.f32 s4
; CHECK-DAG: vmov.f32 s5 ; CHECK-DAG: vmov.f32 s5
; CHECK: bl {{.*}} float6 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} float6
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @float7(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0, call void @float7(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0,
float 6.0, float 7.0) float 6.0, float 7.0)
; CHECK-DAG: vmov.f32 s0 ; CHECK-DAG: vmov.f32 s0
...@@ -104,7 +116,9 @@ define internal void @floatHarness() nounwind { ...@@ -104,7 +116,9 @@ define internal void @floatHarness() nounwind {
; CHECK-DAG: vmov.f32 s4 ; CHECK-DAG: vmov.f32 s4
; CHECK-DAG: vmov.f32 s5 ; CHECK-DAG: vmov.f32 s5
; CHECK-DAG: vmov.f32 s6 ; CHECK-DAG: vmov.f32 s6
; CHECK: bl {{.*}} float7 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} float7
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @float8(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0, call void @float8(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0,
float 6.0, float 7.0, float 8.0) float 6.0, float 7.0, float 8.0)
; CHECK-DAG: vmov.f32 s0 ; CHECK-DAG: vmov.f32 s0
...@@ -115,7 +129,9 @@ define internal void @floatHarness() nounwind { ...@@ -115,7 +129,9 @@ define internal void @floatHarness() nounwind {
; CHECK-DAG: vmov.f32 s5 ; CHECK-DAG: vmov.f32 s5
; CHECK-DAG: vmov.f32 s6 ; CHECK-DAG: vmov.f32 s6
; CHECK-DAG: vmov.f32 s7 ; CHECK-DAG: vmov.f32 s7
; CHECK: bl {{.*}} float8 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} float8
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @float9(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0, call void @float9(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0,
float 6.0, float 7.0, float 8.0, float 9.0) float 6.0, float 7.0, float 8.0, float 9.0)
; CHECK-DAG: vmov.f32 s0 ; CHECK-DAG: vmov.f32 s0
...@@ -127,7 +143,9 @@ define internal void @floatHarness() nounwind { ...@@ -127,7 +143,9 @@ define internal void @floatHarness() nounwind {
; CHECK-DAG: vmov.f32 s6 ; CHECK-DAG: vmov.f32 s6
; CHECK-DAG: vmov.f32 s7 ; CHECK-DAG: vmov.f32 s7
; CHECK-DAG: vmov.f32 s8 ; CHECK-DAG: vmov.f32 s8
; CHECK: bl {{.*}} float9 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} float9
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @float10(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0, call void @float10(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0,
float 6.0, float 7.0, float 8.0, float 9.0, float 10.0) float 6.0, float 7.0, float 8.0, float 9.0, float 10.0)
; CHECK-DAG: vmov.f32 s0 ; CHECK-DAG: vmov.f32 s0
...@@ -140,7 +158,9 @@ define internal void @floatHarness() nounwind { ...@@ -140,7 +158,9 @@ define internal void @floatHarness() nounwind {
; CHECK-DAG: vmov.f32 s7 ; CHECK-DAG: vmov.f32 s7
; CHECK-DAG: vmov.f32 s8 ; CHECK-DAG: vmov.f32 s8
; CHECK-DAG: vmov.f32 s9 ; CHECK-DAG: vmov.f32 s9
; CHECK: bl {{.*}} float10 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} float10
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @float11(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0, call void @float11(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0,
float 6.0, float 7.0, float 8.0, float 9.0, float 10.0, float 6.0, float 7.0, float 8.0, float 9.0, float 10.0,
float 11.0) float 11.0)
...@@ -155,7 +175,9 @@ define internal void @floatHarness() nounwind { ...@@ -155,7 +175,9 @@ define internal void @floatHarness() nounwind {
; CHECK-DAG: vmov.f32 s8 ; CHECK-DAG: vmov.f32 s8
; CHECK-DAG: vmov.f32 s9 ; CHECK-DAG: vmov.f32 s9
; CHECK-DAG: vmov.f32 s10 ; CHECK-DAG: vmov.f32 s10
; CHECK: bl {{.*}} float11 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} float11
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @float12(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0, call void @float12(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0,
float 6.0, float 7.0, float 8.0, float 9.0, float 10.0, float 6.0, float 7.0, float 8.0, float 9.0, float 10.0,
float 11.0, float 12.0) float 11.0, float 12.0)
...@@ -171,7 +193,9 @@ define internal void @floatHarness() nounwind { ...@@ -171,7 +193,9 @@ define internal void @floatHarness() nounwind {
; CHECK-DAG: vmov.f32 s9 ; CHECK-DAG: vmov.f32 s9
; CHECK-DAG: vmov.f32 s10 ; CHECK-DAG: vmov.f32 s10
; CHECK-DAG: vmov.f32 s11 ; CHECK-DAG: vmov.f32 s11
; CHECK: bl {{.*}} float12 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} float12
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @float13(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0, call void @float13(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0,
float 6.0, float 7.0, float 8.0, float 9.0, float 10.0, float 6.0, float 7.0, float 8.0, float 9.0, float 10.0,
float 11.0, float 12.0, float 13.0) float 11.0, float 12.0, float 13.0)
...@@ -188,7 +212,9 @@ define internal void @floatHarness() nounwind { ...@@ -188,7 +212,9 @@ define internal void @floatHarness() nounwind {
; CHECK-DAG: vmov.f32 s10 ; CHECK-DAG: vmov.f32 s10
; CHECK-DAG: vmov.f32 s11 ; CHECK-DAG: vmov.f32 s11
; CHECK-DAG: vmov.f32 s12 ; CHECK-DAG: vmov.f32 s12
; CHECK: bl {{.*}} float13 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} float13
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @float14(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0, call void @float14(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0,
float 6.0, float 7.0, float 8.0, float 9.0, float 10.0, float 6.0, float 7.0, float 8.0, float 9.0, float 10.0,
float 11.0, float 12.0, float 13.0, float 14.0) float 11.0, float 12.0, float 13.0, float 14.0)
...@@ -206,7 +232,9 @@ define internal void @floatHarness() nounwind { ...@@ -206,7 +232,9 @@ define internal void @floatHarness() nounwind {
; CHECK-DAG: vmov.f32 s11 ; CHECK-DAG: vmov.f32 s11
; CHECK-DAG: vmov.f32 s12 ; CHECK-DAG: vmov.f32 s12
; CHECK-DAG: vmov.f32 s13 ; CHECK-DAG: vmov.f32 s13
; CHECK: bl {{.*}} float14 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} float14
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @float15(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0, call void @float15(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0,
float 6.0, float 7.0, float 8.0, float 9.0, float 10.0, float 6.0, float 7.0, float 8.0, float 9.0, float 10.0,
float 11.0, float 12.0, float 13.0, float 14.0, float 11.0, float 12.0, float 13.0, float 14.0,
...@@ -226,7 +254,9 @@ define internal void @floatHarness() nounwind { ...@@ -226,7 +254,9 @@ define internal void @floatHarness() nounwind {
; CHECK-DAG: vmov.f32 s12 ; CHECK-DAG: vmov.f32 s12
; CHECK-DAG: vmov.f32 s13 ; CHECK-DAG: vmov.f32 s13
; CHECK-DAG: vmov.f32 s14 ; CHECK-DAG: vmov.f32 s14
; CHECK: bl {{.*}} float15 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} float15
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @float16(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0, call void @float16(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0,
float 6.0, float 7.0, float 8.0, float 9.0, float 10.0, float 6.0, float 7.0, float 8.0, float 9.0, float 10.0,
float 11.0, float 12.0, float 13.0, float 14.0, float 11.0, float 12.0, float 13.0, float 14.0,
...@@ -247,7 +277,9 @@ define internal void @floatHarness() nounwind { ...@@ -247,7 +277,9 @@ define internal void @floatHarness() nounwind {
; CHECK-DAG: vmov.f32 s13 ; CHECK-DAG: vmov.f32 s13
; CHECK-DAG: vmov.f32 s14 ; CHECK-DAG: vmov.f32 s14
; CHECK-DAG: vmov.f32 s15 ; CHECK-DAG: vmov.f32 s15
; CHECK: bl {{.*}} float16 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} float16
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @float17(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0, call void @float17(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0,
float 6.0, float 7.0, float 8.0, float 9.0, float 10.0, float 6.0, float 7.0, float 8.0, float 9.0, float 10.0,
float 11.0, float 12.0, float 13.0, float 14.0, float 11.0, float 12.0, float 13.0, float 14.0,
...@@ -269,7 +301,9 @@ define internal void @floatHarness() nounwind { ...@@ -269,7 +301,9 @@ define internal void @floatHarness() nounwind {
; CHECK-DAG: vmov.f32 s14 ; CHECK-DAG: vmov.f32 s14
; CHECK-DAG: vmov.f32 s15 ; CHECK-DAG: vmov.f32 s15
; CHECK-DAG: vstr s{{.*}}, [sp] ; CHECK-DAG: vstr s{{.*}}, [sp]
; CHECK: bl {{.*}} float17 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} float17
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @float18(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0, call void @float18(float 1.0, float 2.0, float 3.0, float 4.0, float 5.0,
float 6.0, float 7.0, float 8.0, float 9.0, float 10.0, float 6.0, float 7.0, float 8.0, float 9.0, float 10.0,
float 11.0, float 12.0, float 13.0, float 14.0, float 11.0, float 12.0, float 13.0, float 14.0,
...@@ -292,7 +326,9 @@ define internal void @floatHarness() nounwind { ...@@ -292,7 +326,9 @@ define internal void @floatHarness() nounwind {
; CHECK-DAG: vmov.f32 s15 ; CHECK-DAG: vmov.f32 s15
; CHECK-DAG: vstr s{{.*}}, [sp] ; CHECK-DAG: vstr s{{.*}}, [sp]
; CHECK-DAG: vstr s{{.*}}, [sp, #4] ; CHECK-DAG: vstr s{{.*}}, [sp, #4]
; CHECK: bl {{.*}} float18 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} float18
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
ret void ret void
} }
...@@ -318,22 +354,30 @@ define internal void @doubleHarness() nounwind { ...@@ -318,22 +354,30 @@ define internal void @doubleHarness() nounwind {
; CHECK-LABEL: doubleHarness ; CHECK-LABEL: doubleHarness
call void @double1(double 1.0) call void @double1(double 1.0)
; CHECK-DAG: vmov.f64 d0 ; CHECK-DAG: vmov.f64 d0
; CHECK: bl {{.*}} double1 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} double1
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @double2(double 1.0, double 2.0) call void @double2(double 1.0, double 2.0)
; CHECK-DAG: vmov.f64 d0 ; CHECK-DAG: vmov.f64 d0
; CHECK-DAG: vmov.f64 d1 ; CHECK-DAG: vmov.f64 d1
; CHECK: bl {{.*}} double2 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} double2
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @double3(double 1.0, double 2.0, double 3.0) call void @double3(double 1.0, double 2.0, double 3.0)
; CHECK-DAG: vmov.f64 d0 ; CHECK-DAG: vmov.f64 d0
; CHECK-DAG: vmov.f64 d1 ; CHECK-DAG: vmov.f64 d1
; CHECK-DAG: vmov.f64 d2 ; CHECK-DAG: vmov.f64 d2
; CHECK: bl {{.*}} double3 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} double3
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @double4(double 1.0, double 2.0, double 3.0, double 4.0) call void @double4(double 1.0, double 2.0, double 3.0, double 4.0)
; CHECK-DAG: vmov.f64 d0 ; CHECK-DAG: vmov.f64 d0
; CHECK-DAG: vmov.f64 d1 ; CHECK-DAG: vmov.f64 d1
; CHECK-DAG: vmov.f64 d2 ; CHECK-DAG: vmov.f64 d2
; CHECK-DAG: vmov.f64 d3 ; CHECK-DAG: vmov.f64 d3
; CHECK: bl {{.*}} double4 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} double4
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @double5(double 1.0, double 2.0, double 3.0, double 4.0, call void @double5(double 1.0, double 2.0, double 3.0, double 4.0,
double 5.0) double 5.0)
; CHECK-DAG: vmov.f64 d0 ; CHECK-DAG: vmov.f64 d0
...@@ -341,7 +385,9 @@ define internal void @doubleHarness() nounwind { ...@@ -341,7 +385,9 @@ define internal void @doubleHarness() nounwind {
; CHECK-DAG: vmov.f64 d2 ; CHECK-DAG: vmov.f64 d2
; CHECK-DAG: vmov.f64 d3 ; CHECK-DAG: vmov.f64 d3
; CHECK-DAG: vmov.f64 d4 ; CHECK-DAG: vmov.f64 d4
; CHECK: bl {{.*}} double5 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} double5
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @double6(double 1.0, double 2.0, double 3.0, double 4.0, call void @double6(double 1.0, double 2.0, double 3.0, double 4.0,
double 5.0, double 6.0) double 5.0, double 6.0)
; CHECK-DAG: vmov.f64 d0 ; CHECK-DAG: vmov.f64 d0
...@@ -350,7 +396,9 @@ define internal void @doubleHarness() nounwind { ...@@ -350,7 +396,9 @@ define internal void @doubleHarness() nounwind {
; CHECK-DAG: vmov.f64 d3 ; CHECK-DAG: vmov.f64 d3
; CHECK-DAG: vmov.f64 d4 ; CHECK-DAG: vmov.f64 d4
; CHECK-DAG: vmov.f64 d5 ; CHECK-DAG: vmov.f64 d5
; CHECK: bl {{.*}} double6 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} double6
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @double7(double 1.0, double 2.0, double 3.0, double 4.0, call void @double7(double 1.0, double 2.0, double 3.0, double 4.0,
double 5.0, double 6.0, double 7.0) double 5.0, double 6.0, double 7.0)
; CHECK-DAG: vmov.f64 d0 ; CHECK-DAG: vmov.f64 d0
...@@ -360,7 +408,9 @@ define internal void @doubleHarness() nounwind { ...@@ -360,7 +408,9 @@ define internal void @doubleHarness() nounwind {
; CHECK-DAG: vmov.f64 d4 ; CHECK-DAG: vmov.f64 d4
; CHECK-DAG: vmov.f64 d5 ; CHECK-DAG: vmov.f64 d5
; CHECK-DAG: vmov.f64 d6 ; CHECK-DAG: vmov.f64 d6
; CHECK: bl {{.*}} double7 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} double7
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @double8(double 1.0, double 2.0, double 3.0, double 4.0, call void @double8(double 1.0, double 2.0, double 3.0, double 4.0,
double 5.0, double 6.0, double 7.0, double 8.0) double 5.0, double 6.0, double 7.0, double 8.0)
; CHECK-DAG: vmov.f64 d0 ; CHECK-DAG: vmov.f64 d0
...@@ -371,7 +421,9 @@ define internal void @doubleHarness() nounwind { ...@@ -371,7 +421,9 @@ define internal void @doubleHarness() nounwind {
; CHECK-DAG: vmov.f64 d5 ; CHECK-DAG: vmov.f64 d5
; CHECK-DAG: vmov.f64 d6 ; CHECK-DAG: vmov.f64 d6
; CHECK-DAG: vmov.f64 d7 ; CHECK-DAG: vmov.f64 d7
; CHECK: bl {{.*}} double8 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} double8
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @double9(double 1.0, double 2.0, double 3.0, double 4.0, call void @double9(double 1.0, double 2.0, double 3.0, double 4.0,
double 5.0, double 6.0, double 7.0, double 8.0, double 5.0, double 6.0, double 7.0, double 8.0,
double 9.0) double 9.0)
...@@ -383,8 +435,10 @@ define internal void @doubleHarness() nounwind { ...@@ -383,8 +435,10 @@ define internal void @doubleHarness() nounwind {
; CHECK-DAG: vmov.f64 d5 ; CHECK-DAG: vmov.f64 d5
; CHECK-DAG: vmov.f64 d6 ; CHECK-DAG: vmov.f64 d6
; CHECK-DAG: vmov.f64 d7 ; CHECK-DAG: vmov.f64 d7
; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} double9
; CHECK-DAG: movt [[CALL]]
; CHECK-DAG: vstr d{{.*}}, [sp] ; CHECK-DAG: vstr d{{.*}}, [sp]
; CHECK: bl {{.*}} double9 ; CHECK: blx [[CALL]]
call void @double10(double 1.0, double 2.0, double 3.0, double 4.0, call void @double10(double 1.0, double 2.0, double 3.0, double 4.0,
double 5.0, double 6.0, double 7.0, double 8.0, double 5.0, double 6.0, double 7.0, double 8.0,
double 9.0, double 10.0) double 9.0, double 10.0)
...@@ -398,7 +452,9 @@ define internal void @doubleHarness() nounwind { ...@@ -398,7 +452,9 @@ define internal void @doubleHarness() nounwind {
; CHECK-DAG: vmov.f64 d7 ; CHECK-DAG: vmov.f64 d7
; CHECK-DAG: vstr d{{.*}}, [sp] ; CHECK-DAG: vstr d{{.*}}, [sp]
; CHECK-DAG: vstr d{{.*}}, [sp, #8] ; CHECK-DAG: vstr d{{.*}}, [sp, #8]
; CHECK: bl {{.*}} double10 ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} double10
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
ret void ret void
} }
...@@ -437,13 +493,17 @@ define internal void @packsFloats() nounwind { ...@@ -437,13 +493,17 @@ define internal void @packsFloats() nounwind {
; CHECK-DAG: vmov.f32 s0 ; CHECK-DAG: vmov.f32 s0
; CHECK-DAG: vmov.f64 d1 ; CHECK-DAG: vmov.f64 d1
; CHECK-DAG: vmov.f32 s1 ; CHECK-DAG: vmov.f32 s1
; CHECK: bl {{.*}} testFDF ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} testFDF
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @testFDDF(float 1.0, double 2.0, double 3.0, float 4.0) call void @testFDDF(float 1.0, double 2.0, double 3.0, float 4.0)
; CHECK-DAG: vmov.f32 s0 ; CHECK-DAG: vmov.f32 s0
; CHECK-DAG: vmov.f64 d1 ; CHECK-DAG: vmov.f64 d1
; CHECK-DAG: vmov.f64 d2 ; CHECK-DAG: vmov.f64 d2
; CHECK-DAG: vmov.f32 s1 ; CHECK-DAG: vmov.f32 s1
; CHECK: bl {{.*}} testFDDF ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} testFDDF
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @testFDDDF(float 1.0, double 2.0, double 3.0, double 4.0, call void @testFDDDF(float 1.0, double 2.0, double 3.0, double 4.0,
float 5.0) float 5.0)
; CHECK-DAG: vmov.f32 s0 ; CHECK-DAG: vmov.f32 s0
...@@ -451,7 +511,9 @@ define internal void @packsFloats() nounwind { ...@@ -451,7 +511,9 @@ define internal void @packsFloats() nounwind {
; CHECK-DAG: vmov.f64 d2 ; CHECK-DAG: vmov.f64 d2
; CHECK-DAG: vmov.f64 d3 ; CHECK-DAG: vmov.f64 d3
; CHECK-DAG: vmov.f32 s1 ; CHECK-DAG: vmov.f32 s1
; CHECK: bl {{.*}} testFDDDF ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} testFDDDF
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @testFDDDDF(float 1.0, double 2.0, double 3.0, double 4.0, call void @testFDDDDF(float 1.0, double 2.0, double 3.0, double 4.0,
double 5.0, float 6.0) double 5.0, float 6.0)
; CHECK-DAG: vmov.f32 s0 ; CHECK-DAG: vmov.f32 s0
...@@ -460,7 +522,9 @@ define internal void @packsFloats() nounwind { ...@@ -460,7 +522,9 @@ define internal void @packsFloats() nounwind {
; CHECK-DAG: vmov.f64 d3 ; CHECK-DAG: vmov.f64 d3
; CHECK-DAG: vmov.f64 d4 ; CHECK-DAG: vmov.f64 d4
; CHECK-DAG: vmov.f32 s1 ; CHECK-DAG: vmov.f32 s1
; CHECK: bl {{.*}} testFDDDDF ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} testFDDDDF
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @testFDDDDDF(float 1.0, double 2.0, double 3.0, double 4.0, call void @testFDDDDDF(float 1.0, double 2.0, double 3.0, double 4.0,
double 5.0, double 6.0, float 7.0) double 5.0, double 6.0, float 7.0)
; CHECK-DAG: vmov.f32 s0 ; CHECK-DAG: vmov.f32 s0
...@@ -470,7 +534,9 @@ define internal void @packsFloats() nounwind { ...@@ -470,7 +534,9 @@ define internal void @packsFloats() nounwind {
; CHECK-DAG: vmov.f64 d4 ; CHECK-DAG: vmov.f64 d4
; CHECK-DAG: vmov.f64 d5 ; CHECK-DAG: vmov.f64 d5
; CHECK-DAG: vmov.f32 s1 ; CHECK-DAG: vmov.f32 s1
; CHECK: bl {{.*}} testFDDDDDF ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} testFDDDDDF
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @testFDDDDDDF(float 1.0, double 2.0, double 3.0, double 4.0, call void @testFDDDDDDF(float 1.0, double 2.0, double 3.0, double 4.0,
double 5.0, double 6.0, double 7.0, float 8.0) double 5.0, double 6.0, double 7.0, float 8.0)
; CHECK-DAG: vmov.f32 s0 ; CHECK-DAG: vmov.f32 s0
...@@ -481,7 +547,9 @@ define internal void @packsFloats() nounwind { ...@@ -481,7 +547,9 @@ define internal void @packsFloats() nounwind {
; CHECK-DAG: vmov.f64 d5 ; CHECK-DAG: vmov.f64 d5
; CHECK-DAG: vmov.f64 d6 ; CHECK-DAG: vmov.f64 d6
; CHECK-DAG: vmov.f32 s1 ; CHECK-DAG: vmov.f32 s1
; CHECK: bl {{.*}} testFDDDDDDF ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} testFDDDDDDF
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @testFDDDDDDDF(float 1.0, double 2.0, double 3.0, double 4.0, call void @testFDDDDDDDF(float 1.0, double 2.0, double 3.0, double 4.0,
double 5.0, double 6.0, double 7.0, double 8.0, double 5.0, double 6.0, double 7.0, double 8.0,
float 9.0) float 9.0)
...@@ -494,7 +562,9 @@ define internal void @packsFloats() nounwind { ...@@ -494,7 +562,9 @@ define internal void @packsFloats() nounwind {
; CHECK-DAG: vmov.f64 d6 ; CHECK-DAG: vmov.f64 d6
; CHECK-DAG: vmov.f64 d7 ; CHECK-DAG: vmov.f64 d7
; CHECK-DAG: vmov.f32 s1 ; CHECK-DAG: vmov.f32 s1
; CHECK: bl {{.*}} testFDDDDDDDF ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} testFDDDDDDDF
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @testFDDDDDDDFD(float 1.0, double 2.0, double 3.0, double 4.0, call void @testFDDDDDDDFD(float 1.0, double 2.0, double 3.0, double 4.0,
double 5.0, double 6.0, double 7.0, double 8.0, double 5.0, double 6.0, double 7.0, double 8.0,
float 9.0, double 10.0) float 9.0, double 10.0)
...@@ -508,7 +578,9 @@ define internal void @packsFloats() nounwind { ...@@ -508,7 +578,9 @@ define internal void @packsFloats() nounwind {
; CHECK-DAG: vmov.f64 d7 ; CHECK-DAG: vmov.f64 d7
; CHECK-DAG: vstr d{{.*}}, [sp] ; CHECK-DAG: vstr d{{.*}}, [sp]
; CHECK-DAG: vmov.f32 s1 ; CHECK-DAG: vmov.f32 s1
; CHECK: bl {{.*}} testFDDDDDDDFD ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} testFDDDDDDDFD
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @testFDDDDDDDDF(float 1.0, double 2.0, double 3.0, double 4.0, call void @testFDDDDDDDDF(float 1.0, double 2.0, double 3.0, double 4.0,
double 5.0, double 6.0, double 7.0, double 8.0, double 5.0, double 6.0, double 7.0, double 8.0,
double 9.0, float 10.0) double 9.0, float 10.0)
...@@ -522,7 +594,9 @@ define internal void @packsFloats() nounwind { ...@@ -522,7 +594,9 @@ define internal void @packsFloats() nounwind {
; CHECK-DAG: vmov.f64 d7 ; CHECK-DAG: vmov.f64 d7
; CHECK-DAG: vstr d{{.*}}, [sp] ; CHECK-DAG: vstr d{{.*}}, [sp]
; CHECK-DAG: vstr s{{.*}}, [sp, #8] ; CHECK-DAG: vstr s{{.*}}, [sp, #8]
; CHECK: bl {{.*}} testFDDDDDDDDF ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} testFDDDDDDDDF
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @testFDDDDDDDDDF(float 1.0, double 2.0, double 3.0, double 4.0, call void @testFDDDDDDDDDF(float 1.0, double 2.0, double 3.0, double 4.0,
double 5.0, double 6.0, double 7.0, double 8.0, double 5.0, double 6.0, double 7.0, double 8.0,
double 9.0, double 10.0, float 11.0) double 9.0, double 10.0, float 11.0)
...@@ -537,7 +611,9 @@ define internal void @packsFloats() nounwind { ...@@ -537,7 +611,9 @@ define internal void @packsFloats() nounwind {
; CHECK-DAG: vstr d{{.*}}, [sp] ; CHECK-DAG: vstr d{{.*}}, [sp]
; CHECK-DAG: vstr d{{.*}}, [sp, #8] ; CHECK-DAG: vstr d{{.*}}, [sp, #8]
; CHECK-DAG: vstr s{{.*}}, [sp, #16] ; CHECK-DAG: vstr s{{.*}}, [sp, #16]
; CHECK: bl {{.*}} testFDDDDDDDDDF ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} testFDDDDDDDDDF
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @testFDDDDDDDDFD(float 1.0, double 2.0, double 3.0, double 4.0, call void @testFDDDDDDDDFD(float 1.0, double 2.0, double 3.0, double 4.0,
double 5.0, double 6.0, double 7.0, double 8.0, double 5.0, double 6.0, double 7.0, double 8.0,
double 9.0, float 10.0, double 11.0) double 9.0, float 10.0, double 11.0)
...@@ -552,7 +628,9 @@ define internal void @packsFloats() nounwind { ...@@ -552,7 +628,9 @@ define internal void @packsFloats() nounwind {
; CHECK-DAG: vstr d{{.*}}, [sp] ; CHECK-DAG: vstr d{{.*}}, [sp]
; CHECK-DAG: vstr s{{.*}}, [sp, #8] ; CHECK-DAG: vstr s{{.*}}, [sp, #8]
; CHECK-DAG: vstr d{{.*}}, [sp, #16] ; CHECK-DAG: vstr d{{.*}}, [sp, #16]
; CHECK: bl {{.*}} testFDDDDDDDDFD ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} testFDDDDDDDDFD
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
call void @testFDDDDDDDDFDF(float 1.0, double 2.0, double 3.0, double 4.0, call void @testFDDDDDDDDFDF(float 1.0, double 2.0, double 3.0, double 4.0,
double 5.0, double 6.0, double 7.0, double 8.0, double 5.0, double 6.0, double 7.0, double 8.0,
double 9.0, float 10.0, double 11.0, float 12.0) double 9.0, float 10.0, double 11.0, float 12.0)
...@@ -568,7 +646,9 @@ define internal void @packsFloats() nounwind { ...@@ -568,7 +646,9 @@ define internal void @packsFloats() nounwind {
; CHECK-DAG: vstr s{{.*}}, [sp, #8] ; CHECK-DAG: vstr s{{.*}}, [sp, #8]
; CHECK-DAG: vstr d{{.*}}, [sp, #16] ; CHECK-DAG: vstr d{{.*}}, [sp, #16]
; CHECK-DAG: vstr s{{.*}}, [sp, #24] ; CHECK-DAG: vstr s{{.*}}, [sp, #24]
; CHECK: bl {{.*}} testFDDDDDDDDFD ; CHECK-DAG: movw [[CALL:r[0-9]]], {{.+}} testFDDDDDDDDFD
; CHECK-DAG: movt [[CALL]]
; CHECK: blx [[CALL]]
ret void ret void
} }
......
...@@ -61,7 +61,9 @@ if.end3: ; preds = %if.then2, %if.end ...@@ -61,7 +61,9 @@ if.end3: ; preds = %if.then2, %if.end
; ARM32-OM1: mov [[R0:r[0-9]+]], #0 ; ARM32-OM1: mov [[R0:r[0-9]+]], #0
; ARM32-OM1: moveq [[R0]], #1 ; ARM32-OM1: moveq [[R0]], #1
; ARM32-O2: bne ; ARM32-O2: bne
; ARM32: bl func ; ARM32: movw [[CALL:r[0-9]]], #:lower16:func
; ARM32: movt [[CALL:r[0-9]]], #:upper16:func
; ARM32: blx [[CALL]]
; ARM32: vcmp.f64 ; ARM32: vcmp.f64
; ARM32: vmrs ; ARM32: vmrs
; ARM32-OM1: mov [[R1:r[0-9]+]], #0 ; ARM32-OM1: mov [[R1:r[0-9]+]], #0
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
; RUN: %if --need=target_ARM32 --need=allow_dump \ ; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble --disassemble --target arm32 \ ; RUN: --command %p2i --filetype=asm --assemble --disassemble --target arm32 \
; RUN: -i %s --args -Om1 --skip-unimplemented --test-stack-extra 4096 \ ; RUN: -i %s --args -Om1 --test-stack-extra 4096 \
; RUN: -allow-externally-defined-symbols \ ; RUN: -allow-externally-defined-symbols \
; RUN: | %if --need=target_ARM32 --need=allow_dump \ ; RUN: | %if --need=target_ARM32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix ARM32 %s ; RUN: --command FileCheck --check-prefix ARM32 %s
...@@ -63,12 +63,16 @@ end: ...@@ -63,12 +63,16 @@ end:
; Now skip ahead to where the call in br_1 begins, to check how %t2 is used. ; Now skip ahead to where the call in br_1 begins, to check how %t2 is used.
; ARM32: movw ip, #4232 ; ARM32: movw ip, #4232
; ARM32-NEXT: add ip, sp, ip ; ARM32-NEXT: add ip, sp, ip
; ARM32: movw [[CALL:r[0-9]]], {{.+}} dummy
; ARM32: movt [[CALL]]
; ARM32: ldr r2, [ip, #-4] ; ARM32: ldr r2, [ip, #-4]
; ARM32: bl {{.*}} dummy ; ARM32: blx [[CALL]]
; The call clobbers ip, so we need to re-create the base register. ; The call clobbers ip, so we need to re-create the base register.
; ARM32: movw ip, #4{{.*}} ; ARM32: movw ip, #4{{.*}}
; ARM32: b {{[a-f0-9]+}} ; ARM32: b {{[a-f0-9]+}}
; ARM32: bl {{.*}} dummy ; ARM32: movw [[CALL:r[0-9]]], {{.+}} dummy
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
; Similar, but test a function that uses FP as the base register (originally). ; Similar, but test a function that uses FP as the base register (originally).
define internal i64 @usesFrameReg(i32 %a, i32 %b, i32 %c, i32 %d) { define internal i64 @usesFrameReg(i32 %a, i32 %b, i32 %c, i32 %d) {
...@@ -118,9 +122,13 @@ end: ...@@ -118,9 +122,13 @@ end:
; Now skip ahead to where the call in br_1 begins, to check how %t2 is used. ; Now skip ahead to where the call in br_1 begins, to check how %t2 is used.
; ARM32: movw ip, #4120 ; ARM32: movw ip, #4120
; ARM32-NEXT: sub ip, fp, ip ; ARM32-NEXT: sub ip, fp, ip
; ARM32: movw [[CALL:r[0-9]]], {{.+}} dummy
; ARM32: movt [[CALL]]
; ARM32: ldr r2, [ip, #-4] ; ARM32: ldr r2, [ip, #-4]
; ARM32: bl {{.*}} dummy ; ARM32: blx [[CALL]]
; The call clobbers ip, so we need to re-create the base register. ; The call clobbers ip, so we need to re-create the base register.
; ARM32: movw ip, #4{{.*}} ; ARM32: movw ip, #4{{.*}}
; ARM32: b {{[a-f0-9]+}} ; ARM32: b {{[a-f0-9]+}}
; ARM32: bl {{.*}} dummy ; ARM32: movw [[CALL:r[0-9]]], {{.+}} dummy
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
...@@ -11,8 +11,8 @@ ...@@ -11,8 +11,8 @@
; RUN: | %if --need=target_X8632 --command FileCheck --check-prefix OM1 %s ; RUN: | %if --need=target_X8632 --command FileCheck --check-prefix OM1 %s
; RUN: %if --need=target_ARM32 --need=allow_dump \ ; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble --disassemble --target arm32 \ ; RUN: --command %p2i --filetype=obj --assemble --disassemble --target arm32 \
; RUN: -i %s --args -O2 --skip-unimplemented \ ; RUN: -i %s --args -O2 \
; RUN: | %if --need=target_ARM32 --need=allow_dump \ ; RUN: | %if --need=target_ARM32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix ARM32 %s ; RUN: --command FileCheck --check-prefix ARM32 %s
...@@ -33,7 +33,9 @@ entry: ...@@ -33,7 +33,9 @@ entry:
; OM1-LABEL: test_memcpy ; OM1-LABEL: test_memcpy
; OM1: call {{.*}} memcpy ; OM1: call {{.*}} memcpy
; ARM32-LABEL: test_memcpy ; ARM32-LABEL: test_memcpy
; ARM32: bl {{.*}} memcpy ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memcpy
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memcpy_long_const_len(i32 %iptr_dst, i32 %iptr_src) { define internal void @test_memcpy_long_const_len(i32 %iptr_dst, i32 %iptr_src) {
entry: entry:
...@@ -48,7 +50,9 @@ entry: ...@@ -48,7 +50,9 @@ entry:
; OM1-LABEL: test_memcpy_long_const_len ; OM1-LABEL: test_memcpy_long_const_len
; OM1: call {{.*}} memcpy ; OM1: call {{.*}} memcpy
; ARM32-LABEL: test_memcpy_long_const_len ; ARM32-LABEL: test_memcpy_long_const_len
; ARM32: bl {{.*}} memcpy ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memcpy
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memcpy_very_small_const_len(i32 %iptr_dst, define internal void @test_memcpy_very_small_const_len(i32 %iptr_dst,
i32 %iptr_src) { i32 %iptr_src) {
...@@ -66,7 +70,9 @@ entry: ...@@ -66,7 +70,9 @@ entry:
; OM1-LABEL: test_memcpy_very_small_const_len ; OM1-LABEL: test_memcpy_very_small_const_len
; OM1: call {{.*}} memcpy ; OM1: call {{.*}} memcpy
; ARM32-LABEL: test_memcpy_very_small_const_len ; ARM32-LABEL: test_memcpy_very_small_const_len
; ARM32: bl {{.*}} memcpy ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memcpy
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memcpy_const_len_3(i32 %iptr_dst, i32 %iptr_src) { define internal void @test_memcpy_const_len_3(i32 %iptr_dst, i32 %iptr_src) {
entry: entry:
...@@ -85,7 +91,9 @@ entry: ...@@ -85,7 +91,9 @@ entry:
; OM1-LABEL: test_memcpy_const_len_3 ; OM1-LABEL: test_memcpy_const_len_3
; OM1: call {{.*}} memcpy ; OM1: call {{.*}} memcpy
; ARM32-LABEL: test_memcpy_const_len_3 ; ARM32-LABEL: test_memcpy_const_len_3
; ARM32: bl {{.*}} memcpy ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memcpy
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memcpy_mid_const_len(i32 %iptr_dst, i32 %iptr_src) { define internal void @test_memcpy_mid_const_len(i32 %iptr_dst, i32 %iptr_src) {
entry: entry:
...@@ -104,7 +112,9 @@ entry: ...@@ -104,7 +112,9 @@ entry:
; OM1-LABEL: test_memcpy_mid_const_len ; OM1-LABEL: test_memcpy_mid_const_len
; OM1: call {{.*}} memcpy ; OM1: call {{.*}} memcpy
; ARM32-LABEL: test_memcpy_mid_const_len ; ARM32-LABEL: test_memcpy_mid_const_len
; ARM32: bl {{.*}} memcpy ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memcpy
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memcpy_mid_const_len_overlap(i32 %iptr_dst, define internal void @test_memcpy_mid_const_len_overlap(i32 %iptr_dst,
i32 %iptr_src) { i32 %iptr_src) {
...@@ -124,7 +134,9 @@ entry: ...@@ -124,7 +134,9 @@ entry:
; OM1-LABEL: test_memcpy_mid_const_len_overlap ; OM1-LABEL: test_memcpy_mid_const_len_overlap
; OM1: call {{.*}} memcpy ; OM1: call {{.*}} memcpy
; ARM32-LABEL: test_memcpy_mid_const_len_overlap ; ARM32-LABEL: test_memcpy_mid_const_len_overlap
; ARM32: bl {{.*}} memcpy ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memcpy
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memcpy_big_const_len_overlap(i32 %iptr_dst, define internal void @test_memcpy_big_const_len_overlap(i32 %iptr_dst,
i32 %iptr_src) { i32 %iptr_src) {
...@@ -144,7 +156,9 @@ entry: ...@@ -144,7 +156,9 @@ entry:
; OM1-LABEL: test_memcpy_big_const_len_overlap ; OM1-LABEL: test_memcpy_big_const_len_overlap
; OM1: call {{.*}} memcpy ; OM1: call {{.*}} memcpy
; ARM32-LABEL: test_memcpy_big_const_len_overlap ; ARM32-LABEL: test_memcpy_big_const_len_overlap
; ARM32: bl {{.*}} memcpy ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memcpy
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memcpy_large_const_len(i32 %iptr_dst, define internal void @test_memcpy_large_const_len(i32 %iptr_dst,
i32 %iptr_src) { i32 %iptr_src) {
...@@ -166,7 +180,9 @@ entry: ...@@ -166,7 +180,9 @@ entry:
; OM1-LABEL: test_memcpy_large_const_len ; OM1-LABEL: test_memcpy_large_const_len
; OM1: call {{.*}} memcpy ; OM1: call {{.*}} memcpy
; ARM32-LABEL: test_memcpy_large_const_len ; ARM32-LABEL: test_memcpy_large_const_len
; ARM32: bl {{.*}} memcpy ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memcpy
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memmove(i32 %iptr_dst, i32 %iptr_src, i32 %len) { define internal void @test_memmove(i32 %iptr_dst, i32 %iptr_src, i32 %len) {
entry: entry:
...@@ -181,7 +197,9 @@ entry: ...@@ -181,7 +197,9 @@ entry:
; OM1-LABEL: test_memmove ; OM1-LABEL: test_memmove
; OM1: call {{.*}} memmove ; OM1: call {{.*}} memmove
; ARM32-LABEL: test_memmove ; ARM32-LABEL: test_memmove
; ARM32: bl {{.*}} memmove ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memmove
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memmove_long_const_len(i32 %iptr_dst, define internal void @test_memmove_long_const_len(i32 %iptr_dst,
i32 %iptr_src) { i32 %iptr_src) {
...@@ -197,7 +215,9 @@ entry: ...@@ -197,7 +215,9 @@ entry:
; OM1-LABEL: test_memmove_long_const_len ; OM1-LABEL: test_memmove_long_const_len
; OM1: call {{.*}} memmove ; OM1: call {{.*}} memmove
; ARM32-LABEL: test_memmove_long_const_len ; ARM32-LABEL: test_memmove_long_const_len
; ARM32: bl {{.*}} memmove ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memmove
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memmove_very_small_const_len(i32 %iptr_dst, define internal void @test_memmove_very_small_const_len(i32 %iptr_dst,
i32 %iptr_src) { i32 %iptr_src) {
...@@ -215,7 +235,9 @@ entry: ...@@ -215,7 +235,9 @@ entry:
; OM1-LABEL: test_memmove_very_small_const_len ; OM1-LABEL: test_memmove_very_small_const_len
; OM1: call {{.*}} memmove ; OM1: call {{.*}} memmove
; ARM32-LABEL: test_memmove_very_small_const_len ; ARM32-LABEL: test_memmove_very_small_const_len
; ARM32: bl {{.*}} memmove ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memmove
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memmove_const_len_3(i32 %iptr_dst, i32 %iptr_src) { define internal void @test_memmove_const_len_3(i32 %iptr_dst, i32 %iptr_src) {
entry: entry:
...@@ -234,7 +256,9 @@ entry: ...@@ -234,7 +256,9 @@ entry:
; OM1-LABEL: test_memmove_const_len_3 ; OM1-LABEL: test_memmove_const_len_3
; OM1: call {{.*}} memmove ; OM1: call {{.*}} memmove
; ARM32-LABEL: test_memmove_const_len_3 ; ARM32-LABEL: test_memmove_const_len_3
; ARM32: bl {{.*}} memmove ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memmove
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memmove_mid_const_len(i32 %iptr_dst, i32 %iptr_src) { define internal void @test_memmove_mid_const_len(i32 %iptr_dst, i32 %iptr_src) {
entry: entry:
...@@ -253,7 +277,9 @@ entry: ...@@ -253,7 +277,9 @@ entry:
; OM1-LABEL: test_memmove_mid_const_len ; OM1-LABEL: test_memmove_mid_const_len
; OM1: call {{.*}} memmove ; OM1: call {{.*}} memmove
; ARM32-LABEL: test_memmove_mid_const_len ; ARM32-LABEL: test_memmove_mid_const_len
; ARM32: bl {{.*}} memmove ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memmove
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memmove_mid_const_len_overlap(i32 %iptr_dst, define internal void @test_memmove_mid_const_len_overlap(i32 %iptr_dst,
i32 %iptr_src) { i32 %iptr_src) {
...@@ -273,7 +299,9 @@ entry: ...@@ -273,7 +299,9 @@ entry:
; OM1-LABEL: test_memmove_mid_const_len_overlap ; OM1-LABEL: test_memmove_mid_const_len_overlap
; OM1: call {{.*}} memmove ; OM1: call {{.*}} memmove
; ARM32-LABEL: test_memmove_mid_const_len_overlap ; ARM32-LABEL: test_memmove_mid_const_len_overlap
; ARM32: bl {{.*}} memmove ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memmove
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memmove_big_const_len_overlap(i32 %iptr_dst, define internal void @test_memmove_big_const_len_overlap(i32 %iptr_dst,
i32 %iptr_src) { i32 %iptr_src) {
...@@ -293,7 +321,9 @@ entry: ...@@ -293,7 +321,9 @@ entry:
; OM1-LABEL: test_memmove_big_const_len_overlap ; OM1-LABEL: test_memmove_big_const_len_overlap
; OM1: call {{.*}} memmove ; OM1: call {{.*}} memmove
; ARM32-LABEL: test_memmove_big_const_len_overlap ; ARM32-LABEL: test_memmove_big_const_len_overlap
; ARM32: bl {{.*}} memmove ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memmove
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memmove_large_const_len(i32 %iptr_dst, define internal void @test_memmove_large_const_len(i32 %iptr_dst,
i32 %iptr_src) { i32 %iptr_src) {
...@@ -315,7 +345,9 @@ entry: ...@@ -315,7 +345,9 @@ entry:
; OM1-LABEL: test_memmove_large_const_len ; OM1-LABEL: test_memmove_large_const_len
; OM1: call {{.*}} memmove ; OM1: call {{.*}} memmove
; ARM32-LABEL: test_memmove_large_const_len ; ARM32-LABEL: test_memmove_large_const_len
; ARM32: bl {{.*}} memmove ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memmove
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memset(i32 %iptr_dst, i32 %wide_val, i32 %len) { define internal void @test_memset(i32 %iptr_dst, i32 %wide_val, i32 %len) {
entry: entry:
...@@ -333,7 +365,9 @@ entry: ...@@ -333,7 +365,9 @@ entry:
; OM1: call {{.*}} R_{{.*}} memset ; OM1: call {{.*}} R_{{.*}} memset
; ARM32-LABEL: test_memset ; ARM32-LABEL: test_memset
; ARM32: uxtb ; ARM32: uxtb
; ARM32: bl {{.*}} memset ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memset
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memset_const_len_align(i32 %iptr_dst, define internal void @test_memset_const_len_align(i32 %iptr_dst,
i32 %wide_val) { i32 %wide_val) {
...@@ -352,7 +386,9 @@ entry: ...@@ -352,7 +386,9 @@ entry:
; OM1: call {{.*}} R_{{.*}} memset ; OM1: call {{.*}} R_{{.*}} memset
; ARM32-LABEL: test_memset_const_len_align ; ARM32-LABEL: test_memset_const_len_align
; ARM32: uxtb ; ARM32: uxtb
; ARM32: bl {{.*}} memset ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memset
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memset_long_const_len_zero_val_align( define internal void @test_memset_long_const_len_zero_val_align(
i32 %iptr_dst) { i32 %iptr_dst) {
...@@ -368,7 +404,9 @@ entry: ...@@ -368,7 +404,9 @@ entry:
; OM1: call {{.*}} R_{{.*}} memset ; OM1: call {{.*}} R_{{.*}} memset
; ARM32-LABEL: test_memset_long_const_len_zero_val_align ; ARM32-LABEL: test_memset_long_const_len_zero_val_align
; ARM32: uxtb ; ARM32: uxtb
; ARM32: bl {{.*}} memset ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memset
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memset_const_val(i32 %iptr_dst, i32 %len) { define internal void @test_memset_const_val(i32 %iptr_dst, i32 %len) {
entry: entry:
...@@ -383,7 +421,9 @@ entry: ...@@ -383,7 +421,9 @@ entry:
; OM1: call {{.*}} R_{{.*}} memset ; OM1: call {{.*}} R_{{.*}} memset
; ARM32-LABEL: test_memset_const_val ; ARM32-LABEL: test_memset_const_val
; ARM32: uxtb ; ARM32: uxtb
; ARM32: bl {{.*}} memset ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memset
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memset_const_val_len_very_small(i32 %iptr_dst) { define internal void @test_memset_const_val_len_very_small(i32 %iptr_dst) {
entry: entry:
...@@ -398,7 +438,9 @@ entry: ...@@ -398,7 +438,9 @@ entry:
; OM1: call {{.*}} R_{{.*}} memset ; OM1: call {{.*}} R_{{.*}} memset
; ARM32-LABEL: test_memset_const_val_len_very_small ; ARM32-LABEL: test_memset_const_val_len_very_small
; ARM32: uxtb ; ARM32: uxtb
; ARM32: bl {{.*}} memset ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memset
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memset_const_val_len_3(i32 %iptr_dst) { define internal void @test_memset_const_val_len_3(i32 %iptr_dst) {
entry: entry:
...@@ -414,7 +456,9 @@ entry: ...@@ -414,7 +456,9 @@ entry:
; OM1: call {{.*}} R_{{.*}} memset ; OM1: call {{.*}} R_{{.*}} memset
; ARM32-LABEL: test_memset_const_val_len_3 ; ARM32-LABEL: test_memset_const_val_len_3
; ARM32: uxtb ; ARM32: uxtb
; ARM32: bl {{.*}} memset ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memset
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memset_const_val_len_mid(i32 %iptr_dst) { define internal void @test_memset_const_val_len_mid(i32 %iptr_dst) {
entry: entry:
...@@ -431,7 +475,9 @@ entry: ...@@ -431,7 +475,9 @@ entry:
; OM1: call {{.*}} R_{{.*}} memset ; OM1: call {{.*}} R_{{.*}} memset
; ARM32-LABEL: test_memset_const_val_len_mid ; ARM32-LABEL: test_memset_const_val_len_mid
; ARM32: uxtb ; ARM32: uxtb
; ARM32: bl {{.*}} memset ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memset
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memset_zero_const_len_small(i32 %iptr_dst) { define internal void @test_memset_zero_const_len_small(i32 %iptr_dst) {
entry: entry:
...@@ -448,7 +494,9 @@ entry: ...@@ -448,7 +494,9 @@ entry:
; OM1: call {{.*}} R_{{.*}} memset ; OM1: call {{.*}} R_{{.*}} memset
; ARM32-LABEL: test_memset_zero_const_len_small ; ARM32-LABEL: test_memset_zero_const_len_small
; ARM32: uxtb ; ARM32: uxtb
; ARM32: bl {{.*}} memset ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memset
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memset_zero_const_len_small_overlap(i32 %iptr_dst) { define internal void @test_memset_zero_const_len_small_overlap(i32 %iptr_dst) {
entry: entry:
...@@ -465,7 +513,9 @@ entry: ...@@ -465,7 +513,9 @@ entry:
; OM1: call {{.*}} R_{{.*}} memset ; OM1: call {{.*}} R_{{.*}} memset
; ARM32-LABEL: test_memset_zero_const_len_small_overlap ; ARM32-LABEL: test_memset_zero_const_len_small_overlap
; ARM32: uxtb ; ARM32: uxtb
; ARM32: bl {{.*}} memset ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memset
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memset_zero_const_len_big_overlap(i32 %iptr_dst) { define internal void @test_memset_zero_const_len_big_overlap(i32 %iptr_dst) {
entry: entry:
...@@ -482,7 +532,9 @@ entry: ...@@ -482,7 +532,9 @@ entry:
; OM1: call {{.*}} R_{{.*}} memset ; OM1: call {{.*}} R_{{.*}} memset
; ARM32-LABEL: test_memset_zero_const_len_big_overlap ; ARM32-LABEL: test_memset_zero_const_len_big_overlap
; ARM32: uxtb ; ARM32: uxtb
; ARM32: bl {{.*}} memset ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memset
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal void @test_memset_zero_const_len_large(i32 %iptr_dst) { define internal void @test_memset_zero_const_len_large(i32 %iptr_dst) {
entry: entry:
...@@ -500,4 +552,6 @@ entry: ...@@ -500,4 +552,6 @@ entry:
; OM1: call {{.*}} R_{{.*}} memset ; OM1: call {{.*}} R_{{.*}} memset
; ARM32-LABEL: test_memset_zero_const_len_large ; ARM32-LABEL: test_memset_zero_const_len_large
; ARM32: uxtb ; ARM32: uxtb
; ARM32: bl {{.*}} memset ; ARM32: movw [[CALL:r[0-9]]], {{.+}} memset
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
...@@ -129,8 +129,12 @@ NonZero: ...@@ -129,8 +129,12 @@ NonZero:
; CHECKO2REM: call {{.*}} R_{{.*}} setjmp ; CHECKO2REM: call {{.*}} R_{{.*}} setjmp
; CHECKO2REM: call {{.*}} R_{{.*}} longjmp ; CHECKO2REM: call {{.*}} R_{{.*}} longjmp
; ARM32-LABEL: test_setjmplongjmp ; ARM32-LABEL: test_setjmplongjmp
; ARM32: bl {{.*}} setjmp ; ARM32: movw [[CALL:r[0-9]]], {{.+}} setjmp
; ARM32: bl {{.*}} longjmp ; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
; ARM32: movw [[CALL:r[0-9]]], {{.+}} longjmp
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal i32 @test_setjmp_unused(i32 %iptr_env, i32 %i_other) { define internal i32 @test_setjmp_unused(i32 %iptr_env, i32 %i_other) {
entry: entry:
...@@ -471,7 +475,9 @@ entry: ...@@ -471,7 +475,9 @@ entry:
; CHECK-LABEL: test_popcount_32 ; CHECK-LABEL: test_popcount_32
; CHECK: call {{.*}} R_{{.*}} __popcountsi2 ; CHECK: call {{.*}} R_{{.*}} __popcountsi2
; ARM32-LABEL: test_popcount_32 ; ARM32-LABEL: test_popcount_32
; ARM32: bl {{.*}} __popcountsi2 ; ARM32: movw [[CALL:r[0-9]]], {{.+}} __popcountsi2
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
define internal i64 @test_popcount_64(i64 %x) { define internal i64 @test_popcount_64(i64 %x) {
entry: entry:
...@@ -484,7 +490,9 @@ entry: ...@@ -484,7 +490,9 @@ entry:
; the return value just in case. ; the return value just in case.
; CHECK: mov {{.*}},0x0 ; CHECK: mov {{.*}},0x0
; ARM32-LABEL: test_popcount_64 ; ARM32-LABEL: test_popcount_64
; ARM32: bl {{.*}} __popcountdi2 ; ARM32: movw [[CALL:r[0-9]]], {{.+}} __popcountdi2
; ARM32: movt [[CALL]]
; ARM32: blx [[CALL]]
; ARM32: mov {{.*}}, #0 ; ARM32: mov {{.*}}, #0
define internal i32 @test_popcount_64_ret_i32(i64 %x) { define internal i32 @test_popcount_64_ret_i32(i64 %x) {
......
...@@ -51,15 +51,23 @@ declare void @useInt(i32 %x) ...@@ -51,15 +51,23 @@ declare void @useInt(i32 %x)
; CHECK: ret ; CHECK: ret
; ARM32-LABEL: testSelect ; ARM32-LABEL: testSelect
; ARM32: cmp ; ARM32: cmp
; ARM32: bl {{.*}} useInt ; ARM32: movw [[CALL:r[0-9]]], {{.+}} useInt
; ARM32: movt [[CALL]]
; ARM32; blx [[CALL]]
; ARM32-Om1: mov {{.*}}, #20 ; ARM32-Om1: mov {{.*}}, #20
; ARM32-O2: mov [[REG:r[0-9]+]], #20 ; ARM32-O2: mov [[REG:r[0-9]+]], #20
; ARM32: tst ; ARM32: tst
; ARM32-Om1: movne {{.*}}, #10 ; ARM32-Om1: movne {{.*}}, #10
; ARM32-O2: movne [[REG]], #10 ; ARM32-O2: movne [[REG]], #10
; ARM32: bl {{.*}} useInt ; ARM32: movw [[CALL:r[0-9]]], {{.+}} useInt
; ARM32: bl {{.*}} useInt ; ARM32: movt [[CALL]]
; ARM32: bl {{.*}} useInt ; ARM32; blx [[CALL]]
; ARM32: movw [[CALL:r[0-9]]], {{.+}} useInt
; ARM32: movt [[CALL]]
; ARM32; blx [[CALL]]
; ARM32: movw [[CALL:r[0-9]]], {{.+}} useInt
; ARM32: movt [[CALL]]
; ARM32; blx [[CALL]]
; ARM32: bx lr ; ARM32: bx lr
; Check for valid addressing mode in the cmp instruction when the ; Check for valid addressing mode in the cmp instruction when the
......
...@@ -9,12 +9,12 @@ ...@@ -9,12 +9,12 @@
; RUN: %if --need=target_ARM32 --need=allow_dump \ ; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble \ ; RUN: --command %p2i --filetype=asm --assemble \
; RUN: --disassemble --target arm32 -i %s --args -O2 --skip-unimplemented \ ; RUN: --disassemble --target arm32 -i %s --args -O2 \
; RUN: | %if --need=target_ARM32 --need=allow_dump \ ; RUN: | %if --need=target_ARM32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix ARM32 %s ; RUN: --command FileCheck --check-prefix ARM32 %s
; RUN: %if --need=target_ARM32 --need=allow_dump \ ; RUN: %if --need=target_ARM32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble \ ; RUN: --command %p2i --filetype=asm --assemble \
; RUN: --disassemble --target arm32 -i %s --args -Om1 --skip-unimplemented \ ; RUN: --disassemble --target arm32 -i %s --args -Om1 \
; RUN: | %if --need=target_ARM32 --need=allow_dump \ ; RUN: | %if --need=target_ARM32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix ARM32 %s ; RUN: --command FileCheck --check-prefix ARM32 %s
...@@ -41,5 +41,7 @@ return: ; preds = %entry ...@@ -41,5 +41,7 @@ return: ; preds = %entry
; ARM32-LABEL: divide ; ARM32-LABEL: divide
; ARM32: tst ; ARM32: tst
; ARM32: .word 0xe7fedef0 ; ARM32: .word 0xe7fedef0
; ARM32: bl {{.*}} __divsi3 ; ARM32: movw [[CALL:r[0-9]]], {{.+}} __divsi3
; ARM32: movt [[CALL]]
; ARM32; blx [[CALL]]
; ARM32: bx lr ; ARM32: bx lr
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment