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 -mattr=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 $6, $[[AC:ac[0-3]+]]
     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 $6, $[[AC:ac[0-3]+]]
     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:        d[[m:m]]ult $5, $4
     80 ; 64-DAG:        [[m]]flo $[[T0:[0-9]+]]
     81 ; 64-DAG:        daddu $2, $[[T0]], $6
     82 
     83 ; 64R6-DAG:      dmul $[[T0:[0-9]+]], $5, $4
     84 ; 64R6-DAG:      daddu $2, $[[T0]], $6
     85 
     86 define i64 @madd2(i32 zeroext %a, i32 zeroext %b, i32 zeroext %c) nounwind readnone {
     87 entry:
     88   %conv = zext i32 %a to i64
     89   %conv2 = zext i32 %b to i64
     90   %mul = mul nsw i64 %conv2, %conv
     91   %conv4 = zext i32 %c to i64
     92   %add = add nsw i64 %mul, %conv4
     93   ret i64 %add
     94 }
     95 
     96 ; ALL-LABEL: madd3:
     97 
     98 ; 32-DAG:        mthi $6
     99 ; 32-DAG:        mtlo $7
    100 ; 32-DAG:        [[m:m]]add ${{[45]}}, ${{[45]}}
    101 ; 32-DAG:        [[m]]fhi $2
    102 ; 32-DAG:        [[m]]flo $3
    103 
    104 ; DSP-DAG:       mthi $6, $[[AC:ac[0-3]+]]
    105 ; DSP-DAG:       mtlo $7, $[[AC]]
    106 ; DSP-DAG:       madd $[[AC]], ${{[45]}}, ${{[45]}}
    107 ; DSP-DAG:       mfhi $2, $[[AC]]
    108 ; DSP-DAG:       mflo $3, $[[AC]]
    109 
    110 ; 32R6-DAG:      mul  $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
    111 ; 32R6-DAG:      addu $[[T1:[0-9]+]], $[[T0]], $7
    112 ; 32R6-DAG:      sltu $[[T2:[0-9]+]], $[[T1]], $7
    113 ; 32R6-DAG:      addu $[[T4:[0-9]+]], $[[T2]], $6
    114 ; 32R6-DAG:      muh  $[[T5:[0-9]+]], ${{[45]}}, ${{[45]}}
    115 ; 32R6-DAG:      addu $2, $[[T5]], $[[T4]]
    116 
    117 ; 64-DAG:        sll $[[T0:[0-9]+]], $4, 0
    118 ; 64-DAG:        sll $[[T1:[0-9]+]], $5, 0
    119 ; 64-DAG:        d[[m:m]]ult $[[T1]], $[[T0]]
    120 ; 64-DAG:        [[m]]flo $[[T2:[0-9]+]]
    121 ; 64-DAG:        daddu $2, $[[T2]], $6
    122 
    123 ; 64R6-DAG:      sll $[[T0:[0-9]+]], $4, 0
    124 ; 64R6-DAG:      sll $[[T1:[0-9]+]], $5, 0
    125 ; 64R6-DAG:      dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
    126 ; 64R6-DAG:      daddu $2, $[[T2]], $6
    127 
    128 define i64 @madd3(i32 %a, i32 %b, i64 %c) nounwind readnone {
    129 entry:
    130   %conv = sext i32 %a to i64
    131   %conv2 = sext i32 %b to i64
    132   %mul = mul nsw i64 %conv2, %conv
    133   %add = add nsw i64 %mul, %c
    134   ret i64 %add
    135 }
    136 
    137 ; ALL-LABEL: msub1:
    138 
    139 ; 32-DAG:        sra $[[T0:[0-9]+]], $6, 31
    140 ; 32-DAG:        mtlo $6
    141 ; 32-DAG:        [[m:m]]sub ${{[45]}}, ${{[45]}}
    142 ; 32-DAG:        [[m]]fhi $2
    143 ; 32-DAG:        [[m]]flo $3
    144 
    145 ; DSP-DAG:       sra $[[T0:[0-9]+]], $6, 31
    146 ; DSP-DAG:       mtlo $6, $[[AC:ac[0-3]+]]
    147 ; DSP-DAG:       msub $[[AC]], ${{[45]}}, ${{[45]}}
    148 ; DSP-DAG:       mfhi $2, $[[AC]]
    149 ; DSP-DAG:       mflo $3, $[[AC]]
    150 
    151 ; 32R6-DAG:      muh  $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
    152 ; 32R6-DAG:      mul  $[[T1:[0-9]+]], ${{[45]}}, ${{[45]}}
    153 ; 32R6-DAG:      sltu $[[T3:[0-9]+]], $6, $[[T1]]
    154 ; 32R6-DAG:      addu $[[T4:[0-9]+]], $[[T3]], $[[T0]]
    155 ; 32R6-DAG:      sra  $[[T5:[0-9]+]], $6, 31
    156 ; 32R6-DAG:      subu $2, $[[T5]], $[[T4]]
    157 ; 32R6-DAG:      subu $3, $6, $[[T1]]
    158 
    159 ; 64-DAG:        sll $[[T0:[0-9]+]], $4, 0
    160 ; 64-DAG:        sll $[[T1:[0-9]+]], $5, 0
    161 ; 64-DAG:        d[[m:m]]ult $[[T1]], $[[T0]]
    162 ; 64-DAG:        [[m]]flo $[[T2:[0-9]+]]
    163 ; 64-DAG:        sll $[[T3:[0-9]+]], $6, 0
    164 ; 64-DAG:        dsubu $2, $[[T3]], $[[T2]]
    165 
    166 ; 64R6-DAG:      sll $[[T0:[0-9]+]], $4, 0
    167 ; 64R6-DAG:      sll $[[T1:[0-9]+]], $5, 0
    168 ; 64R6-DAG:      dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
    169 ; 64R6-DAG:      sll $[[T3:[0-9]+]], $6, 0
    170 ; 64R6-DAG:      dsubu $2, $[[T3]], $[[T2]]
    171 
    172 define i64 @msub1(i32 %a, i32 %b, i32 %c) nounwind readnone {
    173 entry:
    174   %conv = sext i32 %c to i64
    175   %conv2 = sext i32 %a to i64
    176   %conv4 = sext i32 %b to i64
    177   %mul = mul nsw i64 %conv4, %conv2
    178   %sub = sub nsw i64 %conv, %mul
    179   ret i64 %sub
    180 }
    181 
    182 ; ALL-LABEL: msub2:
    183 
    184 ; FIXME: We don't really need this instruction
    185 ; 32-DAG:        addiu $[[T0:[0-9]+]], $zero, 0
    186 ; 32-DAG:        mtlo $6
    187 ; 32-DAG:        [[m:m]]subu ${{[45]}}, ${{[45]}}
    188 ; 32-DAG:        [[m]]fhi $2
    189 ; 32-DAG:        [[m]]flo $3
    190 
    191 ; DSP-DAG:       addiu $[[T0:[0-9]+]], $zero, 0
    192 ; DSP-DAG:       mtlo $6, $[[AC:ac[0-3]+]]
    193 ; DSP-DAG:       msubu $[[AC]], ${{[45]}}, ${{[45]}}
    194 ; DSP-DAG:       mfhi $2, $[[AC]]
    195 ; DSP-DAG:       mflo $3, $[[AC]]
    196 
    197 ; 32R6-DAG:      muhu $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
    198 ; 32R6-DAG:      mul $[[T1:[0-9]+]], ${{[45]}}, ${{[45]}}
    199 
    200 ; 32R6-DAG:      sltu $[[T2:[0-9]+]], $6, $[[T1]]
    201 ; 32R6-DAG:      addu $[[T3:[0-9]+]], $[[T2]], $[[T0]]
    202 ; 32R6-DAG:      negu $2, $[[T3]]
    203 ; 32R6-DAG:      subu $3, $6, $[[T1]]
    204 
    205 ; 64-DAG:        d[[m:m]]ult $5, $4
    206 ; 64-DAG:        [[m]]flo $[[T0:[0-9]+]]
    207 ; 64-DAG:        dsubu $2, $6, $[[T0]]
    208 
    209 ; 64R6-DAG:      dmul $[[T0:[0-9]+]], $5, $4
    210 ; 64R6-DAG:      dsubu $2, $6, $[[T0]]
    211 
    212 define i64 @msub2(i32 zeroext %a, i32 zeroext %b, i32 zeroext %c) nounwind readnone {
    213 entry:
    214   %conv = zext i32 %c to i64
    215   %conv2 = zext i32 %a to i64
    216   %conv4 = zext i32 %b to i64
    217   %mul = mul nsw i64 %conv4, %conv2
    218   %sub = sub nsw i64 %conv, %mul
    219   ret i64 %sub
    220 }
    221 
    222 ; ALL-LABEL: msub3:
    223 
    224 ; FIXME: We don't really need this instruction
    225 ; 32-DAG:        mthi $6
    226 ; 32-DAG:        mtlo $7
    227 ; 32-DAG:        [[m:m]]sub ${{[45]}}, ${{[45]}}
    228 ; 32-DAG:        [[m]]fhi $2
    229 ; 32-DAG:        [[m]]flo $3
    230 
    231 ; DSP-DAG:       addiu $[[T0:[0-9]+]], $zero, 0
    232 ; DSP-DAG:       mtlo $6, $[[AC:ac[0-3]+]]
    233 ; DSP-DAG:       msub $[[AC]], ${{[45]}}, ${{[45]}}
    234 ; DSP-DAG:       mfhi $2, $[[AC]]
    235 ; DSP-DAG:       mflo $3, $[[AC]]
    236 
    237 ; 32R6-DAG:      muh $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
    238 ; 32R6-DAG:      mul $[[T1:[0-9]+]], ${{[45]}}, ${{[45]}}
    239 ; 32R6-DAG:      sltu $[[T2:[0-9]+]], $7, $[[T1]]
    240 ; 32R6-DAG:      addu $[[T3:[0-9]+]], $[[T2]], $[[T0]]
    241 ; 32R6-DAG:      subu $2, $6, $[[T3]]
    242 ; 32R6-DAG:      subu $3, $7, $[[T1]]
    243 
    244 ; 64-DAG:        sll $[[T0:[0-9]+]], $4, 0
    245 ; 64-DAG:        sll $[[T1:[0-9]+]], $5, 0
    246 ; 64-DAG:        d[[m:m]]ult $[[T1]], $[[T0]]
    247 ; 64-DAG:        [[m]]flo $[[T2:[0-9]+]]
    248 ; 64-DAG:        dsubu $2, $6, $[[T2]]
    249 
    250 ; 64R6-DAG:      sll $[[T0:[0-9]+]], $4, 0
    251 ; 64R6-DAG:      sll $[[T1:[0-9]+]], $5, 0
    252 ; 64R6-DAG:      dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
    253 ; 64R6-DAG:      dsubu $2, $6, $[[T2]]
    254 
    255 define i64 @msub3(i32 %a, i32 %b, i64 %c) nounwind readnone {
    256 entry:
    257   %conv = sext i32 %a to i64
    258   %conv3 = sext i32 %b to i64
    259   %mul = mul nsw i64 %conv3, %conv
    260   %sub = sub nsw i64 %c, %mul
    261   ret i64 %sub
    262 }
    263