Home | History | Annotate | Download | only in SystemZ
      1 //===-- SystemZOperands.td - SystemZ instruction operands ----*- tblgen-*--===//
      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 
     10 //===----------------------------------------------------------------------===//
     11 // Class definitions
     12 //===----------------------------------------------------------------------===//
     13 
     14 class ImmediateAsmOperand<string name>
     15   : AsmOperandClass {
     16   let Name = name;
     17   let RenderMethod = "addImmOperands";
     18 }
     19 
     20 // Constructs both a DAG pattern and instruction operand for an immediate
     21 // of type VT.  PRED returns true if a node is acceptable and XFORM returns
     22 // the operand value associated with the node.  ASMOP is the name of the
     23 // associated asm operand, and also forms the basis of the asm print method.
     24 class Immediate<ValueType vt, code pred, SDNodeXForm xform, string asmop>
     25   : PatLeaf<(vt imm), pred, xform>, Operand<vt> {
     26   let PrintMethod = "print"##asmop##"Operand";
     27   let DecoderMethod = "decode"##asmop##"Operand";
     28   let ParserMatchClass = !cast<AsmOperandClass>(asmop);
     29 }
     30 
     31 // Constructs an asm operand for a PC-relative address.  SIZE says how
     32 // many bits there are.
     33 class PCRelAsmOperand<string size> : ImmediateAsmOperand<"PCRel"##size> {
     34   let PredicateMethod = "isImm";
     35   let ParserMethod = "parsePCRel"##size;
     36 }
     37 
     38 // Constructs an operand for a PC-relative address with address type VT.
     39 // ASMOP is the associated asm operand.
     40 class PCRelOperand<ValueType vt, AsmOperandClass asmop> : Operand<vt> {
     41   let PrintMethod = "printPCRelOperand";
     42   let ParserMatchClass = asmop;
     43 }
     44 
     45 // Constructs both a DAG pattern and instruction operand for a PC-relative
     46 // address with address size VT.  SELF is the name of the operand and
     47 // ASMOP is the associated asm operand.
     48 class PCRelAddress<ValueType vt, string self, AsmOperandClass asmop>
     49   : ComplexPattern<vt, 1, "selectPCRelAddress",
     50                    [z_pcrel_wrapper, z_pcrel_offset]>,
     51     PCRelOperand<vt, asmop> {
     52   let MIOperandInfo = (ops !cast<Operand>(self));
     53 }
     54 
     55 // Constructs an AsmOperandClass for addressing mode FORMAT, treating the
     56 // registers as having BITSIZE bits and displacements as having DISPSIZE bits.
     57 // LENGTH is "LenN" for addresses with an N-bit length field, otherwise it
     58 // is "".
     59 class AddressAsmOperand<string format, string bitsize, string dispsize,
     60                         string length = "">
     61   : AsmOperandClass {
     62   let Name = format##bitsize##"Disp"##dispsize##length;
     63   let ParserMethod = "parse"##format##bitsize;
     64   let RenderMethod = "add"##format##"Operands";
     65 }
     66 
     67 // Constructs both a DAG pattern and instruction operand for an addressing mode.
     68 // FORMAT, BITSIZE, DISPSIZE and LENGTH are the parameters to an associated
     69 // AddressAsmOperand.  OPERANDS is a list of NUMOPS individual operands
     70 // (base register, displacement, etc.).  SELTYPE is the type of the memory
     71 // operand for selection purposes; sometimes we want different selection
     72 // choices for the same underlying addressing mode.  SUFFIX is similarly
     73 // a suffix appended to the displacement for selection purposes;
     74 // e.g. we want to reject small 20-bit displacements if a 12-bit form
     75 // also exists, but we want to accept them otherwise.
     76 class AddressingMode<string seltype, string bitsize, string dispsize,
     77                      string suffix, string length, int numops, string format,
     78                      dag operands>
     79   : ComplexPattern<!cast<ValueType>("i"##bitsize), numops,
     80                    "select"##seltype##dispsize##suffix##length,
     81                    [add, sub, or, frameindex, z_adjdynalloc]>,
     82     Operand<!cast<ValueType>("i"##bitsize)> {
     83   let PrintMethod = "print"##format##"Operand";
     84   let EncoderMethod = "get"##format##dispsize##length##"Encoding";
     85   let DecoderMethod =
     86     "decode"##format##bitsize##"Disp"##dispsize##length##"Operand";
     87   let MIOperandInfo = operands;
     88   let ParserMatchClass =
     89     !cast<AddressAsmOperand>(format##bitsize##"Disp"##dispsize##length);
     90 }
     91 
     92 // An addressing mode with a base and displacement but no index.
     93 class BDMode<string type, string bitsize, string dispsize, string suffix>
     94   : AddressingMode<type, bitsize, dispsize, suffix, "", 2, "BDAddr",
     95                    (ops !cast<RegisterOperand>("ADDR"##bitsize),
     96                         !cast<Immediate>("disp"##dispsize##"imm"##bitsize))>;
     97 
     98 // An addressing mode with a base, displacement and index.
     99 class BDXMode<string type, string bitsize, string dispsize, string suffix>
    100   : AddressingMode<type, bitsize, dispsize, suffix, "", 3, "BDXAddr",
    101                    (ops !cast<RegisterOperand>("ADDR"##bitsize),
    102                         !cast<Immediate>("disp"##dispsize##"imm"##bitsize),
    103                         !cast<RegisterOperand>("ADDR"##bitsize))>;
    104 
    105 // A BDMode paired with an immediate length operand of LENSIZE bits.
    106 class BDLMode<string type, string bitsize, string dispsize, string suffix,
    107               string lensize>
    108   : AddressingMode<type, bitsize, dispsize, suffix, "Len"##lensize, 3,
    109                    "BDLAddr",
    110                    (ops !cast<RegisterOperand>("ADDR"##bitsize),
    111                         !cast<Immediate>("disp"##dispsize##"imm"##bitsize),
    112                         !cast<Immediate>("imm"##bitsize))>;
    113 
    114 //===----------------------------------------------------------------------===//
    115 // Extracting immediate operands from nodes
    116 // These all create MVT::i64 nodes to ensure the value is not sign-extended
    117 // when converted from an SDNode to a MachineOperand later on.
    118 //===----------------------------------------------------------------------===//
    119 
    120 // Bits 0-15 (counting from the lsb).
    121 def LL16 : SDNodeXForm<imm, [{
    122   uint64_t Value = N->getZExtValue() & 0x000000000000FFFFULL;
    123   return CurDAG->getTargetConstant(Value, MVT::i64);
    124 }]>;
    125 
    126 // Bits 16-31 (counting from the lsb).
    127 def LH16 : SDNodeXForm<imm, [{
    128   uint64_t Value = (N->getZExtValue() & 0x00000000FFFF0000ULL) >> 16;
    129   return CurDAG->getTargetConstant(Value, MVT::i64);
    130 }]>;
    131 
    132 // Bits 32-47 (counting from the lsb).
    133 def HL16 : SDNodeXForm<imm, [{
    134   uint64_t Value = (N->getZExtValue() & 0x0000FFFF00000000ULL) >> 32;
    135   return CurDAG->getTargetConstant(Value, MVT::i64);
    136 }]>;
    137 
    138 // Bits 48-63 (counting from the lsb).
    139 def HH16 : SDNodeXForm<imm, [{
    140   uint64_t Value = (N->getZExtValue() & 0xFFFF000000000000ULL) >> 48;
    141   return CurDAG->getTargetConstant(Value, MVT::i64);
    142 }]>;
    143 
    144 // Low 32 bits.
    145 def LF32 : SDNodeXForm<imm, [{
    146   uint64_t Value = N->getZExtValue() & 0x00000000FFFFFFFFULL;
    147   return CurDAG->getTargetConstant(Value, MVT::i64);
    148 }]>;
    149 
    150 // High 32 bits.
    151 def HF32 : SDNodeXForm<imm, [{
    152   uint64_t Value = N->getZExtValue() >> 32;
    153   return CurDAG->getTargetConstant(Value, MVT::i64);
    154 }]>;
    155 
    156 // Truncate an immediate to a 8-bit signed quantity.
    157 def SIMM8 : SDNodeXForm<imm, [{
    158   return CurDAG->getTargetConstant(int8_t(N->getZExtValue()), MVT::i64);
    159 }]>;
    160 
    161 // Truncate an immediate to a 8-bit unsigned quantity.
    162 def UIMM8 : SDNodeXForm<imm, [{
    163   return CurDAG->getTargetConstant(uint8_t(N->getZExtValue()), MVT::i64);
    164 }]>;
    165 
    166 // Truncate an immediate to a 16-bit signed quantity.
    167 def SIMM16 : SDNodeXForm<imm, [{
    168   return CurDAG->getTargetConstant(int16_t(N->getZExtValue()), MVT::i64);
    169 }]>;
    170 
    171 // Truncate an immediate to a 16-bit unsigned quantity.
    172 def UIMM16 : SDNodeXForm<imm, [{
    173   return CurDAG->getTargetConstant(uint16_t(N->getZExtValue()), MVT::i64);
    174 }]>;
    175 
    176 // Truncate an immediate to a 32-bit signed quantity.
    177 def SIMM32 : SDNodeXForm<imm, [{
    178   return CurDAG->getTargetConstant(int32_t(N->getZExtValue()), MVT::i64);
    179 }]>;
    180 
    181 // Truncate an immediate to a 32-bit unsigned quantity.
    182 def UIMM32 : SDNodeXForm<imm, [{
    183   return CurDAG->getTargetConstant(uint32_t(N->getZExtValue()), MVT::i64);
    184 }]>;
    185 
    186 // Negate and then truncate an immediate to a 32-bit unsigned quantity.
    187 def NEGIMM32 : SDNodeXForm<imm, [{
    188   return CurDAG->getTargetConstant(uint32_t(-N->getZExtValue()), MVT::i64);
    189 }]>;
    190 
    191 //===----------------------------------------------------------------------===//
    192 // Immediate asm operands.
    193 //===----------------------------------------------------------------------===//
    194 
    195 def U4Imm  : ImmediateAsmOperand<"U4Imm">;
    196 def U6Imm  : ImmediateAsmOperand<"U6Imm">;
    197 def S8Imm  : ImmediateAsmOperand<"S8Imm">;
    198 def U8Imm  : ImmediateAsmOperand<"U8Imm">;
    199 def S16Imm : ImmediateAsmOperand<"S16Imm">;
    200 def U16Imm : ImmediateAsmOperand<"U16Imm">;
    201 def S32Imm : ImmediateAsmOperand<"S32Imm">;
    202 def U32Imm : ImmediateAsmOperand<"U32Imm">;
    203 
    204 //===----------------------------------------------------------------------===//
    205 // i32 immediates
    206 //===----------------------------------------------------------------------===//
    207 
    208 // Immediates for the lower and upper 16 bits of an i32, with the other
    209 // bits of the i32 being zero.
    210 def imm32ll16 : Immediate<i32, [{
    211   return SystemZ::isImmLL(N->getZExtValue());
    212 }], LL16, "U16Imm">;
    213 
    214 def imm32lh16 : Immediate<i32, [{
    215   return SystemZ::isImmLH(N->getZExtValue());
    216 }], LH16, "U16Imm">;
    217 
    218 // Immediates for the lower and upper 16 bits of an i32, with the other
    219 // bits of the i32 being one.
    220 def imm32ll16c : Immediate<i32, [{
    221   return SystemZ::isImmLL(uint32_t(~N->getZExtValue()));
    222 }], LL16, "U16Imm">;
    223 
    224 def imm32lh16c : Immediate<i32, [{
    225   return SystemZ::isImmLH(uint32_t(~N->getZExtValue()));
    226 }], LH16, "U16Imm">;
    227 
    228 // Short immediates
    229 def imm32zx4 : Immediate<i32, [{
    230   return isUInt<4>(N->getZExtValue());
    231 }], NOOP_SDNodeXForm, "U4Imm">;
    232 
    233 def imm32zx6 : Immediate<i32, [{
    234   return isUInt<6>(N->getZExtValue());
    235 }], NOOP_SDNodeXForm, "U6Imm">;
    236 
    237 def imm32sx8 : Immediate<i32, [{
    238   return isInt<8>(N->getSExtValue());
    239 }], SIMM8, "S8Imm">;
    240 
    241 def imm32zx8 : Immediate<i32, [{
    242   return isUInt<8>(N->getZExtValue());
    243 }], UIMM8, "U8Imm">;
    244 
    245 def imm32zx8trunc : Immediate<i32, [{}], UIMM8, "U8Imm">;
    246 
    247 def imm32sx16 : Immediate<i32, [{
    248   return isInt<16>(N->getSExtValue());
    249 }], SIMM16, "S16Imm">;
    250 
    251 def imm32zx16 : Immediate<i32, [{
    252   return isUInt<16>(N->getZExtValue());
    253 }], UIMM16, "U16Imm">;
    254 
    255 def imm32sx16trunc : Immediate<i32, [{}], SIMM16, "S16Imm">;
    256 
    257 // Full 32-bit immediates.  we need both signed and unsigned versions
    258 // because the assembler is picky.  E.g. AFI requires signed operands
    259 // while NILF requires unsigned ones.
    260 def simm32 : Immediate<i32, [{}], SIMM32, "S32Imm">;
    261 def uimm32 : Immediate<i32, [{}], UIMM32, "U32Imm">;
    262 
    263 def imm32 : ImmLeaf<i32, [{}]>;
    264 
    265 //===----------------------------------------------------------------------===//
    266 // 64-bit immediates
    267 //===----------------------------------------------------------------------===//
    268 
    269 // Immediates for 16-bit chunks of an i64, with the other bits of the
    270 // i32 being zero.
    271 def imm64ll16 : Immediate<i64, [{
    272   return SystemZ::isImmLL(N->getZExtValue());
    273 }], LL16, "U16Imm">;
    274 
    275 def imm64lh16 : Immediate<i64, [{
    276   return SystemZ::isImmLH(N->getZExtValue());
    277 }], LH16, "U16Imm">;
    278 
    279 def imm64hl16 : Immediate<i64, [{
    280   return SystemZ::isImmHL(N->getZExtValue());
    281 }], HL16, "U16Imm">;
    282 
    283 def imm64hh16 : Immediate<i64, [{
    284   return SystemZ::isImmHH(N->getZExtValue());
    285 }], HH16, "U16Imm">;
    286 
    287 // Immediates for 16-bit chunks of an i64, with the other bits of the
    288 // i32 being one.
    289 def imm64ll16c : Immediate<i64, [{
    290   return SystemZ::isImmLL(uint64_t(~N->getZExtValue()));
    291 }], LL16, "U16Imm">;
    292 
    293 def imm64lh16c : Immediate<i64, [{
    294   return SystemZ::isImmLH(uint64_t(~N->getZExtValue()));
    295 }], LH16, "U16Imm">;
    296 
    297 def imm64hl16c : Immediate<i64, [{
    298   return SystemZ::isImmHL(uint64_t(~N->getZExtValue()));
    299 }], HL16, "U16Imm">;
    300 
    301 def imm64hh16c : Immediate<i64, [{
    302   return SystemZ::isImmHH(uint64_t(~N->getZExtValue()));
    303 }], HH16, "U16Imm">;
    304 
    305 // Immediates for the lower and upper 32 bits of an i64, with the other
    306 // bits of the i32 being zero.
    307 def imm64lf32 : Immediate<i64, [{
    308   return SystemZ::isImmLF(N->getZExtValue());
    309 }], LF32, "U32Imm">;
    310 
    311 def imm64hf32 : Immediate<i64, [{
    312   return SystemZ::isImmHF(N->getZExtValue());
    313 }], HF32, "U32Imm">;
    314 
    315 // Immediates for the lower and upper 32 bits of an i64, with the other
    316 // bits of the i32 being one.
    317 def imm64lf32c : Immediate<i64, [{
    318   return SystemZ::isImmLF(uint64_t(~N->getZExtValue()));
    319 }], LF32, "U32Imm">;
    320 
    321 def imm64hf32c : Immediate<i64, [{
    322   return SystemZ::isImmHF(uint64_t(~N->getZExtValue()));
    323 }], HF32, "U32Imm">;
    324 
    325 // Short immediates.
    326 def imm64sx8 : Immediate<i64, [{
    327   return isInt<8>(N->getSExtValue());
    328 }], SIMM8, "S8Imm">;
    329 
    330 def imm64zx8 : Immediate<i64, [{
    331   return isUInt<8>(N->getSExtValue());
    332 }], UIMM8, "U8Imm">;
    333 
    334 def imm64sx16 : Immediate<i64, [{
    335   return isInt<16>(N->getSExtValue());
    336 }], SIMM16, "S16Imm">;
    337 
    338 def imm64zx16 : Immediate<i64, [{
    339   return isUInt<16>(N->getZExtValue());
    340 }], UIMM16, "U16Imm">;
    341 
    342 def imm64sx32 : Immediate<i64, [{
    343   return isInt<32>(N->getSExtValue());
    344 }], SIMM32, "S32Imm">;
    345 
    346 def imm64zx32 : Immediate<i64, [{
    347   return isUInt<32>(N->getZExtValue());
    348 }], UIMM32, "U32Imm">;
    349 
    350 def imm64zx32n : Immediate<i64, [{
    351   return isUInt<32>(-N->getSExtValue());
    352 }], NEGIMM32, "U32Imm">;
    353 
    354 def imm64 : ImmLeaf<i64, [{}]>, Operand<i64>;
    355 
    356 //===----------------------------------------------------------------------===//
    357 // Floating-point immediates
    358 //===----------------------------------------------------------------------===//
    359 
    360 // Floating-point zero.
    361 def fpimm0 : PatLeaf<(fpimm), [{ return N->isExactlyValue(+0.0); }]>;
    362 
    363 // Floating point negative zero.
    364 def fpimmneg0 : PatLeaf<(fpimm), [{ return N->isExactlyValue(-0.0); }]>;
    365 
    366 //===----------------------------------------------------------------------===//
    367 // Symbolic address operands
    368 //===----------------------------------------------------------------------===//
    369 
    370 // PC-relative asm operands.
    371 def PCRel16 : PCRelAsmOperand<"16">;
    372 def PCRel32 : PCRelAsmOperand<"32">;
    373 
    374 // PC-relative offsets of a basic block.  The offset is sign-extended
    375 // and multiplied by 2.
    376 def brtarget16 : PCRelOperand<OtherVT, PCRel16> {
    377   let EncoderMethod = "getPC16DBLEncoding";
    378   let DecoderMethod = "decodePC16DBLOperand";
    379 }
    380 def brtarget32 : PCRelOperand<OtherVT, PCRel32> {
    381   let EncoderMethod = "getPC32DBLEncoding";
    382   let DecoderMethod = "decodePC32DBLOperand";
    383 }
    384 
    385 // A PC-relative offset of a global value.  The offset is sign-extended
    386 // and multiplied by 2.
    387 def pcrel32 : PCRelAddress<i64, "pcrel32", PCRel32> {
    388   let EncoderMethod = "getPC32DBLEncoding";
    389   let DecoderMethod = "decodePC32DBLOperand";
    390 }
    391 
    392 //===----------------------------------------------------------------------===//
    393 // Addressing modes
    394 //===----------------------------------------------------------------------===//
    395 
    396 // 12-bit displacement operands.
    397 def disp12imm32 : Operand<i32>;
    398 def disp12imm64 : Operand<i64>;
    399 
    400 // 20-bit displacement operands.
    401 def disp20imm32 : Operand<i32>;
    402 def disp20imm64 : Operand<i64>;
    403 
    404 def BDAddr32Disp12      : AddressAsmOperand<"BDAddr",   "32", "12">;
    405 def BDAddr32Disp20      : AddressAsmOperand<"BDAddr",   "32", "20">;
    406 def BDAddr64Disp12      : AddressAsmOperand<"BDAddr",   "64", "12">;
    407 def BDAddr64Disp20      : AddressAsmOperand<"BDAddr",   "64", "20">;
    408 def BDXAddr64Disp12     : AddressAsmOperand<"BDXAddr",  "64", "12">;
    409 def BDXAddr64Disp20     : AddressAsmOperand<"BDXAddr",  "64", "20">;
    410 def BDLAddr64Disp12Len8 : AddressAsmOperand<"BDLAddr",  "64", "12", "Len8">;
    411 
    412 // DAG patterns and operands for addressing modes.  Each mode has
    413 // the form <type><range><group>[<len>] where:
    414 //
    415 // <type> is one of:
    416 //   shift    : base + displacement (32-bit)
    417 //   bdaddr   : base + displacement
    418 //   mviaddr  : like bdaddr, but reject cases with a natural index
    419 //   bdxaddr  : base + displacement + index
    420 //   laaddr   : like bdxaddr, but used for Load Address operations
    421 //   dynalloc : base + displacement + index + ADJDYNALLOC
    422 //   bdladdr  : base + displacement with a length field
    423 //
    424 // <range> is one of:
    425 //   12       : the displacement is an unsigned 12-bit value
    426 //   20       : the displacement is a signed 20-bit value
    427 //
    428 // <group> is one of:
    429 //   pair     : used when there is an equivalent instruction with the opposite
    430 //              range value (12 or 20)
    431 //   only     : used when there is no equivalent instruction with the opposite
    432 //              range value
    433 //
    434 // <len> is one of:
    435 //
    436 //   <empty>  : there is no length field
    437 //   len8     : the length field is 8 bits, with a range of [1, 0x100].
    438 def shift12only       : BDMode <"BDAddr",   "32", "12", "Only">;
    439 def shift20only       : BDMode <"BDAddr",   "32", "20", "Only">;
    440 def bdaddr12only      : BDMode <"BDAddr",   "64", "12", "Only">;
    441 def bdaddr12pair      : BDMode <"BDAddr",   "64", "12", "Pair">;
    442 def bdaddr20only      : BDMode <"BDAddr",   "64", "20", "Only">;
    443 def bdaddr20pair      : BDMode <"BDAddr",   "64", "20", "Pair">;
    444 def mviaddr12pair     : BDMode <"MVIAddr",  "64", "12", "Pair">;
    445 def mviaddr20pair     : BDMode <"MVIAddr",  "64", "20", "Pair">;
    446 def bdxaddr12only     : BDXMode<"BDXAddr",  "64", "12", "Only">;
    447 def bdxaddr12pair     : BDXMode<"BDXAddr",  "64", "12", "Pair">;
    448 def bdxaddr20only     : BDXMode<"BDXAddr",  "64", "20", "Only">;
    449 def bdxaddr20only128  : BDXMode<"BDXAddr",  "64", "20", "Only128">;
    450 def bdxaddr20pair     : BDXMode<"BDXAddr",  "64", "20", "Pair">;
    451 def dynalloc12only    : BDXMode<"DynAlloc", "64", "12", "Only">;
    452 def laaddr12pair      : BDXMode<"LAAddr",   "64", "12", "Pair">;
    453 def laaddr20pair      : BDXMode<"LAAddr",   "64", "20", "Pair">;
    454 def bdladdr12onlylen8 : BDLMode<"BDLAddr",  "64", "12", "Only", "8">;
    455 
    456 //===----------------------------------------------------------------------===//
    457 // Miscellaneous
    458 //===----------------------------------------------------------------------===//
    459 
    460 // Access registers.  At present we just use them for accessing the thread
    461 // pointer, so we don't expose them as register to LLVM.
    462 def AccessReg : AsmOperandClass {
    463   let Name = "AccessReg";
    464   let ParserMethod = "parseAccessReg";
    465 }
    466 def access_reg : Immediate<i32, [{ return N->getZExtValue() < 16; }],
    467                            NOOP_SDNodeXForm, "AccessReg"> {
    468   let ParserMatchClass = AccessReg;
    469 }
    470 
    471 // A 4-bit condition-code mask.
    472 def cond4 : PatLeaf<(i32 imm), [{ return (N->getZExtValue() < 16); }]>,
    473             Operand<i32> {
    474   let PrintMethod = "printCond4Operand";
    475 }
    476