xref: /freebsd/contrib/llvm-project/llvm/lib/Target/SystemZ/SystemZOperands.td (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
10b57cec5SDimitry Andric//===-- SystemZOperands.td - SystemZ instruction operands ----*- tblgen-*--===//
20b57cec5SDimitry Andric//
30b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric//
70b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
100b57cec5SDimitry Andric// Class definitions
110b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andricclass ImmediateAsmOperand<string name>
140b57cec5SDimitry Andric  : AsmOperandClass {
150b57cec5SDimitry Andric  let Name = name;
160b57cec5SDimitry Andric  let RenderMethod = "addImmOperands";
170b57cec5SDimitry Andric}
180b57cec5SDimitry Andricclass ImmediateTLSAsmOperand<string name>
190b57cec5SDimitry Andric  : AsmOperandClass {
200b57cec5SDimitry Andric  let Name = name;
210b57cec5SDimitry Andric  let RenderMethod = "addImmTLSOperands";
220b57cec5SDimitry Andric}
230b57cec5SDimitry Andric
248bcb0991SDimitry Andricclass ImmediateOp<ValueType vt, string asmop> : Operand<vt> {
255ffd83dbSDimitry Andric  let PrintMethod = "print"#asmop#"Operand";
2606c3fb27SDimitry Andric  let EncoderMethod = "getImmOpValue<SystemZ::FK_390_"#asmop#">";
275ffd83dbSDimitry Andric  let DecoderMethod = "decode"#asmop#"Operand";
288bcb0991SDimitry Andric  let ParserMatchClass = !cast<AsmOperandClass>(asmop);
29480093f4SDimitry Andric  let OperandType = "OPERAND_IMMEDIATE";
308bcb0991SDimitry Andric}
318bcb0991SDimitry Andric
328bcb0991SDimitry Andricclass ImmOpWithPattern<ValueType vt, string asmop, code pred, SDNodeXForm xform,
338bcb0991SDimitry Andric      SDNode ImmNode = imm> :
348bcb0991SDimitry Andric  ImmediateOp<vt, asmop>, PatLeaf<(vt ImmNode), pred, xform>;
358bcb0991SDimitry Andric
368bcb0991SDimitry Andric// class ImmediatePatLeaf<ValueType vt, code pred,
378bcb0991SDimitry Andric//       SDNodeXForm xform, SDNode ImmNode>
388bcb0991SDimitry Andric//   : PatLeaf<(vt ImmNode), pred, xform>;
398bcb0991SDimitry Andric
408bcb0991SDimitry Andric
410b57cec5SDimitry Andric// Constructs both a DAG pattern and instruction operand for an immediate
420b57cec5SDimitry Andric// of type VT.  PRED returns true if a node is acceptable and XFORM returns
430b57cec5SDimitry Andric// the operand value associated with the node.  ASMOP is the name of the
440b57cec5SDimitry Andric// associated asm operand, and also forms the basis of the asm print method.
458bcb0991SDimitry Andricmulticlass Immediate<ValueType vt, code pred, SDNodeXForm xform, string asmop> {
468bcb0991SDimitry Andric  // def "" : ImmediateOp<vt, asmop>,
478bcb0991SDimitry Andric  //          PatLeaf<(vt imm), pred, xform>;
488bcb0991SDimitry Andric  def "" : ImmOpWithPattern<vt, asmop, pred, xform>;
498bcb0991SDimitry Andric
508bcb0991SDimitry Andric//  def _timm : PatLeaf<(vt timm), pred, xform>;
518bcb0991SDimitry Andric  def _timm : ImmOpWithPattern<vt, asmop, pred, xform, timm>;
520b57cec5SDimitry Andric}
530b57cec5SDimitry Andric
540b57cec5SDimitry Andric// Constructs an asm operand for a PC-relative address.  SIZE says how
550b57cec5SDimitry Andric// many bits there are.
565ffd83dbSDimitry Andricclass PCRelAsmOperand<string size> : ImmediateAsmOperand<"PCRel"#size> {
570b57cec5SDimitry Andric  let PredicateMethod = "isImm";
585ffd83dbSDimitry Andric  let ParserMethod = "parsePCRel"#size;
590b57cec5SDimitry Andric}
600b57cec5SDimitry Andricclass PCRelTLSAsmOperand<string size>
615ffd83dbSDimitry Andric  : ImmediateTLSAsmOperand<"PCRelTLS"#size> {
620b57cec5SDimitry Andric  let PredicateMethod = "isImmTLS";
635ffd83dbSDimitry Andric  let ParserMethod = "parsePCRelTLS"#size;
640b57cec5SDimitry Andric}
650b57cec5SDimitry Andric
660b57cec5SDimitry Andric// Constructs an operand for a PC-relative address with address type VT.
670b57cec5SDimitry Andric// ASMOP is the associated asm operand.
68480093f4SDimitry Andriclet OperandType = "OPERAND_PCREL" in {
690b57cec5SDimitry Andric  class PCRelOperand<ValueType vt, AsmOperandClass asmop> : Operand<vt> {
700b57cec5SDimitry Andric    let PrintMethod = "printPCRelOperand";
710b57cec5SDimitry Andric    let ParserMatchClass = asmop;
720b57cec5SDimitry Andric  }
730b57cec5SDimitry Andric  class PCRelTLSOperand<ValueType vt, AsmOperandClass asmop> : Operand<vt> {
740b57cec5SDimitry Andric    let PrintMethod = "printPCRelTLSOperand";
750b57cec5SDimitry Andric    let ParserMatchClass = asmop;
760b57cec5SDimitry Andric  }
77480093f4SDimitry Andric}
780b57cec5SDimitry Andric
790b57cec5SDimitry Andric// Constructs both a DAG pattern and instruction operand for a PC-relative
800b57cec5SDimitry Andric// address with address size VT.  SELF is the name of the operand and
810b57cec5SDimitry Andric// ASMOP is the associated asm operand.
820b57cec5SDimitry Andricclass PCRelAddress<ValueType vt, string self, AsmOperandClass asmop>
830b57cec5SDimitry Andric  : ComplexPattern<vt, 1, "selectPCRelAddress",
840b57cec5SDimitry Andric                   [z_pcrel_wrapper, z_pcrel_offset]>,
850b57cec5SDimitry Andric    PCRelOperand<vt, asmop> {
860b57cec5SDimitry Andric  let MIOperandInfo = (ops !cast<Operand>(self));
870b57cec5SDimitry Andric}
880b57cec5SDimitry Andric
890b57cec5SDimitry Andric// Constructs an AsmOperandClass for addressing mode FORMAT, treating the
900b57cec5SDimitry Andric// registers as having BITSIZE bits and displacements as having DISPSIZE bits.
910b57cec5SDimitry Andric// LENGTH is "LenN" for addresses with an N-bit length field, otherwise it
920b57cec5SDimitry Andric// is "".
930b57cec5SDimitry Andricclass AddressAsmOperand<string format, string bitsize, string dispsize,
940b57cec5SDimitry Andric                        string length = "">
950b57cec5SDimitry Andric  : AsmOperandClass {
965ffd83dbSDimitry Andric  let Name = format#bitsize#"Disp"#dispsize#length;
975ffd83dbSDimitry Andric  let ParserMethod = "parse"#format#bitsize;
985ffd83dbSDimitry Andric  let RenderMethod = "add"#format#"Operands";
990b57cec5SDimitry Andric}
1000b57cec5SDimitry Andric
1010b57cec5SDimitry Andric// Constructs an instruction operand for an addressing mode.  FORMAT,
1020b57cec5SDimitry Andric// BITSIZE, DISPSIZE and LENGTH are the parameters to an associated
1030b57cec5SDimitry Andric// AddressAsmOperand.  OPERANDS is a list of individual operands
1040b57cec5SDimitry Andric// (base register, displacement, etc.).
1050b57cec5SDimitry Andricclass AddressOperand<string bitsize, string dispsize, string length,
1060b57cec5SDimitry Andric                     string format, dag operands>
1075ffd83dbSDimitry Andric  : Operand<!cast<ValueType>("i"#bitsize)> {
1085ffd83dbSDimitry Andric  let PrintMethod = "print"#format#"Operand";
109480093f4SDimitry Andric  let OperandType = "OPERAND_MEMORY";
1100b57cec5SDimitry Andric  let MIOperandInfo = operands;
1110b57cec5SDimitry Andric  let ParserMatchClass =
1125ffd83dbSDimitry Andric    !cast<AddressAsmOperand>(format#bitsize#"Disp"#dispsize#length);
1130b57cec5SDimitry Andric}
1140b57cec5SDimitry Andric
1150b57cec5SDimitry Andric// Constructs both a DAG pattern and instruction operand for an addressing mode.
1160b57cec5SDimitry Andric// FORMAT, BITSIZE, DISPSIZE and LENGTH are the parameters to an associated
1170b57cec5SDimitry Andric// AddressAsmOperand.  OPERANDS is a list of NUMOPS individual operands
1180b57cec5SDimitry Andric// (base register, displacement, etc.).  SELTYPE is the type of the memory
1190b57cec5SDimitry Andric// operand for selection purposes; sometimes we want different selection
1200b57cec5SDimitry Andric// choices for the same underlying addressing mode.  SUFFIX is similarly
1210b57cec5SDimitry Andric// a suffix appended to the displacement for selection purposes;
1220b57cec5SDimitry Andric// e.g. we want to reject small 20-bit displacements if a 12-bit form
1230b57cec5SDimitry Andric// also exists, but we want to accept them otherwise.
1240b57cec5SDimitry Andricclass AddressingMode<string seltype, string bitsize, string dispsize,
1250b57cec5SDimitry Andric                     string suffix, string length, int numops, string format,
1260b57cec5SDimitry Andric                     dag operands>
1275ffd83dbSDimitry Andric  : ComplexPattern<!cast<ValueType>("i"#bitsize), numops,
1285ffd83dbSDimitry Andric                   "select"#seltype#dispsize#suffix#length,
1290b57cec5SDimitry Andric                   [add, sub, or, frameindex, z_adjdynalloc]>,
1300b57cec5SDimitry Andric    AddressOperand<bitsize, dispsize, length, format, operands>;
1310b57cec5SDimitry Andric
1320b57cec5SDimitry Andric// An addressing mode with a base and displacement but no index.
1330b57cec5SDimitry Andricclass BDMode<string type, string bitsize, string dispsize, string suffix>
1340b57cec5SDimitry Andric  : AddressingMode<type, bitsize, dispsize, suffix, "", 2, "BDAddr",
1355ffd83dbSDimitry Andric                   (ops !cast<RegisterOperand>("ADDR"#bitsize),
1365ffd83dbSDimitry Andric                        !cast<Operand>("disp"#dispsize#"imm"#bitsize))>;
1370b57cec5SDimitry Andric
1380b57cec5SDimitry Andric// An addressing mode with a base, displacement and index.
1390b57cec5SDimitry Andricclass BDXMode<string type, string bitsize, string dispsize, string suffix>
1400b57cec5SDimitry Andric  : AddressingMode<type, bitsize, dispsize, suffix, "", 3, "BDXAddr",
1415ffd83dbSDimitry Andric                   (ops !cast<RegisterOperand>("ADDR"#bitsize),
1425ffd83dbSDimitry Andric                        !cast<Operand>("disp"#dispsize#"imm"#bitsize),
1435ffd83dbSDimitry Andric                        !cast<RegisterOperand>("ADDR"#bitsize))>;
1440b57cec5SDimitry Andric
1450b57cec5SDimitry Andric// A BDMode paired with an immediate length operand of LENSIZE bits.
1460b57cec5SDimitry Andricclass BDLMode<string type, string bitsize, string dispsize, string suffix,
1470b57cec5SDimitry Andric              string lensize>
1485ffd83dbSDimitry Andric  : AddressingMode<type, bitsize, dispsize, suffix, "Len"#lensize, 3,
1490b57cec5SDimitry Andric                   "BDLAddr",
1505ffd83dbSDimitry Andric                   (ops !cast<RegisterOperand>("ADDR"#bitsize),
1515ffd83dbSDimitry Andric                        !cast<Operand>("disp"#dispsize#"imm"#bitsize),
15206c3fb27SDimitry Andric                        !cast<Operand>("len"#lensize#"imm"#bitsize))>;
1530b57cec5SDimitry Andric
1540b57cec5SDimitry Andric// A BDMode paired with a register length operand.
1550b57cec5SDimitry Andricclass BDRMode<string type, string bitsize, string dispsize, string suffix>
1560b57cec5SDimitry Andric  : AddressingMode<type, bitsize, dispsize, suffix, "", 3, "BDRAddr",
1575ffd83dbSDimitry Andric                   (ops !cast<RegisterOperand>("ADDR"#bitsize),
1585ffd83dbSDimitry Andric                        !cast<Operand>("disp"#dispsize#"imm"#bitsize),
1595ffd83dbSDimitry Andric                        !cast<RegisterOperand>("GR"#bitsize))>;
1600b57cec5SDimitry Andric
1610b57cec5SDimitry Andric// An addressing mode with a base, displacement and a vector index.
1620b57cec5SDimitry Andricclass BDVMode<string bitsize, string dispsize>
1630b57cec5SDimitry Andric  : AddressOperand<bitsize, dispsize, "", "BDVAddr",
1645ffd83dbSDimitry Andric                   (ops !cast<RegisterOperand>("ADDR"#bitsize),
1655ffd83dbSDimitry Andric                        !cast<Operand>("disp"#dispsize#"imm"#bitsize),
1660b57cec5SDimitry Andric                        !cast<RegisterOperand>("VR128"))>;
1670b57cec5SDimitry Andric
1680b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
1690b57cec5SDimitry Andric// Extracting immediate operands from nodes
1700b57cec5SDimitry Andric// These all create MVT::i64 nodes to ensure the value is not sign-extended
1710b57cec5SDimitry Andric// when converted from an SDNode to a MachineOperand later on.
1720b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
1730b57cec5SDimitry Andric
1740b57cec5SDimitry Andric// Bits 0-15 (counting from the lsb).
1750b57cec5SDimitry Andricdef LL16 : SDNodeXForm<imm, [{
1760b57cec5SDimitry Andric  uint64_t Value = N->getZExtValue() & 0x000000000000FFFFULL;
1770b57cec5SDimitry Andric  return CurDAG->getTargetConstant(Value, SDLoc(N), MVT::i64);
1780b57cec5SDimitry Andric}]>;
1790b57cec5SDimitry Andric
1800b57cec5SDimitry Andric// Bits 16-31 (counting from the lsb).
1810b57cec5SDimitry Andricdef LH16 : SDNodeXForm<imm, [{
1820b57cec5SDimitry Andric  uint64_t Value = (N->getZExtValue() & 0x00000000FFFF0000ULL) >> 16;
1830b57cec5SDimitry Andric  return CurDAG->getTargetConstant(Value, SDLoc(N), MVT::i64);
1840b57cec5SDimitry Andric}]>;
1850b57cec5SDimitry Andric
1860b57cec5SDimitry Andric// Bits 32-47 (counting from the lsb).
1870b57cec5SDimitry Andricdef HL16 : SDNodeXForm<imm, [{
1880b57cec5SDimitry Andric  uint64_t Value = (N->getZExtValue() & 0x0000FFFF00000000ULL) >> 32;
1890b57cec5SDimitry Andric  return CurDAG->getTargetConstant(Value, SDLoc(N), MVT::i64);
1900b57cec5SDimitry Andric}]>;
1910b57cec5SDimitry Andric
1920b57cec5SDimitry Andric// Bits 48-63 (counting from the lsb).
1930b57cec5SDimitry Andricdef HH16 : SDNodeXForm<imm, [{
1940b57cec5SDimitry Andric  uint64_t Value = (N->getZExtValue() & 0xFFFF000000000000ULL) >> 48;
1950b57cec5SDimitry Andric  return CurDAG->getTargetConstant(Value, SDLoc(N), MVT::i64);
1960b57cec5SDimitry Andric}]>;
1970b57cec5SDimitry Andric
1980b57cec5SDimitry Andric// Low 32 bits.
1990b57cec5SDimitry Andricdef LF32 : SDNodeXForm<imm, [{
2000b57cec5SDimitry Andric  uint64_t Value = N->getZExtValue() & 0x00000000FFFFFFFFULL;
2010b57cec5SDimitry Andric  return CurDAG->getTargetConstant(Value, SDLoc(N), MVT::i64);
2020b57cec5SDimitry Andric}]>;
2030b57cec5SDimitry Andric
2040b57cec5SDimitry Andric// High 32 bits.
2050b57cec5SDimitry Andricdef HF32 : SDNodeXForm<imm, [{
2060b57cec5SDimitry Andric  uint64_t Value = N->getZExtValue() >> 32;
2070b57cec5SDimitry Andric  return CurDAG->getTargetConstant(Value, SDLoc(N), MVT::i64);
2080b57cec5SDimitry Andric}]>;
2090b57cec5SDimitry Andric
2100b57cec5SDimitry Andric// Negated variants.
2110b57cec5SDimitry Andricdef NEGLH16 : SDNodeXForm<imm, [{
2120b57cec5SDimitry Andric  uint64_t Value = (-N->getZExtValue() & 0x00000000FFFF0000ULL) >> 16;
2130b57cec5SDimitry Andric  return CurDAG->getTargetConstant(Value, SDLoc(N), MVT::i64);
2140b57cec5SDimitry Andric}]>;
2150b57cec5SDimitry Andric
2160b57cec5SDimitry Andricdef NEGLF32 : SDNodeXForm<imm, [{
2170b57cec5SDimitry Andric  uint64_t Value = -N->getZExtValue() & 0x00000000FFFFFFFFULL;
2180b57cec5SDimitry Andric  return CurDAG->getTargetConstant(Value, SDLoc(N), MVT::i64);
2190b57cec5SDimitry Andric}]>;
2200b57cec5SDimitry Andric
2210b57cec5SDimitry Andric// Truncate an immediate to a 8-bit signed quantity.
2220b57cec5SDimitry Andricdef SIMM8 : SDNodeXForm<imm, [{
2230b57cec5SDimitry Andric  return CurDAG->getTargetConstant(int8_t(N->getZExtValue()), SDLoc(N),
2240b57cec5SDimitry Andric                                   MVT::i64);
2250b57cec5SDimitry Andric}]>;
2260b57cec5SDimitry Andric
2270b57cec5SDimitry Andric// Truncate an immediate to a 8-bit unsigned quantity.
2280b57cec5SDimitry Andricdef UIMM8 : SDNodeXForm<imm, [{
2290b57cec5SDimitry Andric  return CurDAG->getTargetConstant(uint8_t(N->getZExtValue()), SDLoc(N),
2300b57cec5SDimitry Andric                                   MVT::i64);
2310b57cec5SDimitry Andric}]>;
2320b57cec5SDimitry Andric
2330b57cec5SDimitry Andric// Truncate an immediate to a 8-bit unsigned quantity and mask off low bit.
2340b57cec5SDimitry Andricdef UIMM8EVEN : SDNodeXForm<imm, [{
2350b57cec5SDimitry Andric  return CurDAG->getTargetConstant(N->getZExtValue() & 0xfe, SDLoc(N),
2360b57cec5SDimitry Andric                                   MVT::i64);
2370b57cec5SDimitry Andric}]>;
2380b57cec5SDimitry Andric
2390b57cec5SDimitry Andric// Truncate an immediate to a 12-bit unsigned quantity.
2400b57cec5SDimitry Andricdef UIMM12 : SDNodeXForm<imm, [{
2410b57cec5SDimitry Andric  return CurDAG->getTargetConstant(N->getZExtValue() & 0xfff, SDLoc(N),
2420b57cec5SDimitry Andric                                   MVT::i64);
2430b57cec5SDimitry Andric}]>;
2440b57cec5SDimitry Andric
2450b57cec5SDimitry Andric// Truncate an immediate to a 16-bit signed quantity.
2460b57cec5SDimitry Andricdef SIMM16 : SDNodeXForm<imm, [{
2470b57cec5SDimitry Andric  return CurDAG->getTargetConstant(int16_t(N->getZExtValue()), SDLoc(N),
2480b57cec5SDimitry Andric                                   MVT::i64);
2490b57cec5SDimitry Andric}]>;
2500b57cec5SDimitry Andric
2510b57cec5SDimitry Andric// Negate and then truncate an immediate to a 16-bit signed quantity.
2520b57cec5SDimitry Andricdef NEGSIMM16 : SDNodeXForm<imm, [{
2530b57cec5SDimitry Andric  return CurDAG->getTargetConstant(int16_t(-N->getZExtValue()), SDLoc(N),
2540b57cec5SDimitry Andric                                   MVT::i64);
2550b57cec5SDimitry Andric}]>;
2560b57cec5SDimitry Andric
2570b57cec5SDimitry Andric// Truncate an immediate to a 16-bit unsigned quantity.
2580b57cec5SDimitry Andricdef UIMM16 : SDNodeXForm<imm, [{
2590b57cec5SDimitry Andric  return CurDAG->getTargetConstant(uint16_t(N->getZExtValue()), SDLoc(N),
2600b57cec5SDimitry Andric                                   MVT::i64);
2610b57cec5SDimitry Andric}]>;
2620b57cec5SDimitry Andric
2630b57cec5SDimitry Andric// Truncate an immediate to a 32-bit signed quantity.
2640b57cec5SDimitry Andricdef SIMM32 : SDNodeXForm<imm, [{
2650b57cec5SDimitry Andric  return CurDAG->getTargetConstant(int32_t(N->getZExtValue()), SDLoc(N),
2660b57cec5SDimitry Andric                                   MVT::i64);
2670b57cec5SDimitry Andric}]>;
2680b57cec5SDimitry Andric
2690b57cec5SDimitry Andric// Negate and then truncate an immediate to a 32-bit unsigned quantity.
2700b57cec5SDimitry Andricdef NEGSIMM32 : SDNodeXForm<imm, [{
2710b57cec5SDimitry Andric  return CurDAG->getTargetConstant(int32_t(-N->getZExtValue()), SDLoc(N),
2720b57cec5SDimitry Andric                                   MVT::i64);
2730b57cec5SDimitry Andric}]>;
2740b57cec5SDimitry Andric
2750b57cec5SDimitry Andric// Truncate an immediate to a 32-bit unsigned quantity.
2760b57cec5SDimitry Andricdef UIMM32 : SDNodeXForm<imm, [{
2770b57cec5SDimitry Andric  return CurDAG->getTargetConstant(uint32_t(N->getZExtValue()), SDLoc(N),
2780b57cec5SDimitry Andric                                   MVT::i64);
2790b57cec5SDimitry Andric}]>;
2800b57cec5SDimitry Andric
2810b57cec5SDimitry Andric// Negate and then truncate an immediate to a 32-bit unsigned quantity.
2820b57cec5SDimitry Andricdef NEGUIMM32 : SDNodeXForm<imm, [{
2830b57cec5SDimitry Andric  return CurDAG->getTargetConstant(uint32_t(-N->getZExtValue()), SDLoc(N),
2840b57cec5SDimitry Andric                                   MVT::i64);
2850b57cec5SDimitry Andric}]>;
2860b57cec5SDimitry Andric
2870b57cec5SDimitry Andric// Truncate an immediate to a 48-bit unsigned quantity.
2880b57cec5SDimitry Andricdef UIMM48 : SDNodeXForm<imm, [{
2890b57cec5SDimitry Andric  return CurDAG->getTargetConstant(uint64_t(N->getZExtValue()) & 0xffffffffffff,
2900b57cec5SDimitry Andric                                   SDLoc(N), MVT::i64);
2910b57cec5SDimitry Andric}]>;
2920b57cec5SDimitry Andric
2930b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
2940b57cec5SDimitry Andric// Immediate asm operands.
2950b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
2960b57cec5SDimitry Andric
2970b57cec5SDimitry Andricdef U1Imm  : ImmediateAsmOperand<"U1Imm">;
2980b57cec5SDimitry Andricdef U2Imm  : ImmediateAsmOperand<"U2Imm">;
2990b57cec5SDimitry Andricdef U3Imm  : ImmediateAsmOperand<"U3Imm">;
3000b57cec5SDimitry Andricdef U4Imm  : ImmediateAsmOperand<"U4Imm">;
3010b57cec5SDimitry Andricdef S8Imm  : ImmediateAsmOperand<"S8Imm">;
3020b57cec5SDimitry Andricdef U8Imm  : ImmediateAsmOperand<"U8Imm">;
3030b57cec5SDimitry Andricdef U12Imm : ImmediateAsmOperand<"U12Imm">;
3040b57cec5SDimitry Andricdef S16Imm : ImmediateAsmOperand<"S16Imm">;
3050b57cec5SDimitry Andricdef U16Imm : ImmediateAsmOperand<"U16Imm">;
3060b57cec5SDimitry Andricdef S32Imm : ImmediateAsmOperand<"S32Imm">;
3070b57cec5SDimitry Andricdef U32Imm : ImmediateAsmOperand<"U32Imm">;
3080b57cec5SDimitry Andricdef U48Imm : ImmediateAsmOperand<"U48Imm">;
3090b57cec5SDimitry Andric
3100b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
3110b57cec5SDimitry Andric// i32 immediates
3120b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
3130b57cec5SDimitry Andric
3140b57cec5SDimitry Andric// Immediates for the lower and upper 16 bits of an i32, with the other
3150b57cec5SDimitry Andric// bits of the i32 being zero.
3168bcb0991SDimitry Andricdefm imm32ll16 : Immediate<i32, [{
317*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(32) && SystemZ::isImmLL(N->getZExtValue());
3180b57cec5SDimitry Andric}], LL16, "U16Imm">;
3190b57cec5SDimitry Andric
3208bcb0991SDimitry Andricdefm imm32lh16 : Immediate<i32, [{
321*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(32) && SystemZ::isImmLH(N->getZExtValue());
3220b57cec5SDimitry Andric}], LH16, "U16Imm">;
3230b57cec5SDimitry Andric
3240b57cec5SDimitry Andric// Immediates for the lower and upper 16 bits of an i32, with the other
3250b57cec5SDimitry Andric// bits of the i32 being one.
3268bcb0991SDimitry Andricdefm imm32ll16c : Immediate<i32, [{
327*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(32) &&
328*5f757f3fSDimitry Andric         SystemZ::isImmLL(uint32_t(~N->getZExtValue()));
3290b57cec5SDimitry Andric}], LL16, "U16Imm">;
3300b57cec5SDimitry Andric
3318bcb0991SDimitry Andricdefm imm32lh16c : Immediate<i32, [{
332*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(32) &&
333*5f757f3fSDimitry Andric         SystemZ::isImmLH(uint32_t(~N->getZExtValue()));
3340b57cec5SDimitry Andric}], LH16, "U16Imm">;
3350b57cec5SDimitry Andric
3360b57cec5SDimitry Andric// Short immediates
3378bcb0991SDimitry Andricdefm imm32zx1 : Immediate<i32, [{
338*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(1);
3390b57cec5SDimitry Andric}], NOOP_SDNodeXForm, "U1Imm">;
3400b57cec5SDimitry Andric
3418bcb0991SDimitry Andricdefm imm32zx2 : Immediate<i32, [{
342*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(2);
3430b57cec5SDimitry Andric}], NOOP_SDNodeXForm, "U2Imm">;
3440b57cec5SDimitry Andric
3458bcb0991SDimitry Andricdefm imm32zx3 : Immediate<i32, [{
346*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(3);
3470b57cec5SDimitry Andric}], NOOP_SDNodeXForm, "U3Imm">;
3480b57cec5SDimitry Andric
3498bcb0991SDimitry Andricdefm imm32zx4 : Immediate<i32, [{
350*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(4);
3510b57cec5SDimitry Andric}], NOOP_SDNodeXForm, "U4Imm">;
3520b57cec5SDimitry Andric
3530b57cec5SDimitry Andric// Note: this enforces an even value during code generation only.
3540b57cec5SDimitry Andric// When used from the assembler, any 4-bit value is allowed.
3558bcb0991SDimitry Andricdefm imm32zx4even : Immediate<i32, [{
356*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(4);
3570b57cec5SDimitry Andric}], UIMM8EVEN, "U4Imm">;
3580b57cec5SDimitry Andric
3598bcb0991SDimitry Andricdefm imm32sx8 : Immediate<i32, [{
360*5f757f3fSDimitry Andric  return N->getAPIntValue().isSignedIntN(8);
3610b57cec5SDimitry Andric}], SIMM8, "S8Imm">;
3620b57cec5SDimitry Andric
3638bcb0991SDimitry Andricdefm imm32zx8 : Immediate<i32, [{
364*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(8);
3650b57cec5SDimitry Andric}], UIMM8, "U8Imm">;
3660b57cec5SDimitry Andric
3678bcb0991SDimitry Andricdefm imm32zx8trunc : Immediate<i32, [{}], UIMM8, "U8Imm">;
3680b57cec5SDimitry Andric
3698bcb0991SDimitry Andricdefm imm32zx12 : Immediate<i32, [{
370*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(12);
3710b57cec5SDimitry Andric}], UIMM12, "U12Imm">;
3720b57cec5SDimitry Andric
3738bcb0991SDimitry Andricdefm imm32sx16 : Immediate<i32, [{
374*5f757f3fSDimitry Andric  return N->getAPIntValue().isSignedIntN(16);
3750b57cec5SDimitry Andric}], SIMM16, "S16Imm">;
3760b57cec5SDimitry Andric
3778bcb0991SDimitry Andricdefm imm32sx16n : Immediate<i32, [{
378*5f757f3fSDimitry Andric  return (-N->getAPIntValue()).isSignedIntN(16);
3790b57cec5SDimitry Andric}], NEGSIMM16, "S16Imm">;
3800b57cec5SDimitry Andric
3818bcb0991SDimitry Andricdefm imm32zx16 : Immediate<i32, [{
382*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(16);
3830b57cec5SDimitry Andric}], UIMM16, "U16Imm">;
3840b57cec5SDimitry Andric
3858bcb0991SDimitry Andricdefm imm32sx16trunc : Immediate<i32, [{}], SIMM16, "S16Imm">;
3868bcb0991SDimitry Andricdefm imm32zx16trunc : Immediate<i32, [{}], UIMM16, "U16Imm">;
3870b57cec5SDimitry Andric
3880b57cec5SDimitry Andric// Full 32-bit immediates.  we need both signed and unsigned versions
3890b57cec5SDimitry Andric// because the assembler is picky.  E.g. AFI requires signed operands
3900b57cec5SDimitry Andric// while NILF requires unsigned ones.
3918bcb0991SDimitry Andricdefm simm32 : Immediate<i32, [{}], SIMM32, "S32Imm">;
3928bcb0991SDimitry Andricdefm uimm32 : Immediate<i32, [{}], UIMM32, "U32Imm">;
3930b57cec5SDimitry Andric
3948bcb0991SDimitry Andricdefm simm32n : Immediate<i32, [{
395*5f757f3fSDimitry Andric  auto SImm = N->getAPIntValue().trySExtValue();
396*5f757f3fSDimitry Andric  return SImm.has_value() && isInt<32>(-*SImm);
3970b57cec5SDimitry Andric}], NEGSIMM32, "S32Imm">;
3980b57cec5SDimitry Andric
3990b57cec5SDimitry Andricdef imm32 : ImmLeaf<i32, [{}]>;
4000b57cec5SDimitry Andric
4010b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
4020b57cec5SDimitry Andric// 64-bit immediates
4030b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
4040b57cec5SDimitry Andric
4050b57cec5SDimitry Andric// Immediates for 16-bit chunks of an i64, with the other bits of the
4060b57cec5SDimitry Andric// i32 being zero.
4078bcb0991SDimitry Andricdefm imm64ll16 : Immediate<i64, [{
408*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(64) && SystemZ::isImmLL(N->getZExtValue());
4090b57cec5SDimitry Andric}], LL16, "U16Imm">;
4100b57cec5SDimitry Andric
4118bcb0991SDimitry Andricdefm imm64lh16 : Immediate<i64, [{
412*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(64) && SystemZ::isImmLH(N->getZExtValue());
4130b57cec5SDimitry Andric}], LH16, "U16Imm">;
4140b57cec5SDimitry Andric
4158bcb0991SDimitry Andricdefm imm64hl16 : Immediate<i64, [{
416*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(64) && SystemZ::isImmHL(N->getZExtValue());
4170b57cec5SDimitry Andric}], HL16, "U16Imm">;
4180b57cec5SDimitry Andric
4198bcb0991SDimitry Andricdefm imm64hh16 : Immediate<i64, [{
420*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(64) && SystemZ::isImmHH(N->getZExtValue());
4210b57cec5SDimitry Andric}], HH16, "U16Imm">;
4220b57cec5SDimitry Andric
4230b57cec5SDimitry Andric// Immediates for 16-bit chunks of an i64, with the other bits of the
4240b57cec5SDimitry Andric// i32 being one.
4258bcb0991SDimitry Andricdefm imm64ll16c : Immediate<i64, [{
426*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(64) &&
427*5f757f3fSDimitry Andric         SystemZ::isImmLL(uint64_t(~N->getZExtValue()));
4280b57cec5SDimitry Andric}], LL16, "U16Imm">;
4290b57cec5SDimitry Andric
4308bcb0991SDimitry Andricdefm imm64lh16c : Immediate<i64, [{
431*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(64) &&
432*5f757f3fSDimitry Andric         SystemZ::isImmLH(uint64_t(~N->getZExtValue()));
4330b57cec5SDimitry Andric}], LH16, "U16Imm">;
4340b57cec5SDimitry Andric
4358bcb0991SDimitry Andricdefm imm64hl16c : Immediate<i64, [{
436*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(64) &&
437*5f757f3fSDimitry Andric         SystemZ::isImmHL(uint64_t(~N->getZExtValue()));
4380b57cec5SDimitry Andric}], HL16, "U16Imm">;
4390b57cec5SDimitry Andric
4408bcb0991SDimitry Andricdefm imm64hh16c : Immediate<i64, [{
441*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(64) &&
442*5f757f3fSDimitry Andric         SystemZ::isImmHH(uint64_t(~N->getZExtValue()));
4430b57cec5SDimitry Andric}], HH16, "U16Imm">;
4440b57cec5SDimitry Andric
4450b57cec5SDimitry Andric// Immediates for the lower and upper 32 bits of an i64, with the other
4460b57cec5SDimitry Andric// bits of the i32 being zero.
4478bcb0991SDimitry Andricdefm imm64lf32 : Immediate<i64, [{
448*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(64) && SystemZ::isImmLF(N->getZExtValue());
4490b57cec5SDimitry Andric}], LF32, "U32Imm">;
4500b57cec5SDimitry Andric
4518bcb0991SDimitry Andricdefm imm64hf32 : Immediate<i64, [{
452*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(64) && SystemZ::isImmHF(N->getZExtValue());
4530b57cec5SDimitry Andric}], HF32, "U32Imm">;
4540b57cec5SDimitry Andric
4550b57cec5SDimitry Andric// Immediates for the lower and upper 32 bits of an i64, with the other
4560b57cec5SDimitry Andric// bits of the i32 being one.
4578bcb0991SDimitry Andricdefm imm64lf32c : Immediate<i64, [{
458*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(64) &&
459*5f757f3fSDimitry Andric         SystemZ::isImmLF(uint64_t(~N->getZExtValue()));
4600b57cec5SDimitry Andric}], LF32, "U32Imm">;
4610b57cec5SDimitry Andric
4628bcb0991SDimitry Andricdefm imm64hf32c : Immediate<i64, [{
463*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(64) &&
464*5f757f3fSDimitry Andric         SystemZ::isImmHF(uint64_t(~N->getZExtValue()));
4650b57cec5SDimitry Andric}], HF32, "U32Imm">;
4660b57cec5SDimitry Andric
4670b57cec5SDimitry Andric// Negated immediates that fit LF32 or LH16.
4688bcb0991SDimitry Andricdefm imm64lh16n : Immediate<i64, [{
469*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(64) &&
470*5f757f3fSDimitry Andric         SystemZ::isImmLH(uint64_t(-N->getZExtValue()));
4710b57cec5SDimitry Andric}], NEGLH16, "U16Imm">;
4720b57cec5SDimitry Andric
4738bcb0991SDimitry Andricdefm imm64lf32n : Immediate<i64, [{
474*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(64) &&
475*5f757f3fSDimitry Andric         SystemZ::isImmLF(uint64_t(-N->getZExtValue()));
4760b57cec5SDimitry Andric}], NEGLF32, "U32Imm">;
4770b57cec5SDimitry Andric
4780b57cec5SDimitry Andric// Short immediates.
4798bcb0991SDimitry Andricdefm imm64sx8 : Immediate<i64, [{
480*5f757f3fSDimitry Andric  return N->getAPIntValue().isSignedIntN(8);
4810b57cec5SDimitry Andric}], SIMM8, "S8Imm">;
4820b57cec5SDimitry Andric
4838bcb0991SDimitry Andricdefm imm64zx8 : Immediate<i64, [{
484*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(8);;
4850b57cec5SDimitry Andric}], UIMM8, "U8Imm">;
4860b57cec5SDimitry Andric
4878bcb0991SDimitry Andricdefm imm64sx16 : Immediate<i64, [{
488*5f757f3fSDimitry Andric  return N->getAPIntValue().isSignedIntN(16);
4890b57cec5SDimitry Andric}], SIMM16, "S16Imm">;
4900b57cec5SDimitry Andric
4918bcb0991SDimitry Andricdefm imm64sx16n : Immediate<i64, [{
492*5f757f3fSDimitry Andric  return (-N->getAPIntValue()).isSignedIntN(16);
4930b57cec5SDimitry Andric}], NEGSIMM16, "S16Imm">;
4940b57cec5SDimitry Andric
4958bcb0991SDimitry Andricdefm imm64zx16 : Immediate<i64, [{
496*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(16);
4970b57cec5SDimitry Andric}], UIMM16, "U16Imm">;
4980b57cec5SDimitry Andric
4998bcb0991SDimitry Andricdefm imm64sx32 : Immediate<i64, [{
500*5f757f3fSDimitry Andric  return N->getAPIntValue().isSignedIntN(32);
5010b57cec5SDimitry Andric}], SIMM32, "S32Imm">;
5020b57cec5SDimitry Andric
5038bcb0991SDimitry Andricdefm imm64sx32n : Immediate<i64, [{
504*5f757f3fSDimitry Andric  return (-N->getAPIntValue()).isSignedIntN(32);
5050b57cec5SDimitry Andric}], NEGSIMM32, "S32Imm">;
5060b57cec5SDimitry Andric
5078bcb0991SDimitry Andricdefm imm64zx32 : Immediate<i64, [{
508*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(32);
5090b57cec5SDimitry Andric}], UIMM32, "U32Imm">;
5100b57cec5SDimitry Andric
5118bcb0991SDimitry Andricdefm imm64zx32n : Immediate<i64, [{
512*5f757f3fSDimitry Andric  return (-N->getAPIntValue()).isIntN(32);
5130b57cec5SDimitry Andric}], NEGUIMM32, "U32Imm">;
5140b57cec5SDimitry Andric
5158bcb0991SDimitry Andricdefm imm64zx48 : Immediate<i64, [{
516*5f757f3fSDimitry Andric  return N->getAPIntValue().isIntN(64);
5170b57cec5SDimitry Andric}], UIMM48, "U48Imm">;
5180b57cec5SDimitry Andric
51906c3fb27SDimitry Andricclass Imm64 : ImmLeaf<i64, [{}]>, Operand<i64> {
52006c3fb27SDimitry Andric  let OperandType = "OPERAND_IMMEDIATE";
52106c3fb27SDimitry Andric}
52206c3fb27SDimitry Andricdef imm64 : Imm64;
52306c3fb27SDimitry Andricdef len4imm64 : Imm64 {
52406c3fb27SDimitry Andric  let EncoderMethod = "getLenEncoding<SystemZ::FK_390_U4Imm>";
52506c3fb27SDimitry Andric  let DecoderMethod = "decodeLenOperand<4>";
52606c3fb27SDimitry Andric}
52706c3fb27SDimitry Andricdef len8imm64 : Imm64 {
52806c3fb27SDimitry Andric  let EncoderMethod = "getLenEncoding<SystemZ::FK_390_U8Imm>";
52906c3fb27SDimitry Andric  let DecoderMethod = "decodeLenOperand<8>";
53006c3fb27SDimitry Andric}
5310b57cec5SDimitry Andric
5320b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
5330b57cec5SDimitry Andric// Floating-point immediates
5340b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
5350b57cec5SDimitry Andric
5360b57cec5SDimitry Andric// Floating-point zero.
5370b57cec5SDimitry Andricdef fpimm0 : PatLeaf<(fpimm), [{ return N->isExactlyValue(+0.0); }]>;
5380b57cec5SDimitry Andric
5390b57cec5SDimitry Andric// Floating point negative zero.
5400b57cec5SDimitry Andricdef fpimmneg0 : PatLeaf<(fpimm), [{ return N->isExactlyValue(-0.0); }]>;
5410b57cec5SDimitry Andric
5420b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
5430b57cec5SDimitry Andric// Symbolic address operands
5440b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
5450b57cec5SDimitry Andric
5460b57cec5SDimitry Andric// PC-relative asm operands.
5470b57cec5SDimitry Andricdef PCRel12 : PCRelAsmOperand<"12">;
5480b57cec5SDimitry Andricdef PCRel16 : PCRelAsmOperand<"16">;
5490b57cec5SDimitry Andricdef PCRel24 : PCRelAsmOperand<"24">;
5500b57cec5SDimitry Andricdef PCRel32 : PCRelAsmOperand<"32">;
5510b57cec5SDimitry Andricdef PCRelTLS16 : PCRelTLSAsmOperand<"16">;
5520b57cec5SDimitry Andricdef PCRelTLS32 : PCRelTLSAsmOperand<"32">;
5530b57cec5SDimitry Andric
5540b57cec5SDimitry Andric// PC-relative offsets of a basic block.  The offset is sign-extended
5550b57cec5SDimitry Andric// and multiplied by 2.
5560b57cec5SDimitry Andricdef brtarget16 : PCRelOperand<OtherVT, PCRel16> {
5570b57cec5SDimitry Andric  let EncoderMethod = "getPC16DBLEncoding";
5580b57cec5SDimitry Andric  let DecoderMethod = "decodePC16DBLBranchOperand";
5590b57cec5SDimitry Andric}
5600b57cec5SDimitry Andricdef brtarget32 : PCRelOperand<OtherVT, PCRel32> {
5610b57cec5SDimitry Andric  let EncoderMethod = "getPC32DBLEncoding";
5620b57cec5SDimitry Andric  let DecoderMethod = "decodePC32DBLBranchOperand";
5630b57cec5SDimitry Andric}
5640b57cec5SDimitry Andric
5650b57cec5SDimitry Andric// Variants of brtarget for use with branch prediction preload.
5660b57cec5SDimitry Andricdef brtarget12bpp : PCRelOperand<OtherVT, PCRel12> {
5670b57cec5SDimitry Andric  let EncoderMethod = "getPC12DBLBPPEncoding";
5680b57cec5SDimitry Andric  let DecoderMethod = "decodePC12DBLBranchOperand";
5690b57cec5SDimitry Andric}
5700b57cec5SDimitry Andricdef brtarget16bpp : PCRelOperand<OtherVT, PCRel16> {
5710b57cec5SDimitry Andric  let EncoderMethod = "getPC16DBLBPPEncoding";
5720b57cec5SDimitry Andric  let DecoderMethod = "decodePC16DBLBranchOperand";
5730b57cec5SDimitry Andric}
5740b57cec5SDimitry Andricdef brtarget24bpp : PCRelOperand<OtherVT, PCRel24> {
5750b57cec5SDimitry Andric  let EncoderMethod = "getPC24DBLBPPEncoding";
5760b57cec5SDimitry Andric  let DecoderMethod = "decodePC24DBLBranchOperand";
5770b57cec5SDimitry Andric}
5780b57cec5SDimitry Andric
5790b57cec5SDimitry Andric// Variants of brtarget16/32 with an optional additional TLS symbol.
5800b57cec5SDimitry Andric// These are used to annotate calls to __tls_get_offset.
5810b57cec5SDimitry Andricdef tlssym : Operand<i64> { }
5820b57cec5SDimitry Andricdef brtarget16tls : PCRelTLSOperand<OtherVT, PCRelTLS16> {
5830b57cec5SDimitry Andric  let MIOperandInfo = (ops brtarget16:$func, tlssym:$sym);
5840b57cec5SDimitry Andric  let EncoderMethod = "getPC16DBLTLSEncoding";
5850b57cec5SDimitry Andric  let DecoderMethod = "decodePC16DBLBranchOperand";
5860b57cec5SDimitry Andric}
5870b57cec5SDimitry Andricdef brtarget32tls : PCRelTLSOperand<OtherVT, PCRelTLS32> {
5880b57cec5SDimitry Andric  let MIOperandInfo = (ops brtarget32:$func, tlssym:$sym);
5890b57cec5SDimitry Andric  let EncoderMethod = "getPC32DBLTLSEncoding";
5900b57cec5SDimitry Andric  let DecoderMethod = "decodePC32DBLBranchOperand";
5910b57cec5SDimitry Andric}
5920b57cec5SDimitry Andric
5930b57cec5SDimitry Andric// A PC-relative offset of a global value.  The offset is sign-extended
5940b57cec5SDimitry Andric// and multiplied by 2.
5950b57cec5SDimitry Andricdef pcrel32 : PCRelAddress<i64, "pcrel32", PCRel32> {
5960b57cec5SDimitry Andric  let EncoderMethod = "getPC32DBLEncoding";
5970b57cec5SDimitry Andric  let DecoderMethod = "decodePC32DBLOperand";
5980b57cec5SDimitry Andric}
5990b57cec5SDimitry Andric
6000b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
6010b57cec5SDimitry Andric// Addressing modes
6020b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
6030b57cec5SDimitry Andric
6040b57cec5SDimitry Andric// 12-bit displacement operands.
60506c3fb27SDimitry Andriclet EncoderMethod = "getImmOpValue<SystemZ::FK_390_U12Imm>",
60606c3fb27SDimitry Andric    DecoderMethod = "decodeU12ImmOperand" in {
6070b57cec5SDimitry Andric  def disp12imm32 : Operand<i32>;
6080b57cec5SDimitry Andric  def disp12imm64 : Operand<i64>;
60906c3fb27SDimitry Andric}
6100b57cec5SDimitry Andric
6110b57cec5SDimitry Andric// 20-bit displacement operands.
61206c3fb27SDimitry Andriclet EncoderMethod = "getImmOpValue<SystemZ::FK_390_S20Imm>",
61306c3fb27SDimitry Andric    DecoderMethod = "decodeS20ImmOperand" in {
6140b57cec5SDimitry Andric  def disp20imm32 : Operand<i32>;
6150b57cec5SDimitry Andric  def disp20imm64 : Operand<i64>;
61606c3fb27SDimitry Andric}
6170b57cec5SDimitry Andric
6180b57cec5SDimitry Andricdef BDAddr32Disp12      : AddressAsmOperand<"BDAddr",   "32", "12">;
6190b57cec5SDimitry Andricdef BDAddr32Disp20      : AddressAsmOperand<"BDAddr",   "32", "20">;
6200b57cec5SDimitry Andricdef BDAddr64Disp12      : AddressAsmOperand<"BDAddr",   "64", "12">;
6210b57cec5SDimitry Andricdef BDAddr64Disp20      : AddressAsmOperand<"BDAddr",   "64", "20">;
6220b57cec5SDimitry Andricdef BDXAddr64Disp12     : AddressAsmOperand<"BDXAddr",  "64", "12">;
6230b57cec5SDimitry Andricdef BDXAddr64Disp20     : AddressAsmOperand<"BDXAddr",  "64", "20">;
6240b57cec5SDimitry Andricdef BDLAddr64Disp12Len4 : AddressAsmOperand<"BDLAddr",  "64", "12", "Len4">;
6250b57cec5SDimitry Andricdef BDLAddr64Disp12Len8 : AddressAsmOperand<"BDLAddr",  "64", "12", "Len8">;
6260b57cec5SDimitry Andricdef BDRAddr64Disp12     : AddressAsmOperand<"BDRAddr",  "64", "12">;
6270b57cec5SDimitry Andricdef BDVAddr64Disp12     : AddressAsmOperand<"BDVAddr",  "64", "12">;
6280b57cec5SDimitry Andric
6290b57cec5SDimitry Andric// DAG patterns and operands for addressing modes.  Each mode has
6300b57cec5SDimitry Andric// the form <type><range><group>[<len>] where:
6310b57cec5SDimitry Andric//
6320b57cec5SDimitry Andric// <type> is one of:
6330b57cec5SDimitry Andric//   shift    : base + displacement (32-bit)
6340b57cec5SDimitry Andric//   bdaddr   : base + displacement
6350b57cec5SDimitry Andric//   mviaddr  : like bdaddr, but reject cases with a natural index
6360b57cec5SDimitry Andric//   bdxaddr  : base + displacement + index
6370b57cec5SDimitry Andric//   laaddr   : like bdxaddr, but used for Load Address operations
6380b57cec5SDimitry Andric//   dynalloc : base + displacement + index + ADJDYNALLOC
6390b57cec5SDimitry Andric//   bdladdr  : base + displacement with a length field
6400b57cec5SDimitry Andric//   bdvaddr  : base + displacement with a vector index
6410b57cec5SDimitry Andric//
6420b57cec5SDimitry Andric// <range> is one of:
6430b57cec5SDimitry Andric//   12       : the displacement is an unsigned 12-bit value
6440b57cec5SDimitry Andric//   20       : the displacement is a signed 20-bit value
6450b57cec5SDimitry Andric//
6460b57cec5SDimitry Andric// <group> is one of:
6470b57cec5SDimitry Andric//   pair     : used when there is an equivalent instruction with the opposite
6480b57cec5SDimitry Andric//              range value (12 or 20)
6490b57cec5SDimitry Andric//   only     : used when there is no equivalent instruction with the opposite
6500b57cec5SDimitry Andric//              range value
6510b57cec5SDimitry Andric//
6520b57cec5SDimitry Andric// <len> is one of:
6530b57cec5SDimitry Andric//
6540b57cec5SDimitry Andric//   <empty>  : there is no length field
6550b57cec5SDimitry Andric//   len8     : the length field is 8 bits, with a range of [1, 0x100].
6560b57cec5SDimitry Andricdef shift12only       : BDMode <"BDAddr",   "32", "12", "Only">;
6570b57cec5SDimitry Andricdef shift20only       : BDMode <"BDAddr",   "32", "20", "Only">;
6580b57cec5SDimitry Andricdef bdaddr12only      : BDMode <"BDAddr",   "64", "12", "Only">;
6590b57cec5SDimitry Andricdef bdaddr12pair      : BDMode <"BDAddr",   "64", "12", "Pair">;
6600b57cec5SDimitry Andricdef bdaddr20only      : BDMode <"BDAddr",   "64", "20", "Only">;
6610b57cec5SDimitry Andricdef bdaddr20pair      : BDMode <"BDAddr",   "64", "20", "Pair">;
6620b57cec5SDimitry Andricdef mviaddr12pair     : BDMode <"MVIAddr",  "64", "12", "Pair">;
6630b57cec5SDimitry Andricdef mviaddr20pair     : BDMode <"MVIAddr",  "64", "20", "Pair">;
6640b57cec5SDimitry Andricdef bdxaddr12only     : BDXMode<"BDXAddr",  "64", "12", "Only">;
6650b57cec5SDimitry Andricdef bdxaddr12pair     : BDXMode<"BDXAddr",  "64", "12", "Pair">;
6660b57cec5SDimitry Andricdef bdxaddr20only     : BDXMode<"BDXAddr",  "64", "20", "Only">;
6670b57cec5SDimitry Andricdef bdxaddr20only128  : BDXMode<"BDXAddr",  "64", "20", "Only128">;
6680b57cec5SDimitry Andricdef bdxaddr20pair     : BDXMode<"BDXAddr",  "64", "20", "Pair">;
6690b57cec5SDimitry Andricdef dynalloc12only    : BDXMode<"DynAlloc", "64", "12", "Only">;
6700b57cec5SDimitry Andricdef laaddr12pair      : BDXMode<"LAAddr",   "64", "12", "Pair">;
6710b57cec5SDimitry Andricdef laaddr20pair      : BDXMode<"LAAddr",   "64", "20", "Pair">;
6720b57cec5SDimitry Andricdef bdladdr12onlylen4 : BDLMode<"BDLAddr",  "64", "12", "Only", "4">;
6730b57cec5SDimitry Andricdef bdladdr12onlylen8 : BDLMode<"BDLAddr",  "64", "12", "Only", "8">;
6740b57cec5SDimitry Andricdef bdraddr12only     : BDRMode<"BDRAddr",  "64", "12", "Only">;
6750b57cec5SDimitry Andricdef bdvaddr12only     : BDVMode<            "64", "12">;
6760b57cec5SDimitry Andric
6770b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
6780b57cec5SDimitry Andric// Miscellaneous
6790b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
6800b57cec5SDimitry Andric
6810b57cec5SDimitry Andric// A 4-bit condition-code mask.
6828bcb0991SDimitry Andricdef cond4 : PatLeaf<(i32 timm), [{ return (N->getZExtValue() < 16); }]>,
6830b57cec5SDimitry Andric            Operand<i32> {
6840b57cec5SDimitry Andric  let PrintMethod = "printCond4Operand";
685480093f4SDimitry Andric  let OperandType = "OPERAND_IMMEDIATE";
6860b57cec5SDimitry Andric}
687