1 //==- SPUInstrInfo.td - Describe the Cell SPU Instructions -*- tablegen -*-==// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // Cell SPU Instructions: 10 //===----------------------------------------------------------------------===// 11 12 //===----------------------------------------------------------------------===// 13 // TODO Items (not urgent today, but would be nice, low priority) 14 // 15 // ANDBI, ORBI: SPU constructs a 4-byte constant for these instructions by 16 // concatenating the byte argument b as "bbbb". Could recognize this bit pattern 17 // in 16-bit and 32-bit constants and reduce instruction count. 18 //===----------------------------------------------------------------------===// 19 20 //===----------------------------------------------------------------------===// 21 // Pseudo instructions: 22 //===----------------------------------------------------------------------===// 23 24 let hasCtrlDep = 1, Defs = [R1], Uses = [R1] in { 25 def ADJCALLSTACKDOWN : Pseudo<(outs), (ins u16imm_i32:$amt), 26 "${:comment} ADJCALLSTACKDOWN", 27 [(callseq_start timm:$amt)]>; 28 def ADJCALLSTACKUP : Pseudo<(outs), (ins u16imm_i32:$amt), 29 "${:comment} ADJCALLSTACKUP", 30 [(callseq_end timm:$amt)]>; 31 def HBR_LABEL : Pseudo<(outs), (ins hbrtarget:$targ), 32 "$targ:\t${:comment}branch hint target",[ ]>; 33 } 34 35 //===----------------------------------------------------------------------===// 36 // Loads: 37 // NB: The ordering is actually important, since the instruction selection 38 // will try each of the instructions in sequence, i.e., the D-form first with 39 // the 10-bit displacement, then the A-form with the 16 bit displacement, and 40 // finally the X-form with the register-register. 41 //===----------------------------------------------------------------------===// 42 43 let canFoldAsLoad = 1 in { 44 class LoadDFormVec<ValueType vectype> 45 : RI10Form<0b00101100, (outs VECREG:$rT), (ins dformaddr:$src), 46 "lqd\t$rT, $src", 47 LoadStore, 48 [(set (vectype VECREG:$rT), (load dform_addr:$src))]> 49 { } 50 51 class LoadDForm<RegisterClass rclass> 52 : RI10Form<0b00101100, (outs rclass:$rT), (ins dformaddr:$src), 53 "lqd\t$rT, $src", 54 LoadStore, 55 [(set rclass:$rT, (load dform_addr:$src))]> 56 { } 57 58 multiclass LoadDForms 59 { 60 def v16i8: LoadDFormVec<v16i8>; 61 def v8i16: LoadDFormVec<v8i16>; 62 def v4i32: LoadDFormVec<v4i32>; 63 def v2i64: LoadDFormVec<v2i64>; 64 def v4f32: LoadDFormVec<v4f32>; 65 def v2f64: LoadDFormVec<v2f64>; 66 67 def r128: LoadDForm<GPRC>; 68 def r64: LoadDForm<R64C>; 69 def r32: LoadDForm<R32C>; 70 def f32: LoadDForm<R32FP>; 71 def f64: LoadDForm<R64FP>; 72 def r16: LoadDForm<R16C>; 73 def r8: LoadDForm<R8C>; 74 } 75 76 class LoadAFormVec<ValueType vectype> 77 : RI16Form<0b100001100, (outs VECREG:$rT), (ins addr256k:$src), 78 "lqa\t$rT, $src", 79 LoadStore, 80 [(set (vectype VECREG:$rT), (load aform_addr:$src))]> 81 { } 82 83 class LoadAForm<RegisterClass rclass> 84 : RI16Form<0b100001100, (outs rclass:$rT), (ins addr256k:$src), 85 "lqa\t$rT, $src", 86 LoadStore, 87 [(set rclass:$rT, (load aform_addr:$src))]> 88 { } 89 90 multiclass LoadAForms 91 { 92 def v16i8: LoadAFormVec<v16i8>; 93 def v8i16: LoadAFormVec<v8i16>; 94 def v4i32: LoadAFormVec<v4i32>; 95 def v2i64: LoadAFormVec<v2i64>; 96 def v4f32: LoadAFormVec<v4f32>; 97 def v2f64: LoadAFormVec<v2f64>; 98 99 def r128: LoadAForm<GPRC>; 100 def r64: LoadAForm<R64C>; 101 def r32: LoadAForm<R32C>; 102 def f32: LoadAForm<R32FP>; 103 def f64: LoadAForm<R64FP>; 104 def r16: LoadAForm<R16C>; 105 def r8: LoadAForm<R8C>; 106 } 107 108 class LoadXFormVec<ValueType vectype> 109 : RRForm<0b00100011100, (outs VECREG:$rT), (ins memrr:$src), 110 "lqx\t$rT, $src", 111 LoadStore, 112 [(set (vectype VECREG:$rT), (load xform_addr:$src))]> 113 { } 114 115 class LoadXForm<RegisterClass rclass> 116 : RRForm<0b00100011100, (outs rclass:$rT), (ins memrr:$src), 117 "lqx\t$rT, $src", 118 LoadStore, 119 [(set rclass:$rT, (load xform_addr:$src))]> 120 { } 121 122 multiclass LoadXForms 123 { 124 def v16i8: LoadXFormVec<v16i8>; 125 def v8i16: LoadXFormVec<v8i16>; 126 def v4i32: LoadXFormVec<v4i32>; 127 def v2i64: LoadXFormVec<v2i64>; 128 def v4f32: LoadXFormVec<v4f32>; 129 def v2f64: LoadXFormVec<v2f64>; 130 131 def r128: LoadXForm<GPRC>; 132 def r64: LoadXForm<R64C>; 133 def r32: LoadXForm<R32C>; 134 def f32: LoadXForm<R32FP>; 135 def f64: LoadXForm<R64FP>; 136 def r16: LoadXForm<R16C>; 137 def r8: LoadXForm<R8C>; 138 } 139 140 defm LQA : LoadAForms; 141 defm LQD : LoadDForms; 142 defm LQX : LoadXForms; 143 144 /* Load quadword, PC relative: Not much use at this point in time. 145 Might be of use later for relocatable code. It's effectively the 146 same as LQA, but uses PC-relative addressing. 147 def LQR : RI16Form<0b111001100, (outs VECREG:$rT), (ins s16imm:$disp), 148 "lqr\t$rT, $disp", LoadStore, 149 [(set VECREG:$rT, (load iaddr:$disp))]>; 150 */ 151 } 152 153 //===----------------------------------------------------------------------===// 154 // Stores: 155 //===----------------------------------------------------------------------===// 156 class StoreDFormVec<ValueType vectype> 157 : RI10Form<0b00100100, (outs), (ins VECREG:$rT, dformaddr:$src), 158 "stqd\t$rT, $src", 159 LoadStore, 160 [(store (vectype VECREG:$rT), dform_addr:$src)]> 161 { } 162 163 class StoreDForm<RegisterClass rclass> 164 : RI10Form<0b00100100, (outs), (ins rclass:$rT, dformaddr:$src), 165 "stqd\t$rT, $src", 166 LoadStore, 167 [(store rclass:$rT, dform_addr:$src)]> 168 { } 169 170 multiclass StoreDForms 171 { 172 def v16i8: StoreDFormVec<v16i8>; 173 def v8i16: StoreDFormVec<v8i16>; 174 def v4i32: StoreDFormVec<v4i32>; 175 def v2i64: StoreDFormVec<v2i64>; 176 def v4f32: StoreDFormVec<v4f32>; 177 def v2f64: StoreDFormVec<v2f64>; 178 179 def r128: StoreDForm<GPRC>; 180 def r64: StoreDForm<R64C>; 181 def r32: StoreDForm<R32C>; 182 def f32: StoreDForm<R32FP>; 183 def f64: StoreDForm<R64FP>; 184 def r16: StoreDForm<R16C>; 185 def r8: StoreDForm<R8C>; 186 } 187 188 class StoreAFormVec<ValueType vectype> 189 : RI16Form<0b0010010, (outs), (ins VECREG:$rT, addr256k:$src), 190 "stqa\t$rT, $src", 191 LoadStore, 192 [(store (vectype VECREG:$rT), aform_addr:$src)]>; 193 194 class StoreAForm<RegisterClass rclass> 195 : RI16Form<0b001001, (outs), (ins rclass:$rT, addr256k:$src), 196 "stqa\t$rT, $src", 197 LoadStore, 198 [(store rclass:$rT, aform_addr:$src)]>; 199 200 multiclass StoreAForms 201 { 202 def v16i8: StoreAFormVec<v16i8>; 203 def v8i16: StoreAFormVec<v8i16>; 204 def v4i32: StoreAFormVec<v4i32>; 205 def v2i64: StoreAFormVec<v2i64>; 206 def v4f32: StoreAFormVec<v4f32>; 207 def v2f64: StoreAFormVec<v2f64>; 208 209 def r128: StoreAForm<GPRC>; 210 def r64: StoreAForm<R64C>; 211 def r32: StoreAForm<R32C>; 212 def f32: StoreAForm<R32FP>; 213 def f64: StoreAForm<R64FP>; 214 def r16: StoreAForm<R16C>; 215 def r8: StoreAForm<R8C>; 216 } 217 218 class StoreXFormVec<ValueType vectype> 219 : RRForm<0b00100100, (outs), (ins VECREG:$rT, memrr:$src), 220 "stqx\t$rT, $src", 221 LoadStore, 222 [(store (vectype VECREG:$rT), xform_addr:$src)]> 223 { } 224 225 class StoreXForm<RegisterClass rclass> 226 : RRForm<0b00100100, (outs), (ins rclass:$rT, memrr:$src), 227 "stqx\t$rT, $src", 228 LoadStore, 229 [(store rclass:$rT, xform_addr:$src)]> 230 { } 231 232 multiclass StoreXForms 233 { 234 def v16i8: StoreXFormVec<v16i8>; 235 def v8i16: StoreXFormVec<v8i16>; 236 def v4i32: StoreXFormVec<v4i32>; 237 def v2i64: StoreXFormVec<v2i64>; 238 def v4f32: StoreXFormVec<v4f32>; 239 def v2f64: StoreXFormVec<v2f64>; 240 241 def r128: StoreXForm<GPRC>; 242 def r64: StoreXForm<R64C>; 243 def r32: StoreXForm<R32C>; 244 def f32: StoreXForm<R32FP>; 245 def f64: StoreXForm<R64FP>; 246 def r16: StoreXForm<R16C>; 247 def r8: StoreXForm<R8C>; 248 } 249 250 defm STQD : StoreDForms; 251 defm STQA : StoreAForms; 252 defm STQX : StoreXForms; 253 254 /* Store quadword, PC relative: Not much use at this point in time. Might 255 be useful for relocatable code. 256 def STQR : RI16Form<0b111000100, (outs), (ins VECREG:$rT, s16imm:$disp), 257 "stqr\t$rT, $disp", LoadStore, 258 [(store VECREG:$rT, iaddr:$disp)]>; 259 */ 260 261 //===----------------------------------------------------------------------===// 262 // Generate Controls for Insertion: 263 //===----------------------------------------------------------------------===// 264 265 def CBD: RI7Form<0b10101111100, (outs VECREG:$rT), (ins shufaddr:$src), 266 "cbd\t$rT, $src", ShuffleOp, 267 [(set (v16i8 VECREG:$rT), (SPUshufmask dform2_addr:$src))]>; 268 269 def CBX: RRForm<0b00101011100, (outs VECREG:$rT), (ins memrr:$src), 270 "cbx\t$rT, $src", ShuffleOp, 271 [(set (v16i8 VECREG:$rT), (SPUshufmask xform_addr:$src))]>; 272 273 def CHD: RI7Form<0b10101111100, (outs VECREG:$rT), (ins shufaddr:$src), 274 "chd\t$rT, $src", ShuffleOp, 275 [(set (v8i16 VECREG:$rT), (SPUshufmask dform2_addr:$src))]>; 276 277 def CHX: RRForm<0b10101011100, (outs VECREG:$rT), (ins memrr:$src), 278 "chx\t$rT, $src", ShuffleOp, 279 [(set (v8i16 VECREG:$rT), (SPUshufmask xform_addr:$src))]>; 280 281 def CWD: RI7Form<0b01101111100, (outs VECREG:$rT), (ins shufaddr:$src), 282 "cwd\t$rT, $src", ShuffleOp, 283 [(set (v4i32 VECREG:$rT), (SPUshufmask dform2_addr:$src))]>; 284 285 def CWX: RRForm<0b01101011100, (outs VECREG:$rT), (ins memrr:$src), 286 "cwx\t$rT, $src", ShuffleOp, 287 [(set (v4i32 VECREG:$rT), (SPUshufmask xform_addr:$src))]>; 288 289 def CWDf32: RI7Form<0b01101111100, (outs VECREG:$rT), (ins shufaddr:$src), 290 "cwd\t$rT, $src", ShuffleOp, 291 [(set (v4f32 VECREG:$rT), (SPUshufmask dform2_addr:$src))]>; 292 293 def CWXf32: RRForm<0b01101011100, (outs VECREG:$rT), (ins memrr:$src), 294 "cwx\t$rT, $src", ShuffleOp, 295 [(set (v4f32 VECREG:$rT), (SPUshufmask xform_addr:$src))]>; 296 297 def CDD: RI7Form<0b11101111100, (outs VECREG:$rT), (ins shufaddr:$src), 298 "cdd\t$rT, $src", ShuffleOp, 299 [(set (v2i64 VECREG:$rT), (SPUshufmask dform2_addr:$src))]>; 300 301 def CDX: RRForm<0b11101011100, (outs VECREG:$rT), (ins memrr:$src), 302 "cdx\t$rT, $src", ShuffleOp, 303 [(set (v2i64 VECREG:$rT), (SPUshufmask xform_addr:$src))]>; 304 305 def CDDf64: RI7Form<0b11101111100, (outs VECREG:$rT), (ins shufaddr:$src), 306 "cdd\t$rT, $src", ShuffleOp, 307 [(set (v2f64 VECREG:$rT), (SPUshufmask dform2_addr:$src))]>; 308 309 def CDXf64: RRForm<0b11101011100, (outs VECREG:$rT), (ins memrr:$src), 310 "cdx\t$rT, $src", ShuffleOp, 311 [(set (v2f64 VECREG:$rT), (SPUshufmask xform_addr:$src))]>; 312 313 //===----------------------------------------------------------------------===// 314 // Constant formation: 315 //===----------------------------------------------------------------------===// 316 317 def ILHv8i16: 318 RI16Form<0b110000010, (outs VECREG:$rT), (ins s16imm:$val), 319 "ilh\t$rT, $val", ImmLoad, 320 [(set (v8i16 VECREG:$rT), (v8i16 v8i16SExt16Imm:$val))]>; 321 322 def ILHr16: 323 RI16Form<0b110000010, (outs R16C:$rT), (ins s16imm:$val), 324 "ilh\t$rT, $val", ImmLoad, 325 [(set R16C:$rT, immSExt16:$val)]>; 326 327 // Cell SPU doesn't have a native 8-bit immediate load, but ILH works ("with 328 // the right constant") 329 def ILHr8: 330 RI16Form<0b110000010, (outs R8C:$rT), (ins s16imm_i8:$val), 331 "ilh\t$rT, $val", ImmLoad, 332 [(set R8C:$rT, immSExt8:$val)]>; 333 334 // IL does sign extension! 335 336 class ILInst<dag OOL, dag IOL, list<dag> pattern>: 337 RI16Form<0b100000010, OOL, IOL, "il\t$rT, $val", 338 ImmLoad, pattern>; 339 340 class ILVecInst<ValueType vectype, Operand immtype, PatLeaf xform>: 341 ILInst<(outs VECREG:$rT), (ins immtype:$val), 342 [(set (vectype VECREG:$rT), (vectype xform:$val))]>; 343 344 class ILRegInst<RegisterClass rclass, Operand immtype, PatLeaf xform>: 345 ILInst<(outs rclass:$rT), (ins immtype:$val), 346 [(set rclass:$rT, xform:$val)]>; 347 348 multiclass ImmediateLoad 349 { 350 def v2i64: ILVecInst<v2i64, s16imm_i64, v2i64SExt16Imm>; 351 def v4i32: ILVecInst<v4i32, s16imm_i32, v4i32SExt16Imm>; 352 353 // TODO: Need v2f64, v4f32 354 355 def r64: ILRegInst<R64C, s16imm_i64, immSExt16>; 356 def r32: ILRegInst<R32C, s16imm_i32, immSExt16>; 357 def f32: ILRegInst<R32FP, s16imm_f32, fpimmSExt16>; 358 def f64: ILRegInst<R64FP, s16imm_f64, fpimmSExt16>; 359 } 360 361 defm IL : ImmediateLoad; 362 363 class ILHUInst<dag OOL, dag IOL, list<dag> pattern>: 364 RI16Form<0b010000010, OOL, IOL, "ilhu\t$rT, $val", 365 ImmLoad, pattern>; 366 367 class ILHUVecInst<ValueType vectype, Operand immtype, PatLeaf xform>: 368 ILHUInst<(outs VECREG:$rT), (ins immtype:$val), 369 [(set (vectype VECREG:$rT), (vectype xform:$val))]>; 370 371 class ILHURegInst<RegisterClass rclass, Operand immtype, PatLeaf xform>: 372 ILHUInst<(outs rclass:$rT), (ins immtype:$val), 373 [(set rclass:$rT, xform:$val)]>; 374 375 multiclass ImmLoadHalfwordUpper 376 { 377 def v2i64: ILHUVecInst<v2i64, u16imm_i64, immILHUvec_i64>; 378 def v4i32: ILHUVecInst<v4i32, u16imm_i32, immILHUvec>; 379 380 def r64: ILHURegInst<R64C, u16imm_i64, hi16>; 381 def r32: ILHURegInst<R32C, u16imm_i32, hi16>; 382 383 // Loads the high portion of an address 384 def hi: ILHURegInst<R32C, symbolHi, hi16>; 385 386 // Used in custom lowering constant SFP loads: 387 def f32: ILHURegInst<R32FP, f16imm, hi16_f32>; 388 } 389 390 defm ILHU : ImmLoadHalfwordUpper; 391 392 // Immediate load address (can also be used to load 18-bit unsigned constants, 393 // see the zext 16->32 pattern) 394 395 class ILAInst<dag OOL, dag IOL, list<dag> pattern>: 396 RI18Form<0b1000010, OOL, IOL, "ila\t$rT, $val", 397 LoadNOP, pattern>; 398 399 class ILAVecInst<ValueType vectype, Operand immtype, PatLeaf xform>: 400 ILAInst<(outs VECREG:$rT), (ins immtype:$val), 401 [(set (vectype VECREG:$rT), (vectype xform:$val))]>; 402 403 class ILARegInst<RegisterClass rclass, Operand immtype, PatLeaf xform>: 404 ILAInst<(outs rclass:$rT), (ins immtype:$val), 405 [(set rclass:$rT, xform:$val)]>; 406 407 multiclass ImmLoadAddress 408 { 409 def v2i64: ILAVecInst<v2i64, u18imm, v2i64Uns18Imm>; 410 def v4i32: ILAVecInst<v4i32, u18imm, v4i32Uns18Imm>; 411 412 def r64: ILARegInst<R64C, u18imm_i64, imm18>; 413 def r32: ILARegInst<R32C, u18imm, imm18>; 414 def f32: ILARegInst<R32FP, f18imm, fpimm18>; 415 def f64: ILARegInst<R64FP, f18imm_f64, fpimm18>; 416 417 def hi: ILARegInst<R32C, symbolHi, imm18>; 418 def lo: ILARegInst<R32C, symbolLo, imm18>; 419 420 def lsa: ILAInst<(outs R32C:$rT), (ins symbolLSA:$val), 421 [(set R32C:$rT, imm18:$val)]>; 422 } 423 424 defm ILA : ImmLoadAddress; 425 426 // Immediate OR, Halfword Lower: The "other" part of loading large constants 427 // into 32-bit registers. See the anonymous pattern Pat<(i32 imm:$imm), ...> 428 // Note that these are really two operand instructions, but they're encoded 429 // as three operands with the first two arguments tied-to each other. 430 431 class IOHLInst<dag OOL, dag IOL, list<dag> pattern>: 432 RI16Form<0b100000110, OOL, IOL, "iohl\t$rT, $val", 433 ImmLoad, pattern>, 434 RegConstraint<"$rS = $rT">, 435 NoEncode<"$rS">; 436 437 class IOHLVecInst<ValueType vectype, Operand immtype /* , PatLeaf xform */>: 438 IOHLInst<(outs VECREG:$rT), (ins VECREG:$rS, immtype:$val), 439 [/* no pattern */]>; 440 441 class IOHLRegInst<RegisterClass rclass, Operand immtype /* , PatLeaf xform */>: 442 IOHLInst<(outs rclass:$rT), (ins rclass:$rS, immtype:$val), 443 [/* no pattern */]>; 444 445 multiclass ImmOrHalfwordLower 446 { 447 def v2i64: IOHLVecInst<v2i64, u16imm_i64>; 448 def v4i32: IOHLVecInst<v4i32, u16imm_i32>; 449 450 def r32: IOHLRegInst<R32C, i32imm>; 451 def f32: IOHLRegInst<R32FP, f32imm>; 452 453 def lo: IOHLRegInst<R32C, symbolLo>; 454 } 455 456 defm IOHL: ImmOrHalfwordLower; 457 458 // Form select mask for bytes using immediate, used in conjunction with the 459 // SELB instruction: 460 461 class FSMBIVec<ValueType vectype>: 462 RI16Form<0b101001100, (outs VECREG:$rT), (ins u16imm:$val), 463 "fsmbi\t$rT, $val", 464 SelectOp, 465 [(set (vectype VECREG:$rT), (SPUselmask (i16 immU16:$val)))]>; 466 467 multiclass FormSelectMaskBytesImm 468 { 469 def v16i8: FSMBIVec<v16i8>; 470 def v8i16: FSMBIVec<v8i16>; 471 def v4i32: FSMBIVec<v4i32>; 472 def v2i64: FSMBIVec<v2i64>; 473 } 474 475 defm FSMBI : FormSelectMaskBytesImm; 476 477 // fsmb: Form select mask for bytes. N.B. Input operand, $rA, is 16-bits 478 class FSMBInst<dag OOL, dag IOL, list<dag> pattern>: 479 RRForm_1<0b01101101100, OOL, IOL, "fsmb\t$rT, $rA", SelectOp, 480 pattern>; 481 482 class FSMBRegInst<RegisterClass rclass, ValueType vectype>: 483 FSMBInst<(outs VECREG:$rT), (ins rclass:$rA), 484 [(set (vectype VECREG:$rT), (SPUselmask rclass:$rA))]>; 485 486 class FSMBVecInst<ValueType vectype>: 487 FSMBInst<(outs VECREG:$rT), (ins VECREG:$rA), 488 [(set (vectype VECREG:$rT), 489 (SPUselmask (vectype VECREG:$rA)))]>; 490 491 multiclass FormSelectMaskBits { 492 def v16i8_r16: FSMBRegInst<R16C, v16i8>; 493 def v16i8: FSMBVecInst<v16i8>; 494 } 495 496 defm FSMB: FormSelectMaskBits; 497 498 // fsmh: Form select mask for halfwords. N.B., Input operand, $rA, is 499 // only 8-bits wide (even though it's input as 16-bits here) 500 501 class FSMHInst<dag OOL, dag IOL, list<dag> pattern>: 502 RRForm_1<0b10101101100, OOL, IOL, "fsmh\t$rT, $rA", SelectOp, 503 pattern>; 504 505 class FSMHRegInst<RegisterClass rclass, ValueType vectype>: 506 FSMHInst<(outs VECREG:$rT), (ins rclass:$rA), 507 [(set (vectype VECREG:$rT), (SPUselmask rclass:$rA))]>; 508 509 class FSMHVecInst<ValueType vectype>: 510 FSMHInst<(outs VECREG:$rT), (ins VECREG:$rA), 511 [(set (vectype VECREG:$rT), 512 (SPUselmask (vectype VECREG:$rA)))]>; 513 514 multiclass FormSelectMaskHalfword { 515 def v8i16_r16: FSMHRegInst<R16C, v8i16>; 516 def v8i16: FSMHVecInst<v8i16>; 517 } 518 519 defm FSMH: FormSelectMaskHalfword; 520 521 // fsm: Form select mask for words. Like the other fsm* instructions, 522 // only the lower 4 bits of $rA are significant. 523 524 class FSMInst<dag OOL, dag IOL, list<dag> pattern>: 525 RRForm_1<0b00101101100, OOL, IOL, "fsm\t$rT, $rA", SelectOp, 526 pattern>; 527 528 class FSMRegInst<ValueType vectype, RegisterClass rclass>: 529 FSMInst<(outs VECREG:$rT), (ins rclass:$rA), 530 [(set (vectype VECREG:$rT), (SPUselmask rclass:$rA))]>; 531 532 class FSMVecInst<ValueType vectype>: 533 FSMInst<(outs VECREG:$rT), (ins VECREG:$rA), 534 [(set (vectype VECREG:$rT), (SPUselmask (vectype VECREG:$rA)))]>; 535 536 multiclass FormSelectMaskWord { 537 def v4i32: FSMVecInst<v4i32>; 538 539 def r32 : FSMRegInst<v4i32, R32C>; 540 def r16 : FSMRegInst<v4i32, R16C>; 541 } 542 543 defm FSM : FormSelectMaskWord; 544 545 // Special case when used for i64 math operations 546 multiclass FormSelectMaskWord64 { 547 def r32 : FSMRegInst<v2i64, R32C>; 548 def r16 : FSMRegInst<v2i64, R16C>; 549 } 550 551 defm FSM64 : FormSelectMaskWord64; 552 553 //===----------------------------------------------------------------------===// 554 // Integer and Logical Operations: 555 //===----------------------------------------------------------------------===// 556 557 def AHv8i16: 558 RRForm<0b00010011000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 559 "ah\t$rT, $rA, $rB", IntegerOp, 560 [(set (v8i16 VECREG:$rT), (int_spu_si_ah VECREG:$rA, VECREG:$rB))]>; 561 562 def : Pat<(add (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)), 563 (AHv8i16 VECREG:$rA, VECREG:$rB)>; 564 565 def AHr16: 566 RRForm<0b00010011000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB), 567 "ah\t$rT, $rA, $rB", IntegerOp, 568 [(set R16C:$rT, (add R16C:$rA, R16C:$rB))]>; 569 570 def AHIvec: 571 RI10Form<0b10111000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), 572 "ahi\t$rT, $rA, $val", IntegerOp, 573 [(set (v8i16 VECREG:$rT), (add (v8i16 VECREG:$rA), 574 v8i16SExt10Imm:$val))]>; 575 576 def AHIr16: 577 RI10Form<0b10111000, (outs R16C:$rT), (ins R16C:$rA, s10imm:$val), 578 "ahi\t$rT, $rA, $val", IntegerOp, 579 [(set R16C:$rT, (add R16C:$rA, i16ImmSExt10:$val))]>; 580 581 // v4i32, i32 add instruction: 582 583 class AInst<dag OOL, dag IOL, list<dag> pattern>: 584 RRForm<0b00000011000, OOL, IOL, 585 "a\t$rT, $rA, $rB", IntegerOp, 586 pattern>; 587 588 class AVecInst<ValueType vectype>: 589 AInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 590 [(set (vectype VECREG:$rT), (add (vectype VECREG:$rA), 591 (vectype VECREG:$rB)))]>; 592 593 class ARegInst<RegisterClass rclass>: 594 AInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), 595 [(set rclass:$rT, (add rclass:$rA, rclass:$rB))]>; 596 597 multiclass AddInstruction { 598 def v4i32: AVecInst<v4i32>; 599 def v16i8: AVecInst<v16i8>; 600 def r32: ARegInst<R32C>; 601 } 602 603 defm A : AddInstruction; 604 605 class AIInst<dag OOL, dag IOL, list<dag> pattern>: 606 RI10Form<0b00111000, OOL, IOL, 607 "ai\t$rT, $rA, $val", IntegerOp, 608 pattern>; 609 610 class AIVecInst<ValueType vectype, PatLeaf immpred>: 611 AIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), 612 [(set (vectype VECREG:$rT), (add (vectype VECREG:$rA), immpred:$val))]>; 613 614 class AIFPVecInst<ValueType vectype, PatLeaf immpred>: 615 AIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), 616 [/* no pattern */]>; 617 618 class AIRegInst<RegisterClass rclass, PatLeaf immpred>: 619 AIInst<(outs rclass:$rT), (ins rclass:$rA, s10imm_i32:$val), 620 [(set rclass:$rT, (add rclass:$rA, immpred:$val))]>; 621 622 // This is used to add epsilons to floating point numbers in the f32 fdiv code: 623 class AIFPInst<RegisterClass rclass, PatLeaf immpred>: 624 AIInst<(outs rclass:$rT), (ins rclass:$rA, s10imm_i32:$val), 625 [/* no pattern */]>; 626 627 multiclass AddImmediate { 628 def v4i32: AIVecInst<v4i32, v4i32SExt10Imm>; 629 630 def r32: AIRegInst<R32C, i32ImmSExt10>; 631 632 def v4f32: AIFPVecInst<v4f32, v4i32SExt10Imm>; 633 def f32: AIFPInst<R32FP, i32ImmSExt10>; 634 } 635 636 defm AI : AddImmediate; 637 638 def SFHvec: 639 RRForm<0b00010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 640 "sfh\t$rT, $rA, $rB", IntegerOp, 641 [(set (v8i16 VECREG:$rT), (sub (v8i16 VECREG:$rA), 642 (v8i16 VECREG:$rB)))]>; 643 644 def SFHr16: 645 RRForm<0b00010010000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB), 646 "sfh\t$rT, $rA, $rB", IntegerOp, 647 [(set R16C:$rT, (sub R16C:$rB, R16C:$rA))]>; 648 649 def SFHIvec: 650 RI10Form<0b10110000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), 651 "sfhi\t$rT, $rA, $val", IntegerOp, 652 [(set (v8i16 VECREG:$rT), (sub v8i16SExt10Imm:$val, 653 (v8i16 VECREG:$rA)))]>; 654 655 def SFHIr16 : RI10Form<0b10110000, (outs R16C:$rT), (ins R16C:$rA, s10imm:$val), 656 "sfhi\t$rT, $rA, $val", IntegerOp, 657 [(set R16C:$rT, (sub i16ImmSExt10:$val, R16C:$rA))]>; 658 659 def SFvec : RRForm<0b00000010000, (outs VECREG:$rT), 660 (ins VECREG:$rA, VECREG:$rB), 661 "sf\t$rT, $rA, $rB", IntegerOp, 662 [(set (v4i32 VECREG:$rT), (sub (v4i32 VECREG:$rB), (v4i32 VECREG:$rA)))]>; 663 664 665 def SFr32 : RRForm<0b00000010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), 666 "sf\t$rT, $rA, $rB", IntegerOp, 667 [(set R32C:$rT, (sub R32C:$rB, R32C:$rA))]>; 668 669 def SFIvec: 670 RI10Form<0b00110000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), 671 "sfi\t$rT, $rA, $val", IntegerOp, 672 [(set (v4i32 VECREG:$rT), (sub v4i32SExt10Imm:$val, 673 (v4i32 VECREG:$rA)))]>; 674 675 def SFIr32 : RI10Form<0b00110000, (outs R32C:$rT), 676 (ins R32C:$rA, s10imm_i32:$val), 677 "sfi\t$rT, $rA, $val", IntegerOp, 678 [(set R32C:$rT, (sub i32ImmSExt10:$val, R32C:$rA))]>; 679 680 // ADDX: only available in vector form, doesn't match a pattern. 681 class ADDXInst<dag OOL, dag IOL, list<dag> pattern>: 682 RRForm<0b00000010110, OOL, IOL, 683 "addx\t$rT, $rA, $rB", 684 IntegerOp, pattern>; 685 686 class ADDXVecInst<ValueType vectype>: 687 ADDXInst<(outs VECREG:$rT), 688 (ins VECREG:$rA, VECREG:$rB, VECREG:$rCarry), 689 [/* no pattern */]>, 690 RegConstraint<"$rCarry = $rT">, 691 NoEncode<"$rCarry">; 692 693 class ADDXRegInst<RegisterClass rclass>: 694 ADDXInst<(outs rclass:$rT), 695 (ins rclass:$rA, rclass:$rB, rclass:$rCarry), 696 [/* no pattern */]>, 697 RegConstraint<"$rCarry = $rT">, 698 NoEncode<"$rCarry">; 699 700 multiclass AddExtended { 701 def v2i64 : ADDXVecInst<v2i64>; 702 def v4i32 : ADDXVecInst<v4i32>; 703 def r64 : ADDXRegInst<R64C>; 704 def r32 : ADDXRegInst<R32C>; 705 } 706 707 defm ADDX : AddExtended; 708 709 // CG: Generate carry for add 710 class CGInst<dag OOL, dag IOL, list<dag> pattern>: 711 RRForm<0b01000011000, OOL, IOL, 712 "cg\t$rT, $rA, $rB", 713 IntegerOp, pattern>; 714 715 class CGVecInst<ValueType vectype>: 716 CGInst<(outs VECREG:$rT), 717 (ins VECREG:$rA, VECREG:$rB), 718 [/* no pattern */]>; 719 720 class CGRegInst<RegisterClass rclass>: 721 CGInst<(outs rclass:$rT), 722 (ins rclass:$rA, rclass:$rB), 723 [/* no pattern */]>; 724 725 multiclass CarryGenerate { 726 def v2i64 : CGVecInst<v2i64>; 727 def v4i32 : CGVecInst<v4i32>; 728 def r64 : CGRegInst<R64C>; 729 def r32 : CGRegInst<R32C>; 730 } 731 732 defm CG : CarryGenerate; 733 734 // SFX: Subract from, extended. This is used in conjunction with BG to subtract 735 // with carry (borrow, in this case) 736 class SFXInst<dag OOL, dag IOL, list<dag> pattern>: 737 RRForm<0b10000010110, OOL, IOL, 738 "sfx\t$rT, $rA, $rB", 739 IntegerOp, pattern>; 740 741 class SFXVecInst<ValueType vectype>: 742 SFXInst<(outs VECREG:$rT), 743 (ins VECREG:$rA, VECREG:$rB, VECREG:$rCarry), 744 [/* no pattern */]>, 745 RegConstraint<"$rCarry = $rT">, 746 NoEncode<"$rCarry">; 747 748 class SFXRegInst<RegisterClass rclass>: 749 SFXInst<(outs rclass:$rT), 750 (ins rclass:$rA, rclass:$rB, rclass:$rCarry), 751 [/* no pattern */]>, 752 RegConstraint<"$rCarry = $rT">, 753 NoEncode<"$rCarry">; 754 755 multiclass SubtractExtended { 756 def v2i64 : SFXVecInst<v2i64>; 757 def v4i32 : SFXVecInst<v4i32>; 758 def r64 : SFXRegInst<R64C>; 759 def r32 : SFXRegInst<R32C>; 760 } 761 762 defm SFX : SubtractExtended; 763 764 // BG: only available in vector form, doesn't match a pattern. 765 class BGInst<dag OOL, dag IOL, list<dag> pattern>: 766 RRForm<0b01000010000, OOL, IOL, 767 "bg\t$rT, $rA, $rB", 768 IntegerOp, pattern>; 769 770 class BGVecInst<ValueType vectype>: 771 BGInst<(outs VECREG:$rT), 772 (ins VECREG:$rA, VECREG:$rB), 773 [/* no pattern */]>; 774 775 class BGRegInst<RegisterClass rclass>: 776 BGInst<(outs rclass:$rT), 777 (ins rclass:$rA, rclass:$rB), 778 [/* no pattern */]>; 779 780 multiclass BorrowGenerate { 781 def v4i32 : BGVecInst<v4i32>; 782 def v2i64 : BGVecInst<v2i64>; 783 def r64 : BGRegInst<R64C>; 784 def r32 : BGRegInst<R32C>; 785 } 786 787 defm BG : BorrowGenerate; 788 789 // BGX: Borrow generate, extended. 790 def BGXvec: 791 RRForm<0b11000010110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, 792 VECREG:$rCarry), 793 "bgx\t$rT, $rA, $rB", IntegerOp, 794 []>, 795 RegConstraint<"$rCarry = $rT">, 796 NoEncode<"$rCarry">; 797 798 // Halfword multiply variants: 799 // N.B: These can be used to build up larger quantities (16x16 -> 32) 800 801 def MPYv8i16: 802 RRForm<0b00100011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 803 "mpy\t$rT, $rA, $rB", IntegerMulDiv, 804 [/* no pattern */]>; 805 806 def MPYr16: 807 RRForm<0b00100011110, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB), 808 "mpy\t$rT, $rA, $rB", IntegerMulDiv, 809 [(set R16C:$rT, (mul R16C:$rA, R16C:$rB))]>; 810 811 // Unsigned 16-bit multiply: 812 813 class MPYUInst<dag OOL, dag IOL, list<dag> pattern>: 814 RRForm<0b00110011110, OOL, IOL, 815 "mpyu\t$rT, $rA, $rB", IntegerMulDiv, 816 pattern>; 817 818 def MPYUv4i32: 819 MPYUInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 820 [/* no pattern */]>; 821 822 def MPYUr16: 823 MPYUInst<(outs R32C:$rT), (ins R16C:$rA, R16C:$rB), 824 [(set R32C:$rT, (mul (zext R16C:$rA), (zext R16C:$rB)))]>; 825 826 def MPYUr32: 827 MPYUInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB), 828 [/* no pattern */]>; 829 830 // mpyi: multiply 16 x s10imm -> 32 result. 831 832 class MPYIInst<dag OOL, dag IOL, list<dag> pattern>: 833 RI10Form<0b00101110, OOL, IOL, 834 "mpyi\t$rT, $rA, $val", IntegerMulDiv, 835 pattern>; 836 837 def MPYIvec: 838 MPYIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), 839 [(set (v8i16 VECREG:$rT), 840 (mul (v8i16 VECREG:$rA), v8i16SExt10Imm:$val))]>; 841 842 def MPYIr16: 843 MPYIInst<(outs R16C:$rT), (ins R16C:$rA, s10imm:$val), 844 [(set R16C:$rT, (mul R16C:$rA, i16ImmSExt10:$val))]>; 845 846 // mpyui: same issues as other multiplies, plus, this doesn't match a 847 // pattern... but may be used during target DAG selection or lowering 848 849 class MPYUIInst<dag OOL, dag IOL, list<dag> pattern>: 850 RI10Form<0b10101110, OOL, IOL, 851 "mpyui\t$rT, $rA, $val", IntegerMulDiv, 852 pattern>; 853 854 def MPYUIvec: 855 MPYUIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), 856 []>; 857 858 def MPYUIr16: 859 MPYUIInst<(outs R16C:$rT), (ins R16C:$rA, s10imm:$val), 860 []>; 861 862 // mpya: 16 x 16 + 16 -> 32 bit result 863 class MPYAInst<dag OOL, dag IOL, list<dag> pattern>: 864 RRRForm<0b0011, OOL, IOL, 865 "mpya\t$rT, $rA, $rB, $rC", IntegerMulDiv, 866 pattern>; 867 868 def MPYAv4i32: 869 MPYAInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), 870 [(set (v4i32 VECREG:$rT), 871 (add (v4i32 (bitconvert (mul (v8i16 VECREG:$rA), 872 (v8i16 VECREG:$rB)))), 873 (v4i32 VECREG:$rC)))]>; 874 875 def MPYAr32: 876 MPYAInst<(outs R32C:$rT), (ins R16C:$rA, R16C:$rB, R32C:$rC), 877 [(set R32C:$rT, (add (sext (mul R16C:$rA, R16C:$rB)), 878 R32C:$rC))]>; 879 880 def MPYAr32_sext: 881 MPYAInst<(outs R32C:$rT), (ins R16C:$rA, R16C:$rB, R32C:$rC), 882 [(set R32C:$rT, (add (mul (sext R16C:$rA), (sext R16C:$rB)), 883 R32C:$rC))]>; 884 885 def MPYAr32_sextinreg: 886 MPYAInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB, R32C:$rC), 887 [(set R32C:$rT, (add (mul (sext_inreg R32C:$rA, i16), 888 (sext_inreg R32C:$rB, i16)), 889 R32C:$rC))]>; 890 891 // mpyh: multiply high, used to synthesize 32-bit multiplies 892 class MPYHInst<dag OOL, dag IOL, list<dag> pattern>: 893 RRForm<0b10100011110, OOL, IOL, 894 "mpyh\t$rT, $rA, $rB", IntegerMulDiv, 895 pattern>; 896 897 def MPYHv4i32: 898 MPYHInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 899 [/* no pattern */]>; 900 901 def MPYHr32: 902 MPYHInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB), 903 [/* no pattern */]>; 904 905 // mpys: multiply high and shift right (returns the top half of 906 // a 16-bit multiply, sign extended to 32 bits.) 907 908 class MPYSInst<dag OOL, dag IOL>: 909 RRForm<0b11100011110, OOL, IOL, 910 "mpys\t$rT, $rA, $rB", IntegerMulDiv, 911 [/* no pattern */]>; 912 913 def MPYSv4i32: 914 MPYSInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB)>; 915 916 def MPYSr16: 917 MPYSInst<(outs R32C:$rT), (ins R16C:$rA, R16C:$rB)>; 918 919 // mpyhh: multiply high-high (returns the 32-bit result from multiplying 920 // the top 16 bits of the $rA, $rB) 921 922 class MPYHHInst<dag OOL, dag IOL>: 923 RRForm<0b01100011110, OOL, IOL, 924 "mpyhh\t$rT, $rA, $rB", IntegerMulDiv, 925 [/* no pattern */]>; 926 927 def MPYHHv8i16: 928 MPYHHInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB)>; 929 930 def MPYHHr32: 931 MPYHHInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB)>; 932 933 // mpyhha: Multiply high-high, add to $rT: 934 935 class MPYHHAInst<dag OOL, dag IOL>: 936 RRForm<0b01100010110, OOL, IOL, 937 "mpyhha\t$rT, $rA, $rB", IntegerMulDiv, 938 [/* no pattern */]>; 939 940 def MPYHHAvec: 941 MPYHHAInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB)>; 942 943 def MPYHHAr32: 944 MPYHHAInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB)>; 945 946 // mpyhhu: Multiply high-high, unsigned, e.g.: 947 // 948 // +-------+-------+ +-------+-------+ +---------+ 949 // | a0 . a1 | x | b0 . b1 | = | a0 x b0 | 950 // +-------+-------+ +-------+-------+ +---------+ 951 // 952 // where a0, b0 are the upper 16 bits of the 32-bit word 953 954 class MPYHHUInst<dag OOL, dag IOL>: 955 RRForm<0b01110011110, OOL, IOL, 956 "mpyhhu\t$rT, $rA, $rB", IntegerMulDiv, 957 [/* no pattern */]>; 958 959 def MPYHHUv4i32: 960 MPYHHUInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB)>; 961 962 def MPYHHUr32: 963 MPYHHUInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB)>; 964 965 // mpyhhau: Multiply high-high, unsigned 966 967 class MPYHHAUInst<dag OOL, dag IOL>: 968 RRForm<0b01110010110, OOL, IOL, 969 "mpyhhau\t$rT, $rA, $rB", IntegerMulDiv, 970 [/* no pattern */]>; 971 972 def MPYHHAUvec: 973 MPYHHAUInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB)>; 974 975 def MPYHHAUr32: 976 MPYHHAUInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB)>; 977 978 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 979 // clz: Count leading zeroes 980 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 981 class CLZInst<dag OOL, dag IOL, list<dag> pattern>: 982 RRForm_1<0b10100101010, OOL, IOL, "clz\t$rT, $rA", 983 IntegerOp, pattern>; 984 985 class CLZRegInst<RegisterClass rclass>: 986 CLZInst<(outs rclass:$rT), (ins rclass:$rA), 987 [(set rclass:$rT, (ctlz rclass:$rA))]>; 988 989 class CLZVecInst<ValueType vectype>: 990 CLZInst<(outs VECREG:$rT), (ins VECREG:$rA), 991 [(set (vectype VECREG:$rT), (ctlz (vectype VECREG:$rA)))]>; 992 993 multiclass CountLeadingZeroes { 994 def v4i32 : CLZVecInst<v4i32>; 995 def r32 : CLZRegInst<R32C>; 996 } 997 998 defm CLZ : CountLeadingZeroes; 999 1000 // cntb: Count ones in bytes (aka "population count") 1001 // 1002 // NOTE: This instruction is really a vector instruction, but the custom 1003 // lowering code uses it in unorthodox ways to support CTPOP for other 1004 // data types! 1005 1006 def CNTBv16i8: 1007 RRForm_1<0b00101101010, (outs VECREG:$rT), (ins VECREG:$rA), 1008 "cntb\t$rT, $rA", IntegerOp, 1009 [(set (v16i8 VECREG:$rT), (SPUcntb (v16i8 VECREG:$rA)))]>; 1010 1011 def CNTBv8i16 : 1012 RRForm_1<0b00101101010, (outs VECREG:$rT), (ins VECREG:$rA), 1013 "cntb\t$rT, $rA", IntegerOp, 1014 [(set (v8i16 VECREG:$rT), (SPUcntb (v8i16 VECREG:$rA)))]>; 1015 1016 def CNTBv4i32 : 1017 RRForm_1<0b00101101010, (outs VECREG:$rT), (ins VECREG:$rA), 1018 "cntb\t$rT, $rA", IntegerOp, 1019 [(set (v4i32 VECREG:$rT), (SPUcntb (v4i32 VECREG:$rA)))]>; 1020 1021 // gbb: Gather the low order bits from each byte in $rA into a single 16-bit 1022 // quantity stored into $rT's slot 0, upper 16 bits are zeroed, as are 1023 // slots 1-3. 1024 // 1025 // Note: This instruction "pairs" with the fsmb instruction for all of the 1026 // various types defined here. 1027 // 1028 // Note 2: The "VecInst" and "RegInst" forms refer to the result being either 1029 // a vector or register. 1030 1031 class GBBInst<dag OOL, dag IOL, list<dag> pattern>: 1032 RRForm_1<0b01001101100, OOL, IOL, "gbb\t$rT, $rA", GatherOp, pattern>; 1033 1034 class GBBRegInst<RegisterClass rclass, ValueType vectype>: 1035 GBBInst<(outs rclass:$rT), (ins VECREG:$rA), 1036 [/* no pattern */]>; 1037 1038 class GBBVecInst<ValueType vectype>: 1039 GBBInst<(outs VECREG:$rT), (ins VECREG:$rA), 1040 [/* no pattern */]>; 1041 1042 multiclass GatherBitsFromBytes { 1043 def v16i8_r32: GBBRegInst<R32C, v16i8>; 1044 def v16i8_r16: GBBRegInst<R16C, v16i8>; 1045 def v16i8: GBBVecInst<v16i8>; 1046 } 1047 1048 defm GBB: GatherBitsFromBytes; 1049 1050 // gbh: Gather all low order bits from each halfword in $rA into a single 1051 // 8-bit quantity stored in $rT's slot 0, with the upper bits of $rT set to 0 1052 // and slots 1-3 also set to 0. 1053 // 1054 // See notes for GBBInst, above. 1055 1056 class GBHInst<dag OOL, dag IOL, list<dag> pattern>: 1057 RRForm_1<0b10001101100, OOL, IOL, "gbh\t$rT, $rA", GatherOp, 1058 pattern>; 1059 1060 class GBHRegInst<RegisterClass rclass, ValueType vectype>: 1061 GBHInst<(outs rclass:$rT), (ins VECREG:$rA), 1062 [/* no pattern */]>; 1063 1064 class GBHVecInst<ValueType vectype>: 1065 GBHInst<(outs VECREG:$rT), (ins VECREG:$rA), 1066 [/* no pattern */]>; 1067 1068 multiclass GatherBitsHalfword { 1069 def v8i16_r32: GBHRegInst<R32C, v8i16>; 1070 def v8i16_r16: GBHRegInst<R16C, v8i16>; 1071 def v8i16: GBHVecInst<v8i16>; 1072 } 1073 1074 defm GBH: GatherBitsHalfword; 1075 1076 // gb: Gather all low order bits from each word in $rA into a single 1077 // 4-bit quantity stored in $rT's slot 0, upper bits in $rT set to 0, 1078 // as well as slots 1-3. 1079 // 1080 // See notes for gbb, above. 1081 1082 class GBInst<dag OOL, dag IOL, list<dag> pattern>: 1083 RRForm_1<0b00001101100, OOL, IOL, "gb\t$rT, $rA", GatherOp, 1084 pattern>; 1085 1086 class GBRegInst<RegisterClass rclass, ValueType vectype>: 1087 GBInst<(outs rclass:$rT), (ins VECREG:$rA), 1088 [/* no pattern */]>; 1089 1090 class GBVecInst<ValueType vectype>: 1091 GBInst<(outs VECREG:$rT), (ins VECREG:$rA), 1092 [/* no pattern */]>; 1093 1094 multiclass GatherBitsWord { 1095 def v4i32_r32: GBRegInst<R32C, v4i32>; 1096 def v4i32_r16: GBRegInst<R16C, v4i32>; 1097 def v4i32: GBVecInst<v4i32>; 1098 } 1099 1100 defm GB: GatherBitsWord; 1101 1102 // avgb: average bytes 1103 def AVGB: 1104 RRForm<0b11001011000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 1105 "avgb\t$rT, $rA, $rB", ByteOp, 1106 []>; 1107 1108 // absdb: absolute difference of bytes 1109 def ABSDB: 1110 RRForm<0b11001010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 1111 "absdb\t$rT, $rA, $rB", ByteOp, 1112 []>; 1113 1114 // sumb: sum bytes into halfwords 1115 def SUMB: 1116 RRForm<0b11001010010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 1117 "sumb\t$rT, $rA, $rB", ByteOp, 1118 []>; 1119 1120 // Sign extension operations: 1121 class XSBHInst<dag OOL, dag IOL, list<dag> pattern>: 1122 RRForm_1<0b01101101010, OOL, IOL, 1123 "xsbh\t$rDst, $rSrc", 1124 IntegerOp, pattern>; 1125 1126 class XSBHInRegInst<RegisterClass rclass, list<dag> pattern>: 1127 XSBHInst<(outs rclass:$rDst), (ins rclass:$rSrc), 1128 pattern>; 1129 1130 multiclass ExtendByteHalfword { 1131 def v16i8: XSBHInst<(outs VECREG:$rDst), (ins VECREG:$rSrc), 1132 [ 1133 /*(set (v8i16 VECREG:$rDst), (sext (v8i16 VECREG:$rSrc)))*/]>; 1134 def r8: XSBHInst<(outs R16C:$rDst), (ins R8C:$rSrc), 1135 [(set R16C:$rDst, (sext R8C:$rSrc))]>; 1136 def r16: XSBHInRegInst<R16C, 1137 [(set R16C:$rDst, (sext_inreg R16C:$rSrc, i8))]>; 1138 1139 // 32-bit form for XSBH: used to sign extend 8-bit quantities to 16-bit 1140 // quantities to 32-bit quantities via a 32-bit register (see the sext 8->32 1141 // pattern below). Intentionally doesn't match a pattern because we want the 1142 // sext 8->32 pattern to do the work for us, namely because we need the extra 1143 // XSHWr32. 1144 def r32: XSBHInRegInst<R32C, [/* no pattern */]>; 1145 1146 // Same as the 32-bit version, but for i64 1147 def r64: XSBHInRegInst<R64C, [/* no pattern */]>; 1148 } 1149 1150 defm XSBH : ExtendByteHalfword; 1151 1152 // Sign extend halfwords to words: 1153 1154 class XSHWInst<dag OOL, dag IOL, list<dag> pattern>: 1155 RRForm_1<0b01101101010, OOL, IOL, "xshw\t$rDest, $rSrc", 1156 IntegerOp, pattern>; 1157 1158 class XSHWVecInst<ValueType in_vectype, ValueType out_vectype>: 1159 XSHWInst<(outs VECREG:$rDest), (ins VECREG:$rSrc), 1160 [(set (out_vectype VECREG:$rDest), 1161 (sext (in_vectype VECREG:$rSrc)))]>; 1162 1163 class XSHWInRegInst<RegisterClass rclass, list<dag> pattern>: 1164 XSHWInst<(outs rclass:$rDest), (ins rclass:$rSrc), 1165 pattern>; 1166 1167 class XSHWRegInst<RegisterClass rclass>: 1168 XSHWInst<(outs rclass:$rDest), (ins R16C:$rSrc), 1169 [(set rclass:$rDest, (sext R16C:$rSrc))]>; 1170 1171 multiclass ExtendHalfwordWord { 1172 def v4i32: XSHWVecInst<v8i16, v4i32>; 1173 1174 def r16: XSHWRegInst<R32C>; 1175 1176 def r32: XSHWInRegInst<R32C, 1177 [(set R32C:$rDest, (sext_inreg R32C:$rSrc, i16))]>; 1178 def r64: XSHWInRegInst<R64C, [/* no pattern */]>; 1179 } 1180 1181 defm XSHW : ExtendHalfwordWord; 1182 1183 // Sign-extend words to doublewords (32->64 bits) 1184 1185 class XSWDInst<dag OOL, dag IOL, list<dag> pattern>: 1186 RRForm_1<0b01100101010, OOL, IOL, "xswd\t$rDst, $rSrc", 1187 IntegerOp, pattern>; 1188 1189 class XSWDVecInst<ValueType in_vectype, ValueType out_vectype>: 1190 XSWDInst<(outs VECREG:$rDst), (ins VECREG:$rSrc), 1191 [/*(set (out_vectype VECREG:$rDst), 1192 (sext (out_vectype VECREG:$rSrc)))*/]>; 1193 1194 class XSWDRegInst<RegisterClass in_rclass, RegisterClass out_rclass>: 1195 XSWDInst<(outs out_rclass:$rDst), (ins in_rclass:$rSrc), 1196 [(set out_rclass:$rDst, (sext in_rclass:$rSrc))]>; 1197 1198 multiclass ExtendWordToDoubleWord { 1199 def v2i64: XSWDVecInst<v4i32, v2i64>; 1200 def r64: XSWDRegInst<R32C, R64C>; 1201 1202 def r64_inreg: XSWDInst<(outs R64C:$rDst), (ins R64C:$rSrc), 1203 [(set R64C:$rDst, (sext_inreg R64C:$rSrc, i32))]>; 1204 } 1205 1206 defm XSWD : ExtendWordToDoubleWord; 1207 1208 // AND operations 1209 1210 class ANDInst<dag OOL, dag IOL, list<dag> pattern> : 1211 RRForm<0b10000011000, OOL, IOL, "and\t$rT, $rA, $rB", 1212 IntegerOp, pattern>; 1213 1214 class ANDVecInst<ValueType vectype>: 1215 ANDInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 1216 [(set (vectype VECREG:$rT), (and (vectype VECREG:$rA), 1217 (vectype VECREG:$rB)))]>; 1218 1219 class ANDRegInst<RegisterClass rclass>: 1220 ANDInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), 1221 [(set rclass:$rT, (and rclass:$rA, rclass:$rB))]>; 1222 1223 multiclass BitwiseAnd 1224 { 1225 def v16i8: ANDVecInst<v16i8>; 1226 def v8i16: ANDVecInst<v8i16>; 1227 def v4i32: ANDVecInst<v4i32>; 1228 def v2i64: ANDVecInst<v2i64>; 1229 1230 def r128: ANDRegInst<GPRC>; 1231 def r64: ANDRegInst<R64C>; 1232 def r32: ANDRegInst<R32C>; 1233 def r16: ANDRegInst<R16C>; 1234 def r8: ANDRegInst<R8C>; 1235 1236 //===--------------------------------------------- 1237 // Special instructions to perform the fabs instruction 1238 def fabs32: ANDInst<(outs R32FP:$rT), (ins R32FP:$rA, R32C:$rB), 1239 [/* Intentionally does not match a pattern */]>; 1240 1241 def fabs64: ANDInst<(outs R64FP:$rT), (ins R64FP:$rA, R64C:$rB), 1242 [/* Intentionally does not match a pattern */]>; 1243 1244 def fabsvec: ANDInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 1245 [/* Intentionally does not match a pattern */]>; 1246 1247 //===--------------------------------------------- 1248 1249 // Hacked form of AND to zero-extend 16-bit quantities to 32-bit 1250 // quantities -- see 16->32 zext pattern. 1251 // 1252 // This pattern is somewhat artificial, since it might match some 1253 // compiler generated pattern but it is unlikely to do so. 1254 1255 def i16i32: ANDInst<(outs R32C:$rT), (ins R16C:$rA, R32C:$rB), 1256 [(set R32C:$rT, (and (zext R16C:$rA), R32C:$rB))]>; 1257 } 1258 1259 defm AND : BitwiseAnd; 1260 1261 1262 def vnot_cell_conv : PatFrag<(ops node:$in), 1263 (xor node:$in, (bitconvert (v4i32 immAllOnesV)))>; 1264 1265 // N.B.: vnot_cell_conv is one of those special target selection pattern 1266 // fragments, 1267 // in which we expect there to be a bit_convert on the constant. Bear in mind 1268 // that llvm translates "not <reg>" to "xor <reg>, -1" (or in this case, a 1269 // constant -1 vector.) 1270 1271 class ANDCInst<dag OOL, dag IOL, list<dag> pattern>: 1272 RRForm<0b10000011010, OOL, IOL, "andc\t$rT, $rA, $rB", 1273 IntegerOp, pattern>; 1274 1275 class ANDCVecInst<ValueType vectype, PatFrag vnot_frag = vnot>: 1276 ANDCInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 1277 [(set (vectype VECREG:$rT), 1278 (and (vectype VECREG:$rA), 1279 (vnot_frag (vectype VECREG:$rB))))]>; 1280 1281 class ANDCRegInst<RegisterClass rclass>: 1282 ANDCInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), 1283 [(set rclass:$rT, (and rclass:$rA, (not rclass:$rB)))]>; 1284 1285 multiclass AndComplement 1286 { 1287 def v16i8: ANDCVecInst<v16i8>; 1288 def v8i16: ANDCVecInst<v8i16>; 1289 def v4i32: ANDCVecInst<v4i32>; 1290 def v2i64: ANDCVecInst<v2i64>; 1291 1292 def r128: ANDCRegInst<GPRC>; 1293 def r64: ANDCRegInst<R64C>; 1294 def r32: ANDCRegInst<R32C>; 1295 def r16: ANDCRegInst<R16C>; 1296 def r8: ANDCRegInst<R8C>; 1297 1298 // Sometimes, the xor pattern has a bitcast constant: 1299 def v16i8_conv: ANDCVecInst<v16i8, vnot_cell_conv>; 1300 } 1301 1302 defm ANDC : AndComplement; 1303 1304 class ANDBIInst<dag OOL, dag IOL, list<dag> pattern>: 1305 RI10Form<0b01101000, OOL, IOL, "andbi\t$rT, $rA, $val", 1306 ByteOp, pattern>; 1307 1308 multiclass AndByteImm 1309 { 1310 def v16i8: ANDBIInst<(outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val), 1311 [(set (v16i8 VECREG:$rT), 1312 (and (v16i8 VECREG:$rA), 1313 (v16i8 v16i8U8Imm:$val)))]>; 1314 1315 def r8: ANDBIInst<(outs R8C:$rT), (ins R8C:$rA, u10imm_i8:$val), 1316 [(set R8C:$rT, (and R8C:$rA, immU8:$val))]>; 1317 } 1318 1319 defm ANDBI : AndByteImm; 1320 1321 class ANDHIInst<dag OOL, dag IOL, list<dag> pattern> : 1322 RI10Form<0b10101000, OOL, IOL, "andhi\t$rT, $rA, $val", 1323 ByteOp, pattern>; 1324 1325 multiclass AndHalfwordImm 1326 { 1327 def v8i16: ANDHIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), 1328 [(set (v8i16 VECREG:$rT), 1329 (and (v8i16 VECREG:$rA), v8i16SExt10Imm:$val))]>; 1330 1331 def r16: ANDHIInst<(outs R16C:$rT), (ins R16C:$rA, u10imm:$val), 1332 [(set R16C:$rT, (and R16C:$rA, i16ImmUns10:$val))]>; 1333 1334 // Zero-extend i8 to i16: 1335 def i8i16: ANDHIInst<(outs R16C:$rT), (ins R8C:$rA, u10imm:$val), 1336 [(set R16C:$rT, (and (zext R8C:$rA), i16ImmUns10:$val))]>; 1337 } 1338 1339 defm ANDHI : AndHalfwordImm; 1340 1341 class ANDIInst<dag OOL, dag IOL, list<dag> pattern> : 1342 RI10Form<0b00101000, OOL, IOL, "andi\t$rT, $rA, $val", 1343 IntegerOp, pattern>; 1344 1345 multiclass AndWordImm 1346 { 1347 def v4i32: ANDIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), 1348 [(set (v4i32 VECREG:$rT), 1349 (and (v4i32 VECREG:$rA), v4i32SExt10Imm:$val))]>; 1350 1351 def r32: ANDIInst<(outs R32C:$rT), (ins R32C:$rA, s10imm_i32:$val), 1352 [(set R32C:$rT, (and R32C:$rA, i32ImmSExt10:$val))]>; 1353 1354 // Hacked form of ANDI to zero-extend i8 quantities to i32. See the zext 8->32 1355 // pattern below. 1356 def i8i32: ANDIInst<(outs R32C:$rT), (ins R8C:$rA, s10imm_i32:$val), 1357 [(set R32C:$rT, 1358 (and (zext R8C:$rA), i32ImmSExt10:$val))]>; 1359 1360 // Hacked form of ANDI to zero-extend i16 quantities to i32. See the 1361 // zext 16->32 pattern below. 1362 // 1363 // Note that this pattern is somewhat artificial, since it might match 1364 // something the compiler generates but is unlikely to occur in practice. 1365 def i16i32: ANDIInst<(outs R32C:$rT), (ins R16C:$rA, s10imm_i32:$val), 1366 [(set R32C:$rT, 1367 (and (zext R16C:$rA), i32ImmSExt10:$val))]>; 1368 } 1369 1370 defm ANDI : AndWordImm; 1371 1372 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 1373 // Bitwise OR group: 1374 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 1375 1376 // Bitwise "or" (N.B.: These are also register-register copy instructions...) 1377 class ORInst<dag OOL, dag IOL, list<dag> pattern>: 1378 RRForm<0b10000010000, OOL, IOL, "or\t$rT, $rA, $rB", 1379 IntegerOp, pattern>; 1380 1381 class ORVecInst<ValueType vectype>: 1382 ORInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 1383 [(set (vectype VECREG:$rT), (or (vectype VECREG:$rA), 1384 (vectype VECREG:$rB)))]>; 1385 1386 class ORRegInst<RegisterClass rclass>: 1387 ORInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), 1388 [(set rclass:$rT, (or rclass:$rA, rclass:$rB))]>; 1389 1390 1391 multiclass BitwiseOr 1392 { 1393 def v16i8: ORVecInst<v16i8>; 1394 def v8i16: ORVecInst<v8i16>; 1395 def v4i32: ORVecInst<v4i32>; 1396 def v2i64: ORVecInst<v2i64>; 1397 1398 def v4f32: ORInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 1399 [(set (v4f32 VECREG:$rT), 1400 (v4f32 (bitconvert (or (v4i32 VECREG:$rA), 1401 (v4i32 VECREG:$rB)))))]>; 1402 1403 def v2f64: ORInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 1404 [(set (v2f64 VECREG:$rT), 1405 (v2f64 (bitconvert (or (v2i64 VECREG:$rA), 1406 (v2i64 VECREG:$rB)))))]>; 1407 1408 def r128: ORRegInst<GPRC>; 1409 def r64: ORRegInst<R64C>; 1410 def r32: ORRegInst<R32C>; 1411 def r16: ORRegInst<R16C>; 1412 def r8: ORRegInst<R8C>; 1413 1414 // OR instructions used to copy f32 and f64 registers. 1415 def f32: ORInst<(outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB), 1416 [/* no pattern */]>; 1417 1418 def f64: ORInst<(outs R64FP:$rT), (ins R64FP:$rA, R64FP:$rB), 1419 [/* no pattern */]>; 1420 } 1421 1422 defm OR : BitwiseOr; 1423 1424 //===----------------------------------------------------------------------===// 1425 // SPU::PREFSLOT2VEC and VEC2PREFSLOT re-interpretations of registers 1426 //===----------------------------------------------------------------------===// 1427 def : Pat<(v16i8 (SPUprefslot2vec R8C:$rA)), 1428 (COPY_TO_REGCLASS R8C:$rA, VECREG)>; 1429 1430 def : Pat<(v8i16 (SPUprefslot2vec R16C:$rA)), 1431 (COPY_TO_REGCLASS R16C:$rA, VECREG)>; 1432 1433 def : Pat<(v4i32 (SPUprefslot2vec R32C:$rA)), 1434 (COPY_TO_REGCLASS R32C:$rA, VECREG)>; 1435 1436 def : Pat<(v2i64 (SPUprefslot2vec R64C:$rA)), 1437 (COPY_TO_REGCLASS R64C:$rA, VECREG)>; 1438 1439 def : Pat<(v4f32 (SPUprefslot2vec R32FP:$rA)), 1440 (COPY_TO_REGCLASS R32FP:$rA, VECREG)>; 1441 1442 def : Pat<(v2f64 (SPUprefslot2vec R64FP:$rA)), 1443 (COPY_TO_REGCLASS R64FP:$rA, VECREG)>; 1444 1445 def : Pat<(i8 (SPUvec2prefslot (v16i8 VECREG:$rA))), 1446 (COPY_TO_REGCLASS (v16i8 VECREG:$rA), R8C)>; 1447 1448 def : Pat<(i16 (SPUvec2prefslot (v8i16 VECREG:$rA))), 1449 (COPY_TO_REGCLASS (v8i16 VECREG:$rA), R16C)>; 1450 1451 def : Pat<(i32 (SPUvec2prefslot (v4i32 VECREG:$rA))), 1452 (COPY_TO_REGCLASS (v4i32 VECREG:$rA), R32C)>; 1453 1454 def : Pat<(i64 (SPUvec2prefslot (v2i64 VECREG:$rA))), 1455 (COPY_TO_REGCLASS (v2i64 VECREG:$rA), R64C)>; 1456 1457 def : Pat<(f32 (SPUvec2prefslot (v4f32 VECREG:$rA))), 1458 (COPY_TO_REGCLASS (v4f32 VECREG:$rA), R32FP)>; 1459 1460 def : Pat<(f64 (SPUvec2prefslot (v2f64 VECREG:$rA))), 1461 (COPY_TO_REGCLASS (v2f64 VECREG:$rA), R64FP)>; 1462 1463 // Load Register: This is an assembler alias for a bitwise OR of a register 1464 // against itself. It's here because it brings some clarity to assembly 1465 // language output. 1466 1467 let hasCtrlDep = 1 in { 1468 class LRInst<dag OOL, dag IOL> 1469 : SPUInstr<OOL, IOL, "lr\t$rT, $rA", IntegerOp> { 1470 bits<7> RA; 1471 bits<7> RT; 1472 1473 let Pattern = [/*no pattern*/]; 1474 1475 let Inst{0-10} = 0b10000010000; /* It's an OR operation */ 1476 let Inst{11-17} = RA; 1477 let Inst{18-24} = RA; 1478 let Inst{25-31} = RT; 1479 } 1480 1481 class LRVecInst<ValueType vectype>: 1482 LRInst<(outs VECREG:$rT), (ins VECREG:$rA)>; 1483 1484 class LRRegInst<RegisterClass rclass>: 1485 LRInst<(outs rclass:$rT), (ins rclass:$rA)>; 1486 1487 multiclass LoadRegister { 1488 def v2i64: LRVecInst<v2i64>; 1489 def v2f64: LRVecInst<v2f64>; 1490 def v4i32: LRVecInst<v4i32>; 1491 def v4f32: LRVecInst<v4f32>; 1492 def v8i16: LRVecInst<v8i16>; 1493 def v16i8: LRVecInst<v16i8>; 1494 1495 def r128: LRRegInst<GPRC>; 1496 def r64: LRRegInst<R64C>; 1497 def f64: LRRegInst<R64FP>; 1498 def r32: LRRegInst<R32C>; 1499 def f32: LRRegInst<R32FP>; 1500 def r16: LRRegInst<R16C>; 1501 def r8: LRRegInst<R8C>; 1502 } 1503 1504 defm LR: LoadRegister; 1505 } 1506 1507 // ORC: Bitwise "or" with complement (c = a | ~b) 1508 1509 class ORCInst<dag OOL, dag IOL, list<dag> pattern>: 1510 RRForm<0b10010010000, OOL, IOL, "orc\t$rT, $rA, $rB", 1511 IntegerOp, pattern>; 1512 1513 class ORCVecInst<ValueType vectype>: 1514 ORCInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 1515 [(set (vectype VECREG:$rT), (or (vectype VECREG:$rA), 1516 (vnot (vectype VECREG:$rB))))]>; 1517 1518 class ORCRegInst<RegisterClass rclass>: 1519 ORCInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), 1520 [(set rclass:$rT, (or rclass:$rA, (not rclass:$rB)))]>; 1521 1522 multiclass BitwiseOrComplement 1523 { 1524 def v16i8: ORCVecInst<v16i8>; 1525 def v8i16: ORCVecInst<v8i16>; 1526 def v4i32: ORCVecInst<v4i32>; 1527 def v2i64: ORCVecInst<v2i64>; 1528 1529 def r128: ORCRegInst<GPRC>; 1530 def r64: ORCRegInst<R64C>; 1531 def r32: ORCRegInst<R32C>; 1532 def r16: ORCRegInst<R16C>; 1533 def r8: ORCRegInst<R8C>; 1534 } 1535 1536 defm ORC : BitwiseOrComplement; 1537 1538 // OR byte immediate 1539 class ORBIInst<dag OOL, dag IOL, list<dag> pattern>: 1540 RI10Form<0b01100000, OOL, IOL, "orbi\t$rT, $rA, $val", 1541 IntegerOp, pattern>; 1542 1543 class ORBIVecInst<ValueType vectype, PatLeaf immpred>: 1544 ORBIInst<(outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val), 1545 [(set (v16i8 VECREG:$rT), (or (vectype VECREG:$rA), 1546 (vectype immpred:$val)))]>; 1547 1548 multiclass BitwiseOrByteImm 1549 { 1550 def v16i8: ORBIVecInst<v16i8, v16i8U8Imm>; 1551 1552 def r8: ORBIInst<(outs R8C:$rT), (ins R8C:$rA, u10imm_i8:$val), 1553 [(set R8C:$rT, (or R8C:$rA, immU8:$val))]>; 1554 } 1555 1556 defm ORBI : BitwiseOrByteImm; 1557 1558 // OR halfword immediate 1559 class ORHIInst<dag OOL, dag IOL, list<dag> pattern>: 1560 RI10Form<0b10100000, OOL, IOL, "orhi\t$rT, $rA, $val", 1561 IntegerOp, pattern>; 1562 1563 class ORHIVecInst<ValueType vectype, PatLeaf immpred>: 1564 ORHIInst<(outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val), 1565 [(set (vectype VECREG:$rT), (or (vectype VECREG:$rA), 1566 immpred:$val))]>; 1567 1568 multiclass BitwiseOrHalfwordImm 1569 { 1570 def v8i16: ORHIVecInst<v8i16, v8i16Uns10Imm>; 1571 1572 def r16: ORHIInst<(outs R16C:$rT), (ins R16C:$rA, u10imm:$val), 1573 [(set R16C:$rT, (or R16C:$rA, i16ImmUns10:$val))]>; 1574 1575 // Specialized ORHI form used to promote 8-bit registers to 16-bit 1576 def i8i16: ORHIInst<(outs R16C:$rT), (ins R8C:$rA, s10imm:$val), 1577 [(set R16C:$rT, (or (anyext R8C:$rA), 1578 i16ImmSExt10:$val))]>; 1579 } 1580 1581 defm ORHI : BitwiseOrHalfwordImm; 1582 1583 class ORIInst<dag OOL, dag IOL, list<dag> pattern>: 1584 RI10Form<0b00100000, OOL, IOL, "ori\t$rT, $rA, $val", 1585 IntegerOp, pattern>; 1586 1587 class ORIVecInst<ValueType vectype, PatLeaf immpred>: 1588 ORIInst<(outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val), 1589 [(set (vectype VECREG:$rT), (or (vectype VECREG:$rA), 1590 immpred:$val))]>; 1591 1592 // Bitwise "or" with immediate 1593 multiclass BitwiseOrImm 1594 { 1595 def v4i32: ORIVecInst<v4i32, v4i32Uns10Imm>; 1596 1597 def r32: ORIInst<(outs R32C:$rT), (ins R32C:$rA, u10imm_i32:$val), 1598 [(set R32C:$rT, (or R32C:$rA, i32ImmUns10:$val))]>; 1599 1600 // i16i32: hacked version of the ori instruction to extend 16-bit quantities 1601 // to 32-bit quantities. used exclusively to match "anyext" conversions (vide 1602 // infra "anyext 16->32" pattern.) 1603 def i16i32: ORIInst<(outs R32C:$rT), (ins R16C:$rA, s10imm_i32:$val), 1604 [(set R32C:$rT, (or (anyext R16C:$rA), 1605 i32ImmSExt10:$val))]>; 1606 1607 // i8i32: Hacked version of the ORI instruction to extend 16-bit quantities 1608 // to 32-bit quantities. Used exclusively to match "anyext" conversions (vide 1609 // infra "anyext 16->32" pattern.) 1610 def i8i32: ORIInst<(outs R32C:$rT), (ins R8C:$rA, s10imm_i32:$val), 1611 [(set R32C:$rT, (or (anyext R8C:$rA), 1612 i32ImmSExt10:$val))]>; 1613 } 1614 1615 defm ORI : BitwiseOrImm; 1616 1617 // ORX: "or" across the vector: or's $rA's word slots leaving the result in 1618 // $rT[0], slots 1-3 are zeroed. 1619 // 1620 // FIXME: Needs to match an intrinsic pattern. 1621 def ORXv4i32: 1622 RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 1623 "orx\t$rT, $rA, $rB", IntegerOp, 1624 []>; 1625 1626 // XOR: 1627 1628 class XORInst<dag OOL, dag IOL, list<dag> pattern> : 1629 RRForm<0b10010010000, OOL, IOL, "xor\t$rT, $rA, $rB", 1630 IntegerOp, pattern>; 1631 1632 class XORVecInst<ValueType vectype>: 1633 XORInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 1634 [(set (vectype VECREG:$rT), (xor (vectype VECREG:$rA), 1635 (vectype VECREG:$rB)))]>; 1636 1637 class XORRegInst<RegisterClass rclass>: 1638 XORInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), 1639 [(set rclass:$rT, (xor rclass:$rA, rclass:$rB))]>; 1640 1641 multiclass BitwiseExclusiveOr 1642 { 1643 def v16i8: XORVecInst<v16i8>; 1644 def v8i16: XORVecInst<v8i16>; 1645 def v4i32: XORVecInst<v4i32>; 1646 def v2i64: XORVecInst<v2i64>; 1647 1648 def r128: XORRegInst<GPRC>; 1649 def r64: XORRegInst<R64C>; 1650 def r32: XORRegInst<R32C>; 1651 def r16: XORRegInst<R16C>; 1652 def r8: XORRegInst<R8C>; 1653 1654 // XOR instructions used to negate f32 and f64 quantities. 1655 1656 def fneg32: XORInst<(outs R32FP:$rT), (ins R32FP:$rA, R32C:$rB), 1657 [/* no pattern */]>; 1658 1659 def fneg64: XORInst<(outs R64FP:$rT), (ins R64FP:$rA, R64C:$rB), 1660 [/* no pattern */]>; 1661 1662 def fnegvec: XORInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 1663 [/* no pattern, see fneg{32,64} */]>; 1664 } 1665 1666 defm XOR : BitwiseExclusiveOr; 1667 1668 //==---------------------------------------------------------- 1669 1670 class XORBIInst<dag OOL, dag IOL, list<dag> pattern>: 1671 RI10Form<0b01100000, OOL, IOL, "xorbi\t$rT, $rA, $val", 1672 IntegerOp, pattern>; 1673 1674 multiclass XorByteImm 1675 { 1676 def v16i8: 1677 XORBIInst<(outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val), 1678 [(set (v16i8 VECREG:$rT), (xor (v16i8 VECREG:$rA), v16i8U8Imm:$val))]>; 1679 1680 def r8: 1681 XORBIInst<(outs R8C:$rT), (ins R8C:$rA, u10imm_i8:$val), 1682 [(set R8C:$rT, (xor R8C:$rA, immU8:$val))]>; 1683 } 1684 1685 defm XORBI : XorByteImm; 1686 1687 def XORHIv8i16: 1688 RI10Form<0b10100000, (outs VECREG:$rT), (ins VECREG:$rA, u10imm:$val), 1689 "xorhi\t$rT, $rA, $val", IntegerOp, 1690 [(set (v8i16 VECREG:$rT), (xor (v8i16 VECREG:$rA), 1691 v8i16SExt10Imm:$val))]>; 1692 1693 def XORHIr16: 1694 RI10Form<0b10100000, (outs R16C:$rT), (ins R16C:$rA, s10imm:$val), 1695 "xorhi\t$rT, $rA, $val", IntegerOp, 1696 [(set R16C:$rT, (xor R16C:$rA, i16ImmSExt10:$val))]>; 1697 1698 def XORIv4i32: 1699 RI10Form<0b00100000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm_i32:$val), 1700 "xori\t$rT, $rA, $val", IntegerOp, 1701 [(set (v4i32 VECREG:$rT), (xor (v4i32 VECREG:$rA), 1702 v4i32SExt10Imm:$val))]>; 1703 1704 def XORIr32: 1705 RI10Form<0b00100000, (outs R32C:$rT), (ins R32C:$rA, s10imm_i32:$val), 1706 "xori\t$rT, $rA, $val", IntegerOp, 1707 [(set R32C:$rT, (xor R32C:$rA, i32ImmSExt10:$val))]>; 1708 1709 // NAND: 1710 1711 class NANDInst<dag OOL, dag IOL, list<dag> pattern>: 1712 RRForm<0b10010011000, OOL, IOL, "nand\t$rT, $rA, $rB", 1713 IntegerOp, pattern>; 1714 1715 class NANDVecInst<ValueType vectype>: 1716 NANDInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 1717 [(set (vectype VECREG:$rT), (vnot (and (vectype VECREG:$rA), 1718 (vectype VECREG:$rB))))]>; 1719 class NANDRegInst<RegisterClass rclass>: 1720 NANDInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), 1721 [(set rclass:$rT, (not (and rclass:$rA, rclass:$rB)))]>; 1722 1723 multiclass BitwiseNand 1724 { 1725 def v16i8: NANDVecInst<v16i8>; 1726 def v8i16: NANDVecInst<v8i16>; 1727 def v4i32: NANDVecInst<v4i32>; 1728 def v2i64: NANDVecInst<v2i64>; 1729 1730 def r128: NANDRegInst<GPRC>; 1731 def r64: NANDRegInst<R64C>; 1732 def r32: NANDRegInst<R32C>; 1733 def r16: NANDRegInst<R16C>; 1734 def r8: NANDRegInst<R8C>; 1735 } 1736 1737 defm NAND : BitwiseNand; 1738 1739 // NOR: 1740 1741 class NORInst<dag OOL, dag IOL, list<dag> pattern>: 1742 RRForm<0b10010010000, OOL, IOL, "nor\t$rT, $rA, $rB", 1743 IntegerOp, pattern>; 1744 1745 class NORVecInst<ValueType vectype>: 1746 NORInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 1747 [(set (vectype VECREG:$rT), (vnot (or (vectype VECREG:$rA), 1748 (vectype VECREG:$rB))))]>; 1749 class NORRegInst<RegisterClass rclass>: 1750 NORInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), 1751 [(set rclass:$rT, (not (or rclass:$rA, rclass:$rB)))]>; 1752 1753 multiclass BitwiseNor 1754 { 1755 def v16i8: NORVecInst<v16i8>; 1756 def v8i16: NORVecInst<v8i16>; 1757 def v4i32: NORVecInst<v4i32>; 1758 def v2i64: NORVecInst<v2i64>; 1759 1760 def r128: NORRegInst<GPRC>; 1761 def r64: NORRegInst<R64C>; 1762 def r32: NORRegInst<R32C>; 1763 def r16: NORRegInst<R16C>; 1764 def r8: NORRegInst<R8C>; 1765 } 1766 1767 defm NOR : BitwiseNor; 1768 1769 // Select bits: 1770 class SELBInst<dag OOL, dag IOL, list<dag> pattern>: 1771 RRRForm<0b1000, OOL, IOL, "selb\t$rT, $rA, $rB, $rC", 1772 IntegerOp, pattern>; 1773 1774 class SELBVecInst<ValueType vectype, PatFrag vnot_frag = vnot>: 1775 SELBInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), 1776 [(set (vectype VECREG:$rT), 1777 (or (and (vectype VECREG:$rC), (vectype VECREG:$rB)), 1778 (and (vnot_frag (vectype VECREG:$rC)), 1779 (vectype VECREG:$rA))))]>; 1780 1781 class SELBVecVCondInst<ValueType vectype>: 1782 SELBInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), 1783 [(set (vectype VECREG:$rT), 1784 (select (vectype VECREG:$rC), 1785 (vectype VECREG:$rB), 1786 (vectype VECREG:$rA)))]>; 1787 1788 class SELBVecCondInst<ValueType vectype>: 1789 SELBInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, R32C:$rC), 1790 [(set (vectype VECREG:$rT), 1791 (select R32C:$rC, 1792 (vectype VECREG:$rB), 1793 (vectype VECREG:$rA)))]>; 1794 1795 class SELBRegInst<RegisterClass rclass>: 1796 SELBInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB, rclass:$rC), 1797 [(set rclass:$rT, 1798 (or (and rclass:$rB, rclass:$rC), 1799 (and rclass:$rA, (not rclass:$rC))))]>; 1800 1801 class SELBRegCondInst<RegisterClass rcond, RegisterClass rclass>: 1802 SELBInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB, rcond:$rC), 1803 [(set rclass:$rT, 1804 (select rcond:$rC, rclass:$rB, rclass:$rA))]>; 1805 1806 multiclass SelectBits 1807 { 1808 def v16i8: SELBVecInst<v16i8>; 1809 def v8i16: SELBVecInst<v8i16>; 1810 def v4i32: SELBVecInst<v4i32>; 1811 def v2i64: SELBVecInst<v2i64, vnot_cell_conv>; 1812 1813 def r128: SELBRegInst<GPRC>; 1814 def r64: SELBRegInst<R64C>; 1815 def r32: SELBRegInst<R32C>; 1816 def r16: SELBRegInst<R16C>; 1817 def r8: SELBRegInst<R8C>; 1818 1819 def v16i8_cond: SELBVecCondInst<v16i8>; 1820 def v8i16_cond: SELBVecCondInst<v8i16>; 1821 def v4i32_cond: SELBVecCondInst<v4i32>; 1822 def v2i64_cond: SELBVecCondInst<v2i64>; 1823 1824 def v16i8_vcond: SELBVecCondInst<v16i8>; 1825 def v8i16_vcond: SELBVecCondInst<v8i16>; 1826 def v4i32_vcond: SELBVecCondInst<v4i32>; 1827 def v2i64_vcond: SELBVecCondInst<v2i64>; 1828 1829 def v4f32_cond: 1830 SELBInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), 1831 [(set (v4f32 VECREG:$rT), 1832 (select (v4i32 VECREG:$rC), 1833 (v4f32 VECREG:$rB), 1834 (v4f32 VECREG:$rA)))]>; 1835 1836 // SELBr64_cond is defined in SPU64InstrInfo.td 1837 def r32_cond: SELBRegCondInst<R32C, R32C>; 1838 def f32_cond: SELBRegCondInst<R32C, R32FP>; 1839 def r16_cond: SELBRegCondInst<R16C, R16C>; 1840 def r8_cond: SELBRegCondInst<R8C, R8C>; 1841 } 1842 1843 defm SELB : SelectBits; 1844 1845 class SPUselbPatVec<ValueType vectype, SPUInstr inst>: 1846 Pat<(SPUselb (vectype VECREG:$rA), (vectype VECREG:$rB), (vectype VECREG:$rC)), 1847 (inst VECREG:$rA, VECREG:$rB, VECREG:$rC)>; 1848 1849 def : SPUselbPatVec<v16i8, SELBv16i8>; 1850 def : SPUselbPatVec<v8i16, SELBv8i16>; 1851 def : SPUselbPatVec<v4i32, SELBv4i32>; 1852 def : SPUselbPatVec<v2i64, SELBv2i64>; 1853 1854 class SPUselbPatReg<RegisterClass rclass, SPUInstr inst>: 1855 Pat<(SPUselb rclass:$rA, rclass:$rB, rclass:$rC), 1856 (inst rclass:$rA, rclass:$rB, rclass:$rC)>; 1857 1858 def : SPUselbPatReg<R8C, SELBr8>; 1859 def : SPUselbPatReg<R16C, SELBr16>; 1860 def : SPUselbPatReg<R32C, SELBr32>; 1861 def : SPUselbPatReg<R64C, SELBr64>; 1862 1863 // EQV: Equivalence (1 for each same bit, otherwise 0) 1864 // 1865 // Note: There are a lot of ways to match this bit operator and these patterns 1866 // attempt to be as exhaustive as possible. 1867 1868 class EQVInst<dag OOL, dag IOL, list<dag> pattern>: 1869 RRForm<0b10010010000, OOL, IOL, "eqv\t$rT, $rA, $rB", 1870 IntegerOp, pattern>; 1871 1872 class EQVVecInst<ValueType vectype>: 1873 EQVInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 1874 [(set (vectype VECREG:$rT), 1875 (or (and (vectype VECREG:$rA), (vectype VECREG:$rB)), 1876 (and (vnot (vectype VECREG:$rA)), 1877 (vnot (vectype VECREG:$rB)))))]>; 1878 1879 class EQVRegInst<RegisterClass rclass>: 1880 EQVInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), 1881 [(set rclass:$rT, (or (and rclass:$rA, rclass:$rB), 1882 (and (not rclass:$rA), (not rclass:$rB))))]>; 1883 1884 class EQVVecPattern1<ValueType vectype>: 1885 EQVInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 1886 [(set (vectype VECREG:$rT), 1887 (xor (vectype VECREG:$rA), (vnot (vectype VECREG:$rB))))]>; 1888 1889 class EQVRegPattern1<RegisterClass rclass>: 1890 EQVInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), 1891 [(set rclass:$rT, (xor rclass:$rA, (not rclass:$rB)))]>; 1892 1893 class EQVVecPattern2<ValueType vectype>: 1894 EQVInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 1895 [(set (vectype VECREG:$rT), 1896 (or (and (vectype VECREG:$rA), (vectype VECREG:$rB)), 1897 (vnot (or (vectype VECREG:$rA), (vectype VECREG:$rB)))))]>; 1898 1899 class EQVRegPattern2<RegisterClass rclass>: 1900 EQVInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), 1901 [(set rclass:$rT, 1902 (or (and rclass:$rA, rclass:$rB), 1903 (not (or rclass:$rA, rclass:$rB))))]>; 1904 1905 class EQVVecPattern3<ValueType vectype>: 1906 EQVInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 1907 [(set (vectype VECREG:$rT), 1908 (not (xor (vectype VECREG:$rA), (vectype VECREG:$rB))))]>; 1909 1910 class EQVRegPattern3<RegisterClass rclass>: 1911 EQVInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), 1912 [(set rclass:$rT, (not (xor rclass:$rA, rclass:$rB)))]>; 1913 1914 multiclass BitEquivalence 1915 { 1916 def v16i8: EQVVecInst<v16i8>; 1917 def v8i16: EQVVecInst<v8i16>; 1918 def v4i32: EQVVecInst<v4i32>; 1919 def v2i64: EQVVecInst<v2i64>; 1920 1921 def v16i8_1: EQVVecPattern1<v16i8>; 1922 def v8i16_1: EQVVecPattern1<v8i16>; 1923 def v4i32_1: EQVVecPattern1<v4i32>; 1924 def v2i64_1: EQVVecPattern1<v2i64>; 1925 1926 def v16i8_2: EQVVecPattern2<v16i8>; 1927 def v8i16_2: EQVVecPattern2<v8i16>; 1928 def v4i32_2: EQVVecPattern2<v4i32>; 1929 def v2i64_2: EQVVecPattern2<v2i64>; 1930 1931 def v16i8_3: EQVVecPattern3<v16i8>; 1932 def v8i16_3: EQVVecPattern3<v8i16>; 1933 def v4i32_3: EQVVecPattern3<v4i32>; 1934 def v2i64_3: EQVVecPattern3<v2i64>; 1935 1936 def r128: EQVRegInst<GPRC>; 1937 def r64: EQVRegInst<R64C>; 1938 def r32: EQVRegInst<R32C>; 1939 def r16: EQVRegInst<R16C>; 1940 def r8: EQVRegInst<R8C>; 1941 1942 def r128_1: EQVRegPattern1<GPRC>; 1943 def r64_1: EQVRegPattern1<R64C>; 1944 def r32_1: EQVRegPattern1<R32C>; 1945 def r16_1: EQVRegPattern1<R16C>; 1946 def r8_1: EQVRegPattern1<R8C>; 1947 1948 def r128_2: EQVRegPattern2<GPRC>; 1949 def r64_2: EQVRegPattern2<R64C>; 1950 def r32_2: EQVRegPattern2<R32C>; 1951 def r16_2: EQVRegPattern2<R16C>; 1952 def r8_2: EQVRegPattern2<R8C>; 1953 1954 def r128_3: EQVRegPattern3<GPRC>; 1955 def r64_3: EQVRegPattern3<R64C>; 1956 def r32_3: EQVRegPattern3<R32C>; 1957 def r16_3: EQVRegPattern3<R16C>; 1958 def r8_3: EQVRegPattern3<R8C>; 1959 } 1960 1961 defm EQV: BitEquivalence; 1962 1963 //===----------------------------------------------------------------------===// 1964 // Vector shuffle... 1965 //===----------------------------------------------------------------------===// 1966 // SPUshuffle is generated in LowerVECTOR_SHUFFLE and gets replaced with SHUFB. 1967 // See the SPUshuffle SDNode operand above, which sets up the DAG pattern 1968 // matcher to emit something when the LowerVECTOR_SHUFFLE generates a node with 1969 // the SPUISD::SHUFB opcode. 1970 //===----------------------------------------------------------------------===// 1971 1972 class SHUFBInst<dag OOL, dag IOL, list<dag> pattern>: 1973 RRRForm<0b1000, OOL, IOL, "shufb\t$rT, $rA, $rB, $rC", 1974 ShuffleOp, pattern>; 1975 1976 class SHUFBVecInst<ValueType resultvec, ValueType maskvec>: 1977 SHUFBInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), 1978 [(set (resultvec VECREG:$rT), 1979 (SPUshuffle (resultvec VECREG:$rA), 1980 (resultvec VECREG:$rB), 1981 (maskvec VECREG:$rC)))]>; 1982 1983 class SHUFBGPRCInst: 1984 SHUFBInst<(outs VECREG:$rT), (ins GPRC:$rA, GPRC:$rB, VECREG:$rC), 1985 [/* no pattern */]>; 1986 1987 multiclass ShuffleBytes 1988 { 1989 def v16i8 : SHUFBVecInst<v16i8, v16i8>; 1990 def v16i8_m32 : SHUFBVecInst<v16i8, v4i32>; 1991 def v8i16 : SHUFBVecInst<v8i16, v16i8>; 1992 def v8i16_m32 : SHUFBVecInst<v8i16, v4i32>; 1993 def v4i32 : SHUFBVecInst<v4i32, v16i8>; 1994 def v4i32_m32 : SHUFBVecInst<v4i32, v4i32>; 1995 def v2i64 : SHUFBVecInst<v2i64, v16i8>; 1996 def v2i64_m32 : SHUFBVecInst<v2i64, v4i32>; 1997 1998 def v4f32 : SHUFBVecInst<v4f32, v16i8>; 1999 def v4f32_m32 : SHUFBVecInst<v4f32, v4i32>; 2000 2001 def v2f64 : SHUFBVecInst<v2f64, v16i8>; 2002 def v2f64_m32 : SHUFBVecInst<v2f64, v4i32>; 2003 2004 def gprc : SHUFBGPRCInst; 2005 } 2006 2007 defm SHUFB : ShuffleBytes; 2008 2009 //===----------------------------------------------------------------------===// 2010 // Shift and rotate group: 2011 //===----------------------------------------------------------------------===// 2012 2013 class SHLHInst<dag OOL, dag IOL, list<dag> pattern>: 2014 RRForm<0b11111010000, OOL, IOL, "shlh\t$rT, $rA, $rB", 2015 RotShiftVec, pattern>; 2016 2017 class SHLHVecInst<ValueType vectype>: 2018 SHLHInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 2019 [(set (vectype VECREG:$rT), 2020 (SPUvec_shl (vectype VECREG:$rA), (vectype VECREG:$rB)))]>; 2021 2022 multiclass ShiftLeftHalfword 2023 { 2024 def v8i16: SHLHVecInst<v8i16>; 2025 def r16: SHLHInst<(outs R16C:$rT), (ins R16C:$rA, R16C:$rB), 2026 [(set R16C:$rT, (shl R16C:$rA, R16C:$rB))]>; 2027 def r16_r32: SHLHInst<(outs R16C:$rT), (ins R16C:$rA, R32C:$rB), 2028 [(set R16C:$rT, (shl R16C:$rA, R32C:$rB))]>; 2029 } 2030 2031 defm SHLH : ShiftLeftHalfword; 2032 2033 //===----------------------------------------------------------------------===// 2034 2035 class SHLHIInst<dag OOL, dag IOL, list<dag> pattern>: 2036 RI7Form<0b11111010000, OOL, IOL, "shlhi\t$rT, $rA, $val", 2037 RotShiftVec, pattern>; 2038 2039 class SHLHIVecInst<ValueType vectype>: 2040 SHLHIInst<(outs VECREG:$rT), (ins VECREG:$rA, u7imm:$val), 2041 [(set (vectype VECREG:$rT), 2042 (SPUvec_shl (vectype VECREG:$rA), (i16 uimm7:$val)))]>; 2043 2044 multiclass ShiftLeftHalfwordImm 2045 { 2046 def v8i16: SHLHIVecInst<v8i16>; 2047 def r16: SHLHIInst<(outs R16C:$rT), (ins R16C:$rA, u7imm:$val), 2048 [(set R16C:$rT, (shl R16C:$rA, (i16 uimm7:$val)))]>; 2049 } 2050 2051 defm SHLHI : ShiftLeftHalfwordImm; 2052 2053 def : Pat<(SPUvec_shl (v8i16 VECREG:$rA), (i32 uimm7:$val)), 2054 (SHLHIv8i16 VECREG:$rA, (TO_IMM16 uimm7:$val))>; 2055 2056 def : Pat<(shl R16C:$rA, (i32 uimm7:$val)), 2057 (SHLHIr16 R16C:$rA, (TO_IMM16 uimm7:$val))>; 2058 2059 //===----------------------------------------------------------------------===// 2060 2061 class SHLInst<dag OOL, dag IOL, list<dag> pattern>: 2062 RRForm<0b11111010000, OOL, IOL, "shl\t$rT, $rA, $rB", 2063 RotShiftVec, pattern>; 2064 2065 multiclass ShiftLeftWord 2066 { 2067 def v4i32: 2068 SHLInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 2069 [(set (v4i32 VECREG:$rT), 2070 (SPUvec_shl (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>; 2071 def r32: 2072 SHLInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB), 2073 [(set R32C:$rT, (shl R32C:$rA, R32C:$rB))]>; 2074 } 2075 2076 defm SHL: ShiftLeftWord; 2077 2078 //===----------------------------------------------------------------------===// 2079 2080 class SHLIInst<dag OOL, dag IOL, list<dag> pattern>: 2081 RI7Form<0b11111010000, OOL, IOL, "shli\t$rT, $rA, $val", 2082 RotShiftVec, pattern>; 2083 2084 multiclass ShiftLeftWordImm 2085 { 2086 def v4i32: 2087 SHLIInst<(outs VECREG:$rT), (ins VECREG:$rA, u7imm_i32:$val), 2088 [(set (v4i32 VECREG:$rT), 2089 (SPUvec_shl (v4i32 VECREG:$rA), (i32 uimm7:$val)))]>; 2090 2091 def r32: 2092 SHLIInst<(outs R32C:$rT), (ins R32C:$rA, u7imm_i32:$val), 2093 [(set R32C:$rT, (shl R32C:$rA, (i32 uimm7:$val)))]>; 2094 } 2095 2096 defm SHLI : ShiftLeftWordImm; 2097 2098 //===----------------------------------------------------------------------===// 2099 // SHLQBI vec form: Note that this will shift the entire vector (the 128-bit 2100 // register) to the left. Vector form is here to ensure type correctness. 2101 // 2102 // The shift count is in the lowest 3 bits (29-31) of $rB, so only a bit shift 2103 // of 7 bits is actually possible. 2104 // 2105 // Note also that SHLQBI/SHLQBII are used in conjunction with SHLQBY/SHLQBYI 2106 // to shift i64 and i128. SHLQBI is the residual left over after shifting by 2107 // bytes with SHLQBY. 2108 2109 class SHLQBIInst<dag OOL, dag IOL, list<dag> pattern>: 2110 RRForm<0b11011011100, OOL, IOL, "shlqbi\t$rT, $rA, $rB", 2111 RotShiftQuad, pattern>; 2112 2113 class SHLQBIVecInst<ValueType vectype>: 2114 SHLQBIInst<(outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB), 2115 [(set (vectype VECREG:$rT), 2116 (SPUshlquad_l_bits (vectype VECREG:$rA), R32C:$rB))]>; 2117 2118 class SHLQBIRegInst<RegisterClass rclass>: 2119 SHLQBIInst<(outs rclass:$rT), (ins rclass:$rA, R32C:$rB), 2120 [/* no pattern */]>; 2121 2122 multiclass ShiftLeftQuadByBits 2123 { 2124 def v16i8: SHLQBIVecInst<v16i8>; 2125 def v8i16: SHLQBIVecInst<v8i16>; 2126 def v4i32: SHLQBIVecInst<v4i32>; 2127 def v4f32: SHLQBIVecInst<v4f32>; 2128 def v2i64: SHLQBIVecInst<v2i64>; 2129 def v2f64: SHLQBIVecInst<v2f64>; 2130 2131 def r128: SHLQBIRegInst<GPRC>; 2132 } 2133 2134 defm SHLQBI : ShiftLeftQuadByBits; 2135 2136 // See note above on SHLQBI. In this case, the predicate actually does then 2137 // enforcement, whereas with SHLQBI, we have to "take it on faith." 2138 class SHLQBIIInst<dag OOL, dag IOL, list<dag> pattern>: 2139 RI7Form<0b11011111100, OOL, IOL, "shlqbii\t$rT, $rA, $val", 2140 RotShiftQuad, pattern>; 2141 2142 class SHLQBIIVecInst<ValueType vectype>: 2143 SHLQBIIInst<(outs VECREG:$rT), (ins VECREG:$rA, u7imm_i32:$val), 2144 [(set (vectype VECREG:$rT), 2145 (SPUshlquad_l_bits (vectype VECREG:$rA), (i32 bitshift:$val)))]>; 2146 2147 multiclass ShiftLeftQuadByBitsImm 2148 { 2149 def v16i8 : SHLQBIIVecInst<v16i8>; 2150 def v8i16 : SHLQBIIVecInst<v8i16>; 2151 def v4i32 : SHLQBIIVecInst<v4i32>; 2152 def v4f32 : SHLQBIIVecInst<v4f32>; 2153 def v2i64 : SHLQBIIVecInst<v2i64>; 2154 def v2f64 : SHLQBIIVecInst<v2f64>; 2155 } 2156 2157 defm SHLQBII : ShiftLeftQuadByBitsImm; 2158 2159 // SHLQBY, SHLQBYI vector forms: Shift the entire vector to the left by bytes, 2160 // not by bits. See notes above on SHLQBI. 2161 2162 class SHLQBYInst<dag OOL, dag IOL, list<dag> pattern>: 2163 RI7Form<0b11111011100, OOL, IOL, "shlqby\t$rT, $rA, $rB", 2164 RotShiftQuad, pattern>; 2165 2166 class SHLQBYVecInst<ValueType vectype>: 2167 SHLQBYInst<(outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB), 2168 [(set (vectype VECREG:$rT), 2169 (SPUshlquad_l_bytes (vectype VECREG:$rA), R32C:$rB))]>; 2170 2171 multiclass ShiftLeftQuadBytes 2172 { 2173 def v16i8: SHLQBYVecInst<v16i8>; 2174 def v8i16: SHLQBYVecInst<v8i16>; 2175 def v4i32: SHLQBYVecInst<v4i32>; 2176 def v4f32: SHLQBYVecInst<v4f32>; 2177 def v2i64: SHLQBYVecInst<v2i64>; 2178 def v2f64: SHLQBYVecInst<v2f64>; 2179 def r128: SHLQBYInst<(outs GPRC:$rT), (ins GPRC:$rA, R32C:$rB), 2180 [(set GPRC:$rT, (SPUshlquad_l_bytes GPRC:$rA, R32C:$rB))]>; 2181 } 2182 2183 defm SHLQBY: ShiftLeftQuadBytes; 2184 2185 class SHLQBYIInst<dag OOL, dag IOL, list<dag> pattern>: 2186 RI7Form<0b11111111100, OOL, IOL, "shlqbyi\t$rT, $rA, $val", 2187 RotShiftQuad, pattern>; 2188 2189 class SHLQBYIVecInst<ValueType vectype>: 2190 SHLQBYIInst<(outs VECREG:$rT), (ins VECREG:$rA, u7imm_i32:$val), 2191 [(set (vectype VECREG:$rT), 2192 (SPUshlquad_l_bytes (vectype VECREG:$rA), (i32 uimm7:$val)))]>; 2193 2194 multiclass ShiftLeftQuadBytesImm 2195 { 2196 def v16i8: SHLQBYIVecInst<v16i8>; 2197 def v8i16: SHLQBYIVecInst<v8i16>; 2198 def v4i32: SHLQBYIVecInst<v4i32>; 2199 def v4f32: SHLQBYIVecInst<v4f32>; 2200 def v2i64: SHLQBYIVecInst<v2i64>; 2201 def v2f64: SHLQBYIVecInst<v2f64>; 2202 def r128: SHLQBYIInst<(outs GPRC:$rT), (ins GPRC:$rA, u7imm_i32:$val), 2203 [(set GPRC:$rT, 2204 (SPUshlquad_l_bytes GPRC:$rA, (i32 uimm7:$val)))]>; 2205 } 2206 2207 defm SHLQBYI : ShiftLeftQuadBytesImm; 2208 2209 class SHLQBYBIInst<dag OOL, dag IOL, list<dag> pattern>: 2210 RRForm<0b00111001111, OOL, IOL, "shlqbybi\t$rT, $rA, $rB", 2211 RotShiftQuad, pattern>; 2212 2213 class SHLQBYBIVecInst<ValueType vectype>: 2214 SHLQBYBIInst<(outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB), 2215 [/* no pattern */]>; 2216 2217 class SHLQBYBIRegInst<RegisterClass rclass>: 2218 SHLQBYBIInst<(outs rclass:$rT), (ins rclass:$rA, R32C:$rB), 2219 [/* no pattern */]>; 2220 2221 multiclass ShiftLeftQuadBytesBitCount 2222 { 2223 def v16i8: SHLQBYBIVecInst<v16i8>; 2224 def v8i16: SHLQBYBIVecInst<v8i16>; 2225 def v4i32: SHLQBYBIVecInst<v4i32>; 2226 def v4f32: SHLQBYBIVecInst<v4f32>; 2227 def v2i64: SHLQBYBIVecInst<v2i64>; 2228 def v2f64: SHLQBYBIVecInst<v2f64>; 2229 2230 def r128: SHLQBYBIRegInst<GPRC>; 2231 } 2232 2233 defm SHLQBYBI : ShiftLeftQuadBytesBitCount; 2234 2235 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2236 // Rotate halfword: 2237 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2238 class ROTHInst<dag OOL, dag IOL, list<dag> pattern>: 2239 RRForm<0b00111010000, OOL, IOL, "roth\t$rT, $rA, $rB", 2240 RotShiftVec, pattern>; 2241 2242 class ROTHVecInst<ValueType vectype>: 2243 ROTHInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 2244 [(set (vectype VECREG:$rT), 2245 (SPUvec_rotl VECREG:$rA, (v8i16 VECREG:$rB)))]>; 2246 2247 class ROTHRegInst<RegisterClass rclass>: 2248 ROTHInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), 2249 [(set rclass:$rT, (rotl rclass:$rA, rclass:$rB))]>; 2250 2251 multiclass RotateLeftHalfword 2252 { 2253 def v8i16: ROTHVecInst<v8i16>; 2254 def r16: ROTHRegInst<R16C>; 2255 } 2256 2257 defm ROTH: RotateLeftHalfword; 2258 2259 def ROTHr16_r32: ROTHInst<(outs R16C:$rT), (ins R16C:$rA, R32C:$rB), 2260 [(set R16C:$rT, (rotl R16C:$rA, R32C:$rB))]>; 2261 2262 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2263 // Rotate halfword, immediate: 2264 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2265 class ROTHIInst<dag OOL, dag IOL, list<dag> pattern>: 2266 RI7Form<0b00111110000, OOL, IOL, "rothi\t$rT, $rA, $val", 2267 RotShiftVec, pattern>; 2268 2269 class ROTHIVecInst<ValueType vectype>: 2270 ROTHIInst<(outs VECREG:$rT), (ins VECREG:$rA, u7imm:$val), 2271 [(set (vectype VECREG:$rT), 2272 (SPUvec_rotl VECREG:$rA, (i16 uimm7:$val)))]>; 2273 2274 multiclass RotateLeftHalfwordImm 2275 { 2276 def v8i16: ROTHIVecInst<v8i16>; 2277 def r16: ROTHIInst<(outs R16C:$rT), (ins R16C:$rA, u7imm:$val), 2278 [(set R16C:$rT, (rotl R16C:$rA, (i16 uimm7:$val)))]>; 2279 def r16_r32: ROTHIInst<(outs R16C:$rT), (ins R16C:$rA, u7imm_i32:$val), 2280 [(set R16C:$rT, (rotl R16C:$rA, (i32 uimm7:$val)))]>; 2281 } 2282 2283 defm ROTHI: RotateLeftHalfwordImm; 2284 2285 def : Pat<(SPUvec_rotl (v8i16 VECREG:$rA), (i32 uimm7:$val)), 2286 (ROTHIv8i16 VECREG:$rA, (TO_IMM16 imm:$val))>; 2287 2288 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2289 // Rotate word: 2290 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2291 2292 class ROTInst<dag OOL, dag IOL, list<dag> pattern>: 2293 RRForm<0b00011010000, OOL, IOL, "rot\t$rT, $rA, $rB", 2294 RotShiftVec, pattern>; 2295 2296 class ROTVecInst<ValueType vectype>: 2297 ROTInst<(outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB), 2298 [(set (vectype VECREG:$rT), 2299 (SPUvec_rotl (vectype VECREG:$rA), R32C:$rB))]>; 2300 2301 class ROTRegInst<RegisterClass rclass>: 2302 ROTInst<(outs rclass:$rT), (ins rclass:$rA, R32C:$rB), 2303 [(set rclass:$rT, 2304 (rotl rclass:$rA, R32C:$rB))]>; 2305 2306 multiclass RotateLeftWord 2307 { 2308 def v4i32: ROTVecInst<v4i32>; 2309 def r32: ROTRegInst<R32C>; 2310 } 2311 2312 defm ROT: RotateLeftWord; 2313 2314 // The rotate amount is in the same bits whether we've got an 8-bit, 16-bit or 2315 // 32-bit register 2316 def ROTr32_r16_anyext: 2317 ROTInst<(outs R32C:$rT), (ins R32C:$rA, R16C:$rB), 2318 [(set R32C:$rT, (rotl R32C:$rA, (i32 (anyext R16C:$rB))))]>; 2319 2320 def : Pat<(rotl R32C:$rA, (i32 (zext R16C:$rB))), 2321 (ROTr32_r16_anyext R32C:$rA, R16C:$rB)>; 2322 2323 def : Pat<(rotl R32C:$rA, (i32 (sext R16C:$rB))), 2324 (ROTr32_r16_anyext R32C:$rA, R16C:$rB)>; 2325 2326 def ROTr32_r8_anyext: 2327 ROTInst<(outs R32C:$rT), (ins R32C:$rA, R8C:$rB), 2328 [(set R32C:$rT, (rotl R32C:$rA, (i32 (anyext R8C:$rB))))]>; 2329 2330 def : Pat<(rotl R32C:$rA, (i32 (zext R8C:$rB))), 2331 (ROTr32_r8_anyext R32C:$rA, R8C:$rB)>; 2332 2333 def : Pat<(rotl R32C:$rA, (i32 (sext R8C:$rB))), 2334 (ROTr32_r8_anyext R32C:$rA, R8C:$rB)>; 2335 2336 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2337 // Rotate word, immediate 2338 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2339 2340 class ROTIInst<dag OOL, dag IOL, list<dag> pattern>: 2341 RI7Form<0b00011110000, OOL, IOL, "roti\t$rT, $rA, $val", 2342 RotShiftVec, pattern>; 2343 2344 class ROTIVecInst<ValueType vectype, Operand optype, ValueType inttype, PatLeaf pred>: 2345 ROTIInst<(outs VECREG:$rT), (ins VECREG:$rA, optype:$val), 2346 [(set (vectype VECREG:$rT), 2347 (SPUvec_rotl (vectype VECREG:$rA), (inttype pred:$val)))]>; 2348 2349 class ROTIRegInst<RegisterClass rclass, Operand optype, ValueType inttype, PatLeaf pred>: 2350 ROTIInst<(outs rclass:$rT), (ins rclass:$rA, optype:$val), 2351 [(set rclass:$rT, (rotl rclass:$rA, (inttype pred:$val)))]>; 2352 2353 multiclass RotateLeftWordImm 2354 { 2355 def v4i32: ROTIVecInst<v4i32, u7imm_i32, i32, uimm7>; 2356 def v4i32_i16: ROTIVecInst<v4i32, u7imm, i16, uimm7>; 2357 def v4i32_i8: ROTIVecInst<v4i32, u7imm_i8, i8, uimm7>; 2358 2359 def r32: ROTIRegInst<R32C, u7imm_i32, i32, uimm7>; 2360 def r32_i16: ROTIRegInst<R32C, u7imm, i16, uimm7>; 2361 def r32_i8: ROTIRegInst<R32C, u7imm_i8, i8, uimm7>; 2362 } 2363 2364 defm ROTI : RotateLeftWordImm; 2365 2366 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2367 // Rotate quad by byte (count) 2368 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2369 2370 class ROTQBYInst<dag OOL, dag IOL, list<dag> pattern>: 2371 RRForm<0b00111011100, OOL, IOL, "rotqby\t$rT, $rA, $rB", 2372 RotShiftQuad, pattern>; 2373 2374 class ROTQBYGenInst<ValueType type, RegisterClass rc>: 2375 ROTQBYInst<(outs rc:$rT), (ins rc:$rA, R32C:$rB), 2376 [(set (type rc:$rT), 2377 (SPUrotbytes_left (type rc:$rA), R32C:$rB))]>; 2378 2379 class ROTQBYVecInst<ValueType type>: 2380 ROTQBYGenInst<type, VECREG>; 2381 2382 multiclass RotateQuadLeftByBytes 2383 { 2384 def v16i8: ROTQBYVecInst<v16i8>; 2385 def v8i16: ROTQBYVecInst<v8i16>; 2386 def v4i32: ROTQBYVecInst<v4i32>; 2387 def v4f32: ROTQBYVecInst<v4f32>; 2388 def v2i64: ROTQBYVecInst<v2i64>; 2389 def v2f64: ROTQBYVecInst<v2f64>; 2390 def i128: ROTQBYGenInst<i128, GPRC>; 2391 } 2392 2393 defm ROTQBY: RotateQuadLeftByBytes; 2394 2395 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2396 // Rotate quad by byte (count), immediate 2397 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2398 2399 class ROTQBYIInst<dag OOL, dag IOL, list<dag> pattern>: 2400 RI7Form<0b00111111100, OOL, IOL, "rotqbyi\t$rT, $rA, $val", 2401 RotShiftQuad, pattern>; 2402 2403 class ROTQBYIGenInst<ValueType type, RegisterClass rclass>: 2404 ROTQBYIInst<(outs rclass:$rT), (ins rclass:$rA, u7imm:$val), 2405 [(set (type rclass:$rT), 2406 (SPUrotbytes_left (type rclass:$rA), (i16 uimm7:$val)))]>; 2407 2408 class ROTQBYIVecInst<ValueType vectype>: 2409 ROTQBYIGenInst<vectype, VECREG>; 2410 2411 multiclass RotateQuadByBytesImm 2412 { 2413 def v16i8: ROTQBYIVecInst<v16i8>; 2414 def v8i16: ROTQBYIVecInst<v8i16>; 2415 def v4i32: ROTQBYIVecInst<v4i32>; 2416 def v4f32: ROTQBYIVecInst<v4f32>; 2417 def v2i64: ROTQBYIVecInst<v2i64>; 2418 def vfi64: ROTQBYIVecInst<v2f64>; 2419 def i128: ROTQBYIGenInst<i128, GPRC>; 2420 } 2421 2422 defm ROTQBYI: RotateQuadByBytesImm; 2423 2424 // See ROTQBY note above. 2425 class ROTQBYBIInst<dag OOL, dag IOL, list<dag> pattern>: 2426 RI7Form<0b00110011100, OOL, IOL, 2427 "rotqbybi\t$rT, $rA, $shift", 2428 RotShiftQuad, pattern>; 2429 2430 class ROTQBYBIVecInst<ValueType vectype, RegisterClass rclass>: 2431 ROTQBYBIInst<(outs VECREG:$rT), (ins VECREG:$rA, rclass:$shift), 2432 [(set (vectype VECREG:$rT), 2433 (SPUrotbytes_left_bits (vectype VECREG:$rA), rclass:$shift))]>; 2434 2435 multiclass RotateQuadByBytesByBitshift { 2436 def v16i8_r32: ROTQBYBIVecInst<v16i8, R32C>; 2437 def v8i16_r32: ROTQBYBIVecInst<v8i16, R32C>; 2438 def v4i32_r32: ROTQBYBIVecInst<v4i32, R32C>; 2439 def v2i64_r32: ROTQBYBIVecInst<v2i64, R32C>; 2440 } 2441 2442 defm ROTQBYBI : RotateQuadByBytesByBitshift; 2443 2444 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2445 // See ROTQBY note above. 2446 // 2447 // Assume that the user of this instruction knows to shift the rotate count 2448 // into bit 29 2449 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2450 2451 class ROTQBIInst<dag OOL, dag IOL, list<dag> pattern>: 2452 RRForm<0b00011011100, OOL, IOL, "rotqbi\t$rT, $rA, $rB", 2453 RotShiftQuad, pattern>; 2454 2455 class ROTQBIVecInst<ValueType vectype>: 2456 ROTQBIInst<(outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB), 2457 [/* no pattern yet */]>; 2458 2459 class ROTQBIRegInst<RegisterClass rclass>: 2460 ROTQBIInst<(outs rclass:$rT), (ins rclass:$rA, R32C:$rB), 2461 [/* no pattern yet */]>; 2462 2463 multiclass RotateQuadByBitCount 2464 { 2465 def v16i8: ROTQBIVecInst<v16i8>; 2466 def v8i16: ROTQBIVecInst<v8i16>; 2467 def v4i32: ROTQBIVecInst<v4i32>; 2468 def v2i64: ROTQBIVecInst<v2i64>; 2469 2470 def r128: ROTQBIRegInst<GPRC>; 2471 def r64: ROTQBIRegInst<R64C>; 2472 } 2473 2474 defm ROTQBI: RotateQuadByBitCount; 2475 2476 class ROTQBIIInst<dag OOL, dag IOL, list<dag> pattern>: 2477 RI7Form<0b00011111100, OOL, IOL, "rotqbii\t$rT, $rA, $val", 2478 RotShiftQuad, pattern>; 2479 2480 class ROTQBIIVecInst<ValueType vectype, Operand optype, ValueType inttype, 2481 PatLeaf pred>: 2482 ROTQBIIInst<(outs VECREG:$rT), (ins VECREG:$rA, optype:$val), 2483 [/* no pattern yet */]>; 2484 2485 class ROTQBIIRegInst<RegisterClass rclass, Operand optype, ValueType inttype, 2486 PatLeaf pred>: 2487 ROTQBIIInst<(outs rclass:$rT), (ins rclass:$rA, optype:$val), 2488 [/* no pattern yet */]>; 2489 2490 multiclass RotateQuadByBitCountImm 2491 { 2492 def v16i8: ROTQBIIVecInst<v16i8, u7imm_i32, i32, uimm7>; 2493 def v8i16: ROTQBIIVecInst<v8i16, u7imm_i32, i32, uimm7>; 2494 def v4i32: ROTQBIIVecInst<v4i32, u7imm_i32, i32, uimm7>; 2495 def v2i64: ROTQBIIVecInst<v2i64, u7imm_i32, i32, uimm7>; 2496 2497 def r128: ROTQBIIRegInst<GPRC, u7imm_i32, i32, uimm7>; 2498 def r64: ROTQBIIRegInst<R64C, u7imm_i32, i32, uimm7>; 2499 } 2500 2501 defm ROTQBII : RotateQuadByBitCountImm; 2502 2503 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2504 // ROTHM v8i16 form: 2505 // NOTE(1): No vector rotate is generated by the C/C++ frontend (today), 2506 // so this only matches a synthetically generated/lowered code 2507 // fragment. 2508 // NOTE(2): $rB must be negated before the right rotate! 2509 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2510 2511 class ROTHMInst<dag OOL, dag IOL, list<dag> pattern>: 2512 RRForm<0b10111010000, OOL, IOL, "rothm\t$rT, $rA, $rB", 2513 RotShiftVec, pattern>; 2514 2515 def ROTHMv8i16: 2516 ROTHMInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 2517 [/* see patterns below - $rB must be negated */]>; 2518 2519 def : Pat<(SPUvec_srl (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)), 2520 (ROTHMv8i16 VECREG:$rA, (SFHIvec VECREG:$rB, 0))>; 2521 2522 // ROTHM r16 form: Rotate 16-bit quantity to right, zero fill at the left 2523 // Note: This instruction doesn't match a pattern because rB must be negated 2524 // for the instruction to work. Thus, the pattern below the instruction! 2525 2526 def ROTHMr16: 2527 ROTHMInst<(outs R16C:$rT), (ins R16C:$rA, R32C:$rB), 2528 [/* see patterns below - $rB must be negated! */]>; 2529 2530 def : Pat<(srl R16C:$rA, R32C:$rB), 2531 (ROTHMr16 R16C:$rA, (SFIr32 R32C:$rB, 0))>; 2532 2533 def : Pat<(srl R16C:$rA, R16C:$rB), 2534 (ROTHMr16 R16C:$rA, 2535 (SFIr32 (XSHWr16 R16C:$rB), 0))>; 2536 2537 def : Pat<(srl R16C:$rA, R8C:$rB), 2538 (ROTHMr16 R16C:$rA, 2539 (SFIr32 (XSHWr16 (XSBHr8 R8C:$rB) ), 0))>; 2540 2541 // ROTHMI v8i16 form: See the comment for ROTHM v8i16. The difference here is 2542 // that the immediate can be complemented, so that the user doesn't have to 2543 // worry about it. 2544 2545 class ROTHMIInst<dag OOL, dag IOL, list<dag> pattern>: 2546 RI7Form<0b10111110000, OOL, IOL, "rothmi\t$rT, $rA, $val", 2547 RotShiftVec, pattern>; 2548 2549 def ROTHMIv8i16: 2550 ROTHMIInst<(outs VECREG:$rT), (ins VECREG:$rA, rothNeg7imm:$val), 2551 [/* no pattern */]>; 2552 2553 def : Pat<(SPUvec_srl (v8i16 VECREG:$rA), (i32 imm:$val)), 2554 (ROTHMIv8i16 VECREG:$rA, imm:$val)>; 2555 2556 def: Pat<(SPUvec_srl (v8i16 VECREG:$rA), (i16 imm:$val)), 2557 (ROTHMIv8i16 VECREG:$rA, (TO_IMM32 imm:$val))>; 2558 2559 def: Pat<(SPUvec_srl (v8i16 VECREG:$rA), (i8 imm:$val)), 2560 (ROTHMIv8i16 VECREG:$rA, (TO_IMM32 imm:$val))>; 2561 2562 def ROTHMIr16: 2563 ROTHMIInst<(outs R16C:$rT), (ins R16C:$rA, rothNeg7imm:$val), 2564 [/* no pattern */]>; 2565 2566 def: Pat<(srl R16C:$rA, (i32 uimm7:$val)), 2567 (ROTHMIr16 R16C:$rA, uimm7:$val)>; 2568 2569 def: Pat<(srl R16C:$rA, (i16 uimm7:$val)), 2570 (ROTHMIr16 R16C:$rA, (TO_IMM32 uimm7:$val))>; 2571 2572 def: Pat<(srl R16C:$rA, (i8 uimm7:$val)), 2573 (ROTHMIr16 R16C:$rA, (TO_IMM32 uimm7:$val))>; 2574 2575 // ROTM v4i32 form: See the ROTHM v8i16 comments. 2576 class ROTMInst<dag OOL, dag IOL, list<dag> pattern>: 2577 RRForm<0b10011010000, OOL, IOL, "rotm\t$rT, $rA, $rB", 2578 RotShiftVec, pattern>; 2579 2580 def ROTMv4i32: 2581 ROTMInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 2582 [/* see patterns below - $rB must be negated */]>; 2583 2584 def : Pat<(SPUvec_srl (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)), 2585 (ROTMv4i32 VECREG:$rA, (SFIvec VECREG:$rB, 0))>; 2586 2587 def ROTMr32: 2588 ROTMInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB), 2589 [/* see patterns below - $rB must be negated */]>; 2590 2591 def : Pat<(srl R32C:$rA, R32C:$rB), 2592 (ROTMr32 R32C:$rA, (SFIr32 R32C:$rB, 0))>; 2593 2594 def : Pat<(srl R32C:$rA, R16C:$rB), 2595 (ROTMr32 R32C:$rA, 2596 (SFIr32 (XSHWr16 R16C:$rB), 0))>; 2597 2598 def : Pat<(srl R32C:$rA, R8C:$rB), 2599 (ROTMr32 R32C:$rA, 2600 (SFIr32 (XSHWr16 (XSBHr8 R8C:$rB)), 0))>; 2601 2602 // ROTMI v4i32 form: See the comment for ROTHM v8i16. 2603 def ROTMIv4i32: 2604 RI7Form<0b10011110000, (outs VECREG:$rT), (ins VECREG:$rA, rotNeg7imm:$val), 2605 "rotmi\t$rT, $rA, $val", RotShiftVec, 2606 [(set (v4i32 VECREG:$rT), 2607 (SPUvec_srl VECREG:$rA, (i32 uimm7:$val)))]>; 2608 2609 def : Pat<(SPUvec_srl (v4i32 VECREG:$rA), (i16 uimm7:$val)), 2610 (ROTMIv4i32 VECREG:$rA, (TO_IMM32 uimm7:$val))>; 2611 2612 def : Pat<(SPUvec_srl (v4i32 VECREG:$rA), (i8 uimm7:$val)), 2613 (ROTMIv4i32 VECREG:$rA, (TO_IMM32 uimm7:$val))>; 2614 2615 // ROTMI r32 form: know how to complement the immediate value. 2616 def ROTMIr32: 2617 RI7Form<0b10011110000, (outs R32C:$rT), (ins R32C:$rA, rotNeg7imm:$val), 2618 "rotmi\t$rT, $rA, $val", RotShiftVec, 2619 [(set R32C:$rT, (srl R32C:$rA, (i32 uimm7:$val)))]>; 2620 2621 def : Pat<(srl R32C:$rA, (i16 imm:$val)), 2622 (ROTMIr32 R32C:$rA, (TO_IMM32 uimm7:$val))>; 2623 2624 def : Pat<(srl R32C:$rA, (i8 imm:$val)), 2625 (ROTMIr32 R32C:$rA, (TO_IMM32 uimm7:$val))>; 2626 2627 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2628 // ROTQMBY: This is a vector form merely so that when used in an 2629 // instruction pattern, type checking will succeed. This instruction assumes 2630 // that the user knew to negate $rB. 2631 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2632 2633 class ROTQMBYInst<dag OOL, dag IOL, list<dag> pattern>: 2634 RRForm<0b10111011100, OOL, IOL, "rotqmby\t$rT, $rA, $rB", 2635 RotShiftQuad, pattern>; 2636 2637 class ROTQMBYVecInst<ValueType vectype>: 2638 ROTQMBYInst<(outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB), 2639 [/* no pattern, $rB must be negated */]>; 2640 2641 class ROTQMBYRegInst<RegisterClass rclass>: 2642 ROTQMBYInst<(outs rclass:$rT), (ins rclass:$rA, R32C:$rB), 2643 [/* no pattern */]>; 2644 2645 multiclass RotateQuadBytes 2646 { 2647 def v16i8: ROTQMBYVecInst<v16i8>; 2648 def v8i16: ROTQMBYVecInst<v8i16>; 2649 def v4i32: ROTQMBYVecInst<v4i32>; 2650 def v2i64: ROTQMBYVecInst<v2i64>; 2651 2652 def r128: ROTQMBYRegInst<GPRC>; 2653 def r64: ROTQMBYRegInst<R64C>; 2654 } 2655 2656 defm ROTQMBY : RotateQuadBytes; 2657 2658 def : Pat<(SPUsrl_bytes GPRC:$rA, R32C:$rB), 2659 (ROTQMBYr128 GPRC:$rA, 2660 (SFIr32 R32C:$rB, 0))>; 2661 2662 class ROTQMBYIInst<dag OOL, dag IOL, list<dag> pattern>: 2663 RI7Form<0b10111111100, OOL, IOL, "rotqmbyi\t$rT, $rA, $val", 2664 RotShiftQuad, pattern>; 2665 2666 class ROTQMBYIVecInst<ValueType vectype>: 2667 ROTQMBYIInst<(outs VECREG:$rT), (ins VECREG:$rA, rotNeg7imm:$val), 2668 [/* no pattern */]>; 2669 2670 class ROTQMBYIRegInst<RegisterClass rclass, Operand optype, ValueType inttype, 2671 PatLeaf pred>: 2672 ROTQMBYIInst<(outs rclass:$rT), (ins rclass:$rA, optype:$val), 2673 [/* no pattern */]>; 2674 2675 // 128-bit zero extension form: 2676 class ROTQMBYIZExtInst<RegisterClass rclass, Operand optype, PatLeaf pred>: 2677 ROTQMBYIInst<(outs GPRC:$rT), (ins rclass:$rA, optype:$val), 2678 [/* no pattern */]>; 2679 2680 multiclass RotateQuadBytesImm 2681 { 2682 def v16i8: ROTQMBYIVecInst<v16i8>; 2683 def v8i16: ROTQMBYIVecInst<v8i16>; 2684 def v4i32: ROTQMBYIVecInst<v4i32>; 2685 def v2i64: ROTQMBYIVecInst<v2i64>; 2686 2687 def r128: ROTQMBYIRegInst<GPRC, rotNeg7imm, i32, uimm7>; 2688 def r64: ROTQMBYIRegInst<R64C, rotNeg7imm, i32, uimm7>; 2689 2690 def r128_zext_r8: ROTQMBYIZExtInst<R8C, rotNeg7imm, uimm7>; 2691 def r128_zext_r16: ROTQMBYIZExtInst<R16C, rotNeg7imm, uimm7>; 2692 def r128_zext_r32: ROTQMBYIZExtInst<R32C, rotNeg7imm, uimm7>; 2693 def r128_zext_r64: ROTQMBYIZExtInst<R64C, rotNeg7imm, uimm7>; 2694 } 2695 2696 defm ROTQMBYI : RotateQuadBytesImm; 2697 2698 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2699 // Rotate right and mask by bit count 2700 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2701 2702 class ROTQMBYBIInst<dag OOL, dag IOL, list<dag> pattern>: 2703 RRForm<0b10110011100, OOL, IOL, "rotqmbybi\t$rT, $rA, $rB", 2704 RotShiftQuad, pattern>; 2705 2706 class ROTQMBYBIVecInst<ValueType vectype>: 2707 ROTQMBYBIInst<(outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB), 2708 [/* no pattern, */]>; 2709 2710 multiclass RotateMaskQuadByBitCount 2711 { 2712 def v16i8: ROTQMBYBIVecInst<v16i8>; 2713 def v8i16: ROTQMBYBIVecInst<v8i16>; 2714 def v4i32: ROTQMBYBIVecInst<v4i32>; 2715 def v2i64: ROTQMBYBIVecInst<v2i64>; 2716 def r128: ROTQMBYBIInst<(outs GPRC:$rT), (ins GPRC:$rA, R32C:$rB), 2717 [/*no pattern*/]>; 2718 } 2719 2720 defm ROTQMBYBI: RotateMaskQuadByBitCount; 2721 2722 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2723 // Rotate quad and mask by bits 2724 // Note that the rotate amount has to be negated 2725 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2726 2727 class ROTQMBIInst<dag OOL, dag IOL, list<dag> pattern>: 2728 RRForm<0b10011011100, OOL, IOL, "rotqmbi\t$rT, $rA, $rB", 2729 RotShiftQuad, pattern>; 2730 2731 class ROTQMBIVecInst<ValueType vectype>: 2732 ROTQMBIInst<(outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB), 2733 [/* no pattern */]>; 2734 2735 class ROTQMBIRegInst<RegisterClass rclass>: 2736 ROTQMBIInst<(outs rclass:$rT), (ins rclass:$rA, R32C:$rB), 2737 [/* no pattern */]>; 2738 2739 multiclass RotateMaskQuadByBits 2740 { 2741 def v16i8: ROTQMBIVecInst<v16i8>; 2742 def v8i16: ROTQMBIVecInst<v8i16>; 2743 def v4i32: ROTQMBIVecInst<v4i32>; 2744 def v2i64: ROTQMBIVecInst<v2i64>; 2745 2746 def r128: ROTQMBIRegInst<GPRC>; 2747 def r64: ROTQMBIRegInst<R64C>; 2748 } 2749 2750 defm ROTQMBI: RotateMaskQuadByBits; 2751 2752 def : Pat<(srl GPRC:$rA, R32C:$rB), 2753 (ROTQMBYBIr128 (ROTQMBIr128 GPRC:$rA, 2754 (SFIr32 R32C:$rB, 0)), 2755 (SFIr32 R32C:$rB, 0))>; 2756 2757 2758 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2759 // Rotate quad and mask by bits, immediate 2760 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2761 2762 class ROTQMBIIInst<dag OOL, dag IOL, list<dag> pattern>: 2763 RI7Form<0b10011111100, OOL, IOL, "rotqmbii\t$rT, $rA, $val", 2764 RotShiftQuad, pattern>; 2765 2766 class ROTQMBIIVecInst<ValueType vectype>: 2767 ROTQMBIIInst<(outs VECREG:$rT), (ins VECREG:$rA, rotNeg7imm:$val), 2768 [/* no pattern */]>; 2769 2770 class ROTQMBIIRegInst<RegisterClass rclass>: 2771 ROTQMBIIInst<(outs rclass:$rT), (ins rclass:$rA, rotNeg7imm:$val), 2772 [/* no pattern */]>; 2773 2774 multiclass RotateMaskQuadByBitsImm 2775 { 2776 def v16i8: ROTQMBIIVecInst<v16i8>; 2777 def v8i16: ROTQMBIIVecInst<v8i16>; 2778 def v4i32: ROTQMBIIVecInst<v4i32>; 2779 def v2i64: ROTQMBIIVecInst<v2i64>; 2780 2781 def r128: ROTQMBIIRegInst<GPRC>; 2782 def r64: ROTQMBIIRegInst<R64C>; 2783 } 2784 2785 defm ROTQMBII: RotateMaskQuadByBitsImm; 2786 2787 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2788 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2789 2790 def ROTMAHv8i16: 2791 RRForm<0b01111010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 2792 "rotmah\t$rT, $rA, $rB", RotShiftVec, 2793 [/* see patterns below - $rB must be negated */]>; 2794 2795 def : Pat<(SPUvec_sra (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)), 2796 (ROTMAHv8i16 VECREG:$rA, (SFHIvec VECREG:$rB, 0))>; 2797 2798 def ROTMAHr16: 2799 RRForm<0b01111010000, (outs R16C:$rT), (ins R16C:$rA, R32C:$rB), 2800 "rotmah\t$rT, $rA, $rB", RotShiftVec, 2801 [/* see patterns below - $rB must be negated */]>; 2802 2803 def : Pat<(sra R16C:$rA, R32C:$rB), 2804 (ROTMAHr16 R16C:$rA, (SFIr32 R32C:$rB, 0))>; 2805 2806 def : Pat<(sra R16C:$rA, R16C:$rB), 2807 (ROTMAHr16 R16C:$rA, 2808 (SFIr32 (XSHWr16 R16C:$rB), 0))>; 2809 2810 def : Pat<(sra R16C:$rA, R8C:$rB), 2811 (ROTMAHr16 R16C:$rA, 2812 (SFIr32 (XSHWr16 (XSBHr8 R8C:$rB)), 0))>; 2813 2814 def ROTMAHIv8i16: 2815 RRForm<0b01111110000, (outs VECREG:$rT), (ins VECREG:$rA, rothNeg7imm:$val), 2816 "rotmahi\t$rT, $rA, $val", RotShiftVec, 2817 [(set (v8i16 VECREG:$rT), 2818 (SPUvec_sra (v8i16 VECREG:$rA), (i32 uimm7:$val)))]>; 2819 2820 def : Pat<(SPUvec_sra (v8i16 VECREG:$rA), (i16 uimm7:$val)), 2821 (ROTMAHIv8i16 (v8i16 VECREG:$rA), (TO_IMM32 uimm7:$val))>; 2822 2823 def : Pat<(SPUvec_sra (v8i16 VECREG:$rA), (i8 uimm7:$val)), 2824 (ROTMAHIv8i16 (v8i16 VECREG:$rA), (TO_IMM32 uimm7:$val))>; 2825 2826 def ROTMAHIr16: 2827 RRForm<0b01111110000, (outs R16C:$rT), (ins R16C:$rA, rothNeg7imm_i16:$val), 2828 "rotmahi\t$rT, $rA, $val", RotShiftVec, 2829 [(set R16C:$rT, (sra R16C:$rA, (i16 uimm7:$val)))]>; 2830 2831 def : Pat<(sra R16C:$rA, (i32 imm:$val)), 2832 (ROTMAHIr16 R16C:$rA, (TO_IMM32 uimm7:$val))>; 2833 2834 def : Pat<(sra R16C:$rA, (i8 imm:$val)), 2835 (ROTMAHIr16 R16C:$rA, (TO_IMM32 uimm7:$val))>; 2836 2837 def ROTMAv4i32: 2838 RRForm<0b01011010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 2839 "rotma\t$rT, $rA, $rB", RotShiftVec, 2840 [/* see patterns below - $rB must be negated */]>; 2841 2842 def : Pat<(SPUvec_sra (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)), 2843 (ROTMAv4i32 VECREG:$rA, (SFIvec (v4i32 VECREG:$rB), 0))>; 2844 2845 def ROTMAr32: 2846 RRForm<0b01011010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), 2847 "rotma\t$rT, $rA, $rB", RotShiftVec, 2848 [/* see patterns below - $rB must be negated */]>; 2849 2850 def : Pat<(sra R32C:$rA, R32C:$rB), 2851 (ROTMAr32 R32C:$rA, (SFIr32 R32C:$rB, 0))>; 2852 2853 def : Pat<(sra R32C:$rA, R16C:$rB), 2854 (ROTMAr32 R32C:$rA, 2855 (SFIr32 (XSHWr16 R16C:$rB), 0))>; 2856 2857 def : Pat<(sra R32C:$rA, R8C:$rB), 2858 (ROTMAr32 R32C:$rA, 2859 (SFIr32 (XSHWr16 (XSBHr8 R8C:$rB)), 0))>; 2860 2861 class ROTMAIInst<dag OOL, dag IOL, list<dag> pattern>: 2862 RRForm<0b01011110000, OOL, IOL, 2863 "rotmai\t$rT, $rA, $val", 2864 RotShiftVec, pattern>; 2865 2866 class ROTMAIVecInst<ValueType vectype, Operand intop, ValueType inttype>: 2867 ROTMAIInst<(outs VECREG:$rT), (ins VECREG:$rA, intop:$val), 2868 [(set (vectype VECREG:$rT), 2869 (SPUvec_sra VECREG:$rA, (inttype uimm7:$val)))]>; 2870 2871 class ROTMAIRegInst<RegisterClass rclass, Operand intop, ValueType inttype>: 2872 ROTMAIInst<(outs rclass:$rT), (ins rclass:$rA, intop:$val), 2873 [(set rclass:$rT, (sra rclass:$rA, (inttype uimm7:$val)))]>; 2874 2875 multiclass RotateMaskAlgebraicImm { 2876 def v2i64_i32 : ROTMAIVecInst<v2i64, rotNeg7imm, i32>; 2877 def v4i32_i32 : ROTMAIVecInst<v4i32, rotNeg7imm, i32>; 2878 def r64_i32 : ROTMAIRegInst<R64C, rotNeg7imm, i32>; 2879 def r32_i32 : ROTMAIRegInst<R32C, rotNeg7imm, i32>; 2880 } 2881 2882 defm ROTMAI : RotateMaskAlgebraicImm; 2883 2884 //===----------------------------------------------------------------------===// 2885 // Branch and conditionals: 2886 //===----------------------------------------------------------------------===// 2887 2888 let isTerminator = 1, isBarrier = 1 in { 2889 // Halt If Equal (r32 preferred slot only, no vector form) 2890 def HEQr32: 2891 RRForm_3<0b00011011110, (outs), (ins R32C:$rA, R32C:$rB), 2892 "heq\t$rA, $rB", BranchResolv, 2893 [/* no pattern to match */]>; 2894 2895 def HEQIr32 : 2896 RI10Form_2<0b11111110, (outs), (ins R32C:$rA, s10imm:$val), 2897 "heqi\t$rA, $val", BranchResolv, 2898 [/* no pattern to match */]>; 2899 2900 // HGT/HGTI: These instructions use signed arithmetic for the comparison, 2901 // contrasting with HLGT/HLGTI, which use unsigned comparison: 2902 def HGTr32: 2903 RRForm_3<0b00011010010, (outs), (ins R32C:$rA, R32C:$rB), 2904 "hgt\t$rA, $rB", BranchResolv, 2905 [/* no pattern to match */]>; 2906 2907 def HGTIr32: 2908 RI10Form_2<0b11110010, (outs), (ins R32C:$rA, s10imm:$val), 2909 "hgti\t$rA, $val", BranchResolv, 2910 [/* no pattern to match */]>; 2911 2912 def HLGTr32: 2913 RRForm_3<0b00011011010, (outs), (ins R32C:$rA, R32C:$rB), 2914 "hlgt\t$rA, $rB", BranchResolv, 2915 [/* no pattern to match */]>; 2916 2917 def HLGTIr32: 2918 RI10Form_2<0b11111010, (outs), (ins R32C:$rA, s10imm:$val), 2919 "hlgti\t$rA, $val", BranchResolv, 2920 [/* no pattern to match */]>; 2921 } 2922 2923 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2924 // Comparison operators for i8, i16 and i32: 2925 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2926 2927 class CEQBInst<dag OOL, dag IOL, list<dag> pattern> : 2928 RRForm<0b00001011110, OOL, IOL, "ceqb\t$rT, $rA, $rB", 2929 ByteOp, pattern>; 2930 2931 multiclass CmpEqualByte 2932 { 2933 def v16i8 : 2934 CEQBInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 2935 [(set (v16i8 VECREG:$rT), (seteq (v8i16 VECREG:$rA), 2936 (v8i16 VECREG:$rB)))]>; 2937 2938 def r8 : 2939 CEQBInst<(outs R8C:$rT), (ins R8C:$rA, R8C:$rB), 2940 [(set R8C:$rT, (seteq R8C:$rA, R8C:$rB))]>; 2941 } 2942 2943 class CEQBIInst<dag OOL, dag IOL, list<dag> pattern> : 2944 RI10Form<0b01111110, OOL, IOL, "ceqbi\t$rT, $rA, $val", 2945 ByteOp, pattern>; 2946 2947 multiclass CmpEqualByteImm 2948 { 2949 def v16i8 : 2950 CEQBIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm_i8:$val), 2951 [(set (v16i8 VECREG:$rT), (seteq (v16i8 VECREG:$rA), 2952 v16i8SExt8Imm:$val))]>; 2953 def r8: 2954 CEQBIInst<(outs R8C:$rT), (ins R8C:$rA, s10imm_i8:$val), 2955 [(set R8C:$rT, (seteq R8C:$rA, immSExt8:$val))]>; 2956 } 2957 2958 class CEQHInst<dag OOL, dag IOL, list<dag> pattern> : 2959 RRForm<0b00010011110, OOL, IOL, "ceqh\t$rT, $rA, $rB", 2960 ByteOp, pattern>; 2961 2962 multiclass CmpEqualHalfword 2963 { 2964 def v8i16 : CEQHInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 2965 [(set (v8i16 VECREG:$rT), (seteq (v8i16 VECREG:$rA), 2966 (v8i16 VECREG:$rB)))]>; 2967 2968 def r16 : CEQHInst<(outs R16C:$rT), (ins R16C:$rA, R16C:$rB), 2969 [(set R16C:$rT, (seteq R16C:$rA, R16C:$rB))]>; 2970 } 2971 2972 class CEQHIInst<dag OOL, dag IOL, list<dag> pattern> : 2973 RI10Form<0b10111110, OOL, IOL, "ceqhi\t$rT, $rA, $val", 2974 ByteOp, pattern>; 2975 2976 multiclass CmpEqualHalfwordImm 2977 { 2978 def v8i16 : CEQHIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), 2979 [(set (v8i16 VECREG:$rT), 2980 (seteq (v8i16 VECREG:$rA), 2981 (v8i16 v8i16SExt10Imm:$val)))]>; 2982 def r16 : CEQHIInst<(outs R16C:$rT), (ins R16C:$rA, s10imm:$val), 2983 [(set R16C:$rT, (seteq R16C:$rA, i16ImmSExt10:$val))]>; 2984 } 2985 2986 class CEQInst<dag OOL, dag IOL, list<dag> pattern> : 2987 RRForm<0b00000011110, OOL, IOL, "ceq\t$rT, $rA, $rB", 2988 ByteOp, pattern>; 2989 2990 multiclass CmpEqualWord 2991 { 2992 def v4i32 : CEQInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 2993 [(set (v4i32 VECREG:$rT), 2994 (seteq (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>; 2995 2996 def r32 : CEQInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB), 2997 [(set R32C:$rT, (seteq R32C:$rA, R32C:$rB))]>; 2998 } 2999 3000 class CEQIInst<dag OOL, dag IOL, list<dag> pattern> : 3001 RI10Form<0b00111110, OOL, IOL, "ceqi\t$rT, $rA, $val", 3002 ByteOp, pattern>; 3003 3004 multiclass CmpEqualWordImm 3005 { 3006 def v4i32 : CEQIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), 3007 [(set (v4i32 VECREG:$rT), 3008 (seteq (v4i32 VECREG:$rA), 3009 (v4i32 v4i32SExt16Imm:$val)))]>; 3010 3011 def r32: CEQIInst<(outs R32C:$rT), (ins R32C:$rA, s10imm_i32:$val), 3012 [(set R32C:$rT, (seteq R32C:$rA, i32ImmSExt10:$val))]>; 3013 } 3014 3015 class CGTBInst<dag OOL, dag IOL, list<dag> pattern> : 3016 RRForm<0b00001010010, OOL, IOL, "cgtb\t$rT, $rA, $rB", 3017 ByteOp, pattern>; 3018 3019 multiclass CmpGtrByte 3020 { 3021 def v16i8 : 3022 CGTBInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 3023 [(set (v16i8 VECREG:$rT), (setgt (v8i16 VECREG:$rA), 3024 (v8i16 VECREG:$rB)))]>; 3025 3026 def r8 : 3027 CGTBInst<(outs R8C:$rT), (ins R8C:$rA, R8C:$rB), 3028 [(set R8C:$rT, (setgt R8C:$rA, R8C:$rB))]>; 3029 } 3030 3031 class CGTBIInst<dag OOL, dag IOL, list<dag> pattern> : 3032 RI10Form<0b01110010, OOL, IOL, "cgtbi\t$rT, $rA, $val", 3033 ByteOp, pattern>; 3034 3035 multiclass CmpGtrByteImm 3036 { 3037 def v16i8 : 3038 CGTBIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm_i8:$val), 3039 [(set (v16i8 VECREG:$rT), (setgt (v16i8 VECREG:$rA), 3040 v16i8SExt8Imm:$val))]>; 3041 def r8: 3042 CGTBIInst<(outs R8C:$rT), (ins R8C:$rA, s10imm_i8:$val), 3043 [(set R8C:$rT, (setgt R8C:$rA, immSExt8:$val))]>; 3044 } 3045 3046 class CGTHInst<dag OOL, dag IOL, list<dag> pattern> : 3047 RRForm<0b00010010010, OOL, IOL, "cgth\t$rT, $rA, $rB", 3048 ByteOp, pattern>; 3049 3050 multiclass CmpGtrHalfword 3051 { 3052 def v8i16 : CGTHInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 3053 [(set (v8i16 VECREG:$rT), (setgt (v8i16 VECREG:$rA), 3054 (v8i16 VECREG:$rB)))]>; 3055 3056 def r16 : CGTHInst<(outs R16C:$rT), (ins R16C:$rA, R16C:$rB), 3057 [(set R16C:$rT, (setgt R16C:$rA, R16C:$rB))]>; 3058 } 3059 3060 class CGTHIInst<dag OOL, dag IOL, list<dag> pattern> : 3061 RI10Form<0b10110010, OOL, IOL, "cgthi\t$rT, $rA, $val", 3062 ByteOp, pattern>; 3063 3064 multiclass CmpGtrHalfwordImm 3065 { 3066 def v8i16 : CGTHIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), 3067 [(set (v8i16 VECREG:$rT), 3068 (setgt (v8i16 VECREG:$rA), 3069 (v8i16 v8i16SExt10Imm:$val)))]>; 3070 def r16 : CGTHIInst<(outs R16C:$rT), (ins R16C:$rA, s10imm:$val), 3071 [(set R16C:$rT, (setgt R16C:$rA, i16ImmSExt10:$val))]>; 3072 } 3073 3074 class CGTInst<dag OOL, dag IOL, list<dag> pattern> : 3075 RRForm<0b00000010010, OOL, IOL, "cgt\t$rT, $rA, $rB", 3076 ByteOp, pattern>; 3077 3078 multiclass CmpGtrWord 3079 { 3080 def v4i32 : CGTInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 3081 [(set (v4i32 VECREG:$rT), 3082 (setgt (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>; 3083 3084 def r32 : CGTInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB), 3085 [(set R32C:$rT, (setgt R32C:$rA, R32C:$rB))]>; 3086 } 3087 3088 class CGTIInst<dag OOL, dag IOL, list<dag> pattern> : 3089 RI10Form<0b00110010, OOL, IOL, "cgti\t$rT, $rA, $val", 3090 ByteOp, pattern>; 3091 3092 multiclass CmpGtrWordImm 3093 { 3094 def v4i32 : CGTIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), 3095 [(set (v4i32 VECREG:$rT), 3096 (setgt (v4i32 VECREG:$rA), 3097 (v4i32 v4i32SExt16Imm:$val)))]>; 3098 3099 def r32: CGTIInst<(outs R32C:$rT), (ins R32C:$rA, s10imm_i32:$val), 3100 [(set R32C:$rT, (setgt R32C:$rA, i32ImmSExt10:$val))]>; 3101 3102 // CGTIv4f32, CGTIf32: These are used in the f32 fdiv instruction sequence: 3103 def v4f32: CGTIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), 3104 [(set (v4i32 VECREG:$rT), 3105 (setgt (v4i32 (bitconvert (v4f32 VECREG:$rA))), 3106 (v4i32 v4i32SExt16Imm:$val)))]>; 3107 3108 def f32: CGTIInst<(outs R32C:$rT), (ins R32FP:$rA, s10imm_i32:$val), 3109 [/* no pattern */]>; 3110 } 3111 3112 class CLGTBInst<dag OOL, dag IOL, list<dag> pattern> : 3113 RRForm<0b00001011010, OOL, IOL, "clgtb\t$rT, $rA, $rB", 3114 ByteOp, pattern>; 3115 3116 multiclass CmpLGtrByte 3117 { 3118 def v16i8 : 3119 CLGTBInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 3120 [(set (v16i8 VECREG:$rT), (setugt (v8i16 VECREG:$rA), 3121 (v8i16 VECREG:$rB)))]>; 3122 3123 def r8 : 3124 CLGTBInst<(outs R8C:$rT), (ins R8C:$rA, R8C:$rB), 3125 [(set R8C:$rT, (setugt R8C:$rA, R8C:$rB))]>; 3126 } 3127 3128 class CLGTBIInst<dag OOL, dag IOL, list<dag> pattern> : 3129 RI10Form<0b01111010, OOL, IOL, "clgtbi\t$rT, $rA, $val", 3130 ByteOp, pattern>; 3131 3132 multiclass CmpLGtrByteImm 3133 { 3134 def v16i8 : 3135 CLGTBIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm_i8:$val), 3136 [(set (v16i8 VECREG:$rT), (setugt (v16i8 VECREG:$rA), 3137 v16i8SExt8Imm:$val))]>; 3138 def r8: 3139 CLGTBIInst<(outs R8C:$rT), (ins R8C:$rA, s10imm_i8:$val), 3140 [(set R8C:$rT, (setugt R8C:$rA, immSExt8:$val))]>; 3141 } 3142 3143 class CLGTHInst<dag OOL, dag IOL, list<dag> pattern> : 3144 RRForm<0b00010011010, OOL, IOL, "clgth\t$rT, $rA, $rB", 3145 ByteOp, pattern>; 3146 3147 multiclass CmpLGtrHalfword 3148 { 3149 def v8i16 : CLGTHInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 3150 [(set (v8i16 VECREG:$rT), (setugt (v8i16 VECREG:$rA), 3151 (v8i16 VECREG:$rB)))]>; 3152 3153 def r16 : CLGTHInst<(outs R16C:$rT), (ins R16C:$rA, R16C:$rB), 3154 [(set R16C:$rT, (setugt R16C:$rA, R16C:$rB))]>; 3155 } 3156 3157 class CLGTHIInst<dag OOL, dag IOL, list<dag> pattern> : 3158 RI10Form<0b10111010, OOL, IOL, "clgthi\t$rT, $rA, $val", 3159 ByteOp, pattern>; 3160 3161 multiclass CmpLGtrHalfwordImm 3162 { 3163 def v8i16 : CLGTHIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), 3164 [(set (v8i16 VECREG:$rT), 3165 (setugt (v8i16 VECREG:$rA), 3166 (v8i16 v8i16SExt10Imm:$val)))]>; 3167 def r16 : CLGTHIInst<(outs R16C:$rT), (ins R16C:$rA, s10imm:$val), 3168 [(set R16C:$rT, (setugt R16C:$rA, i16ImmSExt10:$val))]>; 3169 } 3170 3171 class CLGTInst<dag OOL, dag IOL, list<dag> pattern> : 3172 RRForm<0b00000011010, OOL, IOL, "clgt\t$rT, $rA, $rB", 3173 ByteOp, pattern>; 3174 3175 multiclass CmpLGtrWord 3176 { 3177 def v4i32 : CLGTInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 3178 [(set (v4i32 VECREG:$rT), 3179 (setugt (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>; 3180 3181 def r32 : CLGTInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB), 3182 [(set R32C:$rT, (setugt R32C:$rA, R32C:$rB))]>; 3183 } 3184 3185 class CLGTIInst<dag OOL, dag IOL, list<dag> pattern> : 3186 RI10Form<0b00111010, OOL, IOL, "clgti\t$rT, $rA, $val", 3187 ByteOp, pattern>; 3188 3189 multiclass CmpLGtrWordImm 3190 { 3191 def v4i32 : CLGTIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), 3192 [(set (v4i32 VECREG:$rT), 3193 (setugt (v4i32 VECREG:$rA), 3194 (v4i32 v4i32SExt16Imm:$val)))]>; 3195 3196 def r32: CLGTIInst<(outs R32C:$rT), (ins R32C:$rA, s10imm_i32:$val), 3197 [(set R32C:$rT, (setugt R32C:$rA, i32ImmSExt10:$val))]>; 3198 } 3199 3200 defm CEQB : CmpEqualByte; 3201 defm CEQBI : CmpEqualByteImm; 3202 defm CEQH : CmpEqualHalfword; 3203 defm CEQHI : CmpEqualHalfwordImm; 3204 defm CEQ : CmpEqualWord; 3205 defm CEQI : CmpEqualWordImm; 3206 defm CGTB : CmpGtrByte; 3207 defm CGTBI : CmpGtrByteImm; 3208 defm CGTH : CmpGtrHalfword; 3209 defm CGTHI : CmpGtrHalfwordImm; 3210 defm CGT : CmpGtrWord; 3211 defm CGTI : CmpGtrWordImm; 3212 defm CLGTB : CmpLGtrByte; 3213 defm CLGTBI : CmpLGtrByteImm; 3214 defm CLGTH : CmpLGtrHalfword; 3215 defm CLGTHI : CmpLGtrHalfwordImm; 3216 defm CLGT : CmpLGtrWord; 3217 defm CLGTI : CmpLGtrWordImm; 3218 3219 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 3220 // For SETCC primitives not supported above (setlt, setle, setge, etc.) 3221 // define a pattern to generate the right code, as a binary operator 3222 // (in a manner of speaking.) 3223 // 3224 // Notes: 3225 // 1. This only matches the setcc set of conditionals. Special pattern 3226 // matching is used for select conditionals. 3227 // 3228 // 2. The "DAG" versions of these classes is almost exclusively used for 3229 // i64 comparisons. See the tblgen fundamentals documentation for what 3230 // ".ResultInstrs[0]" means; see TargetSelectionDAG.td and the Pattern 3231 // class for where ResultInstrs originates. 3232 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 3233 3234 class SETCCNegCondReg<PatFrag cond, RegisterClass rclass, ValueType inttype, 3235 SPUInstr xorinst, SPUInstr cmpare>: 3236 Pat<(cond rclass:$rA, rclass:$rB), 3237 (xorinst (cmpare rclass:$rA, rclass:$rB), (inttype -1))>; 3238 3239 class SETCCNegCondImm<PatFrag cond, RegisterClass rclass, ValueType inttype, 3240 PatLeaf immpred, SPUInstr xorinst, SPUInstr cmpare>: 3241 Pat<(cond rclass:$rA, (inttype immpred:$imm)), 3242 (xorinst (cmpare rclass:$rA, (inttype immpred:$imm)), (inttype -1))>; 3243 3244 def : SETCCNegCondReg<setne, R8C, i8, XORBIr8, CEQBr8>; 3245 def : SETCCNegCondImm<setne, R8C, i8, immSExt8, XORBIr8, CEQBIr8>; 3246 3247 def : SETCCNegCondReg<setne, R16C, i16, XORHIr16, CEQHr16>; 3248 def : SETCCNegCondImm<setne, R16C, i16, i16ImmSExt10, XORHIr16, CEQHIr16>; 3249 3250 def : SETCCNegCondReg<setne, R32C, i32, XORIr32, CEQr32>; 3251 def : SETCCNegCondImm<setne, R32C, i32, i32ImmSExt10, XORIr32, CEQIr32>; 3252 3253 class SETCCBinOpReg<PatFrag cond, RegisterClass rclass, 3254 SPUInstr binop, SPUInstr cmpOp1, SPUInstr cmpOp2>: 3255 Pat<(cond rclass:$rA, rclass:$rB), 3256 (binop (cmpOp1 rclass:$rA, rclass:$rB), 3257 (cmpOp2 rclass:$rA, rclass:$rB))>; 3258 3259 class SETCCBinOpImm<PatFrag cond, RegisterClass rclass, PatLeaf immpred, 3260 ValueType immtype, 3261 SPUInstr binop, SPUInstr cmpOp1, SPUInstr cmpOp2>: 3262 Pat<(cond rclass:$rA, (immtype immpred:$imm)), 3263 (binop (cmpOp1 rclass:$rA, (immtype immpred:$imm)), 3264 (cmpOp2 rclass:$rA, (immtype immpred:$imm)))>; 3265 3266 def : SETCCBinOpReg<setge, R8C, ORr8, CGTBr8, CEQBr8>; 3267 def : SETCCBinOpImm<setge, R8C, immSExt8, i8, ORr8, CGTBIr8, CEQBIr8>; 3268 def : SETCCBinOpReg<setlt, R8C, NORr8, CGTBr8, CEQBr8>; 3269 def : SETCCBinOpImm<setlt, R8C, immSExt8, i8, NORr8, CGTBIr8, CEQBIr8>; 3270 def : Pat<(setle R8C:$rA, R8C:$rB), 3271 (XORBIr8 (CGTBr8 R8C:$rA, R8C:$rB), 0xff)>; 3272 def : Pat<(setle R8C:$rA, immU8:$imm), 3273 (XORBIr8 (CGTBIr8 R8C:$rA, immU8:$imm), 0xff)>; 3274 3275 def : SETCCBinOpReg<setge, R16C, ORr16, CGTHr16, CEQHr16>; 3276 def : SETCCBinOpImm<setge, R16C, i16ImmSExt10, i16, 3277 ORr16, CGTHIr16, CEQHIr16>; 3278 def : SETCCBinOpReg<setlt, R16C, NORr16, CGTHr16, CEQHr16>; 3279 def : SETCCBinOpImm<setlt, R16C, i16ImmSExt10, i16, NORr16, CGTHIr16, CEQHIr16>; 3280 def : Pat<(setle R16C:$rA, R16C:$rB), 3281 (XORHIr16 (CGTHr16 R16C:$rA, R16C:$rB), 0xffff)>; 3282 def : Pat<(setle R16C:$rA, i16ImmSExt10:$imm), 3283 (XORHIr16 (CGTHIr16 R16C:$rA, i16ImmSExt10:$imm), 0xffff)>; 3284 3285 def : SETCCBinOpReg<setge, R32C, ORr32, CGTr32, CEQr32>; 3286 def : SETCCBinOpImm<setge, R32C, i32ImmSExt10, i32, 3287 ORr32, CGTIr32, CEQIr32>; 3288 def : SETCCBinOpReg<setlt, R32C, NORr32, CGTr32, CEQr32>; 3289 def : SETCCBinOpImm<setlt, R32C, i32ImmSExt10, i32, NORr32, CGTIr32, CEQIr32>; 3290 def : Pat<(setle R32C:$rA, R32C:$rB), 3291 (XORIr32 (CGTr32 R32C:$rA, R32C:$rB), 0xffffffff)>; 3292 def : Pat<(setle R32C:$rA, i32ImmSExt10:$imm), 3293 (XORIr32 (CGTIr32 R32C:$rA, i32ImmSExt10:$imm), 0xffffffff)>; 3294 3295 def : SETCCBinOpReg<setuge, R8C, ORr8, CLGTBr8, CEQBr8>; 3296 def : SETCCBinOpImm<setuge, R8C, immSExt8, i8, ORr8, CLGTBIr8, CEQBIr8>; 3297 def : SETCCBinOpReg<setult, R8C, NORr8, CLGTBr8, CEQBr8>; 3298 def : SETCCBinOpImm<setult, R8C, immSExt8, i8, NORr8, CLGTBIr8, CEQBIr8>; 3299 def : Pat<(setule R8C:$rA, R8C:$rB), 3300 (XORBIr8 (CLGTBr8 R8C:$rA, R8C:$rB), 0xff)>; 3301 def : Pat<(setule R8C:$rA, immU8:$imm), 3302 (XORBIr8 (CLGTBIr8 R8C:$rA, immU8:$imm), 0xff)>; 3303 3304 def : SETCCBinOpReg<setuge, R16C, ORr16, CLGTHr16, CEQHr16>; 3305 def : SETCCBinOpImm<setuge, R16C, i16ImmSExt10, i16, 3306 ORr16, CLGTHIr16, CEQHIr16>; 3307 def : SETCCBinOpReg<setult, R16C, NORr16, CLGTHr16, CEQHr16>; 3308 def : SETCCBinOpImm<setult, R16C, i16ImmSExt10, i16, NORr16, 3309 CLGTHIr16, CEQHIr16>; 3310 def : Pat<(setule R16C:$rA, R16C:$rB), 3311 (XORHIr16 (CLGTHr16 R16C:$rA, R16C:$rB), 0xffff)>; 3312 def : Pat<(setule R16C:$rA, i16ImmSExt10:$imm), 3313 (XORHIr16 (CLGTHIr16 R16C:$rA, i16ImmSExt10:$imm), 0xffff)>; 3314 3315 def : SETCCBinOpReg<setuge, R32C, ORr32, CLGTr32, CEQr32>; 3316 def : SETCCBinOpImm<setuge, R32C, i32ImmSExt10, i32, 3317 ORr32, CLGTIr32, CEQIr32>; 3318 def : SETCCBinOpReg<setult, R32C, NORr32, CLGTr32, CEQr32>; 3319 def : SETCCBinOpImm<setult, R32C, i32ImmSExt10, i32, NORr32, CLGTIr32, CEQIr32>; 3320 def : Pat<(setule R32C:$rA, R32C:$rB), 3321 (XORIr32 (CLGTr32 R32C:$rA, R32C:$rB), 0xffffffff)>; 3322 def : Pat<(setule R32C:$rA, i32ImmSExt10:$imm), 3323 (XORIr32 (CLGTIr32 R32C:$rA, i32ImmSExt10:$imm), 0xffffffff)>; 3324 3325 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 3326 // select conditional patterns: 3327 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 3328 3329 class SELECTNegCondReg<PatFrag cond, RegisterClass rclass, ValueType inttype, 3330 SPUInstr selinstr, SPUInstr cmpare>: 3331 Pat<(select (inttype (cond rclass:$rA, rclass:$rB)), 3332 rclass:$rTrue, rclass:$rFalse), 3333 (selinstr rclass:$rTrue, rclass:$rFalse, 3334 (cmpare rclass:$rA, rclass:$rB))>; 3335 3336 class SELECTNegCondImm<PatFrag cond, RegisterClass rclass, ValueType inttype, 3337 PatLeaf immpred, SPUInstr selinstr, SPUInstr cmpare>: 3338 Pat<(select (inttype (cond rclass:$rA, immpred:$imm)), 3339 rclass:$rTrue, rclass:$rFalse), 3340 (selinstr rclass:$rTrue, rclass:$rFalse, 3341 (cmpare rclass:$rA, immpred:$imm))>; 3342 3343 def : SELECTNegCondReg<setne, R8C, i8, SELBr8, CEQBr8>; 3344 def : SELECTNegCondImm<setne, R8C, i8, immSExt8, SELBr8, CEQBIr8>; 3345 def : SELECTNegCondReg<setle, R8C, i8, SELBr8, CGTBr8>; 3346 def : SELECTNegCondImm<setle, R8C, i8, immSExt8, SELBr8, CGTBr8>; 3347 def : SELECTNegCondReg<setule, R8C, i8, SELBr8, CLGTBr8>; 3348 def : SELECTNegCondImm<setule, R8C, i8, immU8, SELBr8, CLGTBIr8>; 3349 3350 def : SELECTNegCondReg<setne, R16C, i16, SELBr16, CEQHr16>; 3351 def : SELECTNegCondImm<setne, R16C, i16, i16ImmSExt10, SELBr16, CEQHIr16>; 3352 def : SELECTNegCondReg<setle, R16C, i16, SELBr16, CGTHr16>; 3353 def : SELECTNegCondImm<setle, R16C, i16, i16ImmSExt10, SELBr16, CGTHIr16>; 3354 def : SELECTNegCondReg<setule, R16C, i16, SELBr16, CLGTHr16>; 3355 def : SELECTNegCondImm<setule, R16C, i16, i16ImmSExt10, SELBr16, CLGTHIr16>; 3356 3357 def : SELECTNegCondReg<setne, R32C, i32, SELBr32, CEQr32>; 3358 def : SELECTNegCondImm<setne, R32C, i32, i32ImmSExt10, SELBr32, CEQIr32>; 3359 def : SELECTNegCondReg<setle, R32C, i32, SELBr32, CGTr32>; 3360 def : SELECTNegCondImm<setle, R32C, i32, i32ImmSExt10, SELBr32, CGTIr32>; 3361 def : SELECTNegCondReg<setule, R32C, i32, SELBr32, CLGTr32>; 3362 def : SELECTNegCondImm<setule, R32C, i32, i32ImmSExt10, SELBr32, CLGTIr32>; 3363 3364 class SELECTBinOpReg<PatFrag cond, RegisterClass rclass, ValueType inttype, 3365 SPUInstr selinstr, SPUInstr binop, SPUInstr cmpOp1, 3366 SPUInstr cmpOp2>: 3367 Pat<(select (inttype (cond rclass:$rA, rclass:$rB)), 3368 rclass:$rTrue, rclass:$rFalse), 3369 (selinstr rclass:$rFalse, rclass:$rTrue, 3370 (binop (cmpOp1 rclass:$rA, rclass:$rB), 3371 (cmpOp2 rclass:$rA, rclass:$rB)))>; 3372 3373 class SELECTBinOpImm<PatFrag cond, RegisterClass rclass, PatLeaf immpred, 3374 ValueType inttype, 3375 SPUInstr selinstr, SPUInstr binop, SPUInstr cmpOp1, 3376 SPUInstr cmpOp2>: 3377 Pat<(select (inttype (cond rclass:$rA, (inttype immpred:$imm))), 3378 rclass:$rTrue, rclass:$rFalse), 3379 (selinstr rclass:$rFalse, rclass:$rTrue, 3380 (binop (cmpOp1 rclass:$rA, (inttype immpred:$imm)), 3381 (cmpOp2 rclass:$rA, (inttype immpred:$imm))))>; 3382 3383 def : SELECTBinOpReg<setge, R8C, i8, SELBr8, ORr8, CGTBr8, CEQBr8>; 3384 def : SELECTBinOpImm<setge, R8C, immSExt8, i8, 3385 SELBr8, ORr8, CGTBIr8, CEQBIr8>; 3386 3387 def : SELECTBinOpReg<setge, R16C, i16, SELBr16, ORr16, CGTHr16, CEQHr16>; 3388 def : SELECTBinOpImm<setge, R16C, i16ImmSExt10, i16, 3389 SELBr16, ORr16, CGTHIr16, CEQHIr16>; 3390 3391 def : SELECTBinOpReg<setge, R32C, i32, SELBr32, ORr32, CGTr32, CEQr32>; 3392 def : SELECTBinOpImm<setge, R32C, i32ImmSExt10, i32, 3393 SELBr32, ORr32, CGTIr32, CEQIr32>; 3394 3395 def : SELECTBinOpReg<setuge, R8C, i8, SELBr8, ORr8, CLGTBr8, CEQBr8>; 3396 def : SELECTBinOpImm<setuge, R8C, immSExt8, i8, 3397 SELBr8, ORr8, CLGTBIr8, CEQBIr8>; 3398 3399 def : SELECTBinOpReg<setuge, R16C, i16, SELBr16, ORr16, CLGTHr16, CEQHr16>; 3400 def : SELECTBinOpImm<setuge, R16C, i16ImmUns10, i16, 3401 SELBr16, ORr16, CLGTHIr16, CEQHIr16>; 3402 3403 def : SELECTBinOpReg<setuge, R32C, i32, SELBr32, ORr32, CLGTr32, CEQr32>; 3404 def : SELECTBinOpImm<setuge, R32C, i32ImmUns10, i32, 3405 SELBr32, ORr32, CLGTIr32, CEQIr32>; 3406 3407 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 3408 3409 let isCall = 1, 3410 // All calls clobber the non-callee-saved registers: 3411 Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, 3412 R10,R11,R12,R13,R14,R15,R16,R17,R18,R19, 3413 R20,R21,R22,R23,R24,R25,R26,R27,R28,R29, 3414 R30,R31,R32,R33,R34,R35,R36,R37,R38,R39, 3415 R40,R41,R42,R43,R44,R45,R46,R47,R48,R49, 3416 R50,R51,R52,R53,R54,R55,R56,R57,R58,R59, 3417 R60,R61,R62,R63,R64,R65,R66,R67,R68,R69, 3418 R70,R71,R72,R73,R74,R75,R76,R77,R78,R79], 3419 // All of these instructions use $lr (aka $0) 3420 Uses = [R0] in { 3421 // Branch relative and set link: Used if we actually know that the target 3422 // is within [-32768, 32767] bytes of the target 3423 def BRSL: 3424 BranchSetLink<0b011001100, (outs), (ins relcalltarget:$func, variable_ops), 3425 "brsl\t$$lr, $func", 3426 [(SPUcall (SPUpcrel tglobaladdr:$func, 0))]>; 3427 3428 // Branch absolute and set link: Used if we actually know that the target 3429 // is an absolute address 3430 def BRASL: 3431 BranchSetLink<0b011001100, (outs), (ins calltarget:$func, variable_ops), 3432 "brasl\t$$lr, $func", 3433 [(SPUcall (SPUaform tglobaladdr:$func, 0))]>; 3434 3435 // Branch indirect and set link if external data. These instructions are not 3436 // actually generated, matched by an intrinsic: 3437 def BISLED_00: BISLEDForm<0b11, "bisled\t$$lr, $func", [/* empty pattern */]>; 3438 def BISLED_E0: BISLEDForm<0b10, "bisled\t$$lr, $func", [/* empty pattern */]>; 3439 def BISLED_0D: BISLEDForm<0b01, "bisled\t$$lr, $func", [/* empty pattern */]>; 3440 def BISLED_ED: BISLEDForm<0b00, "bisled\t$$lr, $func", [/* empty pattern */]>; 3441 3442 // Branch indirect and set link. This is the "X-form" address version of a 3443 // function call 3444 def BISL: 3445 BIForm<0b10010101100, "bisl\t$$lr, $func", [(SPUcall R32C:$func)]>; 3446 } 3447 3448 // Support calls to external symbols: 3449 def : Pat<(SPUcall (SPUpcrel texternalsym:$func, 0)), 3450 (BRSL texternalsym:$func)>; 3451 3452 def : Pat<(SPUcall (SPUaform texternalsym:$func, 0)), 3453 (BRASL texternalsym:$func)>; 3454 3455 // Unconditional branches: 3456 let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in { 3457 let isBarrier = 1 in { 3458 def BR : 3459 UncondBranch<0b001001100, (outs), (ins brtarget:$dest), 3460 "br\t$dest", 3461 [(br bb:$dest)]>; 3462 3463 // Unconditional, absolute address branch 3464 def BRA: 3465 UncondBranch<0b001100000, (outs), (ins brtarget:$dest), 3466 "bra\t$dest", 3467 [/* no pattern */]>; 3468 3469 // Indirect branch 3470 def BI: 3471 BIForm<0b00010101100, "bi\t$func", [(brind R32C:$func)]>; 3472 } 3473 3474 // Conditional branches: 3475 class BRNZInst<dag IOL, list<dag> pattern>: 3476 RI16Form<0b010000100, (outs), IOL, "brnz\t$rCond,$dest", 3477 BranchResolv, pattern>; 3478 3479 class BRNZRegInst<RegisterClass rclass>: 3480 BRNZInst<(ins rclass:$rCond, brtarget:$dest), 3481 [(brcond rclass:$rCond, bb:$dest)]>; 3482 3483 class BRNZVecInst<ValueType vectype>: 3484 BRNZInst<(ins VECREG:$rCond, brtarget:$dest), 3485 [(brcond (vectype VECREG:$rCond), bb:$dest)]>; 3486 3487 multiclass BranchNotZero { 3488 def v4i32 : BRNZVecInst<v4i32>; 3489 def r32 : BRNZRegInst<R32C>; 3490 } 3491 3492 defm BRNZ : BranchNotZero; 3493 3494 class BRZInst<dag IOL, list<dag> pattern>: 3495 RI16Form<0b000000100, (outs), IOL, "brz\t$rT,$dest", 3496 BranchResolv, pattern>; 3497 3498 class BRZRegInst<RegisterClass rclass>: 3499 BRZInst<(ins rclass:$rT, brtarget:$dest), [/* no pattern */]>; 3500 3501 class BRZVecInst<ValueType vectype>: 3502 BRZInst<(ins VECREG:$rT, brtarget:$dest), [/* no pattern */]>; 3503 3504 multiclass BranchZero { 3505 def v4i32: BRZVecInst<v4i32>; 3506 def r32: BRZRegInst<R32C>; 3507 } 3508 3509 defm BRZ: BranchZero; 3510 3511 // Note: LLVM doesn't do branch conditional, indirect. Otherwise these would 3512 // be useful: 3513 /* 3514 class BINZInst<dag IOL, list<dag> pattern>: 3515 BICondForm<0b10010100100, (outs), IOL, "binz\t$rA, $dest", pattern>; 3516 3517 class BINZRegInst<RegisterClass rclass>: 3518 BINZInst<(ins rclass:$rA, brtarget:$dest), 3519 [(brcond rclass:$rA, R32C:$dest)]>; 3520 3521 class BINZVecInst<ValueType vectype>: 3522 BINZInst<(ins VECREG:$rA, R32C:$dest), 3523 [(brcond (vectype VECREG:$rA), R32C:$dest)]>; 3524 3525 multiclass BranchNotZeroIndirect { 3526 def v4i32: BINZVecInst<v4i32>; 3527 def r32: BINZRegInst<R32C>; 3528 } 3529 3530 defm BINZ: BranchNotZeroIndirect; 3531 3532 class BIZInst<dag IOL, list<dag> pattern>: 3533 BICondForm<0b00010100100, (outs), IOL, "biz\t$rA, $func", pattern>; 3534 3535 class BIZRegInst<RegisterClass rclass>: 3536 BIZInst<(ins rclass:$rA, R32C:$func), [/* no pattern */]>; 3537 3538 class BIZVecInst<ValueType vectype>: 3539 BIZInst<(ins VECREG:$rA, R32C:$func), [/* no pattern */]>; 3540 3541 multiclass BranchZeroIndirect { 3542 def v4i32: BIZVecInst<v4i32>; 3543 def r32: BIZRegInst<R32C>; 3544 } 3545 3546 defm BIZ: BranchZeroIndirect; 3547 */ 3548 3549 class BRHNZInst<dag IOL, list<dag> pattern>: 3550 RI16Form<0b011000100, (outs), IOL, "brhnz\t$rCond,$dest", BranchResolv, 3551 pattern>; 3552 3553 class BRHNZRegInst<RegisterClass rclass>: 3554 BRHNZInst<(ins rclass:$rCond, brtarget:$dest), 3555 [(brcond rclass:$rCond, bb:$dest)]>; 3556 3557 class BRHNZVecInst<ValueType vectype>: 3558 BRHNZInst<(ins VECREG:$rCond, brtarget:$dest), [/* no pattern */]>; 3559 3560 multiclass BranchNotZeroHalfword { 3561 def v8i16: BRHNZVecInst<v8i16>; 3562 def r16: BRHNZRegInst<R16C>; 3563 } 3564 3565 defm BRHNZ: BranchNotZeroHalfword; 3566 3567 class BRHZInst<dag IOL, list<dag> pattern>: 3568 RI16Form<0b001000100, (outs), IOL, "brhz\t$rT,$dest", BranchResolv, 3569 pattern>; 3570 3571 class BRHZRegInst<RegisterClass rclass>: 3572 BRHZInst<(ins rclass:$rT, brtarget:$dest), [/* no pattern */]>; 3573 3574 class BRHZVecInst<ValueType vectype>: 3575 BRHZInst<(ins VECREG:$rT, brtarget:$dest), [/* no pattern */]>; 3576 3577 multiclass BranchZeroHalfword { 3578 def v8i16: BRHZVecInst<v8i16>; 3579 def r16: BRHZRegInst<R16C>; 3580 } 3581 3582 defm BRHZ: BranchZeroHalfword; 3583 } 3584 3585 //===----------------------------------------------------------------------===// 3586 // setcc and brcond patterns: 3587 //===----------------------------------------------------------------------===// 3588 3589 def : Pat<(brcond (i16 (seteq R16C:$rA, 0)), bb:$dest), 3590 (BRHZr16 R16C:$rA, bb:$dest)>; 3591 def : Pat<(brcond (i16 (setne R16C:$rA, 0)), bb:$dest), 3592 (BRHNZr16 R16C:$rA, bb:$dest)>; 3593 3594 def : Pat<(brcond (i32 (seteq R32C:$rA, 0)), bb:$dest), 3595 (BRZr32 R32C:$rA, bb:$dest)>; 3596 def : Pat<(brcond (i32 (setne R32C:$rA, 0)), bb:$dest), 3597 (BRNZr32 R32C:$rA, bb:$dest)>; 3598 3599 multiclass BranchCondEQ<PatFrag cond, SPUInstr brinst16, SPUInstr brinst32> 3600 { 3601 def r16imm: Pat<(brcond (i16 (cond R16C:$rA, i16ImmSExt10:$val)), bb:$dest), 3602 (brinst16 (CEQHIr16 R16C:$rA, i16ImmSExt10:$val), bb:$dest)>; 3603 3604 def r16 : Pat<(brcond (i16 (cond R16C:$rA, R16C:$rB)), bb:$dest), 3605 (brinst16 (CEQHr16 R16C:$rA, R16:$rB), bb:$dest)>; 3606 3607 def r32imm : Pat<(brcond (i32 (cond R32C:$rA, i32ImmSExt10:$val)), bb:$dest), 3608 (brinst32 (CEQIr32 R32C:$rA, i32ImmSExt10:$val), bb:$dest)>; 3609 3610 def r32 : Pat<(brcond (i32 (cond R32C:$rA, R32C:$rB)), bb:$dest), 3611 (brinst32 (CEQr32 R32C:$rA, R32C:$rB), bb:$dest)>; 3612 } 3613 3614 defm BRCONDeq : BranchCondEQ<seteq, BRHNZr16, BRNZr32>; 3615 defm BRCONDne : BranchCondEQ<setne, BRHZr16, BRZr32>; 3616 3617 multiclass BranchCondLGT<PatFrag cond, SPUInstr brinst16, SPUInstr brinst32> 3618 { 3619 def r16imm : Pat<(brcond (i16 (cond R16C:$rA, i16ImmSExt10:$val)), bb:$dest), 3620 (brinst16 (CLGTHIr16 R16C:$rA, i16ImmSExt10:$val), bb:$dest)>; 3621 3622 def r16 : Pat<(brcond (i16 (cond R16C:$rA, R16C:$rB)), bb:$dest), 3623 (brinst16 (CLGTHr16 R16C:$rA, R16:$rB), bb:$dest)>; 3624 3625 def r32imm : Pat<(brcond (i32 (cond R32C:$rA, i32ImmSExt10:$val)), bb:$dest), 3626 (brinst32 (CLGTIr32 R32C:$rA, i32ImmSExt10:$val), bb:$dest)>; 3627 3628 def r32 : Pat<(brcond (i32 (cond R32C:$rA, R32C:$rB)), bb:$dest), 3629 (brinst32 (CLGTr32 R32C:$rA, R32C:$rB), bb:$dest)>; 3630 } 3631 3632 defm BRCONDugt : BranchCondLGT<setugt, BRHNZr16, BRNZr32>; 3633 defm BRCONDule : BranchCondLGT<setule, BRHZr16, BRZr32>; 3634 3635 multiclass BranchCondLGTEQ<PatFrag cond, SPUInstr orinst16, SPUInstr brinst16, 3636 SPUInstr orinst32, SPUInstr brinst32> 3637 { 3638 def r16imm: Pat<(brcond (i16 (cond R16C:$rA, i16ImmSExt10:$val)), bb:$dest), 3639 (brinst16 (orinst16 (CLGTHIr16 R16C:$rA, i16ImmSExt10:$val), 3640 (CEQHIr16 R16C:$rA, i16ImmSExt10:$val)), 3641 bb:$dest)>; 3642 3643 def r16: Pat<(brcond (i16 (cond R16C:$rA, R16C:$rB)), bb:$dest), 3644 (brinst16 (orinst16 (CLGTHr16 R16C:$rA, R16:$rB), 3645 (CEQHr16 R16C:$rA, R16:$rB)), 3646 bb:$dest)>; 3647 3648 def r32imm : Pat<(brcond (i32 (cond R32C:$rA, i32ImmSExt10:$val)), bb:$dest), 3649 (brinst32 (orinst32 (CLGTIr32 R32C:$rA, i32ImmSExt10:$val), 3650 (CEQIr32 R32C:$rA, i32ImmSExt10:$val)), 3651 bb:$dest)>; 3652 3653 def r32 : Pat<(brcond (i32 (cond R32C:$rA, R32C:$rB)), bb:$dest), 3654 (brinst32 (orinst32 (CLGTr32 R32C:$rA, R32C:$rB), 3655 (CEQr32 R32C:$rA, R32C:$rB)), 3656 bb:$dest)>; 3657 } 3658 3659 defm BRCONDuge : BranchCondLGTEQ<setuge, ORr16, BRHNZr16, ORr32, BRNZr32>; 3660 defm BRCONDult : BranchCondLGTEQ<setult, ORr16, BRHZr16, ORr32, BRZr32>; 3661 3662 multiclass BranchCondGT<PatFrag cond, SPUInstr brinst16, SPUInstr brinst32> 3663 { 3664 def r16imm : Pat<(brcond (i16 (cond R16C:$rA, i16ImmSExt10:$val)), bb:$dest), 3665 (brinst16 (CGTHIr16 R16C:$rA, i16ImmSExt10:$val), bb:$dest)>; 3666 3667 def r16 : Pat<(brcond (i16 (cond R16C:$rA, R16C:$rB)), bb:$dest), 3668 (brinst16 (CGTHr16 R16C:$rA, R16:$rB), bb:$dest)>; 3669 3670 def r32imm : Pat<(brcond (i32 (cond R32C:$rA, i32ImmSExt10:$val)), bb:$dest), 3671 (brinst32 (CGTIr32 R32C:$rA, i32ImmSExt10:$val), bb:$dest)>; 3672 3673 def r32 : Pat<(brcond (i32 (cond R32C:$rA, R32C:$rB)), bb:$dest), 3674 (brinst32 (CGTr32 R32C:$rA, R32C:$rB), bb:$dest)>; 3675 } 3676 3677 defm BRCONDgt : BranchCondGT<setgt, BRHNZr16, BRNZr32>; 3678 defm BRCONDle : BranchCondGT<setle, BRHZr16, BRZr32>; 3679 3680 multiclass BranchCondGTEQ<PatFrag cond, SPUInstr orinst16, SPUInstr brinst16, 3681 SPUInstr orinst32, SPUInstr brinst32> 3682 { 3683 def r16imm: Pat<(brcond (i16 (cond R16C:$rA, i16ImmSExt10:$val)), bb:$dest), 3684 (brinst16 (orinst16 (CGTHIr16 R16C:$rA, i16ImmSExt10:$val), 3685 (CEQHIr16 R16C:$rA, i16ImmSExt10:$val)), 3686 bb:$dest)>; 3687 3688 def r16: Pat<(brcond (i16 (cond R16C:$rA, R16C:$rB)), bb:$dest), 3689 (brinst16 (orinst16 (CGTHr16 R16C:$rA, R16:$rB), 3690 (CEQHr16 R16C:$rA, R16:$rB)), 3691 bb:$dest)>; 3692 3693 def r32imm : Pat<(brcond (i32 (cond R32C:$rA, i32ImmSExt10:$val)), bb:$dest), 3694 (brinst32 (orinst32 (CGTIr32 R32C:$rA, i32ImmSExt10:$val), 3695 (CEQIr32 R32C:$rA, i32ImmSExt10:$val)), 3696 bb:$dest)>; 3697 3698 def r32 : Pat<(brcond (i32 (cond R32C:$rA, R32C:$rB)), bb:$dest), 3699 (brinst32 (orinst32 (CGTr32 R32C:$rA, R32C:$rB), 3700 (CEQr32 R32C:$rA, R32C:$rB)), 3701 bb:$dest)>; 3702 } 3703 3704 defm BRCONDge : BranchCondGTEQ<setge, ORr16, BRHNZr16, ORr32, BRNZr32>; 3705 defm BRCONDlt : BranchCondGTEQ<setlt, ORr16, BRHZr16, ORr32, BRZr32>; 3706 3707 let isTerminator = 1, isBarrier = 1 in { 3708 let isReturn = 1 in { 3709 def RET: 3710 RETForm<"bi\t$$lr", [(retflag)]>; 3711 } 3712 } 3713 3714 //===----------------------------------------------------------------------===// 3715 // Single precision floating point instructions 3716 //===----------------------------------------------------------------------===// 3717 3718 class FAInst<dag OOL, dag IOL, list<dag> pattern>: 3719 RRForm<0b01011000100, OOL, IOL, "fa\t$rT, $rA, $rB", 3720 SPrecFP, pattern>; 3721 3722 class FAVecInst<ValueType vectype>: 3723 FAInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 3724 [(set (vectype VECREG:$rT), 3725 (fadd (vectype VECREG:$rA), (vectype VECREG:$rB)))]>; 3726 3727 multiclass SFPAdd 3728 { 3729 def v4f32: FAVecInst<v4f32>; 3730 def f32: FAInst<(outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB), 3731 [(set R32FP:$rT, (fadd R32FP:$rA, R32FP:$rB))]>; 3732 } 3733 3734 defm FA : SFPAdd; 3735 3736 class FSInst<dag OOL, dag IOL, list<dag> pattern>: 3737 RRForm<0b01011000100, OOL, IOL, "fs\t$rT, $rA, $rB", 3738 SPrecFP, pattern>; 3739 3740 class FSVecInst<ValueType vectype>: 3741 FSInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 3742 [(set (vectype VECREG:$rT), 3743 (fsub (vectype VECREG:$rA), (vectype VECREG:$rB)))]>; 3744 3745 multiclass SFPSub 3746 { 3747 def v4f32: FSVecInst<v4f32>; 3748 def f32: FSInst<(outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB), 3749 [(set R32FP:$rT, (fsub R32FP:$rA, R32FP:$rB))]>; 3750 } 3751 3752 defm FS : SFPSub; 3753 3754 class FMInst<dag OOL, dag IOL, list<dag> pattern>: 3755 RRForm<0b01100011010, OOL, IOL, 3756 "fm\t$rT, $rA, $rB", SPrecFP, 3757 pattern>; 3758 3759 class FMVecInst<ValueType type>: 3760 FMInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 3761 [(set (type VECREG:$rT), 3762 (fmul (type VECREG:$rA), (type VECREG:$rB)))]>; 3763 3764 multiclass SFPMul 3765 { 3766 def v4f32: FMVecInst<v4f32>; 3767 def f32: FMInst<(outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB), 3768 [(set R32FP:$rT, (fmul R32FP:$rA, R32FP:$rB))]>; 3769 } 3770 3771 defm FM : SFPMul; 3772 3773 // Floating point multiply and add 3774 // e.g. d = c + (a * b) 3775 def FMAv4f32: 3776 RRRForm<0b0111, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), 3777 "fma\t$rT, $rA, $rB, $rC", SPrecFP, 3778 [(set (v4f32 VECREG:$rT), 3779 (fadd (v4f32 VECREG:$rC), 3780 (fmul (v4f32 VECREG:$rA), (v4f32 VECREG:$rB))))]>; 3781 3782 def FMAf32: 3783 RRRForm<0b0111, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB, R32FP:$rC), 3784 "fma\t$rT, $rA, $rB, $rC", SPrecFP, 3785 [(set R32FP:$rT, (fadd R32FP:$rC, (fmul R32FP:$rA, R32FP:$rB)))]>; 3786 3787 // FP multiply and subtract 3788 // Subtracts value in rC from product 3789 // res = a * b - c 3790 def FMSv4f32 : 3791 RRRForm<0b0111, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), 3792 "fms\t$rT, $rA, $rB, $rC", SPrecFP, 3793 [(set (v4f32 VECREG:$rT), 3794 (fsub (fmul (v4f32 VECREG:$rA), (v4f32 VECREG:$rB)), 3795 (v4f32 VECREG:$rC)))]>; 3796 3797 def FMSf32 : 3798 RRRForm<0b0111, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB, R32FP:$rC), 3799 "fms\t$rT, $rA, $rB, $rC", SPrecFP, 3800 [(set R32FP:$rT, 3801 (fsub (fmul R32FP:$rA, R32FP:$rB), R32FP:$rC))]>; 3802 3803 // Floating Negative Mulitply and Subtract 3804 // Subtracts product from value in rC 3805 // res = fneg(fms a b c) 3806 // = - (a * b - c) 3807 // = c - a * b 3808 // NOTE: subtraction order 3809 // fsub a b = a - b 3810 // fs a b = b - a? 3811 def FNMSf32 : 3812 RRRForm<0b1101, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB, R32FP:$rC), 3813 "fnms\t$rT, $rA, $rB, $rC", SPrecFP, 3814 [(set R32FP:$rT, (fsub R32FP:$rC, (fmul R32FP:$rA, R32FP:$rB)))]>; 3815 3816 def FNMSv4f32 : 3817 RRRForm<0b1101, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), 3818 "fnms\t$rT, $rA, $rB, $rC", SPrecFP, 3819 [(set (v4f32 VECREG:$rT), 3820 (fsub (v4f32 VECREG:$rC), 3821 (fmul (v4f32 VECREG:$rA), 3822 (v4f32 VECREG:$rB))))]>; 3823 3824 3825 3826 3827 // Floating point reciprocal estimate 3828 3829 class FRESTInst<dag OOL, dag IOL>: 3830 RRForm_1<0b00110111000, OOL, IOL, 3831 "frest\t$rT, $rA", SPrecFP, 3832 [/* no pattern */]>; 3833 3834 def FRESTv4f32 : 3835 FRESTInst<(outs VECREG:$rT), (ins VECREG:$rA)>; 3836 3837 def FRESTf32 : 3838 FRESTInst<(outs R32FP:$rT), (ins R32FP:$rA)>; 3839 3840 // Floating point interpolate (used in conjunction with reciprocal estimate) 3841 def FIv4f32 : 3842 RRForm<0b00101011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 3843 "fi\t$rT, $rA, $rB", SPrecFP, 3844 [/* no pattern */]>; 3845 3846 def FIf32 : 3847 RRForm<0b00101011110, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB), 3848 "fi\t$rT, $rA, $rB", SPrecFP, 3849 [/* no pattern */]>; 3850 3851 //-------------------------------------------------------------------------- 3852 // Basic single precision floating point comparisons: 3853 // 3854 // Note: There is no support on SPU for single precision NaN. Consequently, 3855 // ordered and unordered comparisons are the same. 3856 //-------------------------------------------------------------------------- 3857 3858 def FCEQf32 : 3859 RRForm<0b01000011110, (outs R32C:$rT), (ins R32FP:$rA, R32FP:$rB), 3860 "fceq\t$rT, $rA, $rB", SPrecFP, 3861 [(set R32C:$rT, (setueq R32FP:$rA, R32FP:$rB))]>; 3862 3863 def : Pat<(setoeq R32FP:$rA, R32FP:$rB), 3864 (FCEQf32 R32FP:$rA, R32FP:$rB)>; 3865 3866 def FCMEQf32 : 3867 RRForm<0b01010011110, (outs R32C:$rT), (ins R32FP:$rA, R32FP:$rB), 3868 "fcmeq\t$rT, $rA, $rB", SPrecFP, 3869 [(set R32C:$rT, (setueq (fabs R32FP:$rA), (fabs R32FP:$rB)))]>; 3870 3871 def : Pat<(setoeq (fabs R32FP:$rA), (fabs R32FP:$rB)), 3872 (FCMEQf32 R32FP:$rA, R32FP:$rB)>; 3873 3874 def FCGTf32 : 3875 RRForm<0b01000011010, (outs R32C:$rT), (ins R32FP:$rA, R32FP:$rB), 3876 "fcgt\t$rT, $rA, $rB", SPrecFP, 3877 [(set R32C:$rT, (setugt R32FP:$rA, R32FP:$rB))]>; 3878 3879 def : Pat<(setogt R32FP:$rA, R32FP:$rB), 3880 (FCGTf32 R32FP:$rA, R32FP:$rB)>; 3881 3882 def FCMGTf32 : 3883 RRForm<0b01010011010, (outs R32C:$rT), (ins R32FP:$rA, R32FP:$rB), 3884 "fcmgt\t$rT, $rA, $rB", SPrecFP, 3885 [(set R32C:$rT, (setugt (fabs R32FP:$rA), (fabs R32FP:$rB)))]>; 3886 3887 def : Pat<(setogt (fabs R32FP:$rA), (fabs R32FP:$rB)), 3888 (FCMGTf32 R32FP:$rA, R32FP:$rB)>; 3889 3890 //-------------------------------------------------------------------------- 3891 // Single precision floating point comparisons and SETCC equivalents: 3892 //-------------------------------------------------------------------------- 3893 3894 def : SETCCNegCondReg<setune, R32FP, i32, XORIr32, FCEQf32>; 3895 def : SETCCNegCondReg<setone, R32FP, i32, XORIr32, FCEQf32>; 3896 3897 def : SETCCBinOpReg<setuge, R32FP, ORr32, FCGTf32, FCEQf32>; 3898 def : SETCCBinOpReg<setoge, R32FP, ORr32, FCGTf32, FCEQf32>; 3899 3900 def : SETCCBinOpReg<setult, R32FP, NORr32, FCGTf32, FCEQf32>; 3901 def : SETCCBinOpReg<setolt, R32FP, NORr32, FCGTf32, FCEQf32>; 3902 3903 def : Pat<(setule R32FP:$rA, R32FP:$rB), 3904 (XORIr32 (FCGTf32 R32FP:$rA, R32FP:$rB), 0xffffffff)>; 3905 def : Pat<(setole R32FP:$rA, R32FP:$rB), 3906 (XORIr32 (FCGTf32 R32FP:$rA, R32FP:$rB), 0xffffffff)>; 3907 3908 // FP Status and Control Register Write 3909 // Why isn't rT a don't care in the ISA? 3910 // Should we create a special RRForm_3 for this guy and zero out the rT? 3911 def FSCRWf32 : 3912 RRForm_1<0b01011101110, (outs R32FP:$rT), (ins R32FP:$rA), 3913 "fscrwr\t$rA", SPrecFP, 3914 [/* This instruction requires an intrinsic. Note: rT is unused. */]>; 3915 3916 // FP Status and Control Register Read 3917 def FSCRRf32 : 3918 RRForm_2<0b01011101110, (outs R32FP:$rT), (ins), 3919 "fscrrd\t$rT", SPrecFP, 3920 [/* This instruction requires an intrinsic */]>; 3921 3922 // llvm instruction space 3923 // How do these map onto cell instructions? 3924 // fdiv rA rB 3925 // frest rC rB # c = 1/b (both lines) 3926 // fi rC rB rC 3927 // fm rD rA rC # d = a * 1/b 3928 // fnms rB rD rB rA # b = - (d * b - a) --should == 0 in a perfect world 3929 // fma rB rB rC rD # b = b * c + d 3930 // = -(d *b -a) * c + d 3931 // = a * c - c ( a *b *c - a) 3932 3933 // fcopysign (???) 3934 3935 // Library calls: 3936 // These llvm instructions will actually map to library calls. 3937 // All that's needed, then, is to check that the appropriate library is 3938 // imported and do a brsl to the proper function name. 3939 // frem # fmod(x, y): x - (x/y) * y 3940 // (Note: fmod(double, double), fmodf(float,float) 3941 // fsqrt? 3942 // fsin? 3943 // fcos? 3944 // Unimplemented SPU instruction space 3945 // floating reciprocal absolute square root estimate (frsqest) 3946 3947 // The following are probably just intrinsics 3948 // status and control register write 3949 // status and control register read 3950 3951 //-------------------------------------- 3952 // Floating Point Conversions 3953 // Signed conversions: 3954 def CSiFv4f32: 3955 CVTIntFPForm<0b0101101110, (outs VECREG:$rT), (ins VECREG:$rA), 3956 "csflt\t$rT, $rA, 0", SPrecFP, 3957 [(set (v4f32 VECREG:$rT), (sint_to_fp (v4i32 VECREG:$rA)))]>; 3958 3959 // Convert signed integer to floating point 3960 def CSiFf32 : 3961 CVTIntFPForm<0b0101101110, (outs R32FP:$rT), (ins R32C:$rA), 3962 "csflt\t$rT, $rA, 0", SPrecFP, 3963 [(set R32FP:$rT, (sint_to_fp R32C:$rA))]>; 3964 3965 // Convert unsigned into to float 3966 def CUiFv4f32 : 3967 CVTIntFPForm<0b1101101110, (outs VECREG:$rT), (ins VECREG:$rA), 3968 "cuflt\t$rT, $rA, 0", SPrecFP, 3969 [(set (v4f32 VECREG:$rT), (uint_to_fp (v4i32 VECREG:$rA)))]>; 3970 3971 def CUiFf32 : 3972 CVTIntFPForm<0b1101101110, (outs R32FP:$rT), (ins R32C:$rA), 3973 "cuflt\t$rT, $rA, 0", SPrecFP, 3974 [(set R32FP:$rT, (uint_to_fp R32C:$rA))]>; 3975 3976 // Convert float to unsigned int 3977 // Assume that scale = 0 3978 3979 def CFUiv4f32 : 3980 CVTIntFPForm<0b1101101110, (outs VECREG:$rT), (ins VECREG:$rA), 3981 "cfltu\t$rT, $rA, 0", SPrecFP, 3982 [(set (v4i32 VECREG:$rT), (fp_to_uint (v4f32 VECREG:$rA)))]>; 3983 3984 def CFUif32 : 3985 CVTIntFPForm<0b1101101110, (outs R32C:$rT), (ins R32FP:$rA), 3986 "cfltu\t$rT, $rA, 0", SPrecFP, 3987 [(set R32C:$rT, (fp_to_uint R32FP:$rA))]>; 3988 3989 // Convert float to signed int 3990 // Assume that scale = 0 3991 3992 def CFSiv4f32 : 3993 CVTIntFPForm<0b1101101110, (outs VECREG:$rT), (ins VECREG:$rA), 3994 "cflts\t$rT, $rA, 0", SPrecFP, 3995 [(set (v4i32 VECREG:$rT), (fp_to_sint (v4f32 VECREG:$rA)))]>; 3996 3997 def CFSif32 : 3998 CVTIntFPForm<0b1101101110, (outs R32C:$rT), (ins R32FP:$rA), 3999 "cflts\t$rT, $rA, 0", SPrecFP, 4000 [(set R32C:$rT, (fp_to_sint R32FP:$rA))]>; 4001 4002 //===----------------------------------------------------------------------==// 4003 // Single<->Double precision conversions 4004 //===----------------------------------------------------------------------==// 4005 4006 // NOTE: We use "vec" name suffix here to avoid confusion (e.g. input is a 4007 // v4f32, output is v2f64--which goes in the name?) 4008 4009 // Floating point extend single to double 4010 // NOTE: Not sure if passing in v4f32 to FESDvec is correct since it 4011 // operates on two double-word slots (i.e. 1st and 3rd fp numbers 4012 // are ignored). 4013 def FESDvec : 4014 RRForm_1<0b00011101110, (outs VECREG:$rT), (ins VECREG:$rA), 4015 "fesd\t$rT, $rA", SPrecFP, 4016 [/*(set (v2f64 VECREG:$rT), (fextend (v4f32 VECREG:$rA)))*/]>; 4017 4018 def FESDf32 : 4019 RRForm_1<0b00011101110, (outs R64FP:$rT), (ins R32FP:$rA), 4020 "fesd\t$rT, $rA", SPrecFP, 4021 [(set R64FP:$rT, (fextend R32FP:$rA))]>; 4022 4023 // Floating point round double to single 4024 //def FRDSvec : 4025 // RRForm_1<0b10011101110, (outs VECREG:$rT), (ins VECREG:$rA), 4026 // "frds\t$rT, $rA,", SPrecFP, 4027 // [(set (v4f32 R32FP:$rT), (fround (v2f64 R64FP:$rA)))]>; 4028 4029 def FRDSf64 : 4030 RRForm_1<0b10011101110, (outs R32FP:$rT), (ins R64FP:$rA), 4031 "frds\t$rT, $rA", SPrecFP, 4032 [(set R32FP:$rT, (fround R64FP:$rA))]>; 4033 4034 //ToDo include anyextend? 4035 4036 //===----------------------------------------------------------------------==// 4037 // Double precision floating point instructions 4038 //===----------------------------------------------------------------------==// 4039 def FAf64 : 4040 RRForm<0b00110011010, (outs R64FP:$rT), (ins R64FP:$rA, R64FP:$rB), 4041 "dfa\t$rT, $rA, $rB", DPrecFP, 4042 [(set R64FP:$rT, (fadd R64FP:$rA, R64FP:$rB))]>; 4043 4044 def FAv2f64 : 4045 RRForm<0b00110011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 4046 "dfa\t$rT, $rA, $rB", DPrecFP, 4047 [(set (v2f64 VECREG:$rT), (fadd (v2f64 VECREG:$rA), (v2f64 VECREG:$rB)))]>; 4048 4049 def FSf64 : 4050 RRForm<0b10100011010, (outs R64FP:$rT), (ins R64FP:$rA, R64FP:$rB), 4051 "dfs\t$rT, $rA, $rB", DPrecFP, 4052 [(set R64FP:$rT, (fsub R64FP:$rA, R64FP:$rB))]>; 4053 4054 def FSv2f64 : 4055 RRForm<0b10100011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 4056 "dfs\t$rT, $rA, $rB", DPrecFP, 4057 [(set (v2f64 VECREG:$rT), 4058 (fsub (v2f64 VECREG:$rA), (v2f64 VECREG:$rB)))]>; 4059 4060 def FMf64 : 4061 RRForm<0b01100011010, (outs R64FP:$rT), (ins R64FP:$rA, R64FP:$rB), 4062 "dfm\t$rT, $rA, $rB", DPrecFP, 4063 [(set R64FP:$rT, (fmul R64FP:$rA, R64FP:$rB))]>; 4064 4065 def FMv2f64: 4066 RRForm<0b00100011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 4067 "dfm\t$rT, $rA, $rB", DPrecFP, 4068 [(set (v2f64 VECREG:$rT), 4069 (fmul (v2f64 VECREG:$rA), (v2f64 VECREG:$rB)))]>; 4070 4071 def FMAf64: 4072 RRForm<0b00111010110, (outs R64FP:$rT), 4073 (ins R64FP:$rA, R64FP:$rB, R64FP:$rC), 4074 "dfma\t$rT, $rA, $rB", DPrecFP, 4075 [(set R64FP:$rT, (fadd R64FP:$rC, (fmul R64FP:$rA, R64FP:$rB)))]>, 4076 RegConstraint<"$rC = $rT">, 4077 NoEncode<"$rC">; 4078 4079 def FMAv2f64: 4080 RRForm<0b00111010110, (outs VECREG:$rT), 4081 (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), 4082 "dfma\t$rT, $rA, $rB", DPrecFP, 4083 [(set (v2f64 VECREG:$rT), 4084 (fadd (v2f64 VECREG:$rC), 4085 (fmul (v2f64 VECREG:$rA), (v2f64 VECREG:$rB))))]>, 4086 RegConstraint<"$rC = $rT">, 4087 NoEncode<"$rC">; 4088 4089 def FMSf64 : 4090 RRForm<0b10111010110, (outs R64FP:$rT), 4091 (ins R64FP:$rA, R64FP:$rB, R64FP:$rC), 4092 "dfms\t$rT, $rA, $rB", DPrecFP, 4093 [(set R64FP:$rT, (fsub (fmul R64FP:$rA, R64FP:$rB), R64FP:$rC))]>, 4094 RegConstraint<"$rC = $rT">, 4095 NoEncode<"$rC">; 4096 4097 def FMSv2f64 : 4098 RRForm<0b10111010110, (outs VECREG:$rT), 4099 (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), 4100 "dfms\t$rT, $rA, $rB", DPrecFP, 4101 [(set (v2f64 VECREG:$rT), 4102 (fsub (fmul (v2f64 VECREG:$rA), (v2f64 VECREG:$rB)), 4103 (v2f64 VECREG:$rC)))]>; 4104 4105 // DFNMS: - (a * b - c) 4106 // - (a * b) + c => c - (a * b) 4107 4108 class DFNMSInst<dag OOL, dag IOL, list<dag> pattern>: 4109 RRForm<0b01111010110, OOL, IOL, "dfnms\t$rT, $rA, $rB", 4110 DPrecFP, pattern>, 4111 RegConstraint<"$rC = $rT">, 4112 NoEncode<"$rC">; 4113 4114 class DFNMSVecInst<list<dag> pattern>: 4115 DFNMSInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), 4116 pattern>; 4117 4118 class DFNMSRegInst<list<dag> pattern>: 4119 DFNMSInst<(outs R64FP:$rT), (ins R64FP:$rA, R64FP:$rB, R64FP:$rC), 4120 pattern>; 4121 4122 multiclass DFMultiplySubtract 4123 { 4124 def v2f64 : DFNMSVecInst<[(set (v2f64 VECREG:$rT), 4125 (fsub (v2f64 VECREG:$rC), 4126 (fmul (v2f64 VECREG:$rA), 4127 (v2f64 VECREG:$rB))))]>; 4128 4129 def f64 : DFNMSRegInst<[(set R64FP:$rT, 4130 (fsub R64FP:$rC, 4131 (fmul R64FP:$rA, R64FP:$rB)))]>; 4132 } 4133 4134 defm DFNMS : DFMultiplySubtract; 4135 4136 // - (a * b + c) 4137 // - (a * b) - c 4138 def FNMAf64 : 4139 RRForm<0b11111010110, (outs R64FP:$rT), 4140 (ins R64FP:$rA, R64FP:$rB, R64FP:$rC), 4141 "dfnma\t$rT, $rA, $rB", DPrecFP, 4142 [(set R64FP:$rT, (fneg (fadd R64FP:$rC, (fmul R64FP:$rA, R64FP:$rB))))]>, 4143 RegConstraint<"$rC = $rT">, 4144 NoEncode<"$rC">; 4145 4146 def FNMAv2f64 : 4147 RRForm<0b11111010110, (outs VECREG:$rT), 4148 (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), 4149 "dfnma\t$rT, $rA, $rB", DPrecFP, 4150 [(set (v2f64 VECREG:$rT), 4151 (fneg (fadd (v2f64 VECREG:$rC), 4152 (fmul (v2f64 VECREG:$rA), 4153 (v2f64 VECREG:$rB)))))]>, 4154 RegConstraint<"$rC = $rT">, 4155 NoEncode<"$rC">; 4156 4157 //===----------------------------------------------------------------------==// 4158 // Floating point negation and absolute value 4159 //===----------------------------------------------------------------------==// 4160 4161 def : Pat<(fneg (v4f32 VECREG:$rA)), 4162 (XORfnegvec (v4f32 VECREG:$rA), 4163 (v4f32 (ILHUv4i32 0x8000)))>; 4164 4165 def : Pat<(fneg R32FP:$rA), 4166 (XORfneg32 R32FP:$rA, (ILHUr32 0x8000))>; 4167 4168 // Floating point absolute value 4169 // Note: f64 fabs is custom-selected. 4170 4171 def : Pat<(fabs R32FP:$rA), 4172 (ANDfabs32 R32FP:$rA, (IOHLr32 (ILHUr32 0x7fff), 0xffff))>; 4173 4174 def : Pat<(fabs (v4f32 VECREG:$rA)), 4175 (ANDfabsvec (v4f32 VECREG:$rA), 4176 (IOHLv4i32 (ILHUv4i32 0x7fff), 0xffff))>; 4177 4178 //===----------------------------------------------------------------------===// 4179 // Hint for branch instructions: 4180 //===----------------------------------------------------------------------===// 4181 def HBRA : 4182 HBI16Form<0b0001001,(ins hbrtarget:$brinst, brtarget:$btarg), "hbra\t$brinst, $btarg">; 4183 4184 //===----------------------------------------------------------------------===// 4185 // Execution, Load NOP (execute NOPs belong in even pipeline, load NOPs belong 4186 // in the odd pipeline) 4187 //===----------------------------------------------------------------------===// 4188 4189 def ENOP : SPUInstr<(outs), (ins), "nop", ExecNOP> { 4190 let Pattern = []; 4191 4192 let Inst{0-10} = 0b10000000010; 4193 let Inst{11-17} = 0; 4194 let Inst{18-24} = 0; 4195 let Inst{25-31} = 0; 4196 } 4197 4198 def LNOP : SPUInstr<(outs), (ins), "lnop", LoadNOP> { 4199 let Pattern = []; 4200 4201 let Inst{0-10} = 0b10000000000; 4202 let Inst{11-17} = 0; 4203 let Inst{18-24} = 0; 4204 let Inst{25-31} = 0; 4205 } 4206 4207 //===----------------------------------------------------------------------===// 4208 // Bit conversions (type conversions between vector/packed types) 4209 // NOTE: Promotions are handled using the XS* instructions. 4210 //===----------------------------------------------------------------------===// 4211 def : Pat<(v16i8 (bitconvert (v8i16 VECREG:$src))), (v16i8 VECREG:$src)>; 4212 def : Pat<(v16i8 (bitconvert (v4i32 VECREG:$src))), (v16i8 VECREG:$src)>; 4213 def : Pat<(v16i8 (bitconvert (v2i64 VECREG:$src))), (v16i8 VECREG:$src)>; 4214 def : Pat<(v16i8 (bitconvert (v4f32 VECREG:$src))), (v16i8 VECREG:$src)>; 4215 def : Pat<(v16i8 (bitconvert (v2f64 VECREG:$src))), (v16i8 VECREG:$src)>; 4216 4217 def : Pat<(v8i16 (bitconvert (v16i8 VECREG:$src))), (v8i16 VECREG:$src)>; 4218 def : Pat<(v8i16 (bitconvert (v4i32 VECREG:$src))), (v8i16 VECREG:$src)>; 4219 def : Pat<(v8i16 (bitconvert (v2i64 VECREG:$src))), (v8i16 VECREG:$src)>; 4220 def : Pat<(v8i16 (bitconvert (v4f32 VECREG:$src))), (v8i16 VECREG:$src)>; 4221 def : Pat<(v8i16 (bitconvert (v2f64 VECREG:$src))), (v8i16 VECREG:$src)>; 4222 4223 def : Pat<(v4i32 (bitconvert (v16i8 VECREG:$src))), (v4i32 VECREG:$src)>; 4224 def : Pat<(v4i32 (bitconvert (v8i16 VECREG:$src))), (v4i32 VECREG:$src)>; 4225 def : Pat<(v4i32 (bitconvert (v2i64 VECREG:$src))), (v4i32 VECREG:$src)>; 4226 def : Pat<(v4i32 (bitconvert (v4f32 VECREG:$src))), (v4i32 VECREG:$src)>; 4227 def : Pat<(v4i32 (bitconvert (v2f64 VECREG:$src))), (v4i32 VECREG:$src)>; 4228 4229 def : Pat<(v2i64 (bitconvert (v16i8 VECREG:$src))), (v2i64 VECREG:$src)>; 4230 def : Pat<(v2i64 (bitconvert (v8i16 VECREG:$src))), (v2i64 VECREG:$src)>; 4231 def : Pat<(v2i64 (bitconvert (v4i32 VECREG:$src))), (v2i64 VECREG:$src)>; 4232 def : Pat<(v2i64 (bitconvert (v4f32 VECREG:$src))), (v2i64 VECREG:$src)>; 4233 def : Pat<(v2i64 (bitconvert (v2f64 VECREG:$src))), (v2i64 VECREG:$src)>; 4234 4235 def : Pat<(v4f32 (bitconvert (v16i8 VECREG:$src))), (v4f32 VECREG:$src)>; 4236 def : Pat<(v4f32 (bitconvert (v8i16 VECREG:$src))), (v4f32 VECREG:$src)>; 4237 def : Pat<(v4f32 (bitconvert (v2i64 VECREG:$src))), (v4f32 VECREG:$src)>; 4238 def : Pat<(v4f32 (bitconvert (v4i32 VECREG:$src))), (v4f32 VECREG:$src)>; 4239 def : Pat<(v4f32 (bitconvert (v2f64 VECREG:$src))), (v4f32 VECREG:$src)>; 4240 4241 def : Pat<(v2f64 (bitconvert (v16i8 VECREG:$src))), (v2f64 VECREG:$src)>; 4242 def : Pat<(v2f64 (bitconvert (v8i16 VECREG:$src))), (v2f64 VECREG:$src)>; 4243 def : Pat<(v2f64 (bitconvert (v4i32 VECREG:$src))), (v2f64 VECREG:$src)>; 4244 def : Pat<(v2f64 (bitconvert (v2i64 VECREG:$src))), (v2f64 VECREG:$src)>; 4245 def : Pat<(v2f64 (bitconvert (v4f32 VECREG:$src))), (v2f64 VECREG:$src)>; 4246 4247 def : Pat<(i128 (bitconvert (v16i8 VECREG:$src))), 4248 (COPY_TO_REGCLASS VECREG:$src, GPRC)>; 4249 def : Pat<(i128 (bitconvert (v8i16 VECREG:$src))), 4250 (COPY_TO_REGCLASS VECREG:$src, GPRC)>; 4251 def : Pat<(i128 (bitconvert (v4i32 VECREG:$src))), 4252 (COPY_TO_REGCLASS VECREG:$src, GPRC)>; 4253 def : Pat<(i128 (bitconvert (v2i64 VECREG:$src))), 4254 (COPY_TO_REGCLASS VECREG:$src, GPRC)>; 4255 def : Pat<(i128 (bitconvert (v4f32 VECREG:$src))), 4256 (COPY_TO_REGCLASS VECREG:$src, GPRC)>; 4257 def : Pat<(i128 (bitconvert (v2f64 VECREG:$src))), 4258 (COPY_TO_REGCLASS VECREG:$src, GPRC)>; 4259 4260 def : Pat<(v16i8 (bitconvert (i128 GPRC:$src))), 4261 (v16i8 (COPY_TO_REGCLASS GPRC:$src, VECREG))>; 4262 def : Pat<(v8i16 (bitconvert (i128 GPRC:$src))), 4263 (v8i16 (COPY_TO_REGCLASS GPRC:$src, VECREG))>; 4264 def : Pat<(v4i32 (bitconvert (i128 GPRC:$src))), 4265 (v4i32 (COPY_TO_REGCLASS GPRC:$src, VECREG))>; 4266 def : Pat<(v2i64 (bitconvert (i128 GPRC:$src))), 4267 (v2i64 (COPY_TO_REGCLASS GPRC:$src, VECREG))>; 4268 def : Pat<(v4f32 (bitconvert (i128 GPRC:$src))), 4269 (v4f32 (COPY_TO_REGCLASS GPRC:$src, VECREG))>; 4270 def : Pat<(v2f64 (bitconvert (i128 GPRC:$src))), 4271 (v2f64 (COPY_TO_REGCLASS GPRC:$src, VECREG))>; 4272 4273 def : Pat<(i32 (bitconvert R32FP:$rA)), 4274 (COPY_TO_REGCLASS R32FP:$rA, R32C)>; 4275 4276 def : Pat<(f32 (bitconvert R32C:$rA)), 4277 (COPY_TO_REGCLASS R32C:$rA, R32FP)>; 4278 4279 def : Pat<(i64 (bitconvert R64FP:$rA)), 4280 (COPY_TO_REGCLASS R64FP:$rA, R64C)>; 4281 4282 def : Pat<(f64 (bitconvert R64C:$rA)), 4283 (COPY_TO_REGCLASS R64C:$rA, R64FP)>; 4284 4285 4286 //===----------------------------------------------------------------------===// 4287 // Instruction patterns: 4288 //===----------------------------------------------------------------------===// 4289 4290 // General 32-bit constants: 4291 def : Pat<(i32 imm:$imm), 4292 (IOHLr32 (ILHUr32 (HI16 imm:$imm)), (LO16 imm:$imm))>; 4293 4294 // Single precision float constants: 4295 def : Pat<(f32 fpimm:$imm), 4296 (IOHLf32 (ILHUf32 (HI16_f32 fpimm:$imm)), (LO16_f32 fpimm:$imm))>; 4297 4298 // General constant 32-bit vectors 4299 def : Pat<(v4i32 v4i32Imm:$imm), 4300 (IOHLv4i32 (v4i32 (ILHUv4i32 (HI16_vec v4i32Imm:$imm))), 4301 (LO16_vec v4i32Imm:$imm))>; 4302 4303 // 8-bit constants 4304 def : Pat<(i8 imm:$imm), 4305 (ILHr8 imm:$imm)>; 4306 4307 //===----------------------------------------------------------------------===// 4308 // Zero/Any/Sign extensions 4309 //===----------------------------------------------------------------------===// 4310 4311 // sext 8->32: Sign extend bytes to words 4312 def : Pat<(sext_inreg R32C:$rSrc, i8), 4313 (XSHWr32 (XSBHr32 R32C:$rSrc))>; 4314 4315 def : Pat<(i32 (sext R8C:$rSrc)), 4316 (XSHWr16 (XSBHr8 R8C:$rSrc))>; 4317 4318 // sext 8->64: Sign extend bytes to double word 4319 def : Pat<(sext_inreg R64C:$rSrc, i8), 4320 (XSWDr64_inreg (XSHWr64 (XSBHr64 R64C:$rSrc)))>; 4321 4322 def : Pat<(i64 (sext R8C:$rSrc)), 4323 (XSWDr64 (XSHWr16 (XSBHr8 R8C:$rSrc)))>; 4324 4325 // zext 8->16: Zero extend bytes to halfwords 4326 def : Pat<(i16 (zext R8C:$rSrc)), 4327 (ANDHIi8i16 R8C:$rSrc, 0xff)>; 4328 4329 // zext 8->32: Zero extend bytes to words 4330 def : Pat<(i32 (zext R8C:$rSrc)), 4331 (ANDIi8i32 R8C:$rSrc, 0xff)>; 4332 4333 // zext 8->64: Zero extend bytes to double words 4334 def : Pat<(i64 (zext R8C:$rSrc)), 4335 (COPY_TO_REGCLASS (SELBv4i32 (ROTQMBYv4i32 4336 (COPY_TO_REGCLASS 4337 (ANDIi8i32 R8C:$rSrc,0xff), VECREG), 4338 0x4), 4339 (ILv4i32 0x0), 4340 (FSMBIv4i32 0x0f0f)), R64C)>; 4341 4342 // anyext 8->16: Extend 8->16 bits, irrespective of sign, preserves high bits 4343 def : Pat<(i16 (anyext R8C:$rSrc)), 4344 (ORHIi8i16 R8C:$rSrc, 0)>; 4345 4346 // anyext 8->32: Extend 8->32 bits, irrespective of sign, preserves high bits 4347 def : Pat<(i32 (anyext R8C:$rSrc)), 4348 (COPY_TO_REGCLASS R8C:$rSrc, R32C)>; 4349 4350 // sext 16->64: Sign extend halfword to double word 4351 def : Pat<(sext_inreg R64C:$rSrc, i16), 4352 (XSWDr64_inreg (XSHWr64 R64C:$rSrc))>; 4353 4354 def : Pat<(sext R16C:$rSrc), 4355 (XSWDr64 (XSHWr16 R16C:$rSrc))>; 4356 4357 // zext 16->32: Zero extend halfwords to words 4358 def : Pat<(i32 (zext R16C:$rSrc)), 4359 (ANDi16i32 R16C:$rSrc, (ILAr32 0xffff))>; 4360 4361 def : Pat<(i32 (zext (and R16C:$rSrc, 0xf))), 4362 (ANDIi16i32 R16C:$rSrc, 0xf)>; 4363 4364 def : Pat<(i32 (zext (and R16C:$rSrc, 0xff))), 4365 (ANDIi16i32 R16C:$rSrc, 0xff)>; 4366 4367 def : Pat<(i32 (zext (and R16C:$rSrc, 0xfff))), 4368 (ANDIi16i32 R16C:$rSrc, 0xfff)>; 4369 4370 // anyext 16->32: Extend 16->32 bits, irrespective of sign 4371 def : Pat<(i32 (anyext R16C:$rSrc)), 4372 (COPY_TO_REGCLASS R16C:$rSrc, R32C)>; 4373 4374 //===----------------------------------------------------------------------===// 4375 // Truncates: 4376 // These truncates are for the SPU's supported types (i8, i16, i32). i64 and 4377 // above are custom lowered. 4378 //===----------------------------------------------------------------------===// 4379 4380 def : Pat<(i8 (trunc GPRC:$src)), 4381 (COPY_TO_REGCLASS 4382 (SHUFBgprc GPRC:$src, GPRC:$src, 4383 (IOHLv4i32 (ILHUv4i32 0x0f0f), 0x0f0f)), R8C)>; 4384 4385 def : Pat<(i8 (trunc R64C:$src)), 4386 (COPY_TO_REGCLASS 4387 (SHUFBv2i64_m32 4388 (COPY_TO_REGCLASS R64C:$src, VECREG), 4389 (COPY_TO_REGCLASS R64C:$src, VECREG), 4390 (IOHLv4i32 (ILHUv4i32 0x0707), 0x0707)), R8C)>; 4391 4392 def : Pat<(i8 (trunc R32C:$src)), 4393 (COPY_TO_REGCLASS 4394 (SHUFBv4i32_m32 4395 (COPY_TO_REGCLASS R32C:$src, VECREG), 4396 (COPY_TO_REGCLASS R32C:$src, VECREG), 4397 (IOHLv4i32 (ILHUv4i32 0x0303), 0x0303)), R8C)>; 4398 4399 def : Pat<(i8 (trunc R16C:$src)), 4400 (COPY_TO_REGCLASS 4401 (SHUFBv4i32_m32 4402 (COPY_TO_REGCLASS R16C:$src, VECREG), 4403 (COPY_TO_REGCLASS R16C:$src, VECREG), 4404 (IOHLv4i32 (ILHUv4i32 0x0303), 0x0303)), R8C)>; 4405 4406 def : Pat<(i16 (trunc GPRC:$src)), 4407 (COPY_TO_REGCLASS 4408 (SHUFBgprc GPRC:$src, GPRC:$src, 4409 (IOHLv4i32 (ILHUv4i32 0x0e0f), 0x0e0f)), R16C)>; 4410 4411 def : Pat<(i16 (trunc R64C:$src)), 4412 (COPY_TO_REGCLASS 4413 (SHUFBv2i64_m32 4414 (COPY_TO_REGCLASS R64C:$src, VECREG), 4415 (COPY_TO_REGCLASS R64C:$src, VECREG), 4416 (IOHLv4i32 (ILHUv4i32 0x0607), 0x0607)), R16C)>; 4417 4418 def : Pat<(i16 (trunc R32C:$src)), 4419 (COPY_TO_REGCLASS 4420 (SHUFBv4i32_m32 4421 (COPY_TO_REGCLASS R32C:$src, VECREG), 4422 (COPY_TO_REGCLASS R32C:$src, VECREG), 4423 (IOHLv4i32 (ILHUv4i32 0x0203), 0x0203)), R16C)>; 4424 4425 def : Pat<(i32 (trunc GPRC:$src)), 4426 (COPY_TO_REGCLASS 4427 (SHUFBgprc GPRC:$src, GPRC:$src, 4428 (IOHLv4i32 (ILHUv4i32 0x0c0d), 0x0e0f)), R32C)>; 4429 4430 def : Pat<(i32 (trunc R64C:$src)), 4431 (COPY_TO_REGCLASS 4432 (SHUFBv2i64_m32 4433 (COPY_TO_REGCLASS R64C:$src, VECREG), 4434 (COPY_TO_REGCLASS R64C:$src, VECREG), 4435 (IOHLv4i32 (ILHUv4i32 0x0405), 0x0607)), R32C)>; 4436 4437 //===----------------------------------------------------------------------===// 4438 // Address generation: SPU, like PPC, has to split addresses into high and 4439 // low parts in order to load them into a register. 4440 //===----------------------------------------------------------------------===// 4441 4442 def : Pat<(SPUaform tglobaladdr:$in, 0), (ILAlsa tglobaladdr:$in)>; 4443 def : Pat<(SPUaform texternalsym:$in, 0), (ILAlsa texternalsym:$in)>; 4444 def : Pat<(SPUaform tjumptable:$in, 0), (ILAlsa tjumptable:$in)>; 4445 def : Pat<(SPUaform tconstpool:$in, 0), (ILAlsa tconstpool:$in)>; 4446 4447 def : Pat<(SPUindirect (SPUhi tglobaladdr:$in, 0), 4448 (SPUlo tglobaladdr:$in, 0)), 4449 (IOHLlo (ILHUhi tglobaladdr:$in), tglobaladdr:$in)>; 4450 4451 def : Pat<(SPUindirect (SPUhi texternalsym:$in, 0), 4452 (SPUlo texternalsym:$in, 0)), 4453 (IOHLlo (ILHUhi texternalsym:$in), texternalsym:$in)>; 4454 4455 def : Pat<(SPUindirect (SPUhi tjumptable:$in, 0), 4456 (SPUlo tjumptable:$in, 0)), 4457 (IOHLlo (ILHUhi tjumptable:$in), tjumptable:$in)>; 4458 4459 def : Pat<(SPUindirect (SPUhi tconstpool:$in, 0), 4460 (SPUlo tconstpool:$in, 0)), 4461 (IOHLlo (ILHUhi tconstpool:$in), tconstpool:$in)>; 4462 4463 def : Pat<(add (SPUhi tglobaladdr:$in, 0), (SPUlo tglobaladdr:$in, 0)), 4464 (IOHLlo (ILHUhi tglobaladdr:$in), tglobaladdr:$in)>; 4465 4466 def : Pat<(add (SPUhi texternalsym:$in, 0), (SPUlo texternalsym:$in, 0)), 4467 (IOHLlo (ILHUhi texternalsym:$in), texternalsym:$in)>; 4468 4469 def : Pat<(add (SPUhi tjumptable:$in, 0), (SPUlo tjumptable:$in, 0)), 4470 (IOHLlo (ILHUhi tjumptable:$in), tjumptable:$in)>; 4471 4472 def : Pat<(add (SPUhi tconstpool:$in, 0), (SPUlo tconstpool:$in, 0)), 4473 (IOHLlo (ILHUhi tconstpool:$in), tconstpool:$in)>; 4474 4475 // Intrinsics: 4476 include "CellSDKIntrinsics.td" 4477 // Various math operator instruction sequences 4478 include "SPUMathInstr.td" 4479 // 64-bit "instructions"/support 4480 include "SPU64InstrInfo.td" 4481 // 128-bit "instructions"/support 4482 include "SPU128InstrInfo.td" 4483