Home | History | Annotate | Download | only in Mips
      1 ; RUN: llc -march=mips -mcpu=mips32   < %s | FileCheck %s -check-prefix=ALL -check-prefix=32
      2 ; RUN: llc -march=mips -mcpu=mips32r2 < %s | FileCheck %s -check-prefix=ALL -check-prefix=32
      3 ; RUN: llc -march=mips -mcpu=mips32r6 < %s | FileCheck %s -check-prefix=ALL -check-prefix=32R6
      4 ; RUN: llc -march=mips -mcpu=mips32 -mattr=dsp < %s | FileCheck %s -check-prefix=DSP
      5 ; RUN: llc -march=mips -mcpu=mips64   < %s | FileCheck %s -check-prefix=ALL -check-prefix=64
      6 ; RUN: llc -march=mips -mcpu=mips64r2 < %s | FileCheck %s -check-prefix=ALL -check-prefix=64
      7 ; RUN: llc -march=mips -mcpu=mips64r6 < %s | FileCheck %s -check-prefix=ALL -check-prefix=64R6
      8 
      9 ; FIXME: The MIPS16 test should check its output
     10 ; RUN: llc -march=mips -mcpu=mips16 < %s
     11 
     12 ; ALL-LABEL: madd1:
     13 
     14 ; 32-DAG:        sra $[[T0:[0-9]+]], $6, 31
     15 ; 32-DAG:        mtlo $6
     16 ; 32-DAG:        [[m:m]]add ${{[45]}}, ${{[45]}}
     17 ; 32-DAG:        [[m]]fhi $2
     18 ; 32-DAG:        [[m]]flo $3
     19 
     20 ; DSP-DAG:       sra $[[T0:[0-9]+]], $6, 31
     21 ; DSP-DAG:       mtlo $[[AC:ac[0-3]+]], $6
     22 ; DSP-DAG:       madd $[[AC]], ${{[45]}}, ${{[45]}}
     23 ; DSP-DAG:       mfhi $2, $[[AC]]
     24 ; DSP-DAG:       mflo $3, $[[AC]]
     25 
     26 ; 32R6-DAG:      mul  $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
     27 ; 32R6-DAG:      addu $[[T1:[0-9]+]], $[[T0]], $6
     28 ; 32R6-DAG:      sltu $[[T2:[0-9]+]], $[[T1]], $6
     29 ; 32R6-DAG:      sra  $[[T3:[0-9]+]], $6, 31
     30 ; 32R6-DAG:      addu $[[T4:[0-9]+]], $[[T2]], $[[T3]]
     31 ; 32R6-DAG:      muh  $[[T5:[0-9]+]], ${{[45]}}, ${{[45]}}
     32 ; 32R6-DAG:      addu $2, $[[T5]], $[[T4]]
     33 
     34 ; 64-DAG:        sll $[[T0:[0-9]+]], $4, 0
     35 ; 64-DAG:        sll $[[T1:[0-9]+]], $5, 0
     36 ; 64-DAG:        d[[m:m]]ult $[[T1]], $[[T0]]
     37 ; 64-DAG:        [[m]]flo $[[T2:[0-9]+]]
     38 ; 64-DAG:        sll $[[T3:[0-9]+]], $6, 0
     39 ; 64-DAG:        daddu $2, $[[T2]], $[[T3]]
     40 
     41 ; 64R6-DAG:      sll $[[T0:[0-9]+]], $4, 0
     42 ; 64R6-DAG:      sll $[[T1:[0-9]+]], $5, 0
     43 ; 64R6-DAG:      dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
     44 ; 64R6-DAG:      sll $[[T3:[0-9]+]], $6, 0
     45 ; 64R6-DAG:      daddu $2, $[[T2]], $[[T3]]
     46 
     47 define i64 @madd1(i32 %a, i32 %b, i32 %c) nounwind readnone {
     48 entry:
     49   %conv = sext i32 %a to i64
     50   %conv2 = sext i32 %b to i64
     51   %mul = mul nsw i64 %conv2, %conv
     52   %conv4 = sext i32 %c to i64
     53   %add = add nsw i64 %mul, %conv4
     54   ret i64 %add
     55 }
     56 
     57 ; ALL-LABEL: madd2:
     58 
     59 ; FIXME: We don't really need this instruction
     60 ; 32-DAG:        addiu $[[T0:[0-9]+]], $zero, 0
     61 ; 32-DAG:        mtlo $6
     62 ; 32-DAG:        [[m:m]]addu ${{[45]}}, ${{[45]}}
     63 ; 32-DAG:        [[m]]fhi $2
     64 ; 32-DAG:        [[m]]flo $3
     65 
     66 ; DSP-DAG:       addiu $[[T0:[0-9]+]], $zero, 0
     67 ; DSP-DAG:       mtlo $[[AC:ac[0-3]+]], $6
     68 ; DSP-DAG:       maddu $[[AC]], ${{[45]}}, ${{[45]}}
     69 ; DSP-DAG:       mfhi $2, $[[AC]]
     70 ; DSP-DAG:       mflo $3, $[[AC]]
     71 
     72 ; 32R6-DAG:      mul  $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
     73 ; 32R6-DAG:      addu $[[T1:[0-9]+]], $[[T0]], $6
     74 ; 32R6-DAG:      sltu $[[T2:[0-9]+]], $[[T1]], $6
     75 ; FIXME: There's a redundant move here. We should remove it
     76 ; 32R6-DAG:      muhu $[[T3:[0-9]+]], ${{[45]}}, ${{[45]}}
     77 ; 32R6-DAG:      addu $2, $[[T3]], $[[T2]]
     78 
     79 ; 64-DAG:        dsll $[[T0:[0-9]+]], $4, 32
     80 ; 64-DAG:        dsrl $[[T1:[0-9]+]], $[[T0]], 32
     81 ; 64-DAG:        dsll $[[T2:[0-9]+]], $5, 32
     82 ; 64-DAG:        dsrl $[[T3:[0-9]+]], $[[T2]], 32
     83 ; 64-DAG:        d[[m:m]]ult $[[T3]], $[[T1]]
     84 ; 64-DAG:        [[m]]flo $[[T4:[0-9]+]]
     85 ; 64-DAG:        dsll $[[T5:[0-9]+]], $6, 32
     86 ; 64-DAG:        dsrl $[[T6:[0-9]+]], $[[T5]], 32
     87 ; 64-DAG:        daddu $2, $[[T4]], $[[T6]]
     88 
     89 ; 64R6-DAG:      dsll $[[T0:[0-9]+]], $4, 32
     90 ; 64R6-DAG:      dsrl $[[T1:[0-9]+]], $[[T0]], 32
     91 ; 64R6-DAG:      dsll $[[T2:[0-9]+]], $5, 32
     92 ; 64R6-DAG:      dsrl $[[T3:[0-9]+]], $[[T2]], 32
     93 ; 64R6-DAG:      dmul $[[T4:[0-9]+]], $[[T3]], $[[T1]]
     94 ; 64R6-DAG:      dsll $[[T5:[0-9]+]], $6, 32
     95 ; 64R6-DAG:      dsrl $[[T6:[0-9]+]], $[[T5]], 32
     96 ; 64R6-DAG:      daddu $2, $[[T4]], $[[T6]]
     97 
     98 define i64 @madd2(i32 %a, i32 %b, i32 %c) nounwind readnone {
     99 entry:
    100   %conv = zext i32 %a to i64
    101   %conv2 = zext i32 %b to i64
    102   %mul = mul nsw i64 %conv2, %conv
    103   %conv4 = zext i32 %c to i64
    104   %add = add nsw i64 %mul, %conv4
    105   ret i64 %add
    106 }
    107 
    108 ; ALL-LABEL: madd3:
    109 
    110 ; 32-DAG:        mthi $6
    111 ; 32-DAG:        mtlo $7
    112 ; 32-DAG:        [[m:m]]add ${{[45]}}, ${{[45]}}
    113 ; 32-DAG:        [[m]]fhi $2
    114 ; 32-DAG:        [[m]]flo $3
    115 
    116 ; DSP-DAG:       mthi $[[AC:ac[0-3]+]], $6
    117 ; DSP-DAG:       mtlo $[[AC]], $7
    118 ; DSP-DAG:       madd $[[AC]], ${{[45]}}, ${{[45]}}
    119 ; DSP-DAG:       mfhi $2, $[[AC]]
    120 ; DSP-DAG:       mflo $3, $[[AC]]
    121 
    122 ; 32R6-DAG:      mul  $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
    123 ; 32R6-DAG:      addu $[[T1:[0-9]+]], $[[T0]], $7
    124 ; 32R6-DAG:      sltu $[[T2:[0-9]+]], $[[T1]], $7
    125 ; 32R6-DAG:      addu $[[T4:[0-9]+]], $[[T2]], $6
    126 ; 32R6-DAG:      muh  $[[T5:[0-9]+]], ${{[45]}}, ${{[45]}}
    127 ; 32R6-DAG:      addu $2, $[[T5]], $[[T4]]
    128 
    129 ; 64-DAG:        sll $[[T0:[0-9]+]], $4, 0
    130 ; 64-DAG:        sll $[[T1:[0-9]+]], $5, 0
    131 ; 64-DAG:        d[[m:m]]ult $[[T1]], $[[T0]]
    132 ; 64-DAG:        [[m]]flo $[[T2:[0-9]+]]
    133 ; 64-DAG:        daddu $2, $[[T2]], $6
    134 
    135 ; 64R6-DAG:      sll $[[T0:[0-9]+]], $4, 0
    136 ; 64R6-DAG:      sll $[[T1:[0-9]+]], $5, 0
    137 ; 64R6-DAG:      dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
    138 ; 64R6-DAG:      daddu $2, $[[T2]], $6
    139 
    140 define i64 @madd3(i32 %a, i32 %b, i64 %c) nounwind readnone {
    141 entry:
    142   %conv = sext i32 %a to i64
    143   %conv2 = sext i32 %b to i64
    144   %mul = mul nsw i64 %conv2, %conv
    145   %add = add nsw i64 %mul, %c
    146   ret i64 %add
    147 }
    148 
    149 ; ALL-LABEL: msub1:
    150 
    151 ; 32-DAG:        sra $[[T0:[0-9]+]], $6, 31
    152 ; 32-DAG:        mtlo $6
    153 ; 32-DAG:        [[m:m]]sub ${{[45]}}, ${{[45]}}
    154 ; 32-DAG:        [[m]]fhi $2
    155 ; 32-DAG:        [[m]]flo $3
    156 
    157 ; DSP-DAG:       sra $[[T0:[0-9]+]], $6, 31
    158 ; DSP-DAG:       mtlo $[[AC:ac[0-3]+]], $6
    159 ; DSP-DAG:       msub $[[AC]], ${{[45]}}, ${{[45]}}
    160 ; DSP-DAG:       mfhi $2, $[[AC]]
    161 ; DSP-DAG:       mflo $3, $[[AC]]
    162 
    163 ; 32R6-DAG:      muh  $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
    164 ; 32R6-DAG:      mul  $[[T1:[0-9]+]], ${{[45]}}, ${{[45]}}
    165 ; 32R6-DAG:      sltu $[[T3:[0-9]+]], $6, $[[T1]]
    166 ; 32R6-DAG:      addu $[[T4:[0-9]+]], $[[T3]], $[[T0]]
    167 ; 32R6-DAG:      sra  $[[T5:[0-9]+]], $6, 31
    168 ; 32R6-DAG:      subu $2, $[[T5]], $[[T4]]
    169 ; 32R6-DAG:      subu $3, $6, $[[T1]]
    170 
    171 ; 64-DAG:        sll $[[T0:[0-9]+]], $4, 0
    172 ; 64-DAG:        sll $[[T1:[0-9]+]], $5, 0
    173 ; 64-DAG:        d[[m:m]]ult $[[T1]], $[[T0]]
    174 ; 64-DAG:        [[m]]flo $[[T2:[0-9]+]]
    175 ; 64-DAG:        sll $[[T3:[0-9]+]], $6, 0
    176 ; 64-DAG:        dsubu $2, $[[T3]], $[[T2]]
    177 
    178 ; 64R6-DAG:      sll $[[T0:[0-9]+]], $4, 0
    179 ; 64R6-DAG:      sll $[[T1:[0-9]+]], $5, 0
    180 ; 64R6-DAG:      dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
    181 ; 64R6-DAG:      sll $[[T3:[0-9]+]], $6, 0
    182 ; 64R6-DAG:      dsubu $2, $[[T3]], $[[T2]]
    183 
    184 define i64 @msub1(i32 %a, i32 %b, i32 %c) nounwind readnone {
    185 entry:
    186   %conv = sext i32 %c to i64
    187   %conv2 = sext i32 %a to i64
    188   %conv4 = sext i32 %b to i64
    189   %mul = mul nsw i64 %conv4, %conv2
    190   %sub = sub nsw i64 %conv, %mul
    191   ret i64 %sub
    192 }
    193 
    194 ; ALL-LABEL: msub2:
    195 
    196 ; FIXME: We don't really need this instruction
    197 ; 32-DAG:        addiu $[[T0:[0-9]+]], $zero, 0
    198 ; 32-DAG:        mtlo $6
    199 ; 32-DAG:        [[m:m]]subu ${{[45]}}, ${{[45]}}
    200 ; 32-DAG:        [[m]]fhi $2
    201 ; 32-DAG:        [[m]]flo $3
    202 
    203 ; DSP-DAG:       addiu $[[T0:[0-9]+]], $zero, 0
    204 ; DSP-DAG:       mtlo $[[AC:ac[0-3]+]], $6
    205 ; DSP-DAG:       msubu $[[AC]], ${{[45]}}, ${{[45]}}
    206 ; DSP-DAG:       mfhi $2, $[[AC]]
    207 ; DSP-DAG:       mflo $3, $[[AC]]
    208 
    209 ; 32R6-DAG:      muhu $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
    210 ; 32R6-DAG:      mul $[[T1:[0-9]+]], ${{[45]}}, ${{[45]}}
    211 
    212 ; 32R6-DAG:      sltu $[[T2:[0-9]+]], $6, $[[T1]]
    213 ; 32R6-DAG:      addu $[[T3:[0-9]+]], $[[T2]], $[[T0]]
    214 ; 32R6-DAG:      negu $2, $[[T3]]
    215 ; 32R6-DAG:      subu $3, $6, $[[T1]]
    216 
    217 ; 64-DAG:        dsll $[[T0:[0-9]+]], $4, 32
    218 ; 64-DAG:        dsrl $[[T1:[0-9]+]], $[[T0]], 32
    219 ; 64-DAG:        dsll $[[T2:[0-9]+]], $5, 32
    220 ; 64-DAG:        dsrl $[[T3:[0-9]+]], $[[T2]], 32
    221 ; 64-DAG:        d[[m:m]]ult $[[T3]], $[[T1]]
    222 ; 64-DAG:        [[m]]flo $[[T4:[0-9]+]]
    223 ; 64-DAG:        dsll $[[T5:[0-9]+]], $6, 32
    224 ; 64-DAG:        dsrl $[[T6:[0-9]+]], $[[T5]], 32
    225 ; 64-DAG:        dsubu $2, $[[T6]], $[[T4]]
    226 
    227 ; 64R6-DAG:      dsll $[[T0:[0-9]+]], $4, 32
    228 ; 64R6-DAG:      dsrl $[[T1:[0-9]+]], $[[T0]], 32
    229 ; 64R6-DAG:      dsll $[[T2:[0-9]+]], $5, 32
    230 ; 64R6-DAG:      dsrl $[[T3:[0-9]+]], $[[T2]], 32
    231 ; 64R6-DAG:      dmul $[[T4:[0-9]+]], $[[T3]], $[[T1]]
    232 ; 64R6-DAG:      dsll $[[T5:[0-9]+]], $6, 32
    233 ; 64R6-DAG:      dsrl $[[T6:[0-9]+]], $[[T5]], 32
    234 ; 64R6-DAG:      dsubu $2, $[[T6]], $[[T4]]
    235 
    236 define i64 @msub2(i32 %a, i32 %b, i32 %c) nounwind readnone {
    237 entry:
    238   %conv = zext i32 %c to i64
    239   %conv2 = zext i32 %a to i64
    240   %conv4 = zext i32 %b to i64
    241   %mul = mul nsw i64 %conv4, %conv2
    242   %sub = sub nsw i64 %conv, %mul
    243   ret i64 %sub
    244 }
    245 
    246 ; ALL-LABEL: msub3:
    247 
    248 ; FIXME: We don't really need this instruction
    249 ; 32-DAG:        mthi $6
    250 ; 32-DAG:        mtlo $7
    251 ; 32-DAG:        [[m:m]]sub ${{[45]}}, ${{[45]}}
    252 ; 32-DAG:        [[m]]fhi $2
    253 ; 32-DAG:        [[m]]flo $3
    254 
    255 ; DSP-DAG:       addiu $[[T0:[0-9]+]], $zero, 0
    256 ; DSP-DAG:       mtlo $[[AC:ac[0-3]+]], $6
    257 ; DSP-DAG:       msub $[[AC]], ${{[45]}}, ${{[45]}}
    258 ; DSP-DAG:       mfhi $2, $[[AC]]
    259 ; DSP-DAG:       mflo $3, $[[AC]]
    260 
    261 ; 32R6-DAG:      muh $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
    262 ; 32R6-DAG:      mul $[[T1:[0-9]+]], ${{[45]}}, ${{[45]}}
    263 ; 32R6-DAG:      sltu $[[T2:[0-9]+]], $7, $[[T1]]
    264 ; 32R6-DAG:      addu $[[T3:[0-9]+]], $[[T2]], $[[T0]]
    265 ; 32R6-DAG:      subu $2, $6, $[[T3]]
    266 ; 32R6-DAG:      subu $3, $7, $[[T1]]
    267 
    268 ; 64-DAG:        sll $[[T0:[0-9]+]], $4, 0
    269 ; 64-DAG:        sll $[[T1:[0-9]+]], $5, 0
    270 ; 64-DAG:        d[[m:m]]ult $[[T1]], $[[T0]]
    271 ; 64-DAG:        [[m]]flo $[[T2:[0-9]+]]
    272 ; 64-DAG:        dsubu $2, $6, $[[T2]]
    273 
    274 ; 64R6-DAG:      sll $[[T0:[0-9]+]], $4, 0
    275 ; 64R6-DAG:      sll $[[T1:[0-9]+]], $5, 0
    276 ; 64R6-DAG:      dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
    277 ; 64R6-DAG:      dsubu $2, $6, $[[T2]]
    278 
    279 define i64 @msub3(i32 %a, i32 %b, i64 %c) nounwind readnone {
    280 entry:
    281   %conv = sext i32 %a to i64
    282   %conv3 = sext i32 %b to i64
    283   %mul = mul nsw i64 %conv3, %conv
    284   %sub = sub nsw i64 %c, %mul
    285   ret i64 %sub
    286 }
    287