Home | History | Annotate | Download | only in Mips
      1 ; RUN: llc -march=mips   -mcpu=mips32   -verify-machineinstrs    < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC32 -check-prefix=ACC32-TRAP
      2 ; RUN: llc -march=mips   -mcpu=mips32r2 -verify-machineinstrs    < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC32 -check-prefix=ACC32-TRAP
      3 ; RUN: llc -march=mips   -mcpu=mips32r6 -verify-machineinstrs    < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR32 -check-prefix=GPR32-TRAP
      4 ; RUN: llc -march=mips64 -mcpu=mips64   -verify-machineinstrs    < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC64 -check-prefix=ACC64-TRAP
      5 ; RUN: llc -march=mips64 -mcpu=mips64r2 -verify-machineinstrs    < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC64 -check-prefix=ACC64-TRAP
      6 ; RUN: llc -march=mips64 -mcpu=mips64r6 -verify-machineinstrs    < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR64 -check-prefix=GPR64-TRAP
      7 
      8 ; RUN: llc -march=mips   -mcpu=mips32   -mno-check-zero-division < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC32 -check-prefix=NOCHECK
      9 ; RUN: llc -march=mips   -mcpu=mips32r2 -mno-check-zero-division < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC32 -check-prefix=NOCHECK
     10 ; RUN: llc -march=mips   -mcpu=mips32r6 -mno-check-zero-division < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR32 -check-prefix=NOCHECK
     11 ; RUN: llc -march=mips64 -mcpu=mips64   -mno-check-zero-division < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC64 -check-prefix=NOCHECK
     12 ; RUN: llc -march=mips64 -mcpu=mips64r2 -mno-check-zero-division < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC64 -check-prefix=NOCHECK
     13 ; RUN: llc -march=mips64 -mcpu=mips64r6 -mno-check-zero-division < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR64 -check-prefix=NOCHECK
     14 
     15 ; FileCheck Prefixes:
     16 ;   ALL - All targets
     17 ;   ACC32 - Accumulator based multiply/divide on 32-bit targets
     18 ;   ACC64 - Same as ACC32 but only for 64-bit targets
     19 ;   GPR32 - GPR based multiply/divide on 32-bit targets
     20 ;   GPR64 - Same as GPR32 but only for 64-bit targets
     21 ;   ACC32-TRAP - Same as TRAP and ACC32 combined
     22 ;   ACC64-TRAP - Same as TRAP and ACC64 combined
     23 ;   GPR32-TRAP - Same as TRAP and GPR32 combined
     24 ;   GPR64-TRAP - Same as TRAP and GPR64 combined
     25 ;   NOCHECK - Division by zero will not be detected
     26 
     27 @g0 = common global i32 0, align 4
     28 @g1 = common global i32 0, align 4
     29 
     30 define i32 @sdiv1(i32 %a0, i32 %a1) nounwind readnone {
     31 entry:
     32 ; ALL-LABEL: sdiv1:
     33 
     34 ; ACC32:         div $zero, $4, $5
     35 ; ACC32-TRAP:    teq $5, $zero, 7
     36 
     37 ; ACC64:         div $zero, $4, $5
     38 ; ACC64-TRAP:    teq $5, $zero, 7
     39 
     40 ; GPR32:         div $2, $4, $5
     41 ; GPR32-TRAP:    teq $5, $zero, 7
     42 
     43 ; GPR64:         div $2, $4, $5
     44 ; GPR64-TRAP:    teq $5, $zero, 7
     45 
     46 ; NOCHECK-NOT:   teq
     47 
     48 ; ACC32:         mflo $2
     49 ; ACC64:         mflo $2
     50 
     51 ; ALL: .end sdiv1
     52 
     53   %div = sdiv i32 %a0, %a1
     54   ret i32 %div
     55 }
     56 
     57 define i32 @srem1(i32 %a0, i32 %a1) nounwind readnone {
     58 entry:
     59 ; ALL-LABEL: srem1:
     60 
     61 ; ACC32:         div $zero, $4, $5
     62 ; ACC32-TRAP:    teq $5, $zero, 7
     63 
     64 ; ACC64:         div $zero, $4, $5
     65 ; ACC64-TRAP:    teq $5, $zero, 7
     66 
     67 ; GPR32:         mod $2, $4, $5
     68 ; GPR32-TRAP:    teq $5, $zero, 7
     69 
     70 ; GPR64:         mod $2, $4, $5
     71 ; GPR64-TRAP:    teq $5, $zero, 7
     72 
     73 ; NOCHECK-NOT:   teq
     74 
     75 ; ACC32:         mfhi $2
     76 ; ACC64:         mfhi $2
     77 
     78 ; ALL: .end srem1
     79 
     80   %rem = srem i32 %a0, %a1
     81   ret i32 %rem
     82 }
     83 
     84 define i32 @udiv1(i32 %a0, i32 %a1) nounwind readnone {
     85 entry:
     86 ; ALL-LABEL: udiv1:
     87 
     88 ; ACC32:         divu $zero, $4, $5
     89 ; ACC32-TRAP:    teq $5, $zero, 7
     90 
     91 ; ACC64:         divu $zero, $4, $5
     92 ; ACC64-TRAP:    teq $5, $zero, 7
     93 
     94 ; GPR32:         divu $2, $4, $5
     95 ; GPR32-TRAP:    teq $5, $zero, 7
     96 
     97 ; GPR64:         divu $2, $4, $5
     98 ; GPR64-TRAP:    teq $5, $zero, 7
     99 
    100 ; NOCHECK-NOT:   teq
    101 
    102 ; ACC32:         mflo $2
    103 ; ACC64:         mflo $2
    104 
    105 ; ALL: .end udiv1
    106   %div = udiv i32 %a0, %a1
    107   ret i32 %div
    108 }
    109 
    110 define i32 @urem1(i32 %a0, i32 %a1) nounwind readnone {
    111 entry:
    112 ; ALL-LABEL: urem1:
    113 
    114 ; ACC32:         divu $zero, $4, $5
    115 ; ACC32-TRAP:    teq $5, $zero, 7
    116 
    117 ; ACC64:         divu $zero, $4, $5
    118 ; ACC64-TRAP:    teq $5, $zero, 7
    119 
    120 ; GPR32:         modu $2, $4, $5
    121 ; GPR32-TRAP:    teq $5, $zero, 7
    122 
    123 ; GPR64:         modu $2, $4, $5
    124 ; GPR64-TRAP:    teq $5, $zero, 7
    125 
    126 ; NOCHECK-NOT:   teq
    127 
    128 ; ACC32:         mfhi $2
    129 ; ACC64:         mfhi $2
    130 
    131 ; ALL: .end urem1
    132 
    133   %rem = urem i32 %a0, %a1
    134   ret i32 %rem
    135 }
    136 
    137 define i32 @sdivrem1(i32 %a0, i32 %a1, i32* nocapture %r) nounwind {
    138 entry:
    139 ; ALL-LABEL: sdivrem1:
    140 
    141 ; ACC32:         div $zero, $4, $5
    142 ; ACC32-TRAP:    teq $5, $zero, 7
    143 ; NOCHECK-NOT:   teq
    144 ; ACC32:         mflo $2
    145 ; ACC32:         mfhi $[[R0:[0-9]+]]
    146 ; ACC32:         sw $[[R0]], 0(${{[0-9]+}})
    147 
    148 ; ACC64:         div $zero, $4, $5
    149 ; ACC64-TRAP:    teq $5, $zero, 7
    150 ; NOCHECK-NOT:   teq
    151 ; ACC64:         mflo $2
    152 ; ACC64:         mfhi $[[R0:[0-9]+]]
    153 ; ACC64:         sw $[[R0]], 0(${{[0-9]+}})
    154 
    155 ; GPR32:         mod $[[R0:[0-9]+]], $4, $5
    156 ; GPR32-TRAP:    teq $5, $zero, 7
    157 ; NOCHECK-NOT:   teq
    158 ; GPR32:         sw $[[R0]], 0(${{[0-9]+}})
    159 ; GPR32-DAG:     div $2, $4, $5
    160 ; GPR32-TRAP:    teq $5, $zero, 7
    161 
    162 ; GPR64:         mod $[[R0:[0-9]+]], $4, $5
    163 ; GPR64-TRAP:    teq $5, $zero, 7
    164 ; NOCHECK-NOT:   teq
    165 ; GPR64:         sw $[[R0]], 0(${{[0-9]+}})
    166 ; GPR64-DAG:     div $2, $4, $5
    167 ; GPR64-TRAP:    teq $5, $zero, 7
    168 ; NOCHECK-NOT:   teq
    169 
    170 ; ALL: .end sdivrem1
    171 
    172   %rem = srem i32 %a0, %a1
    173   store i32 %rem, i32* %r, align 4
    174   %div = sdiv i32 %a0, %a1
    175   ret i32 %div
    176 }
    177 
    178 define i32 @udivrem1(i32 %a0, i32 %a1, i32* nocapture %r) nounwind {
    179 entry:
    180 ; ALL-LABEL: udivrem1:
    181 
    182 ; ACC32:         divu $zero, $4, $5
    183 ; ACC32-TRAP:    teq $5, $zero, 7
    184 ; NOCHECK-NOT:   teq
    185 ; ACC32:         mflo $2
    186 ; ACC32:         mfhi $[[R0:[0-9]+]]
    187 ; ACC32:         sw $[[R0]], 0(${{[0-9]+}})
    188 
    189 ; ACC64:         divu $zero, $4, $5
    190 ; ACC64-TRAP:    teq $5, $zero, 7
    191 ; NOCHECK-NOT:   teq
    192 ; ACC64:         mflo $2
    193 ; ACC64:         mfhi $[[R0:[0-9]+]]
    194 ; ACC64:         sw $[[R0]], 0(${{[0-9]+}})
    195 
    196 ; GPR32:         modu $[[R0:[0-9]+]], $4, $5
    197 ; GPR32-TRAP:    teq $5, $zero, 7
    198 ; NOCHECK-NOT:   teq
    199 ; GPR32:         sw $[[R0]], 0(${{[0-9]+}})
    200 ; GPR32-DAG:     divu $2, $4, $5
    201 ; GPR32-TRAP:    teq $5, $zero, 7
    202 ; NOCHECK-NOT:   teq
    203 
    204 ; GPR64:         modu $[[R0:[0-9]+]], $4, $5
    205 ; GPR64-TRAP:    teq $5, $zero, 7
    206 ; NOCHECK-NOT:   teq
    207 ; GPR64:         sw $[[R0]], 0(${{[0-9]+}})
    208 ; GPR64-DAG:     divu $2, $4, $5
    209 ; GPR64-TRAP:    teq $5, $zero, 7
    210 ; NOCHECK-NOT:   teq
    211 
    212 ; ALL: .end udivrem1
    213 
    214   %rem = urem i32 %a0, %a1
    215   store i32 %rem, i32* %r, align 4
    216   %div = udiv i32 %a0, %a1
    217   ret i32 %div
    218 }
    219 
    220 ; FIXME: It's not clear what this is supposed to test.
    221 define i32 @killFlags() {
    222 entry:
    223   %0 = load i32* @g0, align 4
    224   %1 = load i32* @g1, align 4
    225   %div = sdiv i32 %0, %1
    226   ret i32 %div
    227 }
    228 
    229 define i64 @sdiv2(i64 %a0, i64 %a1) nounwind readnone {
    230 entry:
    231 ; ALL-LABEL: sdiv2:
    232 
    233 ; ACC32:         lw $25, %call16(__divdi3)(
    234 ; ACC32:         jalr $25
    235 
    236 ; ACC64:         ddiv $zero, $4, $5
    237 ; ACC64-TRAP:    teq $5, $zero, 7
    238 
    239 ; GPR64:         ddiv $2, $4, $5
    240 ; GPR64-TRAP:    teq $5, $zero, 7
    241 
    242 ; NOCHECK-NOT:   teq
    243 
    244 ; ACC64:         mflo $2
    245 
    246 ; ALL: .end sdiv2
    247 
    248   %div = sdiv i64 %a0, %a1
    249   ret i64 %div
    250 }
    251 
    252 define i64 @srem2(i64 %a0, i64 %a1) nounwind readnone {
    253 entry:
    254 ; ALL-LABEL: srem2:
    255 
    256 ; ACC32:         lw $25, %call16(__moddi3)(
    257 ; ACC32:         jalr $25
    258 
    259 ; ACC64:         div $zero, $4, $5
    260 ; ACC64-TRAP:    teq $5, $zero, 7
    261 
    262 ; GPR64:         dmod $2, $4, $5
    263 ; GPR64-TRAP:    teq $5, $zero, 7
    264 
    265 ; NOCHECK-NOT:   teq
    266 
    267 ; ACC64:         mfhi $2
    268 
    269 ; ALL: .end srem2
    270 
    271   %rem = srem i64 %a0, %a1
    272   ret i64 %rem
    273 }
    274 
    275 define i64 @udiv2(i64 %a0, i64 %a1) nounwind readnone {
    276 entry:
    277 ; ALL-LABEL: udiv2:
    278 
    279 ; ACC32:         lw $25, %call16(__udivdi3)(
    280 ; ACC32:         jalr $25
    281 
    282 ; ACC64:         divu $zero, $4, $5
    283 ; ACC64-TRAP:    teq $5, $zero, 7
    284 
    285 ; GPR64:         ddivu $2, $4, $5
    286 ; GPR64-TRAP:    teq $5, $zero, 7
    287 
    288 ; NOCHECK-NOT:   teq
    289 
    290 ; ACC64:         mflo $2
    291 
    292 ; ALL: .end udiv2
    293   %div = udiv i64 %a0, %a1
    294   ret i64 %div
    295 }
    296 
    297 define i64 @urem2(i64 %a0, i64 %a1) nounwind readnone {
    298 entry:
    299 ; ALL-LABEL: urem2:
    300 
    301 ; ACC32:         lw $25, %call16(__umoddi3)(
    302 ; ACC32:         jalr $25
    303 
    304 ; ACC64:         divu $zero, $4, $5
    305 ; ACC64-TRAP:    teq $5, $zero, 7
    306 
    307 ; GPR64:         dmodu $2, $4, $5
    308 ; GPR64-TRAP:    teq $5, $zero, 7
    309 
    310 ; NOCHECK-NOT:   teq
    311 
    312 ; ACC64:         mfhi $2
    313 
    314 ; ALL: .end urem2
    315 
    316   %rem = urem i64 %a0, %a1
    317   ret i64 %rem
    318 }
    319 
    320 define i64 @sdivrem2(i64 %a0, i64 %a1, i64* nocapture %r) nounwind {
    321 entry:
    322 ; ALL-LABEL: sdivrem2:
    323 
    324 ; sdivrem2 is too complex to effectively check. We can at least check for the
    325 ; calls though.
    326 ; ACC32:         lw $25, %call16(__moddi3)(
    327 ; ACC32:         jalr $25
    328 ; ACC32:         lw $25, %call16(__divdi3)(
    329 ; ACC32:         jalr $25
    330 
    331 ; ACC64:         ddiv $zero, $4, $5
    332 ; ACC64-TRAP:    teq $5, $zero, 7
    333 ; NOCHECK-NOT:   teq
    334 ; ACC64:         mflo $2
    335 ; ACC64:         mfhi $[[R0:[0-9]+]]
    336 ; ACC64:         sd $[[R0]], 0(${{[0-9]+}})
    337 
    338 ; GPR64:         dmod $[[R0:[0-9]+]], $4, $5
    339 ; GPR64-TRAP:    teq $5, $zero, 7
    340 ; NOCHECK-NOT:   teq
    341 ; GPR64:         sd $[[R0]], 0(${{[0-9]+}})
    342 
    343 ; GPR64-DAG:     ddiv $2, $4, $5
    344 ; GPR64-TRAP:    teq $5, $zero, 7
    345 ; NOCHECK-NOT:   teq
    346 
    347 ; ALL: .end sdivrem2
    348 
    349   %rem = srem i64 %a0, %a1
    350   store i64 %rem, i64* %r, align 8
    351   %div = sdiv i64 %a0, %a1
    352   ret i64 %div
    353 }
    354 
    355 define i64 @udivrem2(i64 %a0, i64 %a1, i64* nocapture %r) nounwind {
    356 entry:
    357 ; ALL-LABEL: udivrem2:
    358 
    359 ; udivrem2 is too complex to effectively check. We can at least check for the
    360 ; calls though.
    361 ; ACC32:         lw $25, %call16(__umoddi3)(
    362 ; ACC32:         jalr $25
    363 ; ACC32:         lw $25, %call16(__udivdi3)(
    364 ; ACC32:         jalr $25
    365 
    366 ; ACC64:         ddivu $zero, $4, $5
    367 ; ACC64-TRAP:    teq $5, $zero, 7
    368 ; NOCHECK-NOT:   teq
    369 ; ACC64:         mflo $2
    370 ; ACC64:         mfhi $[[R0:[0-9]+]]
    371 ; ACC64:         sd $[[R0]], 0(${{[0-9]+}})
    372 
    373 ; GPR64:         dmodu $[[R0:[0-9]+]], $4, $5
    374 ; GPR64-TRAP:    teq $5, $zero, 7
    375 ; NOCHECK-NOT:   teq
    376 ; GPR64:         sd $[[R0]], 0(${{[0-9]+}})
    377 
    378 ; GPR64-DAG:     ddivu $2, $4, $5
    379 ; GPR64-TRAP:    teq $5, $zero, 7
    380 ; NOCHECK-NOT:   teq
    381 
    382 ; ALL: .end udivrem2
    383 
    384   %rem = urem i64 %a0, %a1
    385   store i64 %rem, i64* %r, align 8
    386   %div = udiv i64 %a0, %a1
    387   ret i64 %div
    388 }
    389