| OLD | NEW |
| 1 ; This file checks that Subzero generates code in accordance with the | 1 ; This file checks that Subzero generates code in accordance with the |
| 2 ; calling convention for integers. | 2 ; calling convention for integers. |
| 3 | 3 |
| 4 ; RUN: %if --need=target_X8632 --command %p2i --filetype=obj --disassemble \ | 4 ; RUN: %if --need=target_X8632 --command %p2i --filetype=obj --disassemble \ |
| 5 ; RUN: --target x8632 -i %s --args -O2 \ | 5 ; RUN: --target x8632 -i %s --args -O2 -allow-externally-defined-symbols \ |
| 6 ; RUN: | %if --need=target_X8632 --command FileCheck %s | 6 ; RUN: | %if --need=target_X8632 --command FileCheck %s |
| 7 | 7 |
| 8 ; TODO(jvoung): Stop skipping unimplemented parts (via --skip-unimplemented) | 8 ; TODO(jvoung): Stop skipping unimplemented parts (via --skip-unimplemented) |
| 9 ; once enough infrastructure is in. Also, switch to --filetype=obj | 9 ; once enough infrastructure is in. Also, switch to --filetype=obj |
| 10 ; when possible. | 10 ; when possible. |
| 11 ; RUN: %if --need=target_ARM32 --need=allow_dump \ | 11 ; RUN: %if --need=target_ARM32 --need=allow_dump \ |
| 12 ; RUN: --command %p2i --filetype=asm --assemble \ | 12 ; RUN: --command %p2i --filetype=asm --assemble \ |
| 13 ; RUN: --disassemble --target arm32 -i %s --args -O2 --skip-unimplemented \ | 13 ; RUN: --disassemble --target arm32 -i %s --args -O2 --skip-unimplemented \ |
| 14 ; RUN: -allow-externally-defined-symbols \ |
| 14 ; RUN: | %if --need=target_ARM32 --need=allow_dump \ | 15 ; RUN: | %if --need=target_ARM32 --need=allow_dump \ |
| 15 ; RUN: --command FileCheck --check-prefix ARM32 %s | 16 ; RUN: --command FileCheck --check-prefix ARM32 %s |
| 16 | 17 |
| 17 ; For x86-32, integer arguments use the stack. | 18 ; For x86-32, integer arguments use the stack. |
| 18 ; For ARM32, integer arguments can be r0-r3. i64 arguments occupy two | 19 ; For ARM32, integer arguments can be r0-r3. i64 arguments occupy two |
| 19 ; adjacent 32-bit registers, and require the first to be an even register. | 20 ; adjacent 32-bit registers, and require the first to be an even register. |
| 20 | 21 |
| 21 | 22 |
| 22 ; i32 | 23 ; i32 |
| 23 | 24 |
| 24 define i32 @test_returning32_arg0(i32 %arg0, i32 %arg1, i32 %arg2, i32 %arg3, i3
2 %arg4, i32 %arg5, i32 %arg6, i32 %arg7) { | 25 define internal i32 @test_returning32_arg0(i32 %arg0, i32 %arg1, i32 %arg2, i32
%arg3, i32 %arg4, i32 %arg5, i32 %arg6, i32 %arg7) { |
| 25 entry: | 26 entry: |
| 26 ret i32 %arg0 | 27 ret i32 %arg0 |
| 27 } | 28 } |
| 28 ; CHECK-LABEL: test_returning32_arg0 | 29 ; CHECK-LABEL: test_returning32_arg0 |
| 29 ; CHECK-NEXT: mov eax,{{.*}} [esp+0x4] | 30 ; CHECK-NEXT: mov eax,{{.*}} [esp+0x4] |
| 30 ; CHECK-NEXT: ret | 31 ; CHECK-NEXT: ret |
| 31 ; ARM32-LABEL: test_returning32_arg0 | 32 ; ARM32-LABEL: test_returning32_arg0 |
| 32 ; ARM32-NEXT: bx lr | 33 ; ARM32-NEXT: bx lr |
| 33 | 34 |
| 34 define i32 @test_returning32_arg1(i32 %arg0, i32 %arg1, i32 %arg2, i32 %arg3, i3
2 %arg4, i32 %arg5, i32 %arg6, i32 %arg7) { | 35 define internal i32 @test_returning32_arg1(i32 %arg0, i32 %arg1, i32 %arg2, i32
%arg3, i32 %arg4, i32 %arg5, i32 %arg6, i32 %arg7) { |
| 35 entry: | 36 entry: |
| 36 ret i32 %arg1 | 37 ret i32 %arg1 |
| 37 } | 38 } |
| 38 ; CHECK-LABEL: test_returning32_arg1 | 39 ; CHECK-LABEL: test_returning32_arg1 |
| 39 ; CHECK-NEXT: mov eax,{{.*}} [esp+0x8] | 40 ; CHECK-NEXT: mov eax,{{.*}} [esp+0x8] |
| 40 ; CHECK-NEXT: ret | 41 ; CHECK-NEXT: ret |
| 41 ; ARM32-LABEL: test_returning32_arg1 | 42 ; ARM32-LABEL: test_returning32_arg1 |
| 42 ; ARM32-NEXT: mov r0, r1 | 43 ; ARM32-NEXT: mov r0, r1 |
| 43 ; ARM32-NEXT: bx lr | 44 ; ARM32-NEXT: bx lr |
| 44 | 45 |
| 45 | 46 |
| 46 define i32 @test_returning32_arg2(i32 %arg0, i32 %arg1, i32 %arg2, i32 %arg3, i3
2 %arg4, i32 %arg5, i32 %arg6, i32 %arg7) { | 47 define internal i32 @test_returning32_arg2(i32 %arg0, i32 %arg1, i32 %arg2, i32
%arg3, i32 %arg4, i32 %arg5, i32 %arg6, i32 %arg7) { |
| 47 entry: | 48 entry: |
| 48 ret i32 %arg2 | 49 ret i32 %arg2 |
| 49 } | 50 } |
| 50 ; CHECK-LABEL: test_returning32_arg2 | 51 ; CHECK-LABEL: test_returning32_arg2 |
| 51 ; CHECK-NEXT: mov eax,{{.*}} [esp+0xc] | 52 ; CHECK-NEXT: mov eax,{{.*}} [esp+0xc] |
| 52 ; CHECK-NEXT: ret | 53 ; CHECK-NEXT: ret |
| 53 ; ARM32-LABEL: test_returning32_arg2 | 54 ; ARM32-LABEL: test_returning32_arg2 |
| 54 ; ARM32-NEXT: mov r0, r2 | 55 ; ARM32-NEXT: mov r0, r2 |
| 55 ; ARM32-NEXT: bx lr | 56 ; ARM32-NEXT: bx lr |
| 56 | 57 |
| 57 | 58 |
| 58 define i32 @test_returning32_arg3(i32 %arg0, i32 %arg1, i32 %arg2, i32 %arg3, i3
2 %arg4, i32 %arg5, i32 %arg6, i32 %arg7) { | 59 define internal i32 @test_returning32_arg3(i32 %arg0, i32 %arg1, i32 %arg2, i32
%arg3, i32 %arg4, i32 %arg5, i32 %arg6, i32 %arg7) { |
| 59 entry: | 60 entry: |
| 60 ret i32 %arg3 | 61 ret i32 %arg3 |
| 61 } | 62 } |
| 62 ; CHECK-LABEL: test_returning32_arg3 | 63 ; CHECK-LABEL: test_returning32_arg3 |
| 63 ; CHECK-NEXT: mov eax,{{.*}} [esp+0x10] | 64 ; CHECK-NEXT: mov eax,{{.*}} [esp+0x10] |
| 64 ; CHECK-NEXT: ret | 65 ; CHECK-NEXT: ret |
| 65 ; ARM32-LABEL: test_returning32_arg3 | 66 ; ARM32-LABEL: test_returning32_arg3 |
| 66 ; ARM32-NEXT: mov r0, r3 | 67 ; ARM32-NEXT: mov r0, r3 |
| 67 ; ARM32-NEXT: bx lr | 68 ; ARM32-NEXT: bx lr |
| 68 | 69 |
| 69 | 70 |
| 70 define i32 @test_returning32_arg4(i32 %arg0, i32 %arg1, i32 %arg2, i32 %arg3, i3
2 %arg4, i32 %arg5, i32 %arg6, i32 %arg7) { | 71 define internal i32 @test_returning32_arg4(i32 %arg0, i32 %arg1, i32 %arg2, i32
%arg3, i32 %arg4, i32 %arg5, i32 %arg6, i32 %arg7) { |
| 71 entry: | 72 entry: |
| 72 ret i32 %arg4 | 73 ret i32 %arg4 |
| 73 } | 74 } |
| 74 ; CHECK-LABEL: test_returning32_arg4 | 75 ; CHECK-LABEL: test_returning32_arg4 |
| 75 ; CHECK-NEXT: mov eax,{{.*}} [esp+0x14] | 76 ; CHECK-NEXT: mov eax,{{.*}} [esp+0x14] |
| 76 ; CHECK-NEXT: ret | 77 ; CHECK-NEXT: ret |
| 77 ; ARM32-LABEL: test_returning32_arg4 | 78 ; ARM32-LABEL: test_returning32_arg4 |
| 78 ; ARM32-NEXT: ldr r0, [sp] | 79 ; ARM32-NEXT: ldr r0, [sp] |
| 79 ; ARM32-NEXT: bx lr | 80 ; ARM32-NEXT: bx lr |
| 80 | 81 |
| 81 | 82 |
| 82 define i32 @test_returning32_arg5(i32 %arg0, i32 %arg1, i32 %arg2, i32 %arg3, i3
2 %arg4, i32 %arg5, i32 %arg6, i32 %arg7) { | 83 define internal i32 @test_returning32_arg5(i32 %arg0, i32 %arg1, i32 %arg2, i32
%arg3, i32 %arg4, i32 %arg5, i32 %arg6, i32 %arg7) { |
| 83 entry: | 84 entry: |
| 84 ret i32 %arg5 | 85 ret i32 %arg5 |
| 85 } | 86 } |
| 86 ; CHECK-LABEL: test_returning32_arg5 | 87 ; CHECK-LABEL: test_returning32_arg5 |
| 87 ; CHECK-NEXT: mov eax,{{.*}} [esp+0x18] | 88 ; CHECK-NEXT: mov eax,{{.*}} [esp+0x18] |
| 88 ; CHECK-NEXT: ret | 89 ; CHECK-NEXT: ret |
| 89 ; ARM32-LABEL: test_returning32_arg5 | 90 ; ARM32-LABEL: test_returning32_arg5 |
| 90 ; ARM32-NEXT: ldr r0, [sp, #4] | 91 ; ARM32-NEXT: ldr r0, [sp, #4] |
| 91 ; ARM32-NEXT: bx lr | 92 ; ARM32-NEXT: bx lr |
| 92 | 93 |
| 93 ; i64 | 94 ; i64 |
| 94 | 95 |
| 95 define i64 @test_returning64_arg0(i64 %arg0, i64 %arg1, i64 %arg2, i64 %arg3) { | 96 define internal i64 @test_returning64_arg0(i64 %arg0, i64 %arg1, i64 %arg2, i64
%arg3) { |
| 96 entry: | 97 entry: |
| 97 ret i64 %arg0 | 98 ret i64 %arg0 |
| 98 } | 99 } |
| 99 ; CHECK-LABEL: test_returning64_arg0 | 100 ; CHECK-LABEL: test_returning64_arg0 |
| 100 ; CHECK-NEXT: mov {{.*}} [esp+0x4] | 101 ; CHECK-NEXT: mov {{.*}} [esp+0x4] |
| 101 ; CHECK-NEXT: mov {{.*}} [esp+0x8] | 102 ; CHECK-NEXT: mov {{.*}} [esp+0x8] |
| 102 ; CHECK: ret | 103 ; CHECK: ret |
| 103 ; ARM32-LABEL: test_returning64_arg0 | 104 ; ARM32-LABEL: test_returning64_arg0 |
| 104 ; ARM32-NEXT: bx lr | 105 ; ARM32-NEXT: bx lr |
| 105 | 106 |
| 106 define i64 @test_returning64_arg1(i64 %arg0, i64 %arg1, i64 %arg2, i64 %arg3) { | 107 define internal i64 @test_returning64_arg1(i64 %arg0, i64 %arg1, i64 %arg2, i64
%arg3) { |
| 107 entry: | 108 entry: |
| 108 ret i64 %arg1 | 109 ret i64 %arg1 |
| 109 } | 110 } |
| 110 ; CHECK-LABEL: test_returning64_arg1 | 111 ; CHECK-LABEL: test_returning64_arg1 |
| 111 ; CHECK-NEXT: mov {{.*}} [esp+0xc] | 112 ; CHECK-NEXT: mov {{.*}} [esp+0xc] |
| 112 ; CHECK-NEXT: mov {{.*}} [esp+0x10] | 113 ; CHECK-NEXT: mov {{.*}} [esp+0x10] |
| 113 ; CHECK: ret | 114 ; CHECK: ret |
| 114 ; ARM32-LABEL: test_returning64_arg1 | 115 ; ARM32-LABEL: test_returning64_arg1 |
| 115 ; ARM32-NEXT: mov r0, r2 | 116 ; ARM32-NEXT: mov r0, r2 |
| 116 ; ARM32-NEXT: mov r1, r3 | 117 ; ARM32-NEXT: mov r1, r3 |
| 117 ; ARM32-NEXT: bx lr | 118 ; ARM32-NEXT: bx lr |
| 118 | 119 |
| 119 define i64 @test_returning64_arg2(i64 %arg0, i64 %arg1, i64 %arg2, i64 %arg3) { | 120 define internal i64 @test_returning64_arg2(i64 %arg0, i64 %arg1, i64 %arg2, i64
%arg3) { |
| 120 entry: | 121 entry: |
| 121 ret i64 %arg2 | 122 ret i64 %arg2 |
| 122 } | 123 } |
| 123 ; CHECK-LABEL: test_returning64_arg2 | 124 ; CHECK-LABEL: test_returning64_arg2 |
| 124 ; CHECK-NEXT: mov {{.*}} [esp+0x14] | 125 ; CHECK-NEXT: mov {{.*}} [esp+0x14] |
| 125 ; CHECK-NEXT: mov {{.*}} [esp+0x18] | 126 ; CHECK-NEXT: mov {{.*}} [esp+0x18] |
| 126 ; CHECK: ret | 127 ; CHECK: ret |
| 127 ; ARM32-LABEL: test_returning64_arg2 | 128 ; ARM32-LABEL: test_returning64_arg2 |
| 128 ; This could have been a ldm sp, {r0, r1}, but we don't do the ldm optimization. | 129 ; This could have been a ldm sp, {r0, r1}, but we don't do the ldm optimization. |
| 129 ; ARM32-NEXT: ldr r0, [sp] | 130 ; ARM32-NEXT: ldr r0, [sp] |
| 130 ; ARM32-NEXT: ldr r1, [sp, #4] | 131 ; ARM32-NEXT: ldr r1, [sp, #4] |
| 131 ; ARM32-NEXT: bx lr | 132 ; ARM32-NEXT: bx lr |
| 132 | 133 |
| 133 define i64 @test_returning64_arg3(i64 %arg0, i64 %arg1, i64 %arg2, i64 %arg3) { | 134 define internal i64 @test_returning64_arg3(i64 %arg0, i64 %arg1, i64 %arg2, i64
%arg3) { |
| 134 entry: | 135 entry: |
| 135 ret i64 %arg3 | 136 ret i64 %arg3 |
| 136 } | 137 } |
| 137 ; CHECK-LABEL: test_returning64_arg3 | 138 ; CHECK-LABEL: test_returning64_arg3 |
| 138 ; CHECK-NEXT: mov {{.*}} [esp+0x1c] | 139 ; CHECK-NEXT: mov {{.*}} [esp+0x1c] |
| 139 ; CHECK-NEXT: mov {{.*}} [esp+0x20] | 140 ; CHECK-NEXT: mov {{.*}} [esp+0x20] |
| 140 ; CHECK: ret | 141 ; CHECK: ret |
| 141 ; ARM32-LABEL: test_returning64_arg3 | 142 ; ARM32-LABEL: test_returning64_arg3 |
| 142 ; ARM32-NEXT: ldr r0, [sp, #8] | 143 ; ARM32-NEXT: ldr r0, [sp, #8] |
| 143 ; ARM32-NEXT: ldr r1, [sp, #12] | 144 ; ARM32-NEXT: ldr r1, [sp, #12] |
| 144 ; ARM32-NEXT: bx lr | 145 ; ARM32-NEXT: bx lr |
| 145 | 146 |
| 146 | 147 |
| 147 ; Test that on ARM, the i64 arguments start with an even register. | 148 ; Test that on ARM, the i64 arguments start with an even register. |
| 148 | 149 |
| 149 define i64 @test_returning64_even_arg1(i32 %arg0, i64 %arg1, i64 %arg2) { | 150 define internal i64 @test_returning64_even_arg1(i32 %arg0, i64 %arg1, i64 %arg2)
{ |
| 150 entry: | 151 entry: |
| 151 ret i64 %arg1 | 152 ret i64 %arg1 |
| 152 } | 153 } |
| 153 ; Not padded out x86-32. | 154 ; Not padded out x86-32. |
| 154 ; CHECK-LABEL: test_returning64_even_arg1 | 155 ; CHECK-LABEL: test_returning64_even_arg1 |
| 155 ; CHECK-NEXT: mov {{.*}} [esp+0x8] | 156 ; CHECK-NEXT: mov {{.*}} [esp+0x8] |
| 156 ; CHECK-NEXT: mov {{.*}} [esp+0xc] | 157 ; CHECK-NEXT: mov {{.*}} [esp+0xc] |
| 157 ; CHECK: ret | 158 ; CHECK: ret |
| 158 ; ARM32-LABEL: test_returning64_even_arg1 | 159 ; ARM32-LABEL: test_returning64_even_arg1 |
| 159 ; ARM32-NEXT: mov r0, r2 | 160 ; ARM32-NEXT: mov r0, r2 |
| 160 ; ARM32-NEXT: mov r1, r3 | 161 ; ARM32-NEXT: mov r1, r3 |
| 161 ; ARM32-NEXT: bx lr | 162 ; ARM32-NEXT: bx lr |
| 162 | 163 |
| 163 define i64 @test_returning64_even_arg1b(i32 %arg0, i32 %arg0b, i64 %arg1, i64 %a
rg2) { | 164 define internal i64 @test_returning64_even_arg1b(i32 %arg0, i32 %arg0b, i64 %arg
1, i64 %arg2) { |
| 164 entry: | 165 entry: |
| 165 ret i64 %arg1 | 166 ret i64 %arg1 |
| 166 } | 167 } |
| 167 ; CHECK-LABEL: test_returning64_even_arg1b | 168 ; CHECK-LABEL: test_returning64_even_arg1b |
| 168 ; CHECK-NEXT: mov {{.*}} [esp+0xc] | 169 ; CHECK-NEXT: mov {{.*}} [esp+0xc] |
| 169 ; CHECK-NEXT: mov {{.*}} [esp+0x10] | 170 ; CHECK-NEXT: mov {{.*}} [esp+0x10] |
| 170 ; CHECK: ret | 171 ; CHECK: ret |
| 171 ; ARM32-LABEL: test_returning64_even_arg1b | 172 ; ARM32-LABEL: test_returning64_even_arg1b |
| 172 ; ARM32-NEXT: mov r0, r2 | 173 ; ARM32-NEXT: mov r0, r2 |
| 173 ; ARM32-NEXT: mov r1, r3 | 174 ; ARM32-NEXT: mov r1, r3 |
| 174 ; ARM32-NEXT: bx lr | 175 ; ARM32-NEXT: bx lr |
| 175 | 176 |
| 176 define i64 @test_returning64_even_arg2(i64 %arg0, i32 %arg1, i64 %arg2) { | 177 define internal i64 @test_returning64_even_arg2(i64 %arg0, i32 %arg1, i64 %arg2)
{ |
| 177 entry: | 178 entry: |
| 178 ret i64 %arg2 | 179 ret i64 %arg2 |
| 179 } | 180 } |
| 180 ; Not padded out on x86-32. | 181 ; Not padded out on x86-32. |
| 181 ; CHECK-LABEL: test_returning64_even_arg2 | 182 ; CHECK-LABEL: test_returning64_even_arg2 |
| 182 ; CHECK-NEXT: mov {{.*}} [esp+0x10] | 183 ; CHECK-NEXT: mov {{.*}} [esp+0x10] |
| 183 ; CHECK-NEXT: mov {{.*}} [esp+0x14] | 184 ; CHECK-NEXT: mov {{.*}} [esp+0x14] |
| 184 ; CHECK: ret | 185 ; CHECK: ret |
| 185 ; ARM32-LABEL: test_returning64_even_arg2 | 186 ; ARM32-LABEL: test_returning64_even_arg2 |
| 186 ; ARM32-DAG: ldr r0, [sp] | 187 ; ARM32-DAG: ldr r0, [sp] |
| 187 ; ARM32-DAG: ldr r1, [sp, #4] | 188 ; ARM32-DAG: ldr r1, [sp, #4] |
| 188 ; ARM32-NEXT: bx lr | 189 ; ARM32-NEXT: bx lr |
| 189 | 190 |
| 190 define i64 @test_returning64_even_arg2b(i64 %arg0, i32 %arg1, i32 %arg1b, i64 %a
rg2) { | 191 define internal i64 @test_returning64_even_arg2b(i64 %arg0, i32 %arg1, i32 %arg1
b, i64 %arg2) { |
| 191 entry: | 192 entry: |
| 192 ret i64 %arg2 | 193 ret i64 %arg2 |
| 193 } | 194 } |
| 194 ; CHECK-LABEL: test_returning64_even_arg2b | 195 ; CHECK-LABEL: test_returning64_even_arg2b |
| 195 ; CHECK-NEXT: mov {{.*}} [esp+0x14] | 196 ; CHECK-NEXT: mov {{.*}} [esp+0x14] |
| 196 ; CHECK-NEXT: mov {{.*}} [esp+0x18] | 197 ; CHECK-NEXT: mov {{.*}} [esp+0x18] |
| 197 ; CHECK: ret | 198 ; CHECK: ret |
| 198 ; ARM32-LABEL: test_returning64_even_arg2b | 199 ; ARM32-LABEL: test_returning64_even_arg2b |
| 199 ; ARM32-NEXT: ldr r0, [sp] | 200 ; ARM32-NEXT: ldr r0, [sp] |
| 200 ; ARM32-NEXT: ldr r1, [sp, #4] | 201 ; ARM32-NEXT: ldr r1, [sp, #4] |
| 201 ; ARM32-NEXT: bx lr | 202 ; ARM32-NEXT: bx lr |
| 202 | 203 |
| 203 define i32 @test_returning32_even_arg2(i64 %arg0, i32 %arg1, i32 %arg2) { | 204 define internal i32 @test_returning32_even_arg2(i64 %arg0, i32 %arg1, i32 %arg2)
{ |
| 204 entry: | 205 entry: |
| 205 ret i32 %arg2 | 206 ret i32 %arg2 |
| 206 } | 207 } |
| 207 ; CHECK-LABEL: test_returning32_even_arg2 | 208 ; CHECK-LABEL: test_returning32_even_arg2 |
| 208 ; CHECK-NEXT: mov {{.*}} [esp+0x10] | 209 ; CHECK-NEXT: mov {{.*}} [esp+0x10] |
| 209 ; CHECK-NEXT: ret | 210 ; CHECK-NEXT: ret |
| 210 ; ARM32-LABEL: test_returning32_even_arg2 | 211 ; ARM32-LABEL: test_returning32_even_arg2 |
| 211 ; ARM32-NEXT: mov r0, r3 | 212 ; ARM32-NEXT: mov r0, r3 |
| 212 ; ARM32-NEXT: bx lr | 213 ; ARM32-NEXT: bx lr |
| 213 | 214 |
| 214 define i32 @test_returning32_even_arg2b(i32 %arg0, i32 %arg1, i32 %arg2, i64 %ar
g3) { | 215 define internal i32 @test_returning32_even_arg2b(i32 %arg0, i32 %arg1, i32 %arg2
, i64 %arg3) { |
| 215 entry: | 216 entry: |
| 216 ret i32 %arg2 | 217 ret i32 %arg2 |
| 217 } | 218 } |
| 218 ; CHECK-LABEL: test_returning32_even_arg2b | 219 ; CHECK-LABEL: test_returning32_even_arg2b |
| 219 ; CHECK-NEXT: mov {{.*}} [esp+0xc] | 220 ; CHECK-NEXT: mov {{.*}} [esp+0xc] |
| 220 ; CHECK-NEXT: ret | 221 ; CHECK-NEXT: ret |
| 221 ; ARM32-LABEL: test_returning32_even_arg2b | 222 ; ARM32-LABEL: test_returning32_even_arg2b |
| 222 ; ARM32-NEXT: mov r0, r2 | 223 ; ARM32-NEXT: mov r0, r2 |
| 223 ; ARM32-NEXT: bx lr | 224 ; ARM32-NEXT: bx lr |
| 224 | 225 |
| 225 ; The i64 won't fit in a pair of register, and consumes the last register so a | 226 ; The i64 won't fit in a pair of register, and consumes the last register so a |
| 226 ; following i32 can't use that free register. | 227 ; following i32 can't use that free register. |
| 227 define i32 @test_returning32_even_arg4(i32 %arg0, i32 %arg1, i32 %arg2, i64 %arg
3, i32 %arg4) { | 228 define internal i32 @test_returning32_even_arg4(i32 %arg0, i32 %arg1, i32 %arg2,
i64 %arg3, i32 %arg4) { |
| 228 entry: | 229 entry: |
| 229 ret i32 %arg4 | 230 ret i32 %arg4 |
| 230 } | 231 } |
| 231 ; CHECK-LABEL: test_returning32_even_arg4 | 232 ; CHECK-LABEL: test_returning32_even_arg4 |
| 232 ; CHECK-NEXT: mov {{.*}} [esp+0x18] | 233 ; CHECK-NEXT: mov {{.*}} [esp+0x18] |
| 233 ; CHECK-NEXT: ret | 234 ; CHECK-NEXT: ret |
| 234 ; ARM32-LABEL: test_returning32_even_arg4 | 235 ; ARM32-LABEL: test_returning32_even_arg4 |
| 235 ; ARM32-NEXT: ldr r0, [sp, #8] | 236 ; ARM32-NEXT: ldr r0, [sp, #8] |
| 236 ; ARM32-NEXT: bx lr | 237 ; ARM32-NEXT: bx lr |
| 237 | 238 |
| 238 ; Test interleaving float/double and integer (different register streams on ARM)
. | 239 ; Test interleaving float/double and integer (different register streams on ARM)
. |
| 239 ; TODO(jvoung): Test once the S/D/Q regs are modeled. | 240 ; TODO(jvoung): Test once the S/D/Q regs are modeled. |
| 240 | 241 |
| 241 ; Test that integers are passed correctly as arguments to a function. | 242 ; Test that integers are passed correctly as arguments to a function. |
| 242 | 243 |
| 243 declare void @IntArgs(i32, i32, i32, i32, i32, i32) | 244 declare void @IntArgs(i32, i32, i32, i32, i32, i32) |
| 244 | 245 |
| 245 declare void @killRegisters() | 246 declare void @killRegisters() |
| 246 | 247 |
| 247 define void @test_passing_integers(i32 %arg0, i32 %arg1, i32 %arg2, i32 %arg3, i
32 %arg4, i32 %arg5, i32 %arg6) { | 248 define internal void @test_passing_integers(i32 %arg0, i32 %arg1, i32 %arg2, i32
%arg3, i32 %arg4, i32 %arg5, i32 %arg6) { |
| 248 call void @killRegisters() | 249 call void @killRegisters() |
| 249 call void @IntArgs(i32 %arg6, i32 %arg5, i32 %arg4, i32 %arg3, i32 %arg2, i32
%arg1) | 250 call void @IntArgs(i32 %arg6, i32 %arg5, i32 %arg4, i32 %arg3, i32 %arg2, i32
%arg1) |
| 250 ret void | 251 ret void |
| 251 } | 252 } |
| 252 | 253 |
| 253 ; CHECK-LABEL: test_passing_integers | 254 ; CHECK-LABEL: test_passing_integers |
| 254 ; CHECK-DAG: mov [[REG1:e.*]],DWORD PTR [esp+0x24] | 255 ; CHECK-DAG: mov [[REG1:e.*]],DWORD PTR [esp+0x24] |
| 255 ; CHECK-DAG: mov [[REG2:e.*]],DWORD PTR [esp+0x28] | 256 ; CHECK-DAG: mov [[REG2:e.*]],DWORD PTR [esp+0x28] |
| 256 ; CHECK-DAG: mov [[REG3:e.*]],DWORD PTR [esp+0x2c] | 257 ; CHECK-DAG: mov [[REG3:e.*]],DWORD PTR [esp+0x2c] |
| 257 ; CHECK-DAG: mov [[REG4:e.*]],DWORD PTR [esp+0x30] | 258 ; CHECK-DAG: mov [[REG4:e.*]],DWORD PTR [esp+0x30] |
| 258 ; CHECK: mov DWORD PTR [esp] | 259 ; CHECK: mov DWORD PTR [esp] |
| 259 ; CHECK: mov DWORD PTR [esp+0x4] | 260 ; CHECK: mov DWORD PTR [esp+0x4] |
| 260 ; CHECK-DAG: mov DWORD PTR [esp+0x8],[[REG4]] | 261 ; CHECK-DAG: mov DWORD PTR [esp+0x8],[[REG4]] |
| 261 ; CHECK-DAG: mov DWORD PTR [esp+0xc],[[REG3]] | 262 ; CHECK-DAG: mov DWORD PTR [esp+0xc],[[REG3]] |
| 262 ; CHECK-DAG: mov DWORD PTR [esp+0x10],[[REG2]] | 263 ; CHECK-DAG: mov DWORD PTR [esp+0x10],[[REG2]] |
| 263 ; CHECK-DAG: mov DWORD PTR [esp+0x14],[[REG1]] | 264 ; CHECK-DAG: mov DWORD PTR [esp+0x14],[[REG1]] |
| 264 ; CHECK: call | 265 ; CHECK: call |
| 265 | 266 |
| 266 ; ARM32-LABEL: test_passing_integers | 267 ; ARM32-LABEL: test_passing_integers |
| 267 ; ARM32-DAG: mov [[REG1:.*]], r1 | 268 ; ARM32-DAG: mov [[REG1:.*]], r1 |
| 268 ; ARM32-DAG: mov [[REG2:.*]], r2 | 269 ; ARM32-DAG: mov [[REG2:.*]], r2 |
| 269 ; ARM32-DAG: mov [[REG3:.*]], r3 | 270 ; ARM32-DAG: mov [[REG3:.*]], r3 |
| 270 ; ARM32: str [[REG2]], [sp] | 271 ; ARM32: str [[REG2]], [sp] |
| 271 ; ARM32: str [[REG1]], [sp, #4] | 272 ; ARM32: str [[REG1]], [sp, #4] |
| 272 ; ARM32-DAG: mov r0 | 273 ; ARM32-DAG: mov r0 |
| 273 ; ARM32-DAG: mov r1 | 274 ; ARM32-DAG: mov r1 |
| 274 ; ARM32-DAG: mov r2 | 275 ; ARM32-DAG: mov r2 |
| 275 ; ARM32-DAG: mov r3, [[REG3]] | 276 ; ARM32-DAG: mov r3, [[REG3]] |
| 276 ; ARM32: bl | 277 ; ARM32: bl |
| OLD | NEW |