Home | History | Annotate | Download | only in CellSPU
      1 //===-- SPUOperands.td - Cell SPU Instruction Operands -----*- 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 Instruction Operands:
     10 //===----------------------------------------------------------------------===//
     11 
     12 // TO_IMM32 - Convert an i8/i16 to i32.
     13 def TO_IMM32 : SDNodeXForm<imm, [{
     14   return getI32Imm(N->getZExtValue());
     15 }]>;
     16 
     17 // TO_IMM16 - Convert an i8/i32 to i16.
     18 def TO_IMM16 : SDNodeXForm<imm, [{
     19   return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i16);
     20 }]>;
     21 
     22 
     23 def LO16 : SDNodeXForm<imm, [{
     24   unsigned val = N->getZExtValue();
     25   // Transformation function: get the low 16 bits.
     26   return getI32Imm(val & 0xffff);
     27 }]>;
     28 
     29 def LO16_vec : SDNodeXForm<scalar_to_vector, [{
     30   SDValue OpVal(0, 0);
     31 
     32   // Transformation function: get the low 16 bit immediate from a build_vector
     33   // node.
     34   assert(N->getOpcode() == ISD::BUILD_VECTOR
     35          && "LO16_vec got something other than a BUILD_VECTOR");
     36 
     37   // Get first constant operand...
     38   for (unsigned i = 0, e = N->getNumOperands();
     39        OpVal.getNode() == 0 && i != e; ++i) {
     40     if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
     41     if (OpVal.getNode() == 0)
     42       OpVal = N->getOperand(i);
     43   }
     44   
     45   assert(OpVal.getNode() != 0 && "LO16_vec did not locate a <defined> node");
     46   ConstantSDNode *CN = cast<ConstantSDNode>(OpVal);
     47   return getI32Imm((unsigned)CN->getZExtValue() & 0xffff);
     48 }]>;
     49 
     50 // Transform an immediate, returning the high 16 bits shifted down:
     51 def HI16 : SDNodeXForm<imm, [{
     52   return getI32Imm((unsigned)N->getZExtValue() >> 16);
     53 }]>;
     54 
     55 // Transformation function: shift the high 16 bit immediate from a build_vector
     56 // node into the low 16 bits, and return a 16-bit constant.
     57 def HI16_vec : SDNodeXForm<scalar_to_vector, [{
     58   SDValue OpVal(0, 0);
     59 
     60   assert(N->getOpcode() == ISD::BUILD_VECTOR
     61          && "HI16_vec got something other than a BUILD_VECTOR");
     62   
     63   // Get first constant operand...
     64   for (unsigned i = 0, e = N->getNumOperands();
     65        OpVal.getNode() == 0 && i != e; ++i) {
     66     if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
     67     if (OpVal.getNode() == 0)
     68       OpVal = N->getOperand(i);
     69   }
     70   
     71   assert(OpVal.getNode() != 0 && "HI16_vec did not locate a <defined> node");
     72   ConstantSDNode *CN = cast<ConstantSDNode>(OpVal);
     73   return getI32Imm((unsigned)CN->getZExtValue() >> 16);
     74 }]>;
     75 
     76 // simm7 predicate - True if the immediate fits in an 7-bit signed
     77 // field.
     78 def simm7: PatLeaf<(imm), [{
     79   int sextVal = int(N->getSExtValue());
     80   return (sextVal >= -64 && sextVal <= 63);
     81 }]>;
     82 
     83 // uimm7 predicate - True if the immediate fits in an 7-bit unsigned
     84 // field.
     85 def uimm7: PatLeaf<(imm), [{
     86   return (N->getZExtValue() <= 0x7f);
     87 }]>;
     88 
     89 // immSExt8 predicate - True if the immediate fits in an 8-bit sign extended
     90 // field.
     91 def immSExt8  : PatLeaf<(imm), [{
     92   int Value = int(N->getSExtValue());
     93   return (Value >= -(1 << 8) && Value <= (1 << 8) - 1);
     94 }]>;
     95 
     96 // immU8: immediate, unsigned 8-bit quantity
     97 def immU8 : PatLeaf<(imm), [{
     98   return (N->getZExtValue() <= 0xff);
     99 }]>;
    100 
    101 // i32ImmSExt10 predicate - True if the i32 immediate fits in a 10-bit sign
    102 // extended field.  Used by RI10Form instructions like 'ldq'.
    103 def i32ImmSExt10  : PatLeaf<(imm), [{
    104   return isI32IntS10Immediate(N);
    105 }]>;
    106 
    107 // i32ImmUns10 predicate - True if the i32 immediate fits in a 10-bit unsigned
    108 // field.  Used by RI10Form instructions like 'ldq'.
    109 def i32ImmUns10  : PatLeaf<(imm), [{
    110   return isI32IntU10Immediate(N);
    111 }]>;
    112 
    113 // i16ImmSExt10 predicate - True if the i16 immediate fits in a 10-bit sign
    114 // extended field.  Used by RI10Form instructions like 'ldq'.
    115 def i16ImmSExt10  : PatLeaf<(imm), [{
    116   return isI16IntS10Immediate(N);
    117 }]>;
    118 
    119 // i16ImmUns10 predicate - True if the i16 immediate fits into a 10-bit unsigned
    120 // value. Used by RI10Form instructions.
    121 def i16ImmUns10 : PatLeaf<(imm), [{
    122   return isI16IntU10Immediate(N);
    123 }]>;
    124 
    125 def immSExt16  : PatLeaf<(imm), [{
    126   // immSExt16 predicate - True if the immediate fits in a 16-bit sign extended
    127   // field.
    128   short Ignored;
    129   return isIntS16Immediate(N, Ignored);
    130 }]>;
    131 
    132 def immZExt16  : PatLeaf<(imm), [{
    133   // immZExt16 predicate - True if the immediate fits in a 16-bit zero extended
    134   // field.
    135   return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
    136 }], LO16>;
    137 
    138 def immU16 : PatLeaf<(imm), [{
    139   // immU16 predicate- True if the immediate fits into a 16-bit unsigned field.
    140   return (uint64_t)N->getZExtValue() == (N->getZExtValue() & 0xffff);
    141 }]>;
    142 
    143 def imm18  : PatLeaf<(imm), [{
    144   // imm18 predicate: True if the immediate fits into an 18-bit unsigned field.
    145   int Value = (int) N->getZExtValue();
    146   return isUInt<18>(Value); 
    147 }]>;
    148 
    149 def lo16 : PatLeaf<(imm), [{
    150   // lo16 predicate - returns true if the immediate has all zeros in the
    151   // low order bits and is a 32-bit constant:
    152   if (N->getValueType(0) == MVT::i32) {
    153     uint32_t val = N->getZExtValue();
    154     return ((val & 0x0000ffff) == val);
    155   }
    156 
    157   return false;
    158 }], LO16>;
    159 
    160 def hi16 : PatLeaf<(imm), [{
    161   // hi16 predicate - returns true if the immediate has all zeros in the
    162   // low order bits and is a 32-bit constant:
    163   if (N->getValueType(0) == MVT::i32) {
    164     uint32_t val = uint32_t(N->getZExtValue());
    165     return ((val & 0xffff0000) == val);
    166   } else if (N->getValueType(0) == MVT::i64) {
    167     uint64_t val = N->getZExtValue();
    168     return ((val & 0xffff0000ULL) == val);
    169   }
    170 
    171   return false;
    172 }], HI16>;
    173 
    174 def bitshift : PatLeaf<(imm), [{
    175   // bitshift predicate - returns true if 0 < imm <= 7 for SHLQBII
    176   // (shift left quadword by bits immediate)
    177   int64_t Val = N->getZExtValue();
    178   return (Val > 0 && Val <= 7);
    179 }]>;
    180 
    181 //===----------------------------------------------------------------------===//
    182 // Floating point operands:
    183 //===----------------------------------------------------------------------===//
    184 
    185 // Transform a float, returning the high 16 bits shifted down, as if
    186 // the float was really an unsigned integer:
    187 def HI16_f32 : SDNodeXForm<fpimm, [{
    188   float fval = N->getValueAPF().convertToFloat();
    189   return getI32Imm(FloatToBits(fval) >> 16);
    190 }]>;
    191 
    192 // Transformation function on floats: get the low 16 bits as if the float was
    193 // an unsigned integer.
    194 def LO16_f32 : SDNodeXForm<fpimm, [{
    195   float fval = N->getValueAPF().convertToFloat();
    196   return getI32Imm(FloatToBits(fval) & 0xffff);
    197 }]>;
    198 
    199 def FPimm_sext16 : SDNodeXForm<fpimm, [{
    200   float fval = N->getValueAPF().convertToFloat();
    201   return getI32Imm((int) ((FloatToBits(fval) << 16) >> 16));
    202 }]>;
    203 
    204 def FPimm_u18 : SDNodeXForm<fpimm, [{
    205   float fval = N->getValueAPF().convertToFloat();
    206   return getI32Imm(FloatToBits(fval) & ((1 << 18) - 1));
    207 }]>;
    208 
    209 def fpimmSExt16 : PatLeaf<(fpimm), [{
    210   short Ignored;
    211   return isFPS16Immediate(N, Ignored);  
    212 }], FPimm_sext16>;
    213 
    214 // Does the SFP constant only have upp 16 bits set?
    215 def hi16_f32 : PatLeaf<(fpimm), [{
    216   if (N->getValueType(0) == MVT::f32) {
    217     uint32_t val = FloatToBits(N->getValueAPF().convertToFloat());
    218     return ((val & 0xffff0000) == val);
    219   }
    220 
    221   return false;
    222 }], HI16_f32>;
    223 
    224 // Does the SFP constant fit into 18 bits?
    225 def fpimm18  : PatLeaf<(fpimm), [{
    226   if (N->getValueType(0) == MVT::f32) {
    227     uint32_t Value = FloatToBits(N->getValueAPF().convertToFloat());
    228     return isUInt<18>(Value);
    229   }
    230 
    231   return false;
    232 }], FPimm_u18>;
    233 
    234 //===----------------------------------------------------------------------===//
    235 // 64-bit operands (TODO):
    236 //===----------------------------------------------------------------------===//
    237 
    238 //===----------------------------------------------------------------------===//
    239 // build_vector operands:
    240 //===----------------------------------------------------------------------===//
    241 
    242 // v16i8SExt8Imm_xform function: convert build_vector to 8-bit sign extended
    243 // immediate constant load for v16i8 vectors. N.B.: The incoming constant has
    244 // to be a 16-bit quantity with the upper and lower bytes equal (e.g., 0x2a2a).
    245 def v16i8SExt8Imm_xform: SDNodeXForm<build_vector, [{
    246   return SPU::get_vec_i8imm(N, *CurDAG, MVT::i8);
    247 }]>;
    248 
    249 // v16i8SExt8Imm: Predicate test for 8-bit sign extended immediate constant
    250 // load, works in conjunction with its transform function. N.B.: This relies the
    251 // incoming constant being a 16-bit quantity, where the upper and lower bytes
    252 // are EXACTLY the same (e.g., 0x2a2a)
    253 def v16i8SExt8Imm: PatLeaf<(build_vector), [{
    254   return SPU::get_vec_i8imm(N, *CurDAG, MVT::i8).getNode() != 0;
    255 }], v16i8SExt8Imm_xform>;
    256 
    257 // v16i8U8Imm_xform function: convert build_vector to unsigned 8-bit
    258 // immediate constant load for v16i8 vectors. N.B.: The incoming constant has
    259 // to be a 16-bit quantity with the upper and lower bytes equal (e.g., 0x2a2a).
    260 def v16i8U8Imm_xform: SDNodeXForm<build_vector, [{
    261   return SPU::get_vec_i8imm(N, *CurDAG, MVT::i8);
    262 }]>;
    263 
    264 // v16i8U8Imm: Predicate test for unsigned 8-bit immediate constant
    265 // load, works in conjunction with its transform function. N.B.: This relies the
    266 // incoming constant being a 16-bit quantity, where the upper and lower bytes
    267 // are EXACTLY the same (e.g., 0x2a2a)
    268 def v16i8U8Imm: PatLeaf<(build_vector), [{
    269   return SPU::get_vec_i8imm(N, *CurDAG, MVT::i8).getNode() != 0;
    270 }], v16i8U8Imm_xform>;
    271 
    272 // v8i16SExt8Imm_xform function: convert build_vector to 8-bit sign extended
    273 // immediate constant load for v8i16 vectors.
    274 def v8i16SExt8Imm_xform: SDNodeXForm<build_vector, [{
    275   return SPU::get_vec_i8imm(N, *CurDAG, MVT::i16);
    276 }]>;
    277 
    278 // v8i16SExt8Imm: Predicate test for 8-bit sign extended immediate constant
    279 // load, works in conjunction with its transform function.
    280 def v8i16SExt8Imm: PatLeaf<(build_vector), [{
    281   return SPU::get_vec_i8imm(N, *CurDAG, MVT::i16).getNode() != 0;
    282 }], v8i16SExt8Imm_xform>;
    283 
    284 // v8i16SExt10Imm_xform function: convert build_vector to 16-bit sign extended
    285 // immediate constant load for v8i16 vectors.
    286 def v8i16SExt10Imm_xform: SDNodeXForm<build_vector, [{
    287   return SPU::get_vec_i10imm(N, *CurDAG, MVT::i16);
    288 }]>;
    289 
    290 // v8i16SExt10Imm: Predicate test for 16-bit sign extended immediate constant
    291 // load, works in conjunction with its transform function.
    292 def v8i16SExt10Imm: PatLeaf<(build_vector), [{
    293   return SPU::get_vec_i10imm(N, *CurDAG, MVT::i16).getNode() != 0;
    294 }], v8i16SExt10Imm_xform>;
    295 
    296 // v8i16Uns10Imm_xform function: convert build_vector to 16-bit unsigned
    297 // immediate constant load for v8i16 vectors.
    298 def v8i16Uns10Imm_xform: SDNodeXForm<build_vector, [{
    299   return SPU::get_vec_i10imm(N, *CurDAG, MVT::i16);
    300 }]>;
    301 
    302 // v8i16Uns10Imm: Predicate test for 16-bit unsigned immediate constant
    303 // load, works in conjunction with its transform function.
    304 def v8i16Uns10Imm: PatLeaf<(build_vector), [{
    305   return SPU::get_vec_i10imm(N, *CurDAG, MVT::i16).getNode() != 0;
    306 }], v8i16Uns10Imm_xform>;
    307 
    308 // v8i16SExt16Imm_xform function: convert build_vector to 16-bit sign extended
    309 // immediate constant load for v8i16 vectors.
    310 def v8i16Uns16Imm_xform: SDNodeXForm<build_vector, [{
    311   return SPU::get_vec_i16imm(N, *CurDAG, MVT::i16);
    312 }]>;
    313 
    314 // v8i16SExt16Imm: Predicate test for 16-bit sign extended immediate constant
    315 // load, works in conjunction with its transform function.
    316 def v8i16SExt16Imm: PatLeaf<(build_vector), [{
    317   return SPU::get_vec_i16imm(N, *CurDAG, MVT::i16).getNode() != 0;
    318 }], v8i16Uns16Imm_xform>;
    319 
    320 // v4i32SExt10Imm_xform function: convert build_vector to 10-bit sign extended
    321 // immediate constant load for v4i32 vectors.
    322 def v4i32SExt10Imm_xform: SDNodeXForm<build_vector, [{
    323   return SPU::get_vec_i10imm(N, *CurDAG, MVT::i32);
    324 }]>;
    325 
    326 // v4i32SExt10Imm: Predicate test for 10-bit sign extended immediate constant
    327 // load, works in conjunction with its transform function.
    328 def v4i32SExt10Imm: PatLeaf<(build_vector), [{
    329   return SPU::get_vec_i10imm(N, *CurDAG, MVT::i32).getNode() != 0;
    330 }], v4i32SExt10Imm_xform>;
    331 
    332 // v4i32Uns10Imm_xform function: convert build_vector to 10-bit unsigned
    333 // immediate constant load for v4i32 vectors.
    334 def v4i32Uns10Imm_xform: SDNodeXForm<build_vector, [{
    335   return SPU::get_vec_i10imm(N, *CurDAG, MVT::i32);
    336 }]>;
    337 
    338 // v4i32Uns10Imm: Predicate test for 10-bit unsigned immediate constant
    339 // load, works in conjunction with its transform function.
    340 def v4i32Uns10Imm: PatLeaf<(build_vector), [{
    341   return SPU::get_vec_i10imm(N, *CurDAG, MVT::i32).getNode() != 0;
    342 }], v4i32Uns10Imm_xform>;
    343 
    344 // v4i32SExt16Imm_xform function: convert build_vector to 16-bit sign extended
    345 // immediate constant load for v4i32 vectors.
    346 def v4i32SExt16Imm_xform: SDNodeXForm<build_vector, [{
    347   return SPU::get_vec_i16imm(N, *CurDAG, MVT::i32);
    348 }]>;
    349 
    350 // v4i32SExt16Imm: Predicate test for 16-bit sign extended immediate constant
    351 // load, works in conjunction with its transform function.
    352 def v4i32SExt16Imm: PatLeaf<(build_vector), [{
    353   return SPU::get_vec_i16imm(N, *CurDAG, MVT::i32).getNode() != 0;
    354 }], v4i32SExt16Imm_xform>;
    355 
    356 // v4i32Uns18Imm_xform function: convert build_vector to 18-bit unsigned
    357 // immediate constant load for v4i32 vectors.
    358 def v4i32Uns18Imm_xform: SDNodeXForm<build_vector, [{
    359   return SPU::get_vec_u18imm(N, *CurDAG, MVT::i32);
    360 }]>;
    361 
    362 // v4i32Uns18Imm: Predicate test for 18-bit unsigned immediate constant load,
    363 // works in conjunction with its transform function.
    364 def v4i32Uns18Imm: PatLeaf<(build_vector), [{
    365   return SPU::get_vec_u18imm(N, *CurDAG, MVT::i32).getNode() != 0;
    366 }], v4i32Uns18Imm_xform>;
    367 
    368 // ILHUvec_get_imm xform function: convert build_vector to ILHUvec imm constant
    369 // load.
    370 def ILHUvec_get_imm: SDNodeXForm<build_vector, [{
    371   return SPU::get_ILHUvec_imm(N, *CurDAG, MVT::i32);
    372 }]>;
    373 
    374 /// immILHUvec: Predicate test for a ILHU constant vector.
    375 def immILHUvec: PatLeaf<(build_vector), [{
    376   return SPU::get_ILHUvec_imm(N, *CurDAG, MVT::i32).getNode() != 0;
    377 }], ILHUvec_get_imm>;
    378 
    379 // Catch-all for any other i32 vector constants
    380 def v4i32_get_imm: SDNodeXForm<build_vector, [{
    381   return SPU::get_v4i32_imm(N, *CurDAG);
    382 }]>;
    383 
    384 def v4i32Imm: PatLeaf<(build_vector), [{
    385   return SPU::get_v4i32_imm(N, *CurDAG).getNode() != 0;
    386 }], v4i32_get_imm>;
    387 
    388 // v2i64SExt10Imm_xform function: convert build_vector to 10-bit sign extended
    389 // immediate constant load for v2i64 vectors.
    390 def v2i64SExt10Imm_xform: SDNodeXForm<build_vector, [{
    391   return SPU::get_vec_i10imm(N, *CurDAG, MVT::i64);
    392 }]>;
    393 
    394 // v2i64SExt10Imm: Predicate test for 10-bit sign extended immediate constant
    395 // load, works in conjunction with its transform function.
    396 def v2i64SExt10Imm: PatLeaf<(build_vector), [{
    397   return SPU::get_vec_i10imm(N, *CurDAG, MVT::i64).getNode() != 0;
    398 }], v2i64SExt10Imm_xform>;
    399 
    400 // v2i64SExt16Imm_xform function: convert build_vector to 16-bit sign extended
    401 // immediate constant load for v2i64 vectors.
    402 def v2i64SExt16Imm_xform: SDNodeXForm<build_vector, [{
    403   return SPU::get_vec_i16imm(N, *CurDAG, MVT::i64);
    404 }]>;
    405 
    406 // v2i64SExt16Imm: Predicate test for 16-bit sign extended immediate constant
    407 // load, works in conjunction with its transform function.
    408 def v2i64SExt16Imm: PatLeaf<(build_vector), [{
    409   return SPU::get_vec_i16imm(N, *CurDAG, MVT::i64).getNode() != 0;
    410 }], v2i64SExt16Imm_xform>;
    411 
    412 // v2i64Uns18Imm_xform function: convert build_vector to 18-bit unsigned
    413 // immediate constant load for v2i64 vectors.
    414 def v2i64Uns18Imm_xform: SDNodeXForm<build_vector, [{
    415   return SPU::get_vec_u18imm(N, *CurDAG, MVT::i64);
    416 }]>;
    417 
    418 // v2i64Uns18Imm: Predicate test for 18-bit unsigned immediate constant load,
    419 // works in conjunction with its transform function.
    420 def v2i64Uns18Imm: PatLeaf<(build_vector), [{
    421   return SPU::get_vec_u18imm(N, *CurDAG, MVT::i64).getNode() != 0;
    422 }], v2i64Uns18Imm_xform>;
    423 
    424 /// immILHUvec: Predicate test for a ILHU constant vector.
    425 def immILHUvec_i64: PatLeaf<(build_vector), [{
    426   return SPU::get_ILHUvec_imm(N, *CurDAG, MVT::i64).getNode() != 0;
    427 }], ILHUvec_get_imm>;
    428 
    429 // Catch-all for any other i32 vector constants
    430 def v2i64_get_imm: SDNodeXForm<build_vector, [{
    431   return SPU::get_v2i64_imm(N, *CurDAG);
    432 }]>;
    433 
    434 def v2i64Imm: PatLeaf<(build_vector), [{
    435   return SPU::get_v2i64_imm(N, *CurDAG).getNode() != 0;
    436 }], v2i64_get_imm>;
    437 
    438 //===----------------------------------------------------------------------===//
    439 // Operand Definitions.
    440 
    441 def s7imm: Operand<i8> {
    442   let PrintMethod = "printS7ImmOperand";
    443 }
    444 
    445 def s7imm_i8: Operand<i8> {
    446   let PrintMethod = "printS7ImmOperand";
    447 }
    448 
    449 def u7imm: Operand<i16> {
    450   let PrintMethod = "printU7ImmOperand";
    451 }
    452 
    453 def u7imm_i8: Operand<i8> {
    454   let PrintMethod = "printU7ImmOperand";
    455 }
    456 
    457 def u7imm_i32: Operand<i32> {
    458   let PrintMethod = "printU7ImmOperand";
    459 }
    460 
    461 // Halfword, signed 10-bit constant
    462 def s10imm : Operand<i16> {
    463   let PrintMethod = "printS10ImmOperand";
    464 }
    465 
    466 def s10imm_i8: Operand<i8> {
    467   let PrintMethod = "printS10ImmOperand";
    468 }
    469 
    470 def s10imm_i32: Operand<i32> {
    471   let PrintMethod = "printS10ImmOperand";
    472 }
    473 
    474 def s10imm_i64: Operand<i64> {
    475   let PrintMethod = "printS10ImmOperand";
    476 }
    477 
    478 // Unsigned 10-bit integers:
    479 def u10imm: Operand<i16> {
    480   let PrintMethod = "printU10ImmOperand";
    481 }
    482 
    483 def u10imm_i8: Operand<i8> {
    484   let PrintMethod = "printU10ImmOperand";
    485 }
    486 
    487 def u10imm_i32: Operand<i32> {
    488   let PrintMethod = "printU10ImmOperand";
    489 }
    490 
    491 def s16imm  : Operand<i16> {
    492   let PrintMethod = "printS16ImmOperand";
    493 }
    494 
    495 def s16imm_i8: Operand<i8> {
    496   let PrintMethod = "printS16ImmOperand";
    497 }
    498 
    499 def s16imm_i32: Operand<i32> {
    500   let PrintMethod = "printS16ImmOperand";
    501 }
    502 
    503 def s16imm_i64: Operand<i64> {
    504   let PrintMethod = "printS16ImmOperand";
    505 }
    506 
    507 def s16imm_f32: Operand<f32> {
    508   let PrintMethod = "printS16ImmOperand";
    509 }
    510 
    511 def s16imm_f64: Operand<f64> {
    512   let PrintMethod = "printS16ImmOperand";
    513 }
    514 
    515 def u16imm_i64 : Operand<i64> {
    516   let PrintMethod = "printU16ImmOperand";
    517 }
    518 
    519 def u16imm_i32 : Operand<i32> {
    520   let PrintMethod = "printU16ImmOperand";
    521 }
    522 
    523 def u16imm : Operand<i16> {
    524   let PrintMethod = "printU16ImmOperand";
    525 }
    526 
    527 def f16imm : Operand<f32> {
    528   let PrintMethod = "printU16ImmOperand";
    529 }
    530 
    531 def s18imm  : Operand<i32> {
    532   let PrintMethod = "printS18ImmOperand";
    533 }
    534 
    535 def u18imm : Operand<i32> {
    536   let PrintMethod = "printU18ImmOperand";
    537 }
    538 
    539 def u18imm_i64 : Operand<i64> {
    540   let PrintMethod = "printU18ImmOperand";
    541 }
    542 
    543 def f18imm : Operand<f32> {
    544   let PrintMethod = "printU18ImmOperand";
    545 }
    546 
    547 def f18imm_f64 : Operand<f64> {
    548   let PrintMethod = "printU18ImmOperand";
    549 }
    550 
    551 // Negated 7-bit halfword rotate immediate operands
    552 def rothNeg7imm : Operand<i32> {
    553   let PrintMethod = "printROTHNeg7Imm";
    554 }
    555 
    556 def rothNeg7imm_i16 : Operand<i16> {
    557   let PrintMethod = "printROTHNeg7Imm";
    558 }
    559 
    560 // Negated 7-bit word rotate immediate operands
    561 def rotNeg7imm : Operand<i32> {
    562   let PrintMethod = "printROTNeg7Imm";
    563 }
    564 
    565 def rotNeg7imm_i16 : Operand<i16> {
    566   let PrintMethod = "printROTNeg7Imm";
    567 }
    568 
    569 def rotNeg7imm_i8 : Operand<i8> {
    570   let PrintMethod = "printROTNeg7Imm";
    571 }
    572 
    573 def target : Operand<OtherVT> {
    574   let PrintMethod = "printBranchOperand";
    575 }
    576 
    577 // Absolute address call target
    578 def calltarget : Operand<iPTR> {
    579   let PrintMethod = "printCallOperand";
    580   let MIOperandInfo = (ops u18imm:$calldest);
    581 }
    582 
    583 // PC relative call target
    584 def relcalltarget : Operand<iPTR> {
    585   let PrintMethod = "printPCRelativeOperand";
    586   let MIOperandInfo = (ops s16imm:$calldest);
    587 }
    588 
    589 // Branch targets:
    590 def brtarget : Operand<OtherVT> {
    591   let PrintMethod = "printPCRelativeOperand";
    592 }
    593 
    594 // Hint for branch target
    595 def hbrtarget : Operand<OtherVT> {
    596   let PrintMethod = "printHBROperand";
    597 }
    598 
    599 // Indirect call target
    600 def indcalltarget : Operand<iPTR> {
    601   let PrintMethod = "printCallOperand";
    602   let MIOperandInfo = (ops ptr_rc:$calldest);
    603 }
    604 
    605 def symbolHi: Operand<i32> {
    606   let PrintMethod = "printSymbolHi";
    607 }
    608 
    609 def symbolLo: Operand<i32> {
    610   let PrintMethod = "printSymbolLo";
    611 }
    612 
    613 def symbolLSA: Operand<i32> {
    614   let PrintMethod = "printSymbolLSA";
    615 }
    616 
    617 // Shuffle address memory operaand [s7imm(reg) d-format]
    618 def shufaddr : Operand<iPTR> {
    619   let PrintMethod = "printShufAddr";
    620   let MIOperandInfo = (ops s7imm:$imm, ptr_rc:$reg);
    621 }
    622 
    623 // memory s10imm(reg) operand
    624 def dformaddr : Operand<iPTR> {
    625   let PrintMethod = "printDFormAddr";
    626   let MIOperandInfo = (ops s10imm:$imm, ptr_rc:$reg);
    627 }
    628 
    629 // 256K local store address
    630 // N.B.: The tblgen code generator expects to have two operands, an offset
    631 // and a pointer. Of these, only the immediate is actually used.
    632 def addr256k : Operand<iPTR> {
    633   let PrintMethod = "printAddr256K";
    634   let MIOperandInfo = (ops s16imm:$imm, ptr_rc:$reg);
    635 }
    636 
    637 // memory s18imm(reg) operand
    638 def memri18 : Operand<iPTR> {
    639   let PrintMethod = "printMemRegImmS18";
    640   let MIOperandInfo = (ops s18imm:$imm, ptr_rc:$reg);
    641 }
    642 
    643 // memory register + register operand
    644 def memrr : Operand<iPTR> {
    645   let PrintMethod = "printMemRegReg";
    646   let MIOperandInfo = (ops ptr_rc:$reg_a, ptr_rc:$reg_b);
    647 }
    648 
    649 // Define SPU-specific addressing modes: These come in three basic
    650 // flavors:
    651 //
    652 // D-form   : [r+I10] (10-bit signed offset + reg)
    653 // X-form   : [r+r]   (reg+reg)
    654 // A-form   : abs     (256K LSA offset)
    655 // D-form(2): [r+I7]  (7-bit signed offset + reg)
    656 
    657 def dform_addr   : ComplexPattern<iPTR, 2, "SelectDFormAddr",
    658                                   [], [SDNPWantRoot]>;
    659 def xform_addr   : ComplexPattern<iPTR, 2, "SelectXFormAddr",
    660                                   [], [SDNPWantRoot]>;
    661 def aform_addr   : ComplexPattern<iPTR, 2, "SelectAFormAddr",
    662                                   [], [SDNPWantRoot]>;
    663 def dform2_addr  : ComplexPattern<iPTR, 2, "SelectDForm2Addr",
    664                                   [], [SDNPWantRoot]>;
    665