Chris Dewhurst | 68388a0 | 2016-05-18 09:14:13 +0000 | [diff] [blame] | 1 | ; RUN: llc < %s -march=sparc -disable-sparc-delay-filler -disable-sparc-leaf-proc | FileCheck %s --check-prefix=CHECK --check-prefix=HARD --check-prefix=CHECK-BE |
| 2 | ; RUN: llc < %s -march=sparcel -disable-sparc-delay-filler -disable-sparc-leaf-proc | FileCheck %s --check-prefix=CHECK --check-prefix=HARD --check-prefix=CHECK-LE |
| 3 | ; RUN: llc < %s -march=sparc -disable-sparc-delay-filler -disable-sparc-leaf-proc -mattr=soft-float | FileCheck %s --check-prefix=CHECK --check-prefix=SOFT --check-prefix=CHECK-BE |
James Y Knight | 33beb24 | 2015-12-15 19:23:12 +0000 | [diff] [blame] | 4 | |
| 5 | ; CHECK-LABEL: intarg: |
| 6 | ; The save/restore frame is not strictly necessary here, but we would need to |
| 7 | ; refer to %o registers instead. |
| 8 | ; CHECK: save %sp, -96, %sp |
| 9 | ; CHECK: ld [%fp+96], [[R2:%[gilo][0-7]]] |
| 10 | ; CHECK: ld [%fp+92], [[R1:%[gilo][0-7]]] |
| 11 | ; CHECK: stb %i0, [%i4] |
| 12 | ; CHECK: stb %i1, [%i4] |
| 13 | ; CHECK: sth %i2, [%i4] |
| 14 | ; CHECK: st %i3, [%i4] |
| 15 | ; CHECK: st %i4, [%i4] |
| 16 | ; CHECK: st %i5, [%i4] |
| 17 | ; CHECK: st [[R1]], [%i4] |
| 18 | ; CHECK: st [[R2]], [%i4] |
| 19 | ; CHECK: restore |
| 20 | define void @intarg(i8 %a0, ; %i0 |
| 21 | i8 %a1, ; %i1 |
| 22 | i16 %a2, ; %i2 |
| 23 | i32 %a3, ; %i3 |
| 24 | i8* %a4, ; %i4 |
| 25 | i32 %a5, ; %i5 |
| 26 | i32 signext %a6, ; [%fp+92] |
| 27 | i8* %a7) { ; [%fp+96] |
Nirav Dave | da8f221 | 2017-05-16 19:43:56 +0000 | [diff] [blame] | 28 | store volatile i8 %a0, i8* %a4 |
| 29 | store volatile i8 %a1, i8* %a4 |
James Y Knight | 33beb24 | 2015-12-15 19:23:12 +0000 | [diff] [blame] | 30 | %p16 = bitcast i8* %a4 to i16* |
Nirav Dave | da8f221 | 2017-05-16 19:43:56 +0000 | [diff] [blame] | 31 | store volatile i16 %a2, i16* %p16 |
James Y Knight | 33beb24 | 2015-12-15 19:23:12 +0000 | [diff] [blame] | 32 | %p32 = bitcast i8* %a4 to i32* |
Nirav Dave | da8f221 | 2017-05-16 19:43:56 +0000 | [diff] [blame] | 33 | store volatile i32 %a3, i32* %p32 |
James Y Knight | 33beb24 | 2015-12-15 19:23:12 +0000 | [diff] [blame] | 34 | %pp = bitcast i8* %a4 to i8** |
Nirav Dave | da8f221 | 2017-05-16 19:43:56 +0000 | [diff] [blame] | 35 | store volatile i8* %a4, i8** %pp |
| 36 | store volatile i32 %a5, i32* %p32 |
| 37 | store volatile i32 %a6, i32* %p32 |
| 38 | store volatile i8* %a7, i8** %pp |
James Y Knight | 33beb24 | 2015-12-15 19:23:12 +0000 | [diff] [blame] | 39 | ret void |
| 40 | } |
| 41 | |
| 42 | ; CHECK-LABEL: call_intarg: |
| 43 | ; CHECK: save %sp, -104, %sp |
| 44 | ; Use %o0-%o5 for outgoing arguments |
| 45 | ; CHECK: mov 5, %o5 |
| 46 | ; CHECK: st %i0, [%sp+92] |
| 47 | ; CHECK: call intarg |
| 48 | ; CHECK-NOT: add %sp |
| 49 | ; CHECK: restore |
| 50 | define void @call_intarg(i32 %i0, i8* %i1) { |
| 51 | call void @intarg(i8 0, i8 1, i16 2, i32 3, i8* undef, i32 5, i32 %i0, i8* %i1) |
| 52 | ret void |
| 53 | } |
| 54 | |
| 55 | ;; Verify doubles starting with an even reg, starting with an odd reg, |
| 56 | ;; straddling the boundary of regs and mem, and floats in regs and mem. |
| 57 | ; |
| 58 | ; CHECK-LABEL: floatarg: |
Chris Dewhurst | 68388a0 | 2016-05-18 09:14:13 +0000 | [diff] [blame] | 59 | ; HARD: save %sp, -120, %sp |
| 60 | ; HARD: mov %i5, %g2 |
| 61 | ; HARD-NEXT: ld [%fp+92], %g3 |
| 62 | ; HARD-NEXT: mov %i4, %i5 |
Matthias Braun | 152e7c8 | 2016-07-09 00:19:07 +0000 | [diff] [blame] | 63 | ; HARD-NEXT: ! kill |
Chris Dewhurst | 68388a0 | 2016-05-18 09:14:13 +0000 | [diff] [blame] | 64 | ; HARD-NEXT: std %g2, [%fp+-24] |
| 65 | ; HARD-NEXT: mov %i3, %i4 |
| 66 | ; HARD-NEXT: std %i4, [%fp+-16] |
Matthias Braun | 152e7c8 | 2016-07-09 00:19:07 +0000 | [diff] [blame] | 67 | ; HARD-NEXT: ! kill |
Chris Dewhurst | 68388a0 | 2016-05-18 09:14:13 +0000 | [diff] [blame] | 68 | ; HARD-NEXT: std %i0, [%fp+-8] |
| 69 | ; HARD-NEXT: st %i2, [%fp+-28] |
| 70 | ; HARD-NEXT: ld [%fp+104], %f0 |
| 71 | ; HARD-NEXT: ldd [%fp+96], %f2 |
| 72 | ; HARD-NEXT: ld [%fp+-28], %f1 |
| 73 | ; HARD-NEXT: ldd [%fp+-8], %f4 |
| 74 | ; HARD-NEXT: ldd [%fp+-16], %f6 |
| 75 | ; HARD-NEXT: ldd [%fp+-24], %f8 |
| 76 | ; HARD-NEXT: fstod %f1, %f10 |
| 77 | ; HARD-NEXT: faddd %f4, %f10, %f4 |
| 78 | ; HARD-NEXT: faddd %f6, %f4, %f4 |
| 79 | ; HARD-NEXT: faddd %f8, %f4, %f4 |
| 80 | ; HARD-NEXT: faddd %f2, %f4, %f2 |
| 81 | ; HARD-NEXT: fstod %f0, %f0 |
| 82 | ; HARD-NEXT: faddd %f0, %f2, %f0 |
| 83 | ; SOFT: save %sp, -96, %sp |
| 84 | ; SOFT: ld [%fp+104], %l0 |
| 85 | ; SOFT-NEXT: ld [%fp+96], %l1 |
| 86 | ; SOFT-NEXT: ld [%fp+100], %l2 |
| 87 | ; SOFT-NEXT: ld [%fp+92], %l3 |
| 88 | ; SOFT-NEXT: mov %i2, %o0 |
| 89 | ; SOFT-NEXT: call __extendsfdf2 |
| 90 | ; SOFT-NEXT: nop |
Jonas Paulsson | 8ff0773 | 2018-02-24 08:24:31 +0000 | [diff] [blame] | 91 | ; SOFT-NEXT: mov %o0, %o2 |
| 92 | ; SOFT-NEXT: mov %o1, %o3 |
Chris Dewhurst | 68388a0 | 2016-05-18 09:14:13 +0000 | [diff] [blame] | 93 | ; SOFT-NEXT: mov %i0, %o0 |
| 94 | ; SOFT-NEXT: mov %i1, %o1 |
Chris Dewhurst | 68388a0 | 2016-05-18 09:14:13 +0000 | [diff] [blame] | 95 | ; SOFT-NEXT: call __adddf3 |
| 96 | ; SOFT-NEXT: nop |
Jonas Paulsson | 8ff0773 | 2018-02-24 08:24:31 +0000 | [diff] [blame] | 97 | ; SOFT-NEXT: mov %o0, %o2 |
| 98 | ; SOFT-NEXT: mov %o1, %o3 |
Chris Dewhurst | 68388a0 | 2016-05-18 09:14:13 +0000 | [diff] [blame] | 99 | ; SOFT-NEXT: mov %i3, %o0 |
| 100 | ; SOFT-NEXT: mov %i4, %o1 |
Chris Dewhurst | 68388a0 | 2016-05-18 09:14:13 +0000 | [diff] [blame] | 101 | ; SOFT-NEXT: call __adddf3 |
| 102 | ; SOFT-NEXT: nop |
Jonas Paulsson | 8ff0773 | 2018-02-24 08:24:31 +0000 | [diff] [blame] | 103 | ; SOFT-NEXT: mov %o0, %o2 |
| 104 | ; SOFT-NEXT: mov %o1, %o3 |
Chris Dewhurst | 68388a0 | 2016-05-18 09:14:13 +0000 | [diff] [blame] | 105 | ; SOFT-NEXT: mov %i5, %o0 |
| 106 | ; SOFT-NEXT: mov %l3, %o1 |
Chris Dewhurst | 68388a0 | 2016-05-18 09:14:13 +0000 | [diff] [blame] | 107 | ; SOFT-NEXT: call __adddf3 |
| 108 | ; SOFT-NEXT: nop |
Jonas Paulsson | 8ff0773 | 2018-02-24 08:24:31 +0000 | [diff] [blame] | 109 | ; SOFT-NEXT: mov %o0, %o2 |
| 110 | ; SOFT-NEXT: mov %o1, %o3 |
Chris Dewhurst | 68388a0 | 2016-05-18 09:14:13 +0000 | [diff] [blame] | 111 | ; SOFT-NEXT: mov %l1, %o0 |
| 112 | ; SOFT-NEXT: mov %l2, %o1 |
Chris Dewhurst | 68388a0 | 2016-05-18 09:14:13 +0000 | [diff] [blame] | 113 | ; SOFT-NEXT: call __adddf3 |
| 114 | ; SOFT-NEXT: nop |
| 115 | ; SOFT-NEXT: mov %o0, %i0 |
| 116 | ; SOFT-NEXT: mov %o1, %i1 |
| 117 | ; SOFT-NEXT: mov %l0, %o0 |
| 118 | ; SOFT-NEXT: call __extendsfdf2 |
| 119 | ; SOFT-NEXT: nop |
| 120 | ; SOFT-NEXT: mov %i0, %o2 |
| 121 | ; SOFT-NEXT: mov %i1, %o3 |
| 122 | ; SOFT-NEXT: call __adddf3 |
| 123 | ; SOFT-NEXT: nop |
| 124 | ; SOFT-NEXT: mov %o0, %i0 |
| 125 | ; SOFT-NEXT: mov %o1, %i1 |
| 126 | ; CHECK: restore |
James Y Knight | 33beb24 | 2015-12-15 19:23:12 +0000 | [diff] [blame] | 127 | define double @floatarg(double %a0, ; %i0,%i1 |
| 128 | float %a1, ; %i2 |
| 129 | double %a2, ; %i3, %i4 |
| 130 | double %a3, ; %i5, [%fp+92] (using 4 bytes) |
| 131 | double %a4, ; [%fp+96] (using 8 bytes) |
| 132 | float %a5) { ; [%fp+104] (using 4 bytes) |
| 133 | %d1 = fpext float %a1 to double |
| 134 | %s1 = fadd double %a0, %d1 |
| 135 | %s2 = fadd double %a2, %s1 |
| 136 | %s3 = fadd double %a3, %s2 |
| 137 | %s4 = fadd double %a4, %s3 |
| 138 | %d5 = fpext float %a5 to double |
| 139 | %s5 = fadd double %d5, %s4 |
| 140 | ret double %s5 |
| 141 | } |
| 142 | |
| 143 | ; CHECK-LABEL: call_floatarg: |
Chris Dewhurst | 68388a0 | 2016-05-18 09:14:13 +0000 | [diff] [blame] | 144 | ; HARD: save %sp, -112, %sp |
| 145 | ; HARD: mov %i2, %o1 |
| 146 | ; HARD-NEXT: mov %i1, %o0 |
| 147 | ; HARD-NEXT: st %i0, [%sp+104] |
| 148 | ; HARD-NEXT: std %o0, [%sp+96] |
| 149 | ; HARD-NEXT: st %o1, [%sp+92] |
| 150 | ; HARD-NEXT: mov %i0, %o2 |
Geoff Berry | a2b9011 | 2018-02-27 16:59:10 +0000 | [diff] [blame] | 151 | ; HARD-NEXT: mov %i1, %o3 |
Chris Dewhurst | 68388a0 | 2016-05-18 09:14:13 +0000 | [diff] [blame] | 152 | ; HARD-NEXT: mov %o1, %o4 |
Geoff Berry | a2b9011 | 2018-02-27 16:59:10 +0000 | [diff] [blame] | 153 | ; HARD-NEXT: mov %i1, %o5 |
Chris Dewhurst | 68388a0 | 2016-05-18 09:14:13 +0000 | [diff] [blame] | 154 | ; HARD-NEXT: call floatarg |
| 155 | ; HARD: std %f0, [%i4] |
| 156 | ; SOFT: st %i0, [%sp+104] |
| 157 | ; SOFT-NEXT: st %i2, [%sp+100] |
| 158 | ; SOFT-NEXT: st %i1, [%sp+96] |
| 159 | ; SOFT-NEXT: st %i2, [%sp+92] |
| 160 | ; SOFT-NEXT: mov %i1, %o0 |
| 161 | ; SOFT-NEXT: mov %i2, %o1 |
| 162 | ; SOFT-NEXT: mov %i0, %o2 |
| 163 | ; SOFT-NEXT: mov %i1, %o3 |
| 164 | ; SOFT-NEXT: mov %i2, %o4 |
| 165 | ; SOFT-NEXT: mov %i1, %o5 |
| 166 | ; SOFT-NEXT: call floatarg |
| 167 | ; SOFT: std %o0, [%i4] |
James Y Knight | 33beb24 | 2015-12-15 19:23:12 +0000 | [diff] [blame] | 168 | ; CHECK: restore |
| 169 | define void @call_floatarg(float %f1, double %d2, float %f5, double *%p) { |
| 170 | %r = call double @floatarg(double %d2, float %f1, double %d2, double %d2, |
| 171 | double %d2, float %f1) |
| 172 | store double %r, double* %p |
| 173 | ret void |
| 174 | } |
| 175 | |
| 176 | ;; i64 arguments should effectively work the same as double: split |
| 177 | ;; into two locations. This is different for little-endian vs big |
| 178 | ;; endian, since the 64-bit math needs to be split |
| 179 | ; CHECK-LABEL: i64arg: |
| 180 | ; CHECK: save %sp, -96, %sp |
Vedant Kumar | ee4bfca | 2018-05-01 19:26:15 +0000 | [diff] [blame] | 181 | ; CHECK-BE: ld [%fp+104], %g2 |
| 182 | ; CHECK-BE-NEXT: ld [%fp+100], %g3 |
| 183 | ; CHECK-BE-NEXT: ld [%fp+96], %g4 |
| 184 | ; CHECK-BE-NEXT: ld [%fp+92], %l0 |
James Y Knight | 33beb24 | 2015-12-15 19:23:12 +0000 | [diff] [blame] | 185 | ; CHECK-BE-NEXT: addcc %i1, %i2, %i1 |
| 186 | ; CHECK-BE-NEXT: addxcc %i0, 0, %i0 |
| 187 | ; CHECK-BE-NEXT: addcc %i4, %i1, %i1 |
| 188 | ; CHECK-BE-NEXT: addxcc %i3, %i0, %i0 |
Vedant Kumar | ee4bfca | 2018-05-01 19:26:15 +0000 | [diff] [blame] | 189 | ; CHECK-BE-NEXT: addcc %l0, %i1, %i1 |
James Y Knight | 33beb24 | 2015-12-15 19:23:12 +0000 | [diff] [blame] | 190 | ; CHECK-BE-NEXT: addxcc %i5, %i0, %i0 |
Vedant Kumar | ee4bfca | 2018-05-01 19:26:15 +0000 | [diff] [blame] | 191 | ; CHECK-BE-NEXT: addcc %g3, %i1, %i1 |
| 192 | ; CHECK-BE-NEXT: addxcc %g4, %i0, %i0 |
James Y Knight | 33beb24 | 2015-12-15 19:23:12 +0000 | [diff] [blame] | 193 | ; CHECK-BE-NEXT: addcc %g2, %i1, %i1 |
James Y Knight | 33beb24 | 2015-12-15 19:23:12 +0000 | [diff] [blame] | 194 | ; CHECK-BE-NEXT: addxcc %i0, 0, %i0 |
| 195 | ; |
Vedant Kumar | ee4bfca | 2018-05-01 19:26:15 +0000 | [diff] [blame] | 196 | ; CHECK-LE: ld [%fp+104], %g2 |
| 197 | ; CHECK-LE-NEXT: ld [%fp+96], %g3 |
| 198 | ; CHECK-LE-NEXT: ld [%fp+100], %g4 |
| 199 | ; CHECK-LE-NEXT: ld [%fp+92], %l0 |
James Y Knight | 33beb24 | 2015-12-15 19:23:12 +0000 | [diff] [blame] | 200 | ; CHECK-LE-NEXT: addcc %i0, %i2, %i0 |
| 201 | ; CHECK-LE-NEXT: addxcc %i1, 0, %i1 |
| 202 | ; CHECK-LE-NEXT: addcc %i3, %i0, %i0 |
| 203 | ; CHECK-LE-NEXT: addxcc %i4, %i1, %i1 |
| 204 | ; CHECK-LE-NEXT: addcc %i5, %i0, %i0 |
Vedant Kumar | ee4bfca | 2018-05-01 19:26:15 +0000 | [diff] [blame] | 205 | ; CHECK-LE-NEXT: addxcc %l0, %i1, %i1 |
| 206 | ; CHECK-LE-NEXT: addcc %g3, %i0, %i0 |
James Y Knight | 33beb24 | 2015-12-15 19:23:12 +0000 | [diff] [blame] | 207 | ; CHECK-LE-NEXT: addxcc %g4, %i1, %i1 |
| 208 | ; CHECK-LE-NEXT: addcc %g2, %i0, %i0 |
James Y Knight | 33beb24 | 2015-12-15 19:23:12 +0000 | [diff] [blame] | 209 | ; CHECK-LE-NEXT: addxcc %i1, 0, %i1 |
| 210 | ; CHECK-NEXT: restore |
| 211 | |
| 212 | |
| 213 | define i64 @i64arg(i64 %a0, ; %i0,%i1 |
| 214 | i32 %a1, ; %i2 |
| 215 | i64 %a2, ; %i3, %i4 |
| 216 | i64 %a3, ; %i5, [%fp+92] (using 4 bytes) |
| 217 | i64 %a4, ; [%fp+96] (using 8 bytes) |
| 218 | i32 %a5) { ; [%fp+104] (using 4 bytes) |
| 219 | %a1L = zext i32 %a1 to i64 |
| 220 | %s1 = add i64 %a0, %a1L |
| 221 | %s2 = add i64 %a2, %s1 |
| 222 | %s3 = add i64 %a3, %s2 |
| 223 | %s4 = add i64 %a4, %s3 |
| 224 | %a5L = zext i32 %a5 to i64 |
| 225 | %s5 = add i64 %a5L, %s4 |
| 226 | ret i64 %s5 |
| 227 | } |
| 228 | |
| 229 | ; CHECK-LABEL: call_i64arg: |
| 230 | ; CHECK: save %sp, -112, %sp |
| 231 | ; CHECK: st %i0, [%sp+104] |
| 232 | ; CHECK-NEXT: st %i2, [%sp+100] |
| 233 | ; CHECK-NEXT: st %i1, [%sp+96] |
| 234 | ; CHECK-NEXT: st %i2, [%sp+92] |
| 235 | ; CHECK-NEXT: mov %i1, %o0 |
| 236 | ; CHECK-NEXT: mov %i2, %o1 |
| 237 | ; CHECK-NEXT: mov %i0, %o2 |
| 238 | ; CHECK-NEXT: mov %i1, %o3 |
| 239 | ; CHECK-NEXT: mov %i2, %o4 |
| 240 | ; CHECK-NEXT: mov %i1, %o5 |
| 241 | ; CHECK-NEXT: call i64arg |
| 242 | ; CHECK: std %o0, [%i3] |
| 243 | ; CHECK-NEXT: restore |
| 244 | |
| 245 | define void @call_i64arg(i32 %a0, i64 %a1, i64* %p) { |
| 246 | %r = call i64 @i64arg(i64 %a1, i32 %a0, i64 %a1, i64 %a1, i64 %a1, i32 %a0) |
| 247 | store i64 %r, i64* %p |
| 248 | ret void |
| 249 | } |