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 24let 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 43let 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//===----------------------------------------------------------------------===// 156class 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 163class 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 170multiclass 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 188class 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 194class 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 200multiclass 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 218class 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 225class 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 232multiclass 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 250defm STQD : StoreDForms; 251defm STQA : StoreAForms; 252defm STQX : StoreXForms; 253 254/* Store quadword, PC relative: Not much use at this point in time. Might 255 be useful for relocatable code. 256def 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 265def 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 269def 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 273def 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 277def 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 281def 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 285def 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 289def 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 293def 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 297def 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 301def 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 305def 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 309def 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 317def 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 322def 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") 329def 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 336class ILInst<dag OOL, dag IOL, list<dag> pattern>: 337 RI16Form<0b100000010, OOL, IOL, "il\t$rT, $val", 338 ImmLoad, pattern>; 339 340class ILVecInst<ValueType vectype, Operand immtype, PatLeaf xform>: 341 ILInst<(outs VECREG:$rT), (ins immtype:$val), 342 [(set (vectype VECREG:$rT), (vectype xform:$val))]>; 343 344class ILRegInst<RegisterClass rclass, Operand immtype, PatLeaf xform>: 345 ILInst<(outs rclass:$rT), (ins immtype:$val), 346 [(set rclass:$rT, xform:$val)]>; 347 348multiclass 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 361defm IL : ImmediateLoad; 362 363class ILHUInst<dag OOL, dag IOL, list<dag> pattern>: 364 RI16Form<0b010000010, OOL, IOL, "ilhu\t$rT, $val", 365 ImmLoad, pattern>; 366 367class ILHUVecInst<ValueType vectype, Operand immtype, PatLeaf xform>: 368 ILHUInst<(outs VECREG:$rT), (ins immtype:$val), 369 [(set (vectype VECREG:$rT), (vectype xform:$val))]>; 370 371class ILHURegInst<RegisterClass rclass, Operand immtype, PatLeaf xform>: 372 ILHUInst<(outs rclass:$rT), (ins immtype:$val), 373 [(set rclass:$rT, xform:$val)]>; 374 375multiclass 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 390defm 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 395class ILAInst<dag OOL, dag IOL, list<dag> pattern>: 396 RI18Form<0b1000010, OOL, IOL, "ila\t$rT, $val", 397 LoadNOP, pattern>; 398 399class ILAVecInst<ValueType vectype, Operand immtype, PatLeaf xform>: 400 ILAInst<(outs VECREG:$rT), (ins immtype:$val), 401 [(set (vectype VECREG:$rT), (vectype xform:$val))]>; 402 403class ILARegInst<RegisterClass rclass, Operand immtype, PatLeaf xform>: 404 ILAInst<(outs rclass:$rT), (ins immtype:$val), 405 [(set rclass:$rT, xform:$val)]>; 406 407multiclass 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 424defm 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 431class 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 437class IOHLVecInst<ValueType vectype, Operand immtype /* , PatLeaf xform */>: 438 IOHLInst<(outs VECREG:$rT), (ins VECREG:$rS, immtype:$val), 439 [/* no pattern */]>; 440 441class IOHLRegInst<RegisterClass rclass, Operand immtype /* , PatLeaf xform */>: 442 IOHLInst<(outs rclass:$rT), (ins rclass:$rS, immtype:$val), 443 [/* no pattern */]>; 444 445multiclass 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 456defm IOHL: ImmOrHalfwordLower; 457 458// Form select mask for bytes using immediate, used in conjunction with the 459// SELB instruction: 460 461class 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 467multiclass FormSelectMaskBytesImm 468{ 469 def v16i8: FSMBIVec<v16i8>; 470 def v8i16: FSMBIVec<v8i16>; 471 def v4i32: FSMBIVec<v4i32>; 472 def v2i64: FSMBIVec<v2i64>; 473} 474 475defm FSMBI : FormSelectMaskBytesImm; 476 477// fsmb: Form select mask for bytes. N.B. Input operand, $rA, is 16-bits 478class FSMBInst<dag OOL, dag IOL, list<dag> pattern>: 479 RRForm_1<0b01101101100, OOL, IOL, "fsmb\t$rT, $rA", SelectOp, 480 pattern>; 481 482class FSMBRegInst<RegisterClass rclass, ValueType vectype>: 483 FSMBInst<(outs VECREG:$rT), (ins rclass:$rA), 484 [(set (vectype VECREG:$rT), (SPUselmask rclass:$rA))]>; 485 486class FSMBVecInst<ValueType vectype>: 487 FSMBInst<(outs VECREG:$rT), (ins VECREG:$rA), 488 [(set (vectype VECREG:$rT), 489 (SPUselmask (vectype VECREG:$rA)))]>; 490 491multiclass FormSelectMaskBits { 492 def v16i8_r16: FSMBRegInst<R16C, v16i8>; 493 def v16i8: FSMBVecInst<v16i8>; 494} 495 496defm 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 501class FSMHInst<dag OOL, dag IOL, list<dag> pattern>: 502 RRForm_1<0b10101101100, OOL, IOL, "fsmh\t$rT, $rA", SelectOp, 503 pattern>; 504 505class FSMHRegInst<RegisterClass rclass, ValueType vectype>: 506 FSMHInst<(outs VECREG:$rT), (ins rclass:$rA), 507 [(set (vectype VECREG:$rT), (SPUselmask rclass:$rA))]>; 508 509class FSMHVecInst<ValueType vectype>: 510 FSMHInst<(outs VECREG:$rT), (ins VECREG:$rA), 511 [(set (vectype VECREG:$rT), 512 (SPUselmask (vectype VECREG:$rA)))]>; 513 514multiclass FormSelectMaskHalfword { 515 def v8i16_r16: FSMHRegInst<R16C, v8i16>; 516 def v8i16: FSMHVecInst<v8i16>; 517} 518 519defm 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 524class FSMInst<dag OOL, dag IOL, list<dag> pattern>: 525 RRForm_1<0b00101101100, OOL, IOL, "fsm\t$rT, $rA", SelectOp, 526 pattern>; 527 528class FSMRegInst<ValueType vectype, RegisterClass rclass>: 529 FSMInst<(outs VECREG:$rT), (ins rclass:$rA), 530 [(set (vectype VECREG:$rT), (SPUselmask rclass:$rA))]>; 531 532class FSMVecInst<ValueType vectype>: 533 FSMInst<(outs VECREG:$rT), (ins VECREG:$rA), 534 [(set (vectype VECREG:$rT), (SPUselmask (vectype VECREG:$rA)))]>; 535 536multiclass FormSelectMaskWord { 537 def v4i32: FSMVecInst<v4i32>; 538 539 def r32 : FSMRegInst<v4i32, R32C>; 540 def r16 : FSMRegInst<v4i32, R16C>; 541} 542 543defm FSM : FormSelectMaskWord; 544 545// Special case when used for i64 math operations 546multiclass FormSelectMaskWord64 { 547 def r32 : FSMRegInst<v2i64, R32C>; 548 def r16 : FSMRegInst<v2i64, R16C>; 549} 550 551defm FSM64 : FormSelectMaskWord64; 552 553//===----------------------------------------------------------------------===// 554// Integer and Logical Operations: 555//===----------------------------------------------------------------------===// 556 557def 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 562def : Pat<(add (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)), 563 (AHv8i16 VECREG:$rA, VECREG:$rB)>; 564 565def 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 570def 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 576def 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 583class AInst<dag OOL, dag IOL, list<dag> pattern>: 584 RRForm<0b00000011000, OOL, IOL, 585 "a\t$rT, $rA, $rB", IntegerOp, 586 pattern>; 587 588class 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 593class ARegInst<RegisterClass rclass>: 594 AInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), 595 [(set rclass:$rT, (add rclass:$rA, rclass:$rB))]>; 596 597multiclass AddInstruction { 598 def v4i32: AVecInst<v4i32>; 599 def v16i8: AVecInst<v16i8>; 600 def r32: ARegInst<R32C>; 601} 602 603defm A : AddInstruction; 604 605class AIInst<dag OOL, dag IOL, list<dag> pattern>: 606 RI10Form<0b00111000, OOL, IOL, 607 "ai\t$rT, $rA, $val", IntegerOp, 608 pattern>; 609 610class 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 614class AIFPVecInst<ValueType vectype, PatLeaf immpred>: 615 AIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), 616 [/* no pattern */]>; 617 618class 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: 623class AIFPInst<RegisterClass rclass, PatLeaf immpred>: 624 AIInst<(outs rclass:$rT), (ins rclass:$rA, s10imm_i32:$val), 625 [/* no pattern */]>; 626 627multiclass 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 636defm AI : AddImmediate; 637 638def 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 644def 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 649def 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 655def 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 659def 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 665def 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 669def 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 675def 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. 681class ADDXInst<dag OOL, dag IOL, list<dag> pattern>: 682 RRForm<0b00000010110, OOL, IOL, 683 "addx\t$rT, $rA, $rB", 684 IntegerOp, pattern>; 685 686class 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 693class 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 700multiclass AddExtended { 701 def v2i64 : ADDXVecInst<v2i64>; 702 def v4i32 : ADDXVecInst<v4i32>; 703 def r64 : ADDXRegInst<R64C>; 704 def r32 : ADDXRegInst<R32C>; 705} 706 707defm ADDX : AddExtended; 708 709// CG: Generate carry for add 710class CGInst<dag OOL, dag IOL, list<dag> pattern>: 711 RRForm<0b01000011000, OOL, IOL, 712 "cg\t$rT, $rA, $rB", 713 IntegerOp, pattern>; 714 715class CGVecInst<ValueType vectype>: 716 CGInst<(outs VECREG:$rT), 717 (ins VECREG:$rA, VECREG:$rB), 718 [/* no pattern */]>; 719 720class CGRegInst<RegisterClass rclass>: 721 CGInst<(outs rclass:$rT), 722 (ins rclass:$rA, rclass:$rB), 723 [/* no pattern */]>; 724 725multiclass CarryGenerate { 726 def v2i64 : CGVecInst<v2i64>; 727 def v4i32 : CGVecInst<v4i32>; 728 def r64 : CGRegInst<R64C>; 729 def r32 : CGRegInst<R32C>; 730} 731 732defm CG : CarryGenerate; 733 734// SFX: Subract from, extended. This is used in conjunction with BG to subtract 735// with carry (borrow, in this case) 736class SFXInst<dag OOL, dag IOL, list<dag> pattern>: 737 RRForm<0b10000010110, OOL, IOL, 738 "sfx\t$rT, $rA, $rB", 739 IntegerOp, pattern>; 740 741class 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 748class 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 755multiclass SubtractExtended { 756 def v2i64 : SFXVecInst<v2i64>; 757 def v4i32 : SFXVecInst<v4i32>; 758 def r64 : SFXRegInst<R64C>; 759 def r32 : SFXRegInst<R32C>; 760} 761 762defm SFX : SubtractExtended; 763 764// BG: only available in vector form, doesn't match a pattern. 765class BGInst<dag OOL, dag IOL, list<dag> pattern>: 766 RRForm<0b01000010000, OOL, IOL, 767 "bg\t$rT, $rA, $rB", 768 IntegerOp, pattern>; 769 770class BGVecInst<ValueType vectype>: 771 BGInst<(outs VECREG:$rT), 772 (ins VECREG:$rA, VECREG:$rB), 773 [/* no pattern */]>; 774 775class BGRegInst<RegisterClass rclass>: 776 BGInst<(outs rclass:$rT), 777 (ins rclass:$rA, rclass:$rB), 778 [/* no pattern */]>; 779 780multiclass BorrowGenerate { 781 def v4i32 : BGVecInst<v4i32>; 782 def v2i64 : BGVecInst<v2i64>; 783 def r64 : BGRegInst<R64C>; 784 def r32 : BGRegInst<R32C>; 785} 786 787defm BG : BorrowGenerate; 788 789// BGX: Borrow generate, extended. 790def 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 801def MPYv8i16: 802 RRForm<0b00100011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 803 "mpy\t$rT, $rA, $rB", IntegerMulDiv, 804 [/* no pattern */]>; 805 806def 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 813class MPYUInst<dag OOL, dag IOL, list<dag> pattern>: 814 RRForm<0b00110011110, OOL, IOL, 815 "mpyu\t$rT, $rA, $rB", IntegerMulDiv, 816 pattern>; 817 818def MPYUv4i32: 819 MPYUInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 820 [/* no pattern */]>; 821 822def MPYUr16: 823 MPYUInst<(outs R32C:$rT), (ins R16C:$rA, R16C:$rB), 824 [(set R32C:$rT, (mul (zext R16C:$rA), (zext R16C:$rB)))]>; 825 826def MPYUr32: 827 MPYUInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB), 828 [/* no pattern */]>; 829 830// mpyi: multiply 16 x s10imm -> 32 result. 831 832class MPYIInst<dag OOL, dag IOL, list<dag> pattern>: 833 RI10Form<0b00101110, OOL, IOL, 834 "mpyi\t$rT, $rA, $val", IntegerMulDiv, 835 pattern>; 836 837def MPYIvec: 838 MPYIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), 839 [(set (v8i16 VECREG:$rT), 840 (mul (v8i16 VECREG:$rA), v8i16SExt10Imm:$val))]>; 841 842def 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 849class MPYUIInst<dag OOL, dag IOL, list<dag> pattern>: 850 RI10Form<0b10101110, OOL, IOL, 851 "mpyui\t$rT, $rA, $val", IntegerMulDiv, 852 pattern>; 853 854def MPYUIvec: 855 MPYUIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), 856 []>; 857 858def MPYUIr16: 859 MPYUIInst<(outs R16C:$rT), (ins R16C:$rA, s10imm:$val), 860 []>; 861 862// mpya: 16 x 16 + 16 -> 32 bit result 863class MPYAInst<dag OOL, dag IOL, list<dag> pattern>: 864 RRRForm<0b0011, OOL, IOL, 865 "mpya\t$rT, $rA, $rB, $rC", IntegerMulDiv, 866 pattern>; 867 868def 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 875def 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 880def 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 885def 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 892class MPYHInst<dag OOL, dag IOL, list<dag> pattern>: 893 RRForm<0b10100011110, OOL, IOL, 894 "mpyh\t$rT, $rA, $rB", IntegerMulDiv, 895 pattern>; 896 897def MPYHv4i32: 898 MPYHInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 899 [/* no pattern */]>; 900 901def 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 908class MPYSInst<dag OOL, dag IOL>: 909 RRForm<0b11100011110, OOL, IOL, 910 "mpys\t$rT, $rA, $rB", IntegerMulDiv, 911 [/* no pattern */]>; 912 913def MPYSv4i32: 914 MPYSInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB)>; 915 916def 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 922class MPYHHInst<dag OOL, dag IOL>: 923 RRForm<0b01100011110, OOL, IOL, 924 "mpyhh\t$rT, $rA, $rB", IntegerMulDiv, 925 [/* no pattern */]>; 926 927def MPYHHv8i16: 928 MPYHHInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB)>; 929 930def MPYHHr32: 931 MPYHHInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB)>; 932 933// mpyhha: Multiply high-high, add to $rT: 934 935class MPYHHAInst<dag OOL, dag IOL>: 936 RRForm<0b01100010110, OOL, IOL, 937 "mpyhha\t$rT, $rA, $rB", IntegerMulDiv, 938 [/* no pattern */]>; 939 940def MPYHHAvec: 941 MPYHHAInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB)>; 942 943def 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 954class MPYHHUInst<dag OOL, dag IOL>: 955 RRForm<0b01110011110, OOL, IOL, 956 "mpyhhu\t$rT, $rA, $rB", IntegerMulDiv, 957 [/* no pattern */]>; 958 959def MPYHHUv4i32: 960 MPYHHUInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB)>; 961 962def MPYHHUr32: 963 MPYHHUInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB)>; 964 965// mpyhhau: Multiply high-high, unsigned 966 967class MPYHHAUInst<dag OOL, dag IOL>: 968 RRForm<0b01110010110, OOL, IOL, 969 "mpyhhau\t$rT, $rA, $rB", IntegerMulDiv, 970 [/* no pattern */]>; 971 972def MPYHHAUvec: 973 MPYHHAUInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB)>; 974 975def MPYHHAUr32: 976 MPYHHAUInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB)>; 977 978//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 979// clz: Count leading zeroes 980//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 981class CLZInst<dag OOL, dag IOL, list<dag> pattern>: 982 RRForm_1<0b10100101010, OOL, IOL, "clz\t$rT, $rA", 983 IntegerOp, pattern>; 984 985class CLZRegInst<RegisterClass rclass>: 986 CLZInst<(outs rclass:$rT), (ins rclass:$rA), 987 [(set rclass:$rT, (ctlz rclass:$rA))]>; 988 989class CLZVecInst<ValueType vectype>: 990 CLZInst<(outs VECREG:$rT), (ins VECREG:$rA), 991 [(set (vectype VECREG:$rT), (ctlz (vectype VECREG:$rA)))]>; 992 993multiclass CountLeadingZeroes { 994 def v4i32 : CLZVecInst<v4i32>; 995 def r32 : CLZRegInst<R32C>; 996} 997 998defm 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 1006def 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 1011def 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 1016def 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 1031class GBBInst<dag OOL, dag IOL, list<dag> pattern>: 1032 RRForm_1<0b01001101100, OOL, IOL, "gbb\t$rT, $rA", GatherOp, pattern>; 1033 1034class GBBRegInst<RegisterClass rclass, ValueType vectype>: 1035 GBBInst<(outs rclass:$rT), (ins VECREG:$rA), 1036 [/* no pattern */]>; 1037 1038class GBBVecInst<ValueType vectype>: 1039 GBBInst<(outs VECREG:$rT), (ins VECREG:$rA), 1040 [/* no pattern */]>; 1041 1042multiclass GatherBitsFromBytes { 1043 def v16i8_r32: GBBRegInst<R32C, v16i8>; 1044 def v16i8_r16: GBBRegInst<R16C, v16i8>; 1045 def v16i8: GBBVecInst<v16i8>; 1046} 1047 1048defm 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 1056class GBHInst<dag OOL, dag IOL, list<dag> pattern>: 1057 RRForm_1<0b10001101100, OOL, IOL, "gbh\t$rT, $rA", GatherOp, 1058 pattern>; 1059 1060class GBHRegInst<RegisterClass rclass, ValueType vectype>: 1061 GBHInst<(outs rclass:$rT), (ins VECREG:$rA), 1062 [/* no pattern */]>; 1063 1064class GBHVecInst<ValueType vectype>: 1065 GBHInst<(outs VECREG:$rT), (ins VECREG:$rA), 1066 [/* no pattern */]>; 1067 1068multiclass GatherBitsHalfword { 1069 def v8i16_r32: GBHRegInst<R32C, v8i16>; 1070 def v8i16_r16: GBHRegInst<R16C, v8i16>; 1071 def v8i16: GBHVecInst<v8i16>; 1072} 1073 1074defm 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 1082class GBInst<dag OOL, dag IOL, list<dag> pattern>: 1083 RRForm_1<0b00001101100, OOL, IOL, "gb\t$rT, $rA", GatherOp, 1084 pattern>; 1085 1086class GBRegInst<RegisterClass rclass, ValueType vectype>: 1087 GBInst<(outs rclass:$rT), (ins VECREG:$rA), 1088 [/* no pattern */]>; 1089 1090class GBVecInst<ValueType vectype>: 1091 GBInst<(outs VECREG:$rT), (ins VECREG:$rA), 1092 [/* no pattern */]>; 1093 1094multiclass GatherBitsWord { 1095 def v4i32_r32: GBRegInst<R32C, v4i32>; 1096 def v4i32_r16: GBRegInst<R16C, v4i32>; 1097 def v4i32: GBVecInst<v4i32>; 1098} 1099 1100defm GB: GatherBitsWord; 1101 1102// avgb: average bytes 1103def 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 1109def 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 1115def 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: 1121class XSBHInst<dag OOL, dag IOL, list<dag> pattern>: 1122 RRForm_1<0b01101101010, OOL, IOL, 1123 "xsbh\t$rDst, $rSrc", 1124 IntegerOp, pattern>; 1125 1126class XSBHInRegInst<RegisterClass rclass, list<dag> pattern>: 1127 XSBHInst<(outs rclass:$rDst), (ins rclass:$rSrc), 1128 pattern>; 1129 1130multiclass 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 1150defm XSBH : ExtendByteHalfword; 1151 1152// Sign extend halfwords to words: 1153 1154class XSHWInst<dag OOL, dag IOL, list<dag> pattern>: 1155 RRForm_1<0b01101101010, OOL, IOL, "xshw\t$rDest, $rSrc", 1156 IntegerOp, pattern>; 1157 1158class 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 1163class XSHWInRegInst<RegisterClass rclass, list<dag> pattern>: 1164 XSHWInst<(outs rclass:$rDest), (ins rclass:$rSrc), 1165 pattern>; 1166 1167class XSHWRegInst<RegisterClass rclass>: 1168 XSHWInst<(outs rclass:$rDest), (ins R16C:$rSrc), 1169 [(set rclass:$rDest, (sext R16C:$rSrc))]>; 1170 1171multiclass 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 1181defm XSHW : ExtendHalfwordWord; 1182 1183// Sign-extend words to doublewords (32->64 bits) 1184 1185class XSWDInst<dag OOL, dag IOL, list<dag> pattern>: 1186 RRForm_1<0b01100101010, OOL, IOL, "xswd\t$rDst, $rSrc", 1187 IntegerOp, pattern>; 1188 1189class 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 1194class 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 1198multiclass 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 1206defm XSWD : ExtendWordToDoubleWord; 1207 1208// AND operations 1209 1210class ANDInst<dag OOL, dag IOL, list<dag> pattern> : 1211 RRForm<0b10000011000, OOL, IOL, "and\t$rT, $rA, $rB", 1212 IntegerOp, pattern>; 1213 1214class 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 1219class ANDRegInst<RegisterClass rclass>: 1220 ANDInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), 1221 [(set rclass:$rT, (and rclass:$rA, rclass:$rB))]>; 1222 1223multiclass 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 1259defm AND : BitwiseAnd; 1260 1261 1262def 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 1271class ANDCInst<dag OOL, dag IOL, list<dag> pattern>: 1272 RRForm<0b10000011010, OOL, IOL, "andc\t$rT, $rA, $rB", 1273 IntegerOp, pattern>; 1274 1275class 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 1281class ANDCRegInst<RegisterClass rclass>: 1282 ANDCInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), 1283 [(set rclass:$rT, (and rclass:$rA, (not rclass:$rB)))]>; 1284 1285multiclass 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 1302defm ANDC : AndComplement; 1303 1304class ANDBIInst<dag OOL, dag IOL, list<dag> pattern>: 1305 RI10Form<0b01101000, OOL, IOL, "andbi\t$rT, $rA, $val", 1306 ByteOp, pattern>; 1307 1308multiclass 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 1319defm ANDBI : AndByteImm; 1320 1321class ANDHIInst<dag OOL, dag IOL, list<dag> pattern> : 1322 RI10Form<0b10101000, OOL, IOL, "andhi\t$rT, $rA, $val", 1323 ByteOp, pattern>; 1324 1325multiclass 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 1339defm ANDHI : AndHalfwordImm; 1340 1341class ANDIInst<dag OOL, dag IOL, list<dag> pattern> : 1342 RI10Form<0b00101000, OOL, IOL, "andi\t$rT, $rA, $val", 1343 IntegerOp, pattern>; 1344 1345multiclass 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 1370defm ANDI : AndWordImm; 1371 1372//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 1373// Bitwise OR group: 1374//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 1375 1376// Bitwise "or" (N.B.: These are also register-register copy instructions...) 1377class ORInst<dag OOL, dag IOL, list<dag> pattern>: 1378 RRForm<0b10000010000, OOL, IOL, "or\t$rT, $rA, $rB", 1379 IntegerOp, pattern>; 1380 1381class 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 1386class ORRegInst<RegisterClass rclass>: 1387 ORInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), 1388 [(set rclass:$rT, (or rclass:$rA, rclass:$rB))]>; 1389 1390 1391multiclass 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 1422defm OR : BitwiseOr; 1423 1424//===----------------------------------------------------------------------===// 1425// SPU::PREFSLOT2VEC and VEC2PREFSLOT re-interpretations of registers 1426//===----------------------------------------------------------------------===// 1427def : Pat<(v16i8 (SPUprefslot2vec R8C:$rA)), 1428 (COPY_TO_REGCLASS R8C:$rA, VECREG)>; 1429 1430def : Pat<(v8i16 (SPUprefslot2vec R16C:$rA)), 1431 (COPY_TO_REGCLASS R16C:$rA, VECREG)>; 1432 1433def : Pat<(v4i32 (SPUprefslot2vec R32C:$rA)), 1434 (COPY_TO_REGCLASS R32C:$rA, VECREG)>; 1435 1436def : Pat<(v2i64 (SPUprefslot2vec R64C:$rA)), 1437 (COPY_TO_REGCLASS R64C:$rA, VECREG)>; 1438 1439def : Pat<(v4f32 (SPUprefslot2vec R32FP:$rA)), 1440 (COPY_TO_REGCLASS R32FP:$rA, VECREG)>; 1441 1442def : Pat<(v2f64 (SPUprefslot2vec R64FP:$rA)), 1443 (COPY_TO_REGCLASS R64FP:$rA, VECREG)>; 1444 1445def : Pat<(i8 (SPUvec2prefslot (v16i8 VECREG:$rA))), 1446 (COPY_TO_REGCLASS (v16i8 VECREG:$rA), R8C)>; 1447 1448def : Pat<(i16 (SPUvec2prefslot (v8i16 VECREG:$rA))), 1449 (COPY_TO_REGCLASS (v8i16 VECREG:$rA), R16C)>; 1450 1451def : Pat<(i32 (SPUvec2prefslot (v4i32 VECREG:$rA))), 1452 (COPY_TO_REGCLASS (v4i32 VECREG:$rA), R32C)>; 1453 1454def : Pat<(i64 (SPUvec2prefslot (v2i64 VECREG:$rA))), 1455 (COPY_TO_REGCLASS (v2i64 VECREG:$rA), R64C)>; 1456 1457def : Pat<(f32 (SPUvec2prefslot (v4f32 VECREG:$rA))), 1458 (COPY_TO_REGCLASS (v4f32 VECREG:$rA), R32FP)>; 1459 1460def : 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 1467let 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 1509class ORCInst<dag OOL, dag IOL, list<dag> pattern>: 1510 RRForm<0b10010010000, OOL, IOL, "orc\t$rT, $rA, $rB", 1511 IntegerOp, pattern>; 1512 1513class 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 1518class ORCRegInst<RegisterClass rclass>: 1519 ORCInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), 1520 [(set rclass:$rT, (or rclass:$rA, (not rclass:$rB)))]>; 1521 1522multiclass 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 1536defm ORC : BitwiseOrComplement; 1537 1538// OR byte immediate 1539class ORBIInst<dag OOL, dag IOL, list<dag> pattern>: 1540 RI10Form<0b01100000, OOL, IOL, "orbi\t$rT, $rA, $val", 1541 IntegerOp, pattern>; 1542 1543class 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 1548multiclass 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 1556defm ORBI : BitwiseOrByteImm; 1557 1558// OR halfword immediate 1559class ORHIInst<dag OOL, dag IOL, list<dag> pattern>: 1560 RI10Form<0b10100000, OOL, IOL, "orhi\t$rT, $rA, $val", 1561 IntegerOp, pattern>; 1562 1563class 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 1568multiclass 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 1581defm ORHI : BitwiseOrHalfwordImm; 1582 1583class ORIInst<dag OOL, dag IOL, list<dag> pattern>: 1584 RI10Form<0b00100000, OOL, IOL, "ori\t$rT, $rA, $val", 1585 IntegerOp, pattern>; 1586 1587class 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 1593multiclass BitwiseOrImm 1594{ 1595 def v4i32: ORIVecInst<v4i32, v4i32Uns10Imm>; 1596 1597 def r32: ORIInst<(outs R32C:$rT), (ins R32C:$rA, s10imm_i32:$val), 1598 [(set R32C:$rT, (or R32C:$rA, i32ImmSExt10:$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 1615defm 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. 1621def ORXv4i32: 1622 RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 1623 "orx\t$rT, $rA, $rB", IntegerOp, 1624 []>; 1625 1626// XOR: 1627 1628class XORInst<dag OOL, dag IOL, list<dag> pattern> : 1629 RRForm<0b10010010000, OOL, IOL, "xor\t$rT, $rA, $rB", 1630 IntegerOp, pattern>; 1631 1632class 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 1637class XORRegInst<RegisterClass rclass>: 1638 XORInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), 1639 [(set rclass:$rT, (xor rclass:$rA, rclass:$rB))]>; 1640 1641multiclass 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 1666defm XOR : BitwiseExclusiveOr; 1667 1668//==---------------------------------------------------------- 1669 1670class XORBIInst<dag OOL, dag IOL, list<dag> pattern>: 1671 RI10Form<0b01100000, OOL, IOL, "xorbi\t$rT, $rA, $val", 1672 IntegerOp, pattern>; 1673 1674multiclass 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 1685defm XORBI : XorByteImm; 1686 1687def 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 1693def 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 1698def 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 1704def 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 1711class NANDInst<dag OOL, dag IOL, list<dag> pattern>: 1712 RRForm<0b10010011000, OOL, IOL, "nand\t$rT, $rA, $rB", 1713 IntegerOp, pattern>; 1714 1715class 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))))]>; 1719class NANDRegInst<RegisterClass rclass>: 1720 NANDInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), 1721 [(set rclass:$rT, (not (and rclass:$rA, rclass:$rB)))]>; 1722 1723multiclass 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 1737defm NAND : BitwiseNand; 1738 1739// NOR: 1740 1741class NORInst<dag OOL, dag IOL, list<dag> pattern>: 1742 RRForm<0b10010010000, OOL, IOL, "nor\t$rT, $rA, $rB", 1743 IntegerOp, pattern>; 1744 1745class 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))))]>; 1749class NORRegInst<RegisterClass rclass>: 1750 NORInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), 1751 [(set rclass:$rT, (not (or rclass:$rA, rclass:$rB)))]>; 1752 1753multiclass 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 1767defm NOR : BitwiseNor; 1768 1769// Select bits: 1770class SELBInst<dag OOL, dag IOL, list<dag> pattern>: 1771 RRRForm<0b1000, OOL, IOL, "selb\t$rT, $rA, $rB, $rC", 1772 IntegerOp, pattern>; 1773 1774class 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 1781class 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 1788class 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 1795class 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 1801class 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 1806multiclass 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 1843defm SELB : SelectBits; 1844 1845class 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 1849def : SPUselbPatVec<v16i8, SELBv16i8>; 1850def : SPUselbPatVec<v8i16, SELBv8i16>; 1851def : SPUselbPatVec<v4i32, SELBv4i32>; 1852def : SPUselbPatVec<v2i64, SELBv2i64>; 1853 1854class SPUselbPatReg<RegisterClass rclass, SPUInstr inst>: 1855 Pat<(SPUselb rclass:$rA, rclass:$rB, rclass:$rC), 1856 (inst rclass:$rA, rclass:$rB, rclass:$rC)>; 1857 1858def : SPUselbPatReg<R8C, SELBr8>; 1859def : SPUselbPatReg<R16C, SELBr16>; 1860def : SPUselbPatReg<R32C, SELBr32>; 1861def : 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 1868class EQVInst<dag OOL, dag IOL, list<dag> pattern>: 1869 RRForm<0b10010010000, OOL, IOL, "eqv\t$rT, $rA, $rB", 1870 IntegerOp, pattern>; 1871 1872class 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 1879class 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 1884class 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 1889class EQVRegPattern1<RegisterClass rclass>: 1890 EQVInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), 1891 [(set rclass:$rT, (xor rclass:$rA, (not rclass:$rB)))]>; 1892 1893class 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 1899class 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 1905class 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 1910class EQVRegPattern3<RegisterClass rclass>: 1911 EQVInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), 1912 [(set rclass:$rT, (not (xor rclass:$rA, rclass:$rB)))]>; 1913 1914multiclass 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 1961defm 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 1972class SHUFBInst<dag OOL, dag IOL, list<dag> pattern>: 1973 RRRForm<0b1000, OOL, IOL, "shufb\t$rT, $rA, $rB, $rC", 1974 ShuffleOp, pattern>; 1975 1976class 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 1983class SHUFBGPRCInst: 1984 SHUFBInst<(outs VECREG:$rT), (ins GPRC:$rA, GPRC:$rB, VECREG:$rC), 1985 [/* no pattern */]>; 1986 1987multiclass 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 2007defm SHUFB : ShuffleBytes; 2008 2009//===----------------------------------------------------------------------===// 2010// Shift and rotate group: 2011//===----------------------------------------------------------------------===// 2012 2013class SHLHInst<dag OOL, dag IOL, list<dag> pattern>: 2014 RRForm<0b11111010000, OOL, IOL, "shlh\t$rT, $rA, $rB", 2015 RotShiftVec, pattern>; 2016 2017class 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 2022multiclass 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 2031defm SHLH : ShiftLeftHalfword; 2032 2033//===----------------------------------------------------------------------===// 2034 2035class SHLHIInst<dag OOL, dag IOL, list<dag> pattern>: 2036 RI7Form<0b11111010000, OOL, IOL, "shlhi\t$rT, $rA, $val", 2037 RotShiftVec, pattern>; 2038 2039class 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 2044multiclass 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 2051defm SHLHI : ShiftLeftHalfwordImm; 2052 2053def : Pat<(SPUvec_shl (v8i16 VECREG:$rA), (i32 uimm7:$val)), 2054 (SHLHIv8i16 VECREG:$rA, (TO_IMM16 uimm7:$val))>; 2055 2056def : Pat<(shl R16C:$rA, (i32 uimm7:$val)), 2057 (SHLHIr16 R16C:$rA, (TO_IMM16 uimm7:$val))>; 2058 2059//===----------------------------------------------------------------------===// 2060 2061class SHLInst<dag OOL, dag IOL, list<dag> pattern>: 2062 RRForm<0b11111010000, OOL, IOL, "shl\t$rT, $rA, $rB", 2063 RotShiftVec, pattern>; 2064 2065multiclass 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 2076defm SHL: ShiftLeftWord; 2077 2078//===----------------------------------------------------------------------===// 2079 2080class SHLIInst<dag OOL, dag IOL, list<dag> pattern>: 2081 RI7Form<0b11111010000, OOL, IOL, "shli\t$rT, $rA, $val", 2082 RotShiftVec, pattern>; 2083 2084multiclass 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 2096defm 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 2109class SHLQBIInst<dag OOL, dag IOL, list<dag> pattern>: 2110 RRForm<0b11011011100, OOL, IOL, "shlqbi\t$rT, $rA, $rB", 2111 RotShiftQuad, pattern>; 2112 2113class 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 2118class SHLQBIRegInst<RegisterClass rclass>: 2119 SHLQBIInst<(outs rclass:$rT), (ins rclass:$rA, R32C:$rB), 2120 [/* no pattern */]>; 2121 2122multiclass 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 2134defm 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." 2138class SHLQBIIInst<dag OOL, dag IOL, list<dag> pattern>: 2139 RI7Form<0b11011111100, OOL, IOL, "shlqbii\t$rT, $rA, $val", 2140 RotShiftQuad, pattern>; 2141 2142class 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 2147multiclass 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 2157defm 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 2162class SHLQBYInst<dag OOL, dag IOL, list<dag> pattern>: 2163 RI7Form<0b11111011100, OOL, IOL, "shlqby\t$rT, $rA, $rB", 2164 RotShiftQuad, pattern>; 2165 2166class 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 2171multiclass 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 2183defm SHLQBY: ShiftLeftQuadBytes; 2184 2185class SHLQBYIInst<dag OOL, dag IOL, list<dag> pattern>: 2186 RI7Form<0b11111111100, OOL, IOL, "shlqbyi\t$rT, $rA, $val", 2187 RotShiftQuad, pattern>; 2188 2189class 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 2194multiclass 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 2207defm SHLQBYI : ShiftLeftQuadBytesImm; 2208 2209class SHLQBYBIInst<dag OOL, dag IOL, list<dag> pattern>: 2210 RRForm<0b00111001111, OOL, IOL, "shlqbybi\t$rT, $rA, $rB", 2211 RotShiftQuad, pattern>; 2212 2213class SHLQBYBIVecInst<ValueType vectype>: 2214 SHLQBYBIInst<(outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB), 2215 [/* no pattern */]>; 2216 2217class SHLQBYBIRegInst<RegisterClass rclass>: 2218 SHLQBYBIInst<(outs rclass:$rT), (ins rclass:$rA, R32C:$rB), 2219 [/* no pattern */]>; 2220 2221multiclass 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 2233defm SHLQBYBI : ShiftLeftQuadBytesBitCount; 2234 2235//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2236// Rotate halfword: 2237//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2238class ROTHInst<dag OOL, dag IOL, list<dag> pattern>: 2239 RRForm<0b00111010000, OOL, IOL, "roth\t$rT, $rA, $rB", 2240 RotShiftVec, pattern>; 2241 2242class 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 2247class ROTHRegInst<RegisterClass rclass>: 2248 ROTHInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), 2249 [(set rclass:$rT, (rotl rclass:$rA, rclass:$rB))]>; 2250 2251multiclass RotateLeftHalfword 2252{ 2253 def v8i16: ROTHVecInst<v8i16>; 2254 def r16: ROTHRegInst<R16C>; 2255} 2256 2257defm ROTH: RotateLeftHalfword; 2258 2259def 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//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2265class ROTHIInst<dag OOL, dag IOL, list<dag> pattern>: 2266 RI7Form<0b00111110000, OOL, IOL, "rothi\t$rT, $rA, $val", 2267 RotShiftVec, pattern>; 2268 2269class 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 2274multiclass 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 2283defm ROTHI: RotateLeftHalfwordImm; 2284 2285def : Pat<(SPUvec_rotl (v8i16 VECREG:$rA), (i32 uimm7:$val)), 2286 (ROTHIv8i16 VECREG:$rA, (TO_IMM16 imm:$val))>; 2287 2288//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2289// Rotate word: 2290//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2291 2292class ROTInst<dag OOL, dag IOL, list<dag> pattern>: 2293 RRForm<0b00011010000, OOL, IOL, "rot\t$rT, $rA, $rB", 2294 RotShiftVec, pattern>; 2295 2296class 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 2301class ROTRegInst<RegisterClass rclass>: 2302 ROTInst<(outs rclass:$rT), (ins rclass:$rA, R32C:$rB), 2303 [(set rclass:$rT, 2304 (rotl rclass:$rA, R32C:$rB))]>; 2305 2306multiclass RotateLeftWord 2307{ 2308 def v4i32: ROTVecInst<v4i32>; 2309 def r32: ROTRegInst<R32C>; 2310} 2311 2312defm 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 2316def 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 2320def : Pat<(rotl R32C:$rA, (i32 (zext R16C:$rB))), 2321 (ROTr32_r16_anyext R32C:$rA, R16C:$rB)>; 2322 2323def : Pat<(rotl R32C:$rA, (i32 (sext R16C:$rB))), 2324 (ROTr32_r16_anyext R32C:$rA, R16C:$rB)>; 2325 2326def 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 2330def : Pat<(rotl R32C:$rA, (i32 (zext R8C:$rB))), 2331 (ROTr32_r8_anyext R32C:$rA, R8C:$rB)>; 2332 2333def : Pat<(rotl R32C:$rA, (i32 (sext R8C:$rB))), 2334 (ROTr32_r8_anyext R32C:$rA, R8C:$rB)>; 2335 2336//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2337// Rotate word, immediate 2338//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2339 2340class ROTIInst<dag OOL, dag IOL, list<dag> pattern>: 2341 RI7Form<0b00011110000, OOL, IOL, "roti\t$rT, $rA, $val", 2342 RotShiftVec, pattern>; 2343 2344class 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 2349class 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 2353multiclass 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 2364defm ROTI : RotateLeftWordImm; 2365 2366//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2367// Rotate quad by byte (count) 2368//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2369 2370class ROTQBYInst<dag OOL, dag IOL, list<dag> pattern>: 2371 RRForm<0b00111011100, OOL, IOL, "rotqby\t$rT, $rA, $rB", 2372 RotShiftQuad, pattern>; 2373 2374class 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 2379class ROTQBYVecInst<ValueType type>: 2380 ROTQBYGenInst<type, VECREG>; 2381 2382multiclass 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 2393defm ROTQBY: RotateQuadLeftByBytes; 2394 2395//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2396// Rotate quad by byte (count), immediate 2397//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2398 2399class ROTQBYIInst<dag OOL, dag IOL, list<dag> pattern>: 2400 RI7Form<0b00111111100, OOL, IOL, "rotqbyi\t$rT, $rA, $val", 2401 RotShiftQuad, pattern>; 2402 2403class 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 2408class ROTQBYIVecInst<ValueType vectype>: 2409 ROTQBYIGenInst<vectype, VECREG>; 2410 2411multiclass 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 2422defm ROTQBYI: RotateQuadByBytesImm; 2423 2424// See ROTQBY note above. 2425class ROTQBYBIInst<dag OOL, dag IOL, list<dag> pattern>: 2426 RI7Form<0b00110011100, OOL, IOL, 2427 "rotqbybi\t$rT, $rA, $shift", 2428 RotShiftQuad, pattern>; 2429 2430class 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 2435multiclass 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 2442defm 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 2451class ROTQBIInst<dag OOL, dag IOL, list<dag> pattern>: 2452 RRForm<0b00011011100, OOL, IOL, "rotqbi\t$rT, $rA, $rB", 2453 RotShiftQuad, pattern>; 2454 2455class ROTQBIVecInst<ValueType vectype>: 2456 ROTQBIInst<(outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB), 2457 [/* no pattern yet */]>; 2458 2459class ROTQBIRegInst<RegisterClass rclass>: 2460 ROTQBIInst<(outs rclass:$rT), (ins rclass:$rA, R32C:$rB), 2461 [/* no pattern yet */]>; 2462 2463multiclass 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 2474defm ROTQBI: RotateQuadByBitCount; 2475 2476class ROTQBIIInst<dag OOL, dag IOL, list<dag> pattern>: 2477 RI7Form<0b00011111100, OOL, IOL, "rotqbii\t$rT, $rA, $val", 2478 RotShiftQuad, pattern>; 2479 2480class 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 2485class 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 2490multiclass 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 2501defm 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 2511class ROTHMInst<dag OOL, dag IOL, list<dag> pattern>: 2512 RRForm<0b10111010000, OOL, IOL, "rothm\t$rT, $rA, $rB", 2513 RotShiftVec, pattern>; 2514 2515def ROTHMv8i16: 2516 ROTHMInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 2517 [/* see patterns below - $rB must be negated */]>; 2518 2519def : 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 2526def ROTHMr16: 2527 ROTHMInst<(outs R16C:$rT), (ins R16C:$rA, R32C:$rB), 2528 [/* see patterns below - $rB must be negated! */]>; 2529 2530def : Pat<(srl R16C:$rA, R32C:$rB), 2531 (ROTHMr16 R16C:$rA, (SFIr32 R32C:$rB, 0))>; 2532 2533def : Pat<(srl R16C:$rA, R16C:$rB), 2534 (ROTHMr16 R16C:$rA, 2535 (SFIr32 (XSHWr16 R16C:$rB), 0))>; 2536 2537def : 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 2545class ROTHMIInst<dag OOL, dag IOL, list<dag> pattern>: 2546 RI7Form<0b10111110000, OOL, IOL, "rothmi\t$rT, $rA, $val", 2547 RotShiftVec, pattern>; 2548 2549def ROTHMIv8i16: 2550 ROTHMIInst<(outs VECREG:$rT), (ins VECREG:$rA, rothNeg7imm:$val), 2551 [/* no pattern */]>; 2552 2553def : Pat<(SPUvec_srl (v8i16 VECREG:$rA), (i32 imm:$val)), 2554 (ROTHMIv8i16 VECREG:$rA, imm:$val)>; 2555 2556def: Pat<(SPUvec_srl (v8i16 VECREG:$rA), (i16 imm:$val)), 2557 (ROTHMIv8i16 VECREG:$rA, (TO_IMM32 imm:$val))>; 2558 2559def: Pat<(SPUvec_srl (v8i16 VECREG:$rA), (i8 imm:$val)), 2560 (ROTHMIv8i16 VECREG:$rA, (TO_IMM32 imm:$val))>; 2561 2562def ROTHMIr16: 2563 ROTHMIInst<(outs R16C:$rT), (ins R16C:$rA, rothNeg7imm:$val), 2564 [/* no pattern */]>; 2565 2566def: Pat<(srl R16C:$rA, (i32 uimm7:$val)), 2567 (ROTHMIr16 R16C:$rA, uimm7:$val)>; 2568 2569def: Pat<(srl R16C:$rA, (i16 uimm7:$val)), 2570 (ROTHMIr16 R16C:$rA, (TO_IMM32 uimm7:$val))>; 2571 2572def: 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. 2576class ROTMInst<dag OOL, dag IOL, list<dag> pattern>: 2577 RRForm<0b10011010000, OOL, IOL, "rotm\t$rT, $rA, $rB", 2578 RotShiftVec, pattern>; 2579 2580def ROTMv4i32: 2581 ROTMInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 2582 [/* see patterns below - $rB must be negated */]>; 2583 2584def : Pat<(SPUvec_srl (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)), 2585 (ROTMv4i32 VECREG:$rA, (SFIvec VECREG:$rB, 0))>; 2586 2587def ROTMr32: 2588 ROTMInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB), 2589 [/* see patterns below - $rB must be negated */]>; 2590 2591def : Pat<(srl R32C:$rA, R32C:$rB), 2592 (ROTMr32 R32C:$rA, (SFIr32 R32C:$rB, 0))>; 2593 2594def : Pat<(srl R32C:$rA, R16C:$rB), 2595 (ROTMr32 R32C:$rA, 2596 (SFIr32 (XSHWr16 R16C:$rB), 0))>; 2597 2598def : 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. 2603def 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 2609def : Pat<(SPUvec_srl (v4i32 VECREG:$rA), (i16 uimm7:$val)), 2610 (ROTMIv4i32 VECREG:$rA, (TO_IMM32 uimm7:$val))>; 2611 2612def : 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. 2616def 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 2621def : Pat<(srl R32C:$rA, (i16 imm:$val)), 2622 (ROTMIr32 R32C:$rA, (TO_IMM32 uimm7:$val))>; 2623 2624def : 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 2633class ROTQMBYInst<dag OOL, dag IOL, list<dag> pattern>: 2634 RRForm<0b10111011100, OOL, IOL, "rotqmby\t$rT, $rA, $rB", 2635 RotShiftQuad, pattern>; 2636 2637class ROTQMBYVecInst<ValueType vectype>: 2638 ROTQMBYInst<(outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB), 2639 [/* no pattern, $rB must be negated */]>; 2640 2641class ROTQMBYRegInst<RegisterClass rclass>: 2642 ROTQMBYInst<(outs rclass:$rT), (ins rclass:$rA, R32C:$rB), 2643 [/* no pattern */]>; 2644 2645multiclass 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 2656defm ROTQMBY : RotateQuadBytes; 2657 2658def : Pat<(SPUsrl_bytes GPRC:$rA, R32C:$rB), 2659 (ROTQMBYr128 GPRC:$rA, 2660 (SFIr32 R32C:$rB, 0))>; 2661 2662class ROTQMBYIInst<dag OOL, dag IOL, list<dag> pattern>: 2663 RI7Form<0b10111111100, OOL, IOL, "rotqmbyi\t$rT, $rA, $val", 2664 RotShiftQuad, pattern>; 2665 2666class ROTQMBYIVecInst<ValueType vectype>: 2667 ROTQMBYIInst<(outs VECREG:$rT), (ins VECREG:$rA, rotNeg7imm:$val), 2668 [/* no pattern */]>; 2669 2670class 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: 2676class ROTQMBYIZExtInst<RegisterClass rclass, Operand optype, PatLeaf pred>: 2677 ROTQMBYIInst<(outs GPRC:$rT), (ins rclass:$rA, optype:$val), 2678 [/* no pattern */]>; 2679 2680multiclass 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 2696defm ROTQMBYI : RotateQuadBytesImm; 2697 2698//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2699// Rotate right and mask by bit count 2700//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2701 2702class ROTQMBYBIInst<dag OOL, dag IOL, list<dag> pattern>: 2703 RRForm<0b10110011100, OOL, IOL, "rotqmbybi\t$rT, $rA, $rB", 2704 RotShiftQuad, pattern>; 2705 2706class ROTQMBYBIVecInst<ValueType vectype>: 2707 ROTQMBYBIInst<(outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB), 2708 [/* no pattern, */]>; 2709 2710multiclass 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 2720defm ROTQMBYBI: RotateMaskQuadByBitCount; 2721 2722//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2723// Rotate quad and mask by bits 2724// Note that the rotate amount has to be negated 2725//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2726 2727class ROTQMBIInst<dag OOL, dag IOL, list<dag> pattern>: 2728 RRForm<0b10011011100, OOL, IOL, "rotqmbi\t$rT, $rA, $rB", 2729 RotShiftQuad, pattern>; 2730 2731class ROTQMBIVecInst<ValueType vectype>: 2732 ROTQMBIInst<(outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB), 2733 [/* no pattern */]>; 2734 2735class ROTQMBIRegInst<RegisterClass rclass>: 2736 ROTQMBIInst<(outs rclass:$rT), (ins rclass:$rA, R32C:$rB), 2737 [/* no pattern */]>; 2738 2739multiclass 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 2750defm ROTQMBI: RotateMaskQuadByBits; 2751 2752def : 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 2762class ROTQMBIIInst<dag OOL, dag IOL, list<dag> pattern>: 2763 RI7Form<0b10011111100, OOL, IOL, "rotqmbii\t$rT, $rA, $val", 2764 RotShiftQuad, pattern>; 2765 2766class ROTQMBIIVecInst<ValueType vectype>: 2767 ROTQMBIIInst<(outs VECREG:$rT), (ins VECREG:$rA, rotNeg7imm:$val), 2768 [/* no pattern */]>; 2769 2770class ROTQMBIIRegInst<RegisterClass rclass>: 2771 ROTQMBIIInst<(outs rclass:$rT), (ins rclass:$rA, rotNeg7imm:$val), 2772 [/* no pattern */]>; 2773 2774multiclass 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 2785defm ROTQMBII: RotateMaskQuadByBitsImm; 2786 2787//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2788//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 2789 2790def 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 2795def : Pat<(SPUvec_sra (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)), 2796 (ROTMAHv8i16 VECREG:$rA, (SFHIvec VECREG:$rB, 0))>; 2797 2798def 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 2803def : Pat<(sra R16C:$rA, R32C:$rB), 2804 (ROTMAHr16 R16C:$rA, (SFIr32 R32C:$rB, 0))>; 2805 2806def : Pat<(sra R16C:$rA, R16C:$rB), 2807 (ROTMAHr16 R16C:$rA, 2808 (SFIr32 (XSHWr16 R16C:$rB), 0))>; 2809 2810def : Pat<(sra R16C:$rA, R8C:$rB), 2811 (ROTMAHr16 R16C:$rA, 2812 (SFIr32 (XSHWr16 (XSBHr8 R8C:$rB)), 0))>; 2813 2814def 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 2820def : Pat<(SPUvec_sra (v8i16 VECREG:$rA), (i16 uimm7:$val)), 2821 (ROTMAHIv8i16 (v8i16 VECREG:$rA), (TO_IMM32 uimm7:$val))>; 2822 2823def : Pat<(SPUvec_sra (v8i16 VECREG:$rA), (i8 uimm7:$val)), 2824 (ROTMAHIv8i16 (v8i16 VECREG:$rA), (TO_IMM32 uimm7:$val))>; 2825 2826def 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 2831def : Pat<(sra R16C:$rA, (i32 imm:$val)), 2832 (ROTMAHIr16 R16C:$rA, (TO_IMM32 uimm7:$val))>; 2833 2834def : Pat<(sra R16C:$rA, (i8 imm:$val)), 2835 (ROTMAHIr16 R16C:$rA, (TO_IMM32 uimm7:$val))>; 2836 2837def 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 2842def : Pat<(SPUvec_sra (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)), 2843 (ROTMAv4i32 VECREG:$rA, (SFIvec (v4i32 VECREG:$rB), 0))>; 2844 2845def 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 2850def : Pat<(sra R32C:$rA, R32C:$rB), 2851 (ROTMAr32 R32C:$rA, (SFIr32 R32C:$rB, 0))>; 2852 2853def : Pat<(sra R32C:$rA, R16C:$rB), 2854 (ROTMAr32 R32C:$rA, 2855 (SFIr32 (XSHWr16 R16C:$rB), 0))>; 2856 2857def : Pat<(sra R32C:$rA, R8C:$rB), 2858 (ROTMAr32 R32C:$rA, 2859 (SFIr32 (XSHWr16 (XSBHr8 R8C:$rB)), 0))>; 2860 2861class ROTMAIInst<dag OOL, dag IOL, list<dag> pattern>: 2862 RRForm<0b01011110000, OOL, IOL, 2863 "rotmai\t$rT, $rA, $val", 2864 RotShiftVec, pattern>; 2865 2866class 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 2871class 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 2875multiclass 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 2882defm ROTMAI : RotateMaskAlgebraicImm; 2883 2884//===----------------------------------------------------------------------===// 2885// Branch and conditionals: 2886//===----------------------------------------------------------------------===// 2887 2888let 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 2927class CEQBInst<dag OOL, dag IOL, list<dag> pattern> : 2928 RRForm<0b00001011110, OOL, IOL, "ceqb\t$rT, $rA, $rB", 2929 ByteOp, pattern>; 2930 2931multiclass 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 2943class CEQBIInst<dag OOL, dag IOL, list<dag> pattern> : 2944 RI10Form<0b01111110, OOL, IOL, "ceqbi\t$rT, $rA, $val", 2945 ByteOp, pattern>; 2946 2947multiclass 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 2958class CEQHInst<dag OOL, dag IOL, list<dag> pattern> : 2959 RRForm<0b00010011110, OOL, IOL, "ceqh\t$rT, $rA, $rB", 2960 ByteOp, pattern>; 2961 2962multiclass 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 2972class CEQHIInst<dag OOL, dag IOL, list<dag> pattern> : 2973 RI10Form<0b10111110, OOL, IOL, "ceqhi\t$rT, $rA, $val", 2974 ByteOp, pattern>; 2975 2976multiclass 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 2986class CEQInst<dag OOL, dag IOL, list<dag> pattern> : 2987 RRForm<0b00000011110, OOL, IOL, "ceq\t$rT, $rA, $rB", 2988 ByteOp, pattern>; 2989 2990multiclass 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 3000class CEQIInst<dag OOL, dag IOL, list<dag> pattern> : 3001 RI10Form<0b00111110, OOL, IOL, "ceqi\t$rT, $rA, $val", 3002 ByteOp, pattern>; 3003 3004multiclass 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 3015class CGTBInst<dag OOL, dag IOL, list<dag> pattern> : 3016 RRForm<0b00001010010, OOL, IOL, "cgtb\t$rT, $rA, $rB", 3017 ByteOp, pattern>; 3018 3019multiclass 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 3031class CGTBIInst<dag OOL, dag IOL, list<dag> pattern> : 3032 RI10Form<0b01110010, OOL, IOL, "cgtbi\t$rT, $rA, $val", 3033 ByteOp, pattern>; 3034 3035multiclass 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 3046class CGTHInst<dag OOL, dag IOL, list<dag> pattern> : 3047 RRForm<0b00010010010, OOL, IOL, "cgth\t$rT, $rA, $rB", 3048 ByteOp, pattern>; 3049 3050multiclass 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 3060class CGTHIInst<dag OOL, dag IOL, list<dag> pattern> : 3061 RI10Form<0b10110010, OOL, IOL, "cgthi\t$rT, $rA, $val", 3062 ByteOp, pattern>; 3063 3064multiclass 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 3074class CGTInst<dag OOL, dag IOL, list<dag> pattern> : 3075 RRForm<0b00000010010, OOL, IOL, "cgt\t$rT, $rA, $rB", 3076 ByteOp, pattern>; 3077 3078multiclass 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 3088class CGTIInst<dag OOL, dag IOL, list<dag> pattern> : 3089 RI10Form<0b00110010, OOL, IOL, "cgti\t$rT, $rA, $val", 3090 ByteOp, pattern>; 3091 3092multiclass 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 3112class CLGTBInst<dag OOL, dag IOL, list<dag> pattern> : 3113 RRForm<0b00001011010, OOL, IOL, "clgtb\t$rT, $rA, $rB", 3114 ByteOp, pattern>; 3115 3116multiclass 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 3128class CLGTBIInst<dag OOL, dag IOL, list<dag> pattern> : 3129 RI10Form<0b01111010, OOL, IOL, "clgtbi\t$rT, $rA, $val", 3130 ByteOp, pattern>; 3131 3132multiclass 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 3143class CLGTHInst<dag OOL, dag IOL, list<dag> pattern> : 3144 RRForm<0b00010011010, OOL, IOL, "clgth\t$rT, $rA, $rB", 3145 ByteOp, pattern>; 3146 3147multiclass 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 3157class CLGTHIInst<dag OOL, dag IOL, list<dag> pattern> : 3158 RI10Form<0b10111010, OOL, IOL, "clgthi\t$rT, $rA, $val", 3159 ByteOp, pattern>; 3160 3161multiclass 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 3171class CLGTInst<dag OOL, dag IOL, list<dag> pattern> : 3172 RRForm<0b00000011010, OOL, IOL, "clgt\t$rT, $rA, $rB", 3173 ByteOp, pattern>; 3174 3175multiclass 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 3185class CLGTIInst<dag OOL, dag IOL, list<dag> pattern> : 3186 RI10Form<0b00111010, OOL, IOL, "clgti\t$rT, $rA, $val", 3187 ByteOp, pattern>; 3188 3189multiclass 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 3200defm CEQB : CmpEqualByte; 3201defm CEQBI : CmpEqualByteImm; 3202defm CEQH : CmpEqualHalfword; 3203defm CEQHI : CmpEqualHalfwordImm; 3204defm CEQ : CmpEqualWord; 3205defm CEQI : CmpEqualWordImm; 3206defm CGTB : CmpGtrByte; 3207defm CGTBI : CmpGtrByteImm; 3208defm CGTH : CmpGtrHalfword; 3209defm CGTHI : CmpGtrHalfwordImm; 3210defm CGT : CmpGtrWord; 3211defm CGTI : CmpGtrWordImm; 3212defm CLGTB : CmpLGtrByte; 3213defm CLGTBI : CmpLGtrByteImm; 3214defm CLGTH : CmpLGtrHalfword; 3215defm CLGTHI : CmpLGtrHalfwordImm; 3216defm CLGT : CmpLGtrWord; 3217defm 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 3234class 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 3239class 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 3244def : SETCCNegCondReg<setne, R8C, i8, XORBIr8, CEQBr8>; 3245def : SETCCNegCondImm<setne, R8C, i8, immSExt8, XORBIr8, CEQBIr8>; 3246 3247def : SETCCNegCondReg<setne, R16C, i16, XORHIr16, CEQHr16>; 3248def : SETCCNegCondImm<setne, R16C, i16, i16ImmSExt10, XORHIr16, CEQHIr16>; 3249 3250def : SETCCNegCondReg<setne, R32C, i32, XORIr32, CEQr32>; 3251def : SETCCNegCondImm<setne, R32C, i32, i32ImmSExt10, XORIr32, CEQIr32>; 3252 3253class 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 3259class 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 3266def : SETCCBinOpReg<setge, R8C, ORr8, CGTBr8, CEQBr8>; 3267def : SETCCBinOpImm<setge, R8C, immSExt8, i8, ORr8, CGTBIr8, CEQBIr8>; 3268def : SETCCBinOpReg<setlt, R8C, NORr8, CGTBr8, CEQBr8>; 3269def : SETCCBinOpImm<setlt, R8C, immSExt8, i8, NORr8, CGTBIr8, CEQBIr8>; 3270def : Pat<(setle R8C:$rA, R8C:$rB), 3271 (XORBIr8 (CGTBr8 R8C:$rA, R8C:$rB), 0xff)>; 3272def : Pat<(setle R8C:$rA, immU8:$imm), 3273 (XORBIr8 (CGTBIr8 R8C:$rA, immU8:$imm), 0xff)>; 3274 3275def : SETCCBinOpReg<setge, R16C, ORr16, CGTHr16, CEQHr16>; 3276def : SETCCBinOpImm<setge, R16C, i16ImmSExt10, i16, 3277 ORr16, CGTHIr16, CEQHIr16>; 3278def : SETCCBinOpReg<setlt, R16C, NORr16, CGTHr16, CEQHr16>; 3279def : SETCCBinOpImm<setlt, R16C, i16ImmSExt10, i16, NORr16, CGTHIr16, CEQHIr16>; 3280def : Pat<(setle R16C:$rA, R16C:$rB), 3281 (XORHIr16 (CGTHr16 R16C:$rA, R16C:$rB), 0xffff)>; 3282def : Pat<(setle R16C:$rA, i16ImmSExt10:$imm), 3283 (XORHIr16 (CGTHIr16 R16C:$rA, i16ImmSExt10:$imm), 0xffff)>; 3284 3285def : SETCCBinOpReg<setge, R32C, ORr32, CGTr32, CEQr32>; 3286def : SETCCBinOpImm<setge, R32C, i32ImmSExt10, i32, 3287 ORr32, CGTIr32, CEQIr32>; 3288def : SETCCBinOpReg<setlt, R32C, NORr32, CGTr32, CEQr32>; 3289def : SETCCBinOpImm<setlt, R32C, i32ImmSExt10, i32, NORr32, CGTIr32, CEQIr32>; 3290def : Pat<(setle R32C:$rA, R32C:$rB), 3291 (XORIr32 (CGTr32 R32C:$rA, R32C:$rB), 0xffffffff)>; 3292def : Pat<(setle R32C:$rA, i32ImmSExt10:$imm), 3293 (XORIr32 (CGTIr32 R32C:$rA, i32ImmSExt10:$imm), 0xffffffff)>; 3294 3295def : SETCCBinOpReg<setuge, R8C, ORr8, CLGTBr8, CEQBr8>; 3296def : SETCCBinOpImm<setuge, R8C, immSExt8, i8, ORr8, CLGTBIr8, CEQBIr8>; 3297def : SETCCBinOpReg<setult, R8C, NORr8, CLGTBr8, CEQBr8>; 3298def : SETCCBinOpImm<setult, R8C, immSExt8, i8, NORr8, CLGTBIr8, CEQBIr8>; 3299def : Pat<(setule R8C:$rA, R8C:$rB), 3300 (XORBIr8 (CLGTBr8 R8C:$rA, R8C:$rB), 0xff)>; 3301def : Pat<(setule R8C:$rA, immU8:$imm), 3302 (XORBIr8 (CLGTBIr8 R8C:$rA, immU8:$imm), 0xff)>; 3303 3304def : SETCCBinOpReg<setuge, R16C, ORr16, CLGTHr16, CEQHr16>; 3305def : SETCCBinOpImm<setuge, R16C, i16ImmSExt10, i16, 3306 ORr16, CLGTHIr16, CEQHIr16>; 3307def : SETCCBinOpReg<setult, R16C, NORr16, CLGTHr16, CEQHr16>; 3308def : SETCCBinOpImm<setult, R16C, i16ImmSExt10, i16, NORr16, 3309 CLGTHIr16, CEQHIr16>; 3310def : Pat<(setule R16C:$rA, R16C:$rB), 3311 (XORHIr16 (CLGTHr16 R16C:$rA, R16C:$rB), 0xffff)>; 3312def : Pat<(setule R16C:$rA, i16ImmSExt10:$imm), 3313 (XORHIr16 (CLGTHIr16 R16C:$rA, i16ImmSExt10:$imm), 0xffff)>; 3314 3315def : SETCCBinOpReg<setuge, R32C, ORr32, CLGTr32, CEQr32>; 3316def : SETCCBinOpImm<setuge, R32C, i32ImmSExt10, i32, 3317 ORr32, CLGTIr32, CEQIr32>; 3318def : SETCCBinOpReg<setult, R32C, NORr32, CLGTr32, CEQr32>; 3319def : SETCCBinOpImm<setult, R32C, i32ImmSExt10, i32, NORr32, CLGTIr32, CEQIr32>; 3320def : Pat<(setule R32C:$rA, R32C:$rB), 3321 (XORIr32 (CLGTr32 R32C:$rA, R32C:$rB), 0xffffffff)>; 3322def : Pat<(setule R32C:$rA, i32ImmSExt10:$imm), 3323 (XORIr32 (CLGTIr32 R32C:$rA, i32ImmSExt10:$imm), 0xffffffff)>; 3324 3325//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 3326// select conditional patterns: 3327//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 3328 3329class 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 3336class 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 3343def : SELECTNegCondReg<setne, R8C, i8, SELBr8, CEQBr8>; 3344def : SELECTNegCondImm<setne, R8C, i8, immSExt8, SELBr8, CEQBIr8>; 3345def : SELECTNegCondReg<setle, R8C, i8, SELBr8, CGTBr8>; 3346def : SELECTNegCondImm<setle, R8C, i8, immSExt8, SELBr8, CGTBr8>; 3347def : SELECTNegCondReg<setule, R8C, i8, SELBr8, CLGTBr8>; 3348def : SELECTNegCondImm<setule, R8C, i8, immU8, SELBr8, CLGTBIr8>; 3349 3350def : SELECTNegCondReg<setne, R16C, i16, SELBr16, CEQHr16>; 3351def : SELECTNegCondImm<setne, R16C, i16, i16ImmSExt10, SELBr16, CEQHIr16>; 3352def : SELECTNegCondReg<setle, R16C, i16, SELBr16, CGTHr16>; 3353def : SELECTNegCondImm<setle, R16C, i16, i16ImmSExt10, SELBr16, CGTHIr16>; 3354def : SELECTNegCondReg<setule, R16C, i16, SELBr16, CLGTHr16>; 3355def : SELECTNegCondImm<setule, R16C, i16, i16ImmSExt10, SELBr16, CLGTHIr16>; 3356 3357def : SELECTNegCondReg<setne, R32C, i32, SELBr32, CEQr32>; 3358def : SELECTNegCondImm<setne, R32C, i32, i32ImmSExt10, SELBr32, CEQIr32>; 3359def : SELECTNegCondReg<setle, R32C, i32, SELBr32, CGTr32>; 3360def : SELECTNegCondImm<setle, R32C, i32, i32ImmSExt10, SELBr32, CGTIr32>; 3361def : SELECTNegCondReg<setule, R32C, i32, SELBr32, CLGTr32>; 3362def : SELECTNegCondImm<setule, R32C, i32, i32ImmSExt10, SELBr32, CLGTIr32>; 3363 3364class 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 3373class 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 3383def : SELECTBinOpReg<setge, R8C, i8, SELBr8, ORr8, CGTBr8, CEQBr8>; 3384def : SELECTBinOpImm<setge, R8C, immSExt8, i8, 3385 SELBr8, ORr8, CGTBIr8, CEQBIr8>; 3386 3387def : SELECTBinOpReg<setge, R16C, i16, SELBr16, ORr16, CGTHr16, CEQHr16>; 3388def : SELECTBinOpImm<setge, R16C, i16ImmSExt10, i16, 3389 SELBr16, ORr16, CGTHIr16, CEQHIr16>; 3390 3391def : SELECTBinOpReg<setge, R32C, i32, SELBr32, ORr32, CGTr32, CEQr32>; 3392def : SELECTBinOpImm<setge, R32C, i32ImmSExt10, i32, 3393 SELBr32, ORr32, CGTIr32, CEQIr32>; 3394 3395def : SELECTBinOpReg<setuge, R8C, i8, SELBr8, ORr8, CLGTBr8, CEQBr8>; 3396def : SELECTBinOpImm<setuge, R8C, immSExt8, i8, 3397 SELBr8, ORr8, CLGTBIr8, CEQBIr8>; 3398 3399def : SELECTBinOpReg<setuge, R16C, i16, SELBr16, ORr16, CLGTHr16, CEQHr16>; 3400def : SELECTBinOpImm<setuge, R16C, i16ImmUns10, i16, 3401 SELBr16, ORr16, CLGTHIr16, CEQHIr16>; 3402 3403def : SELECTBinOpReg<setuge, R32C, i32, SELBr32, ORr32, CLGTr32, CEQr32>; 3404def : SELECTBinOpImm<setuge, R32C, i32ImmUns10, i32, 3405 SELBr32, ORr32, CLGTIr32, CEQIr32>; 3406 3407//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ 3408 3409let 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: 3449def : Pat<(SPUcall (SPUpcrel texternalsym:$func, 0)), 3450 (BRSL texternalsym:$func)>; 3451 3452def : Pat<(SPUcall (SPUaform texternalsym:$func, 0)), 3453 (BRASL texternalsym:$func)>; 3454 3455// Unconditional branches: 3456let 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 let isIndirectBranch = 1 in { 3471 def BI: 3472 BIForm<0b00010101100, "bi\t$func", [(brind R32C:$func)]>; 3473 } 3474 } 3475 3476 // Conditional branches: 3477 class BRNZInst<dag IOL, list<dag> pattern>: 3478 RI16Form<0b010000100, (outs), IOL, "brnz\t$rCond,$dest", 3479 BranchResolv, pattern>; 3480 3481 class BRNZRegInst<RegisterClass rclass>: 3482 BRNZInst<(ins rclass:$rCond, brtarget:$dest), 3483 [(brcond rclass:$rCond, bb:$dest)]>; 3484 3485 class BRNZVecInst<ValueType vectype>: 3486 BRNZInst<(ins VECREG:$rCond, brtarget:$dest), 3487 [(brcond (vectype VECREG:$rCond), bb:$dest)]>; 3488 3489 multiclass BranchNotZero { 3490 def v4i32 : BRNZVecInst<v4i32>; 3491 def r32 : BRNZRegInst<R32C>; 3492 } 3493 3494 defm BRNZ : BranchNotZero; 3495 3496 class BRZInst<dag IOL, list<dag> pattern>: 3497 RI16Form<0b000000100, (outs), IOL, "brz\t$rT,$dest", 3498 BranchResolv, pattern>; 3499 3500 class BRZRegInst<RegisterClass rclass>: 3501 BRZInst<(ins rclass:$rT, brtarget:$dest), [/* no pattern */]>; 3502 3503 class BRZVecInst<ValueType vectype>: 3504 BRZInst<(ins VECREG:$rT, brtarget:$dest), [/* no pattern */]>; 3505 3506 multiclass BranchZero { 3507 def v4i32: BRZVecInst<v4i32>; 3508 def r32: BRZRegInst<R32C>; 3509 } 3510 3511 defm BRZ: BranchZero; 3512 3513 // Note: LLVM doesn't do branch conditional, indirect. Otherwise these would 3514 // be useful: 3515 /* 3516 class BINZInst<dag IOL, list<dag> pattern>: 3517 BICondForm<0b10010100100, (outs), IOL, "binz\t$rA, $dest", pattern>; 3518 3519 class BINZRegInst<RegisterClass rclass>: 3520 BINZInst<(ins rclass:$rA, brtarget:$dest), 3521 [(brcond rclass:$rA, R32C:$dest)]>; 3522 3523 class BINZVecInst<ValueType vectype>: 3524 BINZInst<(ins VECREG:$rA, R32C:$dest), 3525 [(brcond (vectype VECREG:$rA), R32C:$dest)]>; 3526 3527 multiclass BranchNotZeroIndirect { 3528 def v4i32: BINZVecInst<v4i32>; 3529 def r32: BINZRegInst<R32C>; 3530 } 3531 3532 defm BINZ: BranchNotZeroIndirect; 3533 3534 class BIZInst<dag IOL, list<dag> pattern>: 3535 BICondForm<0b00010100100, (outs), IOL, "biz\t$rA, $func", pattern>; 3536 3537 class BIZRegInst<RegisterClass rclass>: 3538 BIZInst<(ins rclass:$rA, R32C:$func), [/* no pattern */]>; 3539 3540 class BIZVecInst<ValueType vectype>: 3541 BIZInst<(ins VECREG:$rA, R32C:$func), [/* no pattern */]>; 3542 3543 multiclass BranchZeroIndirect { 3544 def v4i32: BIZVecInst<v4i32>; 3545 def r32: BIZRegInst<R32C>; 3546 } 3547 3548 defm BIZ: BranchZeroIndirect; 3549 */ 3550 3551 class BRHNZInst<dag IOL, list<dag> pattern>: 3552 RI16Form<0b011000100, (outs), IOL, "brhnz\t$rCond,$dest", BranchResolv, 3553 pattern>; 3554 3555 class BRHNZRegInst<RegisterClass rclass>: 3556 BRHNZInst<(ins rclass:$rCond, brtarget:$dest), 3557 [(brcond rclass:$rCond, bb:$dest)]>; 3558 3559 class BRHNZVecInst<ValueType vectype>: 3560 BRHNZInst<(ins VECREG:$rCond, brtarget:$dest), [/* no pattern */]>; 3561 3562 multiclass BranchNotZeroHalfword { 3563 def v8i16: BRHNZVecInst<v8i16>; 3564 def r16: BRHNZRegInst<R16C>; 3565 } 3566 3567 defm BRHNZ: BranchNotZeroHalfword; 3568 3569 class BRHZInst<dag IOL, list<dag> pattern>: 3570 RI16Form<0b001000100, (outs), IOL, "brhz\t$rT,$dest", BranchResolv, 3571 pattern>; 3572 3573 class BRHZRegInst<RegisterClass rclass>: 3574 BRHZInst<(ins rclass:$rT, brtarget:$dest), [/* no pattern */]>; 3575 3576 class BRHZVecInst<ValueType vectype>: 3577 BRHZInst<(ins VECREG:$rT, brtarget:$dest), [/* no pattern */]>; 3578 3579 multiclass BranchZeroHalfword { 3580 def v8i16: BRHZVecInst<v8i16>; 3581 def r16: BRHZRegInst<R16C>; 3582 } 3583 3584 defm BRHZ: BranchZeroHalfword; 3585} 3586 3587//===----------------------------------------------------------------------===// 3588// setcc and brcond patterns: 3589//===----------------------------------------------------------------------===// 3590 3591def : Pat<(brcond (i16 (seteq R16C:$rA, 0)), bb:$dest), 3592 (BRHZr16 R16C:$rA, bb:$dest)>; 3593def : Pat<(brcond (i16 (setne R16C:$rA, 0)), bb:$dest), 3594 (BRHNZr16 R16C:$rA, bb:$dest)>; 3595 3596def : Pat<(brcond (i32 (seteq R32C:$rA, 0)), bb:$dest), 3597 (BRZr32 R32C:$rA, bb:$dest)>; 3598def : Pat<(brcond (i32 (setne R32C:$rA, 0)), bb:$dest), 3599 (BRNZr32 R32C:$rA, bb:$dest)>; 3600 3601multiclass BranchCondEQ<PatFrag cond, SPUInstr brinst16, SPUInstr brinst32> 3602{ 3603 def r16imm: Pat<(brcond (i16 (cond R16C:$rA, i16ImmSExt10:$val)), bb:$dest), 3604 (brinst16 (CEQHIr16 R16C:$rA, i16ImmSExt10:$val), bb:$dest)>; 3605 3606 def r16 : Pat<(brcond (i16 (cond R16C:$rA, R16C:$rB)), bb:$dest), 3607 (brinst16 (CEQHr16 R16C:$rA, R16:$rB), bb:$dest)>; 3608 3609 def r32imm : Pat<(brcond (i32 (cond R32C:$rA, i32ImmSExt10:$val)), bb:$dest), 3610 (brinst32 (CEQIr32 R32C:$rA, i32ImmSExt10:$val), bb:$dest)>; 3611 3612 def r32 : Pat<(brcond (i32 (cond R32C:$rA, R32C:$rB)), bb:$dest), 3613 (brinst32 (CEQr32 R32C:$rA, R32C:$rB), bb:$dest)>; 3614} 3615 3616defm BRCONDeq : BranchCondEQ<seteq, BRHNZr16, BRNZr32>; 3617defm BRCONDne : BranchCondEQ<setne, BRHZr16, BRZr32>; 3618 3619multiclass BranchCondLGT<PatFrag cond, SPUInstr brinst16, SPUInstr brinst32> 3620{ 3621 def r16imm : Pat<(brcond (i16 (cond R16C:$rA, i16ImmSExt10:$val)), bb:$dest), 3622 (brinst16 (CLGTHIr16 R16C:$rA, i16ImmSExt10:$val), bb:$dest)>; 3623 3624 def r16 : Pat<(brcond (i16 (cond R16C:$rA, R16C:$rB)), bb:$dest), 3625 (brinst16 (CLGTHr16 R16C:$rA, R16:$rB), bb:$dest)>; 3626 3627 def r32imm : Pat<(brcond (i32 (cond R32C:$rA, i32ImmSExt10:$val)), bb:$dest), 3628 (brinst32 (CLGTIr32 R32C:$rA, i32ImmSExt10:$val), bb:$dest)>; 3629 3630 def r32 : Pat<(brcond (i32 (cond R32C:$rA, R32C:$rB)), bb:$dest), 3631 (brinst32 (CLGTr32 R32C:$rA, R32C:$rB), bb:$dest)>; 3632} 3633 3634defm BRCONDugt : BranchCondLGT<setugt, BRHNZr16, BRNZr32>; 3635defm BRCONDule : BranchCondLGT<setule, BRHZr16, BRZr32>; 3636 3637multiclass BranchCondLGTEQ<PatFrag cond, SPUInstr orinst16, SPUInstr brinst16, 3638 SPUInstr orinst32, SPUInstr brinst32> 3639{ 3640 def r16imm: Pat<(brcond (i16 (cond R16C:$rA, i16ImmSExt10:$val)), bb:$dest), 3641 (brinst16 (orinst16 (CLGTHIr16 R16C:$rA, i16ImmSExt10:$val), 3642 (CEQHIr16 R16C:$rA, i16ImmSExt10:$val)), 3643 bb:$dest)>; 3644 3645 def r16: Pat<(brcond (i16 (cond R16C:$rA, R16C:$rB)), bb:$dest), 3646 (brinst16 (orinst16 (CLGTHr16 R16C:$rA, R16:$rB), 3647 (CEQHr16 R16C:$rA, R16:$rB)), 3648 bb:$dest)>; 3649 3650 def r32imm : Pat<(brcond (i32 (cond R32C:$rA, i32ImmSExt10:$val)), bb:$dest), 3651 (brinst32 (orinst32 (CLGTIr32 R32C:$rA, i32ImmSExt10:$val), 3652 (CEQIr32 R32C:$rA, i32ImmSExt10:$val)), 3653 bb:$dest)>; 3654 3655 def r32 : Pat<(brcond (i32 (cond R32C:$rA, R32C:$rB)), bb:$dest), 3656 (brinst32 (orinst32 (CLGTr32 R32C:$rA, R32C:$rB), 3657 (CEQr32 R32C:$rA, R32C:$rB)), 3658 bb:$dest)>; 3659} 3660 3661defm BRCONDuge : BranchCondLGTEQ<setuge, ORr16, BRHNZr16, ORr32, BRNZr32>; 3662defm BRCONDult : BranchCondLGTEQ<setult, ORr16, BRHZr16, ORr32, BRZr32>; 3663 3664multiclass BranchCondGT<PatFrag cond, SPUInstr brinst16, SPUInstr brinst32> 3665{ 3666 def r16imm : Pat<(brcond (i16 (cond R16C:$rA, i16ImmSExt10:$val)), bb:$dest), 3667 (brinst16 (CGTHIr16 R16C:$rA, i16ImmSExt10:$val), bb:$dest)>; 3668 3669 def r16 : Pat<(brcond (i16 (cond R16C:$rA, R16C:$rB)), bb:$dest), 3670 (brinst16 (CGTHr16 R16C:$rA, R16:$rB), bb:$dest)>; 3671 3672 def r32imm : Pat<(brcond (i32 (cond R32C:$rA, i32ImmSExt10:$val)), bb:$dest), 3673 (brinst32 (CGTIr32 R32C:$rA, i32ImmSExt10:$val), bb:$dest)>; 3674 3675 def r32 : Pat<(brcond (i32 (cond R32C:$rA, R32C:$rB)), bb:$dest), 3676 (brinst32 (CGTr32 R32C:$rA, R32C:$rB), bb:$dest)>; 3677} 3678 3679defm BRCONDgt : BranchCondGT<setgt, BRHNZr16, BRNZr32>; 3680defm BRCONDle : BranchCondGT<setle, BRHZr16, BRZr32>; 3681 3682multiclass BranchCondGTEQ<PatFrag cond, SPUInstr orinst16, SPUInstr brinst16, 3683 SPUInstr orinst32, SPUInstr brinst32> 3684{ 3685 def r16imm: Pat<(brcond (i16 (cond R16C:$rA, i16ImmSExt10:$val)), bb:$dest), 3686 (brinst16 (orinst16 (CGTHIr16 R16C:$rA, i16ImmSExt10:$val), 3687 (CEQHIr16 R16C:$rA, i16ImmSExt10:$val)), 3688 bb:$dest)>; 3689 3690 def r16: Pat<(brcond (i16 (cond R16C:$rA, R16C:$rB)), bb:$dest), 3691 (brinst16 (orinst16 (CGTHr16 R16C:$rA, R16:$rB), 3692 (CEQHr16 R16C:$rA, R16:$rB)), 3693 bb:$dest)>; 3694 3695 def r32imm : Pat<(brcond (i32 (cond R32C:$rA, i32ImmSExt10:$val)), bb:$dest), 3696 (brinst32 (orinst32 (CGTIr32 R32C:$rA, i32ImmSExt10:$val), 3697 (CEQIr32 R32C:$rA, i32ImmSExt10:$val)), 3698 bb:$dest)>; 3699 3700 def r32 : Pat<(brcond (i32 (cond R32C:$rA, R32C:$rB)), bb:$dest), 3701 (brinst32 (orinst32 (CGTr32 R32C:$rA, R32C:$rB), 3702 (CEQr32 R32C:$rA, R32C:$rB)), 3703 bb:$dest)>; 3704} 3705 3706defm BRCONDge : BranchCondGTEQ<setge, ORr16, BRHNZr16, ORr32, BRNZr32>; 3707defm BRCONDlt : BranchCondGTEQ<setlt, ORr16, BRHZr16, ORr32, BRZr32>; 3708 3709let isTerminator = 1, isBarrier = 1 in { 3710 let isReturn = 1 in { 3711 def RET: 3712 RETForm<"bi\t$$lr", [(retflag)]>; 3713 } 3714} 3715 3716//===----------------------------------------------------------------------===// 3717// Single precision floating point instructions 3718//===----------------------------------------------------------------------===// 3719 3720class FAInst<dag OOL, dag IOL, list<dag> pattern>: 3721 RRForm<0b01011000100, OOL, IOL, "fa\t$rT, $rA, $rB", 3722 SPrecFP, pattern>; 3723 3724class FAVecInst<ValueType vectype>: 3725 FAInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 3726 [(set (vectype VECREG:$rT), 3727 (fadd (vectype VECREG:$rA), (vectype VECREG:$rB)))]>; 3728 3729multiclass SFPAdd 3730{ 3731 def v4f32: FAVecInst<v4f32>; 3732 def f32: FAInst<(outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB), 3733 [(set R32FP:$rT, (fadd R32FP:$rA, R32FP:$rB))]>; 3734} 3735 3736defm FA : SFPAdd; 3737 3738class FSInst<dag OOL, dag IOL, list<dag> pattern>: 3739 RRForm<0b01011000100, OOL, IOL, "fs\t$rT, $rA, $rB", 3740 SPrecFP, pattern>; 3741 3742class FSVecInst<ValueType vectype>: 3743 FSInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 3744 [(set (vectype VECREG:$rT), 3745 (fsub (vectype VECREG:$rA), (vectype VECREG:$rB)))]>; 3746 3747multiclass SFPSub 3748{ 3749 def v4f32: FSVecInst<v4f32>; 3750 def f32: FSInst<(outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB), 3751 [(set R32FP:$rT, (fsub R32FP:$rA, R32FP:$rB))]>; 3752} 3753 3754defm FS : SFPSub; 3755 3756class FMInst<dag OOL, dag IOL, list<dag> pattern>: 3757 RRForm<0b01100011010, OOL, IOL, 3758 "fm\t$rT, $rA, $rB", SPrecFP, 3759 pattern>; 3760 3761class FMVecInst<ValueType type>: 3762 FMInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 3763 [(set (type VECREG:$rT), 3764 (fmul (type VECREG:$rA), (type VECREG:$rB)))]>; 3765 3766multiclass SFPMul 3767{ 3768 def v4f32: FMVecInst<v4f32>; 3769 def f32: FMInst<(outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB), 3770 [(set R32FP:$rT, (fmul R32FP:$rA, R32FP:$rB))]>; 3771} 3772 3773defm FM : SFPMul; 3774 3775// Floating point multiply and add 3776// e.g. d = c + (a * b) 3777def FMAv4f32: 3778 RRRForm<0b0111, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), 3779 "fma\t$rT, $rA, $rB, $rC", SPrecFP, 3780 [(set (v4f32 VECREG:$rT), 3781 (fadd (v4f32 VECREG:$rC), 3782 (fmul (v4f32 VECREG:$rA), (v4f32 VECREG:$rB))))]>; 3783 3784def FMAf32: 3785 RRRForm<0b0111, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB, R32FP:$rC), 3786 "fma\t$rT, $rA, $rB, $rC", SPrecFP, 3787 [(set R32FP:$rT, (fadd R32FP:$rC, (fmul R32FP:$rA, R32FP:$rB)))]>; 3788 3789// FP multiply and subtract 3790// Subtracts value in rC from product 3791// res = a * b - c 3792def FMSv4f32 : 3793 RRRForm<0b0111, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), 3794 "fms\t$rT, $rA, $rB, $rC", SPrecFP, 3795 [(set (v4f32 VECREG:$rT), 3796 (fsub (fmul (v4f32 VECREG:$rA), (v4f32 VECREG:$rB)), 3797 (v4f32 VECREG:$rC)))]>; 3798 3799def FMSf32 : 3800 RRRForm<0b0111, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB, R32FP:$rC), 3801 "fms\t$rT, $rA, $rB, $rC", SPrecFP, 3802 [(set R32FP:$rT, 3803 (fsub (fmul R32FP:$rA, R32FP:$rB), R32FP:$rC))]>; 3804 3805// Floating Negative Mulitply and Subtract 3806// Subtracts product from value in rC 3807// res = fneg(fms a b c) 3808// = - (a * b - c) 3809// = c - a * b 3810// NOTE: subtraction order 3811// fsub a b = a - b 3812// fs a b = b - a? 3813def FNMSf32 : 3814 RRRForm<0b1101, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB, R32FP:$rC), 3815 "fnms\t$rT, $rA, $rB, $rC", SPrecFP, 3816 [(set R32FP:$rT, (fsub R32FP:$rC, (fmul R32FP:$rA, R32FP:$rB)))]>; 3817 3818def FNMSv4f32 : 3819 RRRForm<0b1101, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), 3820 "fnms\t$rT, $rA, $rB, $rC", SPrecFP, 3821 [(set (v4f32 VECREG:$rT), 3822 (fsub (v4f32 VECREG:$rC), 3823 (fmul (v4f32 VECREG:$rA), 3824 (v4f32 VECREG:$rB))))]>; 3825 3826 3827 3828 3829// Floating point reciprocal estimate 3830 3831class FRESTInst<dag OOL, dag IOL>: 3832 RRForm_1<0b00110111000, OOL, IOL, 3833 "frest\t$rT, $rA", SPrecFP, 3834 [/* no pattern */]>; 3835 3836def FRESTv4f32 : 3837 FRESTInst<(outs VECREG:$rT), (ins VECREG:$rA)>; 3838 3839def FRESTf32 : 3840 FRESTInst<(outs R32FP:$rT), (ins R32FP:$rA)>; 3841 3842// Floating point interpolate (used in conjunction with reciprocal estimate) 3843def FIv4f32 : 3844 RRForm<0b00101011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 3845 "fi\t$rT, $rA, $rB", SPrecFP, 3846 [/* no pattern */]>; 3847 3848def FIf32 : 3849 RRForm<0b00101011110, (outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB), 3850 "fi\t$rT, $rA, $rB", SPrecFP, 3851 [/* no pattern */]>; 3852 3853//-------------------------------------------------------------------------- 3854// Basic single precision floating point comparisons: 3855// 3856// Note: There is no support on SPU for single precision NaN. Consequently, 3857// ordered and unordered comparisons are the same. 3858//-------------------------------------------------------------------------- 3859 3860def FCEQf32 : 3861 RRForm<0b01000011110, (outs R32C:$rT), (ins R32FP:$rA, R32FP:$rB), 3862 "fceq\t$rT, $rA, $rB", SPrecFP, 3863 [(set R32C:$rT, (setueq R32FP:$rA, R32FP:$rB))]>; 3864 3865def : Pat<(setoeq R32FP:$rA, R32FP:$rB), 3866 (FCEQf32 R32FP:$rA, R32FP:$rB)>; 3867 3868def FCMEQf32 : 3869 RRForm<0b01010011110, (outs R32C:$rT), (ins R32FP:$rA, R32FP:$rB), 3870 "fcmeq\t$rT, $rA, $rB", SPrecFP, 3871 [(set R32C:$rT, (setueq (fabs R32FP:$rA), (fabs R32FP:$rB)))]>; 3872 3873def : Pat<(setoeq (fabs R32FP:$rA), (fabs R32FP:$rB)), 3874 (FCMEQf32 R32FP:$rA, R32FP:$rB)>; 3875 3876def FCGTf32 : 3877 RRForm<0b01000011010, (outs R32C:$rT), (ins R32FP:$rA, R32FP:$rB), 3878 "fcgt\t$rT, $rA, $rB", SPrecFP, 3879 [(set R32C:$rT, (setugt R32FP:$rA, R32FP:$rB))]>; 3880 3881def : Pat<(setogt R32FP:$rA, R32FP:$rB), 3882 (FCGTf32 R32FP:$rA, R32FP:$rB)>; 3883 3884def FCMGTf32 : 3885 RRForm<0b01010011010, (outs R32C:$rT), (ins R32FP:$rA, R32FP:$rB), 3886 "fcmgt\t$rT, $rA, $rB", SPrecFP, 3887 [(set R32C:$rT, (setugt (fabs R32FP:$rA), (fabs R32FP:$rB)))]>; 3888 3889def : Pat<(setogt (fabs R32FP:$rA), (fabs R32FP:$rB)), 3890 (FCMGTf32 R32FP:$rA, R32FP:$rB)>; 3891 3892//-------------------------------------------------------------------------- 3893// Single precision floating point comparisons and SETCC equivalents: 3894//-------------------------------------------------------------------------- 3895 3896def : SETCCNegCondReg<setune, R32FP, i32, XORIr32, FCEQf32>; 3897def : SETCCNegCondReg<setone, R32FP, i32, XORIr32, FCEQf32>; 3898 3899def : SETCCBinOpReg<setuge, R32FP, ORr32, FCGTf32, FCEQf32>; 3900def : SETCCBinOpReg<setoge, R32FP, ORr32, FCGTf32, FCEQf32>; 3901 3902def : SETCCBinOpReg<setult, R32FP, NORr32, FCGTf32, FCEQf32>; 3903def : SETCCBinOpReg<setolt, R32FP, NORr32, FCGTf32, FCEQf32>; 3904 3905def : Pat<(setule R32FP:$rA, R32FP:$rB), 3906 (XORIr32 (FCGTf32 R32FP:$rA, R32FP:$rB), 0xffffffff)>; 3907def : Pat<(setole R32FP:$rA, R32FP:$rB), 3908 (XORIr32 (FCGTf32 R32FP:$rA, R32FP:$rB), 0xffffffff)>; 3909 3910// FP Status and Control Register Write 3911// Why isn't rT a don't care in the ISA? 3912// Should we create a special RRForm_3 for this guy and zero out the rT? 3913def FSCRWf32 : 3914 RRForm_1<0b01011101110, (outs R32FP:$rT), (ins R32FP:$rA), 3915 "fscrwr\t$rA", SPrecFP, 3916 [/* This instruction requires an intrinsic. Note: rT is unused. */]>; 3917 3918// FP Status and Control Register Read 3919def FSCRRf32 : 3920 RRForm_2<0b01011101110, (outs R32FP:$rT), (ins), 3921 "fscrrd\t$rT", SPrecFP, 3922 [/* This instruction requires an intrinsic */]>; 3923 3924// llvm instruction space 3925// How do these map onto cell instructions? 3926// fdiv rA rB 3927// frest rC rB # c = 1/b (both lines) 3928// fi rC rB rC 3929// fm rD rA rC # d = a * 1/b 3930// fnms rB rD rB rA # b = - (d * b - a) --should == 0 in a perfect world 3931// fma rB rB rC rD # b = b * c + d 3932// = -(d *b -a) * c + d 3933// = a * c - c ( a *b *c - a) 3934 3935// fcopysign (???) 3936 3937// Library calls: 3938// These llvm instructions will actually map to library calls. 3939// All that's needed, then, is to check that the appropriate library is 3940// imported and do a brsl to the proper function name. 3941// frem # fmod(x, y): x - (x/y) * y 3942// (Note: fmod(double, double), fmodf(float,float) 3943// fsqrt? 3944// fsin? 3945// fcos? 3946// Unimplemented SPU instruction space 3947// floating reciprocal absolute square root estimate (frsqest) 3948 3949// The following are probably just intrinsics 3950// status and control register write 3951// status and control register read 3952 3953//-------------------------------------- 3954// Floating Point Conversions 3955// Signed conversions: 3956def CSiFv4f32: 3957 CVTIntFPForm<0b0101101110, (outs VECREG:$rT), (ins VECREG:$rA), 3958 "csflt\t$rT, $rA, 0", SPrecFP, 3959 [(set (v4f32 VECREG:$rT), (sint_to_fp (v4i32 VECREG:$rA)))]>; 3960 3961// Convert signed integer to floating point 3962def CSiFf32 : 3963 CVTIntFPForm<0b0101101110, (outs R32FP:$rT), (ins R32C:$rA), 3964 "csflt\t$rT, $rA, 0", SPrecFP, 3965 [(set R32FP:$rT, (sint_to_fp R32C:$rA))]>; 3966 3967// Convert unsigned into to float 3968def CUiFv4f32 : 3969 CVTIntFPForm<0b1101101110, (outs VECREG:$rT), (ins VECREG:$rA), 3970 "cuflt\t$rT, $rA, 0", SPrecFP, 3971 [(set (v4f32 VECREG:$rT), (uint_to_fp (v4i32 VECREG:$rA)))]>; 3972 3973def CUiFf32 : 3974 CVTIntFPForm<0b1101101110, (outs R32FP:$rT), (ins R32C:$rA), 3975 "cuflt\t$rT, $rA, 0", SPrecFP, 3976 [(set R32FP:$rT, (uint_to_fp R32C:$rA))]>; 3977 3978// Convert float to unsigned int 3979// Assume that scale = 0 3980 3981def CFUiv4f32 : 3982 CVTIntFPForm<0b1101101110, (outs VECREG:$rT), (ins VECREG:$rA), 3983 "cfltu\t$rT, $rA, 0", SPrecFP, 3984 [(set (v4i32 VECREG:$rT), (fp_to_uint (v4f32 VECREG:$rA)))]>; 3985 3986def CFUif32 : 3987 CVTIntFPForm<0b1101101110, (outs R32C:$rT), (ins R32FP:$rA), 3988 "cfltu\t$rT, $rA, 0", SPrecFP, 3989 [(set R32C:$rT, (fp_to_uint R32FP:$rA))]>; 3990 3991// Convert float to signed int 3992// Assume that scale = 0 3993 3994def CFSiv4f32 : 3995 CVTIntFPForm<0b1101101110, (outs VECREG:$rT), (ins VECREG:$rA), 3996 "cflts\t$rT, $rA, 0", SPrecFP, 3997 [(set (v4i32 VECREG:$rT), (fp_to_sint (v4f32 VECREG:$rA)))]>; 3998 3999def CFSif32 : 4000 CVTIntFPForm<0b1101101110, (outs R32C:$rT), (ins R32FP:$rA), 4001 "cflts\t$rT, $rA, 0", SPrecFP, 4002 [(set R32C:$rT, (fp_to_sint R32FP:$rA))]>; 4003 4004//===----------------------------------------------------------------------==// 4005// Single<->Double precision conversions 4006//===----------------------------------------------------------------------==// 4007 4008// NOTE: We use "vec" name suffix here to avoid confusion (e.g. input is a 4009// v4f32, output is v2f64--which goes in the name?) 4010 4011// Floating point extend single to double 4012// NOTE: Not sure if passing in v4f32 to FESDvec is correct since it 4013// operates on two double-word slots (i.e. 1st and 3rd fp numbers 4014// are ignored). 4015def FESDvec : 4016 RRForm_1<0b00011101110, (outs VECREG:$rT), (ins VECREG:$rA), 4017 "fesd\t$rT, $rA", SPrecFP, 4018 [/*(set (v2f64 VECREG:$rT), (fextend (v4f32 VECREG:$rA)))*/]>; 4019 4020def FESDf32 : 4021 RRForm_1<0b00011101110, (outs R64FP:$rT), (ins R32FP:$rA), 4022 "fesd\t$rT, $rA", SPrecFP, 4023 [(set R64FP:$rT, (fextend R32FP:$rA))]>; 4024 4025// Floating point round double to single 4026//def FRDSvec : 4027// RRForm_1<0b10011101110, (outs VECREG:$rT), (ins VECREG:$rA), 4028// "frds\t$rT, $rA,", SPrecFP, 4029// [(set (v4f32 R32FP:$rT), (fround (v2f64 R64FP:$rA)))]>; 4030 4031def FRDSf64 : 4032 RRForm_1<0b10011101110, (outs R32FP:$rT), (ins R64FP:$rA), 4033 "frds\t$rT, $rA", SPrecFP, 4034 [(set R32FP:$rT, (fround R64FP:$rA))]>; 4035 4036//ToDo include anyextend? 4037 4038//===----------------------------------------------------------------------==// 4039// Double precision floating point instructions 4040//===----------------------------------------------------------------------==// 4041def FAf64 : 4042 RRForm<0b00110011010, (outs R64FP:$rT), (ins R64FP:$rA, R64FP:$rB), 4043 "dfa\t$rT, $rA, $rB", DPrecFP, 4044 [(set R64FP:$rT, (fadd R64FP:$rA, R64FP:$rB))]>; 4045 4046def FAv2f64 : 4047 RRForm<0b00110011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 4048 "dfa\t$rT, $rA, $rB", DPrecFP, 4049 [(set (v2f64 VECREG:$rT), (fadd (v2f64 VECREG:$rA), (v2f64 VECREG:$rB)))]>; 4050 4051def FSf64 : 4052 RRForm<0b10100011010, (outs R64FP:$rT), (ins R64FP:$rA, R64FP:$rB), 4053 "dfs\t$rT, $rA, $rB", DPrecFP, 4054 [(set R64FP:$rT, (fsub R64FP:$rA, R64FP:$rB))]>; 4055 4056def FSv2f64 : 4057 RRForm<0b10100011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 4058 "dfs\t$rT, $rA, $rB", DPrecFP, 4059 [(set (v2f64 VECREG:$rT), 4060 (fsub (v2f64 VECREG:$rA), (v2f64 VECREG:$rB)))]>; 4061 4062def FMf64 : 4063 RRForm<0b01100011010, (outs R64FP:$rT), (ins R64FP:$rA, R64FP:$rB), 4064 "dfm\t$rT, $rA, $rB", DPrecFP, 4065 [(set R64FP:$rT, (fmul R64FP:$rA, R64FP:$rB))]>; 4066 4067def FMv2f64: 4068 RRForm<0b00100011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 4069 "dfm\t$rT, $rA, $rB", DPrecFP, 4070 [(set (v2f64 VECREG:$rT), 4071 (fmul (v2f64 VECREG:$rA), (v2f64 VECREG:$rB)))]>; 4072 4073def FMAf64: 4074 RRForm<0b00111010110, (outs R64FP:$rT), 4075 (ins R64FP:$rA, R64FP:$rB, R64FP:$rC), 4076 "dfma\t$rT, $rA, $rB", DPrecFP, 4077 [(set R64FP:$rT, (fadd R64FP:$rC, (fmul R64FP:$rA, R64FP:$rB)))]>, 4078 RegConstraint<"$rC = $rT">, 4079 NoEncode<"$rC">; 4080 4081def FMAv2f64: 4082 RRForm<0b00111010110, (outs VECREG:$rT), 4083 (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), 4084 "dfma\t$rT, $rA, $rB", DPrecFP, 4085 [(set (v2f64 VECREG:$rT), 4086 (fadd (v2f64 VECREG:$rC), 4087 (fmul (v2f64 VECREG:$rA), (v2f64 VECREG:$rB))))]>, 4088 RegConstraint<"$rC = $rT">, 4089 NoEncode<"$rC">; 4090 4091def FMSf64 : 4092 RRForm<0b10111010110, (outs R64FP:$rT), 4093 (ins R64FP:$rA, R64FP:$rB, R64FP:$rC), 4094 "dfms\t$rT, $rA, $rB", DPrecFP, 4095 [(set R64FP:$rT, (fsub (fmul R64FP:$rA, R64FP:$rB), R64FP:$rC))]>, 4096 RegConstraint<"$rC = $rT">, 4097 NoEncode<"$rC">; 4098 4099def FMSv2f64 : 4100 RRForm<0b10111010110, (outs VECREG:$rT), 4101 (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), 4102 "dfms\t$rT, $rA, $rB", DPrecFP, 4103 [(set (v2f64 VECREG:$rT), 4104 (fsub (fmul (v2f64 VECREG:$rA), (v2f64 VECREG:$rB)), 4105 (v2f64 VECREG:$rC)))]>; 4106 4107// DFNMS: - (a * b - c) 4108// - (a * b) + c => c - (a * b) 4109 4110class DFNMSInst<dag OOL, dag IOL, list<dag> pattern>: 4111 RRForm<0b01111010110, OOL, IOL, "dfnms\t$rT, $rA, $rB", 4112 DPrecFP, pattern>, 4113 RegConstraint<"$rC = $rT">, 4114 NoEncode<"$rC">; 4115 4116class DFNMSVecInst<list<dag> pattern>: 4117 DFNMSInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), 4118 pattern>; 4119 4120class DFNMSRegInst<list<dag> pattern>: 4121 DFNMSInst<(outs R64FP:$rT), (ins R64FP:$rA, R64FP:$rB, R64FP:$rC), 4122 pattern>; 4123 4124multiclass DFMultiplySubtract 4125{ 4126 def v2f64 : DFNMSVecInst<[(set (v2f64 VECREG:$rT), 4127 (fsub (v2f64 VECREG:$rC), 4128 (fmul (v2f64 VECREG:$rA), 4129 (v2f64 VECREG:$rB))))]>; 4130 4131 def f64 : DFNMSRegInst<[(set R64FP:$rT, 4132 (fsub R64FP:$rC, 4133 (fmul R64FP:$rA, R64FP:$rB)))]>; 4134} 4135 4136defm DFNMS : DFMultiplySubtract; 4137 4138// - (a * b + c) 4139// - (a * b) - c 4140def FNMAf64 : 4141 RRForm<0b11111010110, (outs R64FP:$rT), 4142 (ins R64FP:$rA, R64FP:$rB, R64FP:$rC), 4143 "dfnma\t$rT, $rA, $rB", DPrecFP, 4144 [(set R64FP:$rT, (fneg (fadd R64FP:$rC, (fmul R64FP:$rA, R64FP:$rB))))]>, 4145 RegConstraint<"$rC = $rT">, 4146 NoEncode<"$rC">; 4147 4148def FNMAv2f64 : 4149 RRForm<0b11111010110, (outs VECREG:$rT), 4150 (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), 4151 "dfnma\t$rT, $rA, $rB", DPrecFP, 4152 [(set (v2f64 VECREG:$rT), 4153 (fneg (fadd (v2f64 VECREG:$rC), 4154 (fmul (v2f64 VECREG:$rA), 4155 (v2f64 VECREG:$rB)))))]>, 4156 RegConstraint<"$rC = $rT">, 4157 NoEncode<"$rC">; 4158 4159//===----------------------------------------------------------------------==// 4160// Floating point negation and absolute value 4161//===----------------------------------------------------------------------==// 4162 4163def : Pat<(fneg (v4f32 VECREG:$rA)), 4164 (XORfnegvec (v4f32 VECREG:$rA), 4165 (v4f32 (ILHUv4i32 0x8000)))>; 4166 4167def : Pat<(fneg R32FP:$rA), 4168 (XORfneg32 R32FP:$rA, (ILHUr32 0x8000))>; 4169 4170// Floating point absolute value 4171// Note: f64 fabs is custom-selected. 4172 4173def : Pat<(fabs R32FP:$rA), 4174 (ANDfabs32 R32FP:$rA, (IOHLr32 (ILHUr32 0x7fff), 0xffff))>; 4175 4176def : Pat<(fabs (v4f32 VECREG:$rA)), 4177 (ANDfabsvec (v4f32 VECREG:$rA), 4178 (IOHLv4i32 (ILHUv4i32 0x7fff), 0xffff))>; 4179 4180//===----------------------------------------------------------------------===// 4181// Hint for branch instructions: 4182//===----------------------------------------------------------------------===// 4183def HBRA : 4184 HBI16Form<0b0001001,(ins hbrtarget:$brinst, brtarget:$btarg), "hbra\t$brinst, $btarg">; 4185 4186//===----------------------------------------------------------------------===// 4187// Execution, Load NOP (execute NOPs belong in even pipeline, load NOPs belong 4188// in the odd pipeline) 4189//===----------------------------------------------------------------------===// 4190 4191def ENOP : SPUInstr<(outs), (ins), "nop", ExecNOP> { 4192 let Pattern = []; 4193 4194 let Inst{0-10} = 0b10000000010; 4195 let Inst{11-17} = 0; 4196 let Inst{18-24} = 0; 4197 let Inst{25-31} = 0; 4198} 4199 4200def LNOP : SPUInstr<(outs), (ins), "lnop", LoadNOP> { 4201 let Pattern = []; 4202 4203 let Inst{0-10} = 0b10000000000; 4204 let Inst{11-17} = 0; 4205 let Inst{18-24} = 0; 4206 let Inst{25-31} = 0; 4207} 4208 4209//===----------------------------------------------------------------------===// 4210// Bit conversions (type conversions between vector/packed types) 4211// NOTE: Promotions are handled using the XS* instructions. 4212//===----------------------------------------------------------------------===// 4213def : Pat<(v16i8 (bitconvert (v8i16 VECREG:$src))), (v16i8 VECREG:$src)>; 4214def : Pat<(v16i8 (bitconvert (v4i32 VECREG:$src))), (v16i8 VECREG:$src)>; 4215def : Pat<(v16i8 (bitconvert (v2i64 VECREG:$src))), (v16i8 VECREG:$src)>; 4216def : Pat<(v16i8 (bitconvert (v4f32 VECREG:$src))), (v16i8 VECREG:$src)>; 4217def : Pat<(v16i8 (bitconvert (v2f64 VECREG:$src))), (v16i8 VECREG:$src)>; 4218 4219def : Pat<(v8i16 (bitconvert (v16i8 VECREG:$src))), (v8i16 VECREG:$src)>; 4220def : Pat<(v8i16 (bitconvert (v4i32 VECREG:$src))), (v8i16 VECREG:$src)>; 4221def : Pat<(v8i16 (bitconvert (v2i64 VECREG:$src))), (v8i16 VECREG:$src)>; 4222def : Pat<(v8i16 (bitconvert (v4f32 VECREG:$src))), (v8i16 VECREG:$src)>; 4223def : Pat<(v8i16 (bitconvert (v2f64 VECREG:$src))), (v8i16 VECREG:$src)>; 4224 4225def : Pat<(v4i32 (bitconvert (v16i8 VECREG:$src))), (v4i32 VECREG:$src)>; 4226def : Pat<(v4i32 (bitconvert (v8i16 VECREG:$src))), (v4i32 VECREG:$src)>; 4227def : Pat<(v4i32 (bitconvert (v2i64 VECREG:$src))), (v4i32 VECREG:$src)>; 4228def : Pat<(v4i32 (bitconvert (v4f32 VECREG:$src))), (v4i32 VECREG:$src)>; 4229def : Pat<(v4i32 (bitconvert (v2f64 VECREG:$src))), (v4i32 VECREG:$src)>; 4230 4231def : Pat<(v2i64 (bitconvert (v16i8 VECREG:$src))), (v2i64 VECREG:$src)>; 4232def : Pat<(v2i64 (bitconvert (v8i16 VECREG:$src))), (v2i64 VECREG:$src)>; 4233def : Pat<(v2i64 (bitconvert (v4i32 VECREG:$src))), (v2i64 VECREG:$src)>; 4234def : Pat<(v2i64 (bitconvert (v4f32 VECREG:$src))), (v2i64 VECREG:$src)>; 4235def : Pat<(v2i64 (bitconvert (v2f64 VECREG:$src))), (v2i64 VECREG:$src)>; 4236 4237def : Pat<(v4f32 (bitconvert (v16i8 VECREG:$src))), (v4f32 VECREG:$src)>; 4238def : Pat<(v4f32 (bitconvert (v8i16 VECREG:$src))), (v4f32 VECREG:$src)>; 4239def : Pat<(v4f32 (bitconvert (v2i64 VECREG:$src))), (v4f32 VECREG:$src)>; 4240def : Pat<(v4f32 (bitconvert (v4i32 VECREG:$src))), (v4f32 VECREG:$src)>; 4241def : Pat<(v4f32 (bitconvert (v2f64 VECREG:$src))), (v4f32 VECREG:$src)>; 4242 4243def : Pat<(v2f64 (bitconvert (v16i8 VECREG:$src))), (v2f64 VECREG:$src)>; 4244def : Pat<(v2f64 (bitconvert (v8i16 VECREG:$src))), (v2f64 VECREG:$src)>; 4245def : Pat<(v2f64 (bitconvert (v4i32 VECREG:$src))), (v2f64 VECREG:$src)>; 4246def : Pat<(v2f64 (bitconvert (v2i64 VECREG:$src))), (v2f64 VECREG:$src)>; 4247def : Pat<(v2f64 (bitconvert (v4f32 VECREG:$src))), (v2f64 VECREG:$src)>; 4248 4249def : Pat<(i128 (bitconvert (v16i8 VECREG:$src))), 4250 (COPY_TO_REGCLASS VECREG:$src, GPRC)>; 4251def : Pat<(i128 (bitconvert (v8i16 VECREG:$src))), 4252 (COPY_TO_REGCLASS VECREG:$src, GPRC)>; 4253def : Pat<(i128 (bitconvert (v4i32 VECREG:$src))), 4254 (COPY_TO_REGCLASS VECREG:$src, GPRC)>; 4255def : Pat<(i128 (bitconvert (v2i64 VECREG:$src))), 4256 (COPY_TO_REGCLASS VECREG:$src, GPRC)>; 4257def : Pat<(i128 (bitconvert (v4f32 VECREG:$src))), 4258 (COPY_TO_REGCLASS VECREG:$src, GPRC)>; 4259def : Pat<(i128 (bitconvert (v2f64 VECREG:$src))), 4260 (COPY_TO_REGCLASS VECREG:$src, GPRC)>; 4261 4262def : Pat<(v16i8 (bitconvert (i128 GPRC:$src))), 4263 (v16i8 (COPY_TO_REGCLASS GPRC:$src, VECREG))>; 4264def : Pat<(v8i16 (bitconvert (i128 GPRC:$src))), 4265 (v8i16 (COPY_TO_REGCLASS GPRC:$src, VECREG))>; 4266def : Pat<(v4i32 (bitconvert (i128 GPRC:$src))), 4267 (v4i32 (COPY_TO_REGCLASS GPRC:$src, VECREG))>; 4268def : Pat<(v2i64 (bitconvert (i128 GPRC:$src))), 4269 (v2i64 (COPY_TO_REGCLASS GPRC:$src, VECREG))>; 4270def : Pat<(v4f32 (bitconvert (i128 GPRC:$src))), 4271 (v4f32 (COPY_TO_REGCLASS GPRC:$src, VECREG))>; 4272def : Pat<(v2f64 (bitconvert (i128 GPRC:$src))), 4273 (v2f64 (COPY_TO_REGCLASS GPRC:$src, VECREG))>; 4274 4275def : Pat<(i32 (bitconvert R32FP:$rA)), 4276 (COPY_TO_REGCLASS R32FP:$rA, R32C)>; 4277 4278def : Pat<(f32 (bitconvert R32C:$rA)), 4279 (COPY_TO_REGCLASS R32C:$rA, R32FP)>; 4280 4281def : Pat<(i64 (bitconvert R64FP:$rA)), 4282 (COPY_TO_REGCLASS R64FP:$rA, R64C)>; 4283 4284def : Pat<(f64 (bitconvert R64C:$rA)), 4285 (COPY_TO_REGCLASS R64C:$rA, R64FP)>; 4286 4287 4288//===----------------------------------------------------------------------===// 4289// Instruction patterns: 4290//===----------------------------------------------------------------------===// 4291 4292// General 32-bit constants: 4293def : Pat<(i32 imm:$imm), 4294 (IOHLr32 (ILHUr32 (HI16 imm:$imm)), (LO16 imm:$imm))>; 4295 4296// Single precision float constants: 4297def : Pat<(f32 fpimm:$imm), 4298 (IOHLf32 (ILHUf32 (HI16_f32 fpimm:$imm)), (LO16_f32 fpimm:$imm))>; 4299 4300// General constant 32-bit vectors 4301def : Pat<(v4i32 v4i32Imm:$imm), 4302 (IOHLv4i32 (v4i32 (ILHUv4i32 (HI16_vec v4i32Imm:$imm))), 4303 (LO16_vec v4i32Imm:$imm))>; 4304 4305// 8-bit constants 4306def : Pat<(i8 imm:$imm), 4307 (ILHr8 imm:$imm)>; 4308 4309//===----------------------------------------------------------------------===// 4310// Zero/Any/Sign extensions 4311//===----------------------------------------------------------------------===// 4312 4313// sext 8->32: Sign extend bytes to words 4314def : Pat<(sext_inreg R32C:$rSrc, i8), 4315 (XSHWr32 (XSBHr32 R32C:$rSrc))>; 4316 4317def : Pat<(i32 (sext R8C:$rSrc)), 4318 (XSHWr16 (XSBHr8 R8C:$rSrc))>; 4319 4320// sext 8->64: Sign extend bytes to double word 4321def : Pat<(sext_inreg R64C:$rSrc, i8), 4322 (XSWDr64_inreg (XSHWr64 (XSBHr64 R64C:$rSrc)))>; 4323 4324def : Pat<(i64 (sext R8C:$rSrc)), 4325 (XSWDr64 (XSHWr16 (XSBHr8 R8C:$rSrc)))>; 4326 4327// zext 8->16: Zero extend bytes to halfwords 4328def : Pat<(i16 (zext R8C:$rSrc)), 4329 (ANDHIi8i16 R8C:$rSrc, 0xff)>; 4330 4331// zext 8->32: Zero extend bytes to words 4332def : Pat<(i32 (zext R8C:$rSrc)), 4333 (ANDIi8i32 R8C:$rSrc, 0xff)>; 4334 4335// zext 8->64: Zero extend bytes to double words 4336def : Pat<(i64 (zext R8C:$rSrc)), 4337 (COPY_TO_REGCLASS (SELBv4i32 (ROTQMBYv4i32 4338 (COPY_TO_REGCLASS 4339 (ANDIi8i32 R8C:$rSrc,0xff), VECREG), 4340 0x4), 4341 (ILv4i32 0x0), 4342 (FSMBIv4i32 0x0f0f)), R64C)>; 4343 4344// anyext 8->16: Extend 8->16 bits, irrespective of sign, preserves high bits 4345def : Pat<(i16 (anyext R8C:$rSrc)), 4346 (ORHIi8i16 R8C:$rSrc, 0)>; 4347 4348// anyext 8->32: Extend 8->32 bits, irrespective of sign, preserves high bits 4349def : Pat<(i32 (anyext R8C:$rSrc)), 4350 (COPY_TO_REGCLASS R8C:$rSrc, R32C)>; 4351 4352// sext 16->64: Sign extend halfword to double word 4353def : Pat<(sext_inreg R64C:$rSrc, i16), 4354 (XSWDr64_inreg (XSHWr64 R64C:$rSrc))>; 4355 4356def : Pat<(sext R16C:$rSrc), 4357 (XSWDr64 (XSHWr16 R16C:$rSrc))>; 4358 4359// zext 16->32: Zero extend halfwords to words 4360def : Pat<(i32 (zext R16C:$rSrc)), 4361 (ANDi16i32 R16C:$rSrc, (ILAr32 0xffff))>; 4362 4363def : Pat<(i32 (zext (and R16C:$rSrc, 0xf))), 4364 (ANDIi16i32 R16C:$rSrc, 0xf)>; 4365 4366def : Pat<(i32 (zext (and R16C:$rSrc, 0xff))), 4367 (ANDIi16i32 R16C:$rSrc, 0xff)>; 4368 4369def : Pat<(i32 (zext (and R16C:$rSrc, 0xfff))), 4370 (ANDIi16i32 R16C:$rSrc, 0xfff)>; 4371 4372// anyext 16->32: Extend 16->32 bits, irrespective of sign 4373def : Pat<(i32 (anyext R16C:$rSrc)), 4374 (COPY_TO_REGCLASS R16C:$rSrc, R32C)>; 4375 4376//===----------------------------------------------------------------------===// 4377// Truncates: 4378// These truncates are for the SPU's supported types (i8, i16, i32). i64 and 4379// above are custom lowered. 4380//===----------------------------------------------------------------------===// 4381 4382def : Pat<(i8 (trunc GPRC:$src)), 4383 (COPY_TO_REGCLASS 4384 (SHUFBgprc GPRC:$src, GPRC:$src, 4385 (IOHLv4i32 (ILHUv4i32 0x0f0f), 0x0f0f)), R8C)>; 4386 4387def : Pat<(i8 (trunc R64C:$src)), 4388 (COPY_TO_REGCLASS 4389 (SHUFBv2i64_m32 4390 (COPY_TO_REGCLASS R64C:$src, VECREG), 4391 (COPY_TO_REGCLASS R64C:$src, VECREG), 4392 (IOHLv4i32 (ILHUv4i32 0x0707), 0x0707)), R8C)>; 4393 4394def : Pat<(i8 (trunc R32C:$src)), 4395 (COPY_TO_REGCLASS 4396 (SHUFBv4i32_m32 4397 (COPY_TO_REGCLASS R32C:$src, VECREG), 4398 (COPY_TO_REGCLASS R32C:$src, VECREG), 4399 (IOHLv4i32 (ILHUv4i32 0x0303), 0x0303)), R8C)>; 4400 4401def : Pat<(i8 (trunc R16C:$src)), 4402 (COPY_TO_REGCLASS 4403 (SHUFBv4i32_m32 4404 (COPY_TO_REGCLASS R16C:$src, VECREG), 4405 (COPY_TO_REGCLASS R16C:$src, VECREG), 4406 (IOHLv4i32 (ILHUv4i32 0x0303), 0x0303)), R8C)>; 4407 4408def : Pat<(i16 (trunc GPRC:$src)), 4409 (COPY_TO_REGCLASS 4410 (SHUFBgprc GPRC:$src, GPRC:$src, 4411 (IOHLv4i32 (ILHUv4i32 0x0e0f), 0x0e0f)), R16C)>; 4412 4413def : Pat<(i16 (trunc R64C:$src)), 4414 (COPY_TO_REGCLASS 4415 (SHUFBv2i64_m32 4416 (COPY_TO_REGCLASS R64C:$src, VECREG), 4417 (COPY_TO_REGCLASS R64C:$src, VECREG), 4418 (IOHLv4i32 (ILHUv4i32 0x0607), 0x0607)), R16C)>; 4419 4420def : Pat<(i16 (trunc R32C:$src)), 4421 (COPY_TO_REGCLASS 4422 (SHUFBv4i32_m32 4423 (COPY_TO_REGCLASS R32C:$src, VECREG), 4424 (COPY_TO_REGCLASS R32C:$src, VECREG), 4425 (IOHLv4i32 (ILHUv4i32 0x0203), 0x0203)), R16C)>; 4426 4427def : Pat<(i32 (trunc GPRC:$src)), 4428 (COPY_TO_REGCLASS 4429 (SHUFBgprc GPRC:$src, GPRC:$src, 4430 (IOHLv4i32 (ILHUv4i32 0x0c0d), 0x0e0f)), R32C)>; 4431 4432def : Pat<(i32 (trunc R64C:$src)), 4433 (COPY_TO_REGCLASS 4434 (SHUFBv2i64_m32 4435 (COPY_TO_REGCLASS R64C:$src, VECREG), 4436 (COPY_TO_REGCLASS R64C:$src, VECREG), 4437 (IOHLv4i32 (ILHUv4i32 0x0405), 0x0607)), R32C)>; 4438 4439//===----------------------------------------------------------------------===// 4440// Address generation: SPU, like PPC, has to split addresses into high and 4441// low parts in order to load them into a register. 4442//===----------------------------------------------------------------------===// 4443 4444def : Pat<(SPUaform tglobaladdr:$in, 0), (ILAlsa tglobaladdr:$in)>; 4445def : Pat<(SPUaform texternalsym:$in, 0), (ILAlsa texternalsym:$in)>; 4446def : Pat<(SPUaform tjumptable:$in, 0), (ILAlsa tjumptable:$in)>; 4447def : Pat<(SPUaform tconstpool:$in, 0), (ILAlsa tconstpool:$in)>; 4448 4449def : Pat<(SPUindirect (SPUhi tglobaladdr:$in, 0), 4450 (SPUlo tglobaladdr:$in, 0)), 4451 (IOHLlo (ILHUhi tglobaladdr:$in), tglobaladdr:$in)>; 4452 4453def : Pat<(SPUindirect (SPUhi texternalsym:$in, 0), 4454 (SPUlo texternalsym:$in, 0)), 4455 (IOHLlo (ILHUhi texternalsym:$in), texternalsym:$in)>; 4456 4457def : Pat<(SPUindirect (SPUhi tjumptable:$in, 0), 4458 (SPUlo tjumptable:$in, 0)), 4459 (IOHLlo (ILHUhi tjumptable:$in), tjumptable:$in)>; 4460 4461def : Pat<(SPUindirect (SPUhi tconstpool:$in, 0), 4462 (SPUlo tconstpool:$in, 0)), 4463 (IOHLlo (ILHUhi tconstpool:$in), tconstpool:$in)>; 4464 4465def : Pat<(add (SPUhi tglobaladdr:$in, 0), (SPUlo tglobaladdr:$in, 0)), 4466 (IOHLlo (ILHUhi tglobaladdr:$in), tglobaladdr:$in)>; 4467 4468def : Pat<(add (SPUhi texternalsym:$in, 0), (SPUlo texternalsym:$in, 0)), 4469 (IOHLlo (ILHUhi texternalsym:$in), texternalsym:$in)>; 4470 4471def : Pat<(add (SPUhi tjumptable:$in, 0), (SPUlo tjumptable:$in, 0)), 4472 (IOHLlo (ILHUhi tjumptable:$in), tjumptable:$in)>; 4473 4474def : Pat<(add (SPUhi tconstpool:$in, 0), (SPUlo tconstpool:$in, 0)), 4475 (IOHLlo (ILHUhi tconstpool:$in), tconstpool:$in)>; 4476 4477// Intrinsics: 4478include "CellSDKIntrinsics.td" 4479// Various math operator instruction sequences 4480include "SPUMathInstr.td" 4481// 64-bit "instructions"/support 4482include "SPU64InstrInfo.td" 4483// 128-bit "instructions"/support 4484include "SPU128InstrInfo.td" 4485