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