1//===-- SystemZOperands.td - SystemZ instruction operands ----*- tblgen-*--===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9//===----------------------------------------------------------------------===// 10// Class definitions 11//===----------------------------------------------------------------------===// 12 13class ImmediateAsmOperand<string name> 14 : AsmOperandClass { 15 let Name = name; 16 let RenderMethod = "addImmOperands"; 17} 18class ImmediateTLSAsmOperand<string name> 19 : AsmOperandClass { 20 let Name = name; 21 let RenderMethod = "addImmTLSOperands"; 22} 23 24class ImmediateOp<ValueType vt, string asmop> : Operand<vt> { 25 let PrintMethod = "print"#asmop#"Operand"; 26 let EncoderMethod = "getImmOpValue<SystemZ::FK_390_"#asmop#">"; 27 let DecoderMethod = "decode"#asmop#"Operand"; 28 let ParserMatchClass = !cast<AsmOperandClass>(asmop); 29 let OperandType = "OPERAND_IMMEDIATE"; 30} 31 32class ImmOpWithPattern<ValueType vt, string asmop, code pred, SDNodeXForm xform, 33 SDNode ImmNode = imm> : 34 ImmediateOp<vt, asmop>, PatLeaf<(vt ImmNode), pred, xform>; 35 36// class ImmediatePatLeaf<ValueType vt, code pred, 37// SDNodeXForm xform, SDNode ImmNode> 38// : PatLeaf<(vt ImmNode), pred, xform>; 39 40 41// Constructs both a DAG pattern and instruction operand for an immediate 42// of type VT. PRED returns true if a node is acceptable and XFORM returns 43// the operand value associated with the node. ASMOP is the name of the 44// associated asm operand, and also forms the basis of the asm print method. 45multiclass Immediate<ValueType vt, code pred, SDNodeXForm xform, string asmop> { 46 // def "" : ImmediateOp<vt, asmop>, 47 // PatLeaf<(vt imm), pred, xform>; 48 def "" : ImmOpWithPattern<vt, asmop, pred, xform>; 49 50// def _timm : PatLeaf<(vt timm), pred, xform>; 51 def _timm : ImmOpWithPattern<vt, asmop, pred, xform, timm>; 52} 53 54// Constructs an asm operand for a PC-relative address. SIZE says how 55// many bits there are. 56class PCRelAsmOperand<string size> : ImmediateAsmOperand<"PCRel"#size> { 57 let PredicateMethod = "isImm"; 58 let ParserMethod = "parsePCRel"#size; 59} 60class PCRelTLSAsmOperand<string size> 61 : ImmediateTLSAsmOperand<"PCRelTLS"#size> { 62 let PredicateMethod = "isImmTLS"; 63 let ParserMethod = "parsePCRelTLS"#size; 64} 65 66// Constructs an operand for a PC-relative address with address type VT. 67// ASMOP is the associated asm operand. 68let OperandType = "OPERAND_PCREL" in { 69 class PCRelOperand<ValueType vt, AsmOperandClass asmop> : Operand<vt> { 70 let PrintMethod = "printPCRelOperand"; 71 let ParserMatchClass = asmop; 72 } 73 class PCRelTLSOperand<ValueType vt, AsmOperandClass asmop> : Operand<vt> { 74 let PrintMethod = "printPCRelTLSOperand"; 75 let ParserMatchClass = asmop; 76 } 77} 78 79// Constructs both a DAG pattern and instruction operand for a PC-relative 80// address with address size VT. SELF is the name of the operand and 81// ASMOP is the associated asm operand. 82class PCRelAddress<ValueType vt, string self, AsmOperandClass asmop> 83 : ComplexPattern<vt, 1, "selectPCRelAddress", 84 [z_pcrel_wrapper, z_pcrel_offset]>, 85 PCRelOperand<vt, asmop> { 86 let MIOperandInfo = (ops !cast<Operand>(self)); 87} 88 89// Constructs an AsmOperandClass for addressing mode FORMAT, treating the 90// registers as having BITSIZE bits and displacements as having DISPSIZE bits. 91// LENGTH is "LenN" for addresses with an N-bit length field, otherwise it 92// is "". 93class AddressAsmOperand<string format, string bitsize, string dispsize, 94 string length = ""> 95 : AsmOperandClass { 96 let Name = format#bitsize#"Disp"#dispsize#length; 97 let ParserMethod = "parse"#format#bitsize; 98 let RenderMethod = "add"#format#"Operands"; 99} 100 101// Constructs an instruction operand for an addressing mode. FORMAT, 102// BITSIZE, DISPSIZE and LENGTH are the parameters to an associated 103// AddressAsmOperand. OPERANDS is a list of individual operands 104// (base register, displacement, etc.). 105class AddressOperand<string bitsize, string dispsize, string length, 106 string format, dag operands> 107 : Operand<!cast<ValueType>("i"#bitsize)> { 108 let PrintMethod = "print"#format#"Operand"; 109 let OperandType = "OPERAND_MEMORY"; 110 let MIOperandInfo = operands; 111 let ParserMatchClass = 112 !cast<AddressAsmOperand>(format#bitsize#"Disp"#dispsize#length); 113} 114 115// Constructs both a DAG pattern and instruction operand for an addressing mode. 116// FORMAT, BITSIZE, DISPSIZE and LENGTH are the parameters to an associated 117// AddressAsmOperand. OPERANDS is a list of NUMOPS individual operands 118// (base register, displacement, etc.). SELTYPE is the type of the memory 119// operand for selection purposes; sometimes we want different selection 120// choices for the same underlying addressing mode. SUFFIX is similarly 121// a suffix appended to the displacement for selection purposes; 122// e.g. we want to reject small 20-bit displacements if a 12-bit form 123// also exists, but we want to accept them otherwise. 124class AddressingMode<string seltype, string bitsize, string dispsize, 125 string suffix, string length, int numops, string format, 126 dag operands> 127 : ComplexPattern<!cast<ValueType>("i"#bitsize), numops, 128 "select"#seltype#dispsize#suffix#length, 129 [add, sub, or, frameindex, z_adjdynalloc]>, 130 AddressOperand<bitsize, dispsize, length, format, operands>; 131 132// An addressing mode with a base and displacement but no index. 133class BDMode<string type, string bitsize, string dispsize, string suffix> 134 : AddressingMode<type, bitsize, dispsize, suffix, "", 2, "BDAddr", 135 (ops !cast<RegisterOperand>("ADDR"#bitsize), 136 !cast<Operand>("disp"#dispsize#"imm"#bitsize))>; 137 138// An addressing mode with a base, displacement and index. 139class BDXMode<string type, string bitsize, string dispsize, string suffix> 140 : AddressingMode<type, bitsize, dispsize, suffix, "", 3, "BDXAddr", 141 (ops !cast<RegisterOperand>("ADDR"#bitsize), 142 !cast<Operand>("disp"#dispsize#"imm"#bitsize), 143 !cast<RegisterOperand>("ADDR"#bitsize))>; 144 145// A BDMode paired with an immediate length operand of LENSIZE bits. 146class BDLMode<string type, string bitsize, string dispsize, string suffix, 147 string lensize> 148 : AddressingMode<type, bitsize, dispsize, suffix, "Len"#lensize, 3, 149 "BDLAddr", 150 (ops !cast<RegisterOperand>("ADDR"#bitsize), 151 !cast<Operand>("disp"#dispsize#"imm"#bitsize), 152 !cast<Operand>("len"#lensize#"imm"#bitsize))>; 153 154// A BDMode paired with a register length operand. 155class BDRMode<string type, string bitsize, string dispsize, string suffix> 156 : AddressingMode<type, bitsize, dispsize, suffix, "", 3, "BDRAddr", 157 (ops !cast<RegisterOperand>("ADDR"#bitsize), 158 !cast<Operand>("disp"#dispsize#"imm"#bitsize), 159 !cast<RegisterOperand>("GR"#bitsize))>; 160 161// An addressing mode with a base, displacement and a vector index. 162class BDVMode<string bitsize, string dispsize> 163 : AddressOperand<bitsize, dispsize, "", "BDVAddr", 164 (ops !cast<RegisterOperand>("ADDR"#bitsize), 165 !cast<Operand>("disp"#dispsize#"imm"#bitsize), 166 !cast<RegisterOperand>("VR128"))>; 167 168// An addressing mode with a base, 32-bit displacement and 32-bit index. 169class LXAMode<string bitsize, string dispsize> 170 : AddressOperand<bitsize, dispsize, "", "LXAAddr", 171 (ops !cast<RegisterOperand>("ADDR"#bitsize), 172 !cast<Operand>("disp"#dispsize#"imm32"), 173 !cast<RegisterOperand>("ADDR32"))>; 174 175//===----------------------------------------------------------------------===// 176// Extracting immediate operands from nodes 177// These all create MVT::i64 nodes to ensure the value is not sign-extended 178// when converted from an SDNode to a MachineOperand later on. 179//===----------------------------------------------------------------------===// 180 181// Bits 0-15 (counting from the lsb). 182def LL16 : SDNodeXForm<imm, [{ 183 uint64_t Value = N->getZExtValue() & 0x000000000000FFFFULL; 184 return CurDAG->getTargetConstant(Value, SDLoc(N), MVT::i64); 185}]>; 186 187// Bits 16-31 (counting from the lsb). 188def LH16 : SDNodeXForm<imm, [{ 189 uint64_t Value = (N->getZExtValue() & 0x00000000FFFF0000ULL) >> 16; 190 return CurDAG->getTargetConstant(Value, SDLoc(N), MVT::i64); 191}]>; 192 193// Bits 32-47 (counting from the lsb). 194def HL16 : SDNodeXForm<imm, [{ 195 uint64_t Value = (N->getZExtValue() & 0x0000FFFF00000000ULL) >> 32; 196 return CurDAG->getTargetConstant(Value, SDLoc(N), MVT::i64); 197}]>; 198 199// Bits 48-63 (counting from the lsb). 200def HH16 : SDNodeXForm<imm, [{ 201 uint64_t Value = (N->getZExtValue() & 0xFFFF000000000000ULL) >> 48; 202 return CurDAG->getTargetConstant(Value, SDLoc(N), MVT::i64); 203}]>; 204 205// Low 32 bits. 206def LF32 : SDNodeXForm<imm, [{ 207 uint64_t Value = N->getZExtValue() & 0x00000000FFFFFFFFULL; 208 return CurDAG->getTargetConstant(Value, SDLoc(N), MVT::i64); 209}]>; 210 211// High 32 bits. 212def HF32 : SDNodeXForm<imm, [{ 213 uint64_t Value = N->getZExtValue() >> 32; 214 return CurDAG->getTargetConstant(Value, SDLoc(N), MVT::i64); 215}]>; 216 217// Negated variants. 218def NEGLH16 : SDNodeXForm<imm, [{ 219 uint64_t Value = (-N->getZExtValue() & 0x00000000FFFF0000ULL) >> 16; 220 return CurDAG->getTargetConstant(Value, SDLoc(N), MVT::i64); 221}]>; 222 223def NEGLF32 : SDNodeXForm<imm, [{ 224 uint64_t Value = -N->getZExtValue() & 0x00000000FFFFFFFFULL; 225 return CurDAG->getTargetConstant(Value, SDLoc(N), MVT::i64); 226}]>; 227 228// Truncate an immediate to a 8-bit signed quantity. 229def SIMM8 : SDNodeXForm<imm, [{ 230 return CurDAG->getSignedTargetConstant(int8_t(N->getSExtValue()), SDLoc(N), 231 MVT::i64); 232}]>; 233 234// Truncate an immediate to a 8-bit unsigned quantity. 235def UIMM8 : SDNodeXForm<imm, [{ 236 return CurDAG->getTargetConstant(uint8_t(N->getZExtValue()), SDLoc(N), 237 MVT::i64); 238}]>; 239 240// Truncate an immediate to a 8-bit unsigned quantity and mask off low bit. 241def UIMM8EVEN : SDNodeXForm<imm, [{ 242 return CurDAG->getTargetConstant(N->getZExtValue() & 0xfe, SDLoc(N), 243 MVT::i64); 244}]>; 245 246// Truncate an immediate to a 12-bit unsigned quantity. 247def UIMM12 : SDNodeXForm<imm, [{ 248 return CurDAG->getTargetConstant(N->getZExtValue() & 0xfff, SDLoc(N), 249 MVT::i64); 250}]>; 251 252// Truncate an immediate to a 16-bit signed quantity. 253def SIMM16 : SDNodeXForm<imm, [{ 254 return CurDAG->getSignedTargetConstant(int16_t(N->getSExtValue()), SDLoc(N), 255 MVT::i64); 256}]>; 257 258// Negate and then truncate an immediate to a 16-bit signed quantity. 259def NEGSIMM16 : SDNodeXForm<imm, [{ 260 return CurDAG->getSignedTargetConstant(int16_t(-N->getSExtValue()), SDLoc(N), 261 MVT::i64); 262}]>; 263 264// Truncate an immediate to a 16-bit unsigned quantity. 265def UIMM16 : SDNodeXForm<imm, [{ 266 return CurDAG->getTargetConstant(uint16_t(N->getZExtValue()), SDLoc(N), 267 MVT::i64); 268}]>; 269 270// Truncate an immediate to a 32-bit signed quantity. 271def SIMM32 : SDNodeXForm<imm, [{ 272 return CurDAG->getSignedTargetConstant(int32_t(N->getSExtValue()), SDLoc(N), 273 MVT::i64); 274}]>; 275 276// Negate and then truncate an immediate to a 32-bit unsigned quantity. 277def NEGSIMM32 : SDNodeXForm<imm, [{ 278 return CurDAG->getSignedTargetConstant(int32_t(-N->getSExtValue()), SDLoc(N), 279 MVT::i64); 280}]>; 281 282// Truncate an immediate to a 32-bit unsigned quantity. 283def UIMM32 : SDNodeXForm<imm, [{ 284 return CurDAG->getTargetConstant(uint32_t(N->getZExtValue()), SDLoc(N), 285 MVT::i64); 286}]>; 287 288// Negate and then truncate an immediate to a 32-bit unsigned quantity. 289def NEGUIMM32 : SDNodeXForm<imm, [{ 290 return CurDAG->getTargetConstant(uint32_t(-N->getZExtValue()), SDLoc(N), 291 MVT::i64); 292}]>; 293 294// Truncate an immediate to a 48-bit unsigned quantity. 295def UIMM48 : SDNodeXForm<imm, [{ 296 return CurDAG->getTargetConstant(uint64_t(N->getZExtValue()) & 0xffffffffffff, 297 SDLoc(N), MVT::i64); 298}]>; 299 300//===----------------------------------------------------------------------===// 301// Immediate asm operands. 302//===----------------------------------------------------------------------===// 303 304def U1Imm : ImmediateAsmOperand<"U1Imm">; 305def U2Imm : ImmediateAsmOperand<"U2Imm">; 306def U3Imm : ImmediateAsmOperand<"U3Imm">; 307def U4Imm : ImmediateAsmOperand<"U4Imm">; 308def S8Imm : ImmediateAsmOperand<"S8Imm">; 309def U8Imm : ImmediateAsmOperand<"U8Imm">; 310def U12Imm : ImmediateAsmOperand<"U12Imm">; 311def S16Imm : ImmediateAsmOperand<"S16Imm">; 312def U16Imm : ImmediateAsmOperand<"U16Imm">; 313def S32Imm : ImmediateAsmOperand<"S32Imm">; 314def U32Imm : ImmediateAsmOperand<"U32Imm">; 315def U48Imm : ImmediateAsmOperand<"U48Imm">; 316 317//===----------------------------------------------------------------------===// 318// i32 immediates 319//===----------------------------------------------------------------------===// 320 321// Immediates for the lower and upper 16 bits of an i32, with the other 322// bits of the i32 being zero. 323defm imm32ll16 : Immediate<i32, [{ 324 return N->getAPIntValue().isIntN(32) && SystemZ::isImmLL(N->getZExtValue()); 325}], LL16, "U16Imm">; 326 327defm imm32lh16 : Immediate<i32, [{ 328 return N->getAPIntValue().isIntN(32) && SystemZ::isImmLH(N->getZExtValue()); 329}], LH16, "U16Imm">; 330 331// Immediates for the lower and upper 16 bits of an i32, with the other 332// bits of the i32 being one. 333defm imm32ll16c : Immediate<i32, [{ 334 return N->getAPIntValue().isIntN(32) && 335 SystemZ::isImmLL(uint32_t(~N->getZExtValue())); 336}], LL16, "U16Imm">; 337 338defm imm32lh16c : Immediate<i32, [{ 339 return N->getAPIntValue().isIntN(32) && 340 SystemZ::isImmLH(uint32_t(~N->getZExtValue())); 341}], LH16, "U16Imm">; 342 343// Short immediates 344defm imm32zx1 : Immediate<i32, [{ 345 return N->getAPIntValue().isIntN(1); 346}], NOOP_SDNodeXForm, "U1Imm">; 347 348defm imm32zx2 : Immediate<i32, [{ 349 return N->getAPIntValue().isIntN(2); 350}], NOOP_SDNodeXForm, "U2Imm">; 351 352defm imm32zx3 : Immediate<i32, [{ 353 return N->getAPIntValue().isIntN(3); 354}], NOOP_SDNodeXForm, "U3Imm">; 355 356defm imm32zx4 : Immediate<i32, [{ 357 return N->getAPIntValue().isIntN(4); 358}], NOOP_SDNodeXForm, "U4Imm">; 359 360// Note: this enforces an even value during code generation only. 361// When used from the assembler, any 4-bit value is allowed. 362defm imm32zx4even : Immediate<i32, [{ 363 return N->getAPIntValue().isIntN(4); 364}], UIMM8EVEN, "U4Imm">; 365 366defm imm32sx8 : Immediate<i32, [{ 367 return N->getAPIntValue().isSignedIntN(8); 368}], SIMM8, "S8Imm">; 369 370defm imm32zx8 : Immediate<i32, [{ 371 return N->getAPIntValue().isIntN(8); 372}], UIMM8, "U8Imm">; 373 374defm imm32zx8trunc : Immediate<i32, [{}], UIMM8, "U8Imm">; 375 376defm imm32zx12 : Immediate<i32, [{ 377 return N->getAPIntValue().isIntN(12); 378}], UIMM12, "U12Imm">; 379 380defm imm32sx16 : Immediate<i32, [{ 381 return N->getAPIntValue().isSignedIntN(16); 382}], SIMM16, "S16Imm">; 383 384defm imm32sx16n : Immediate<i32, [{ 385 return (-N->getAPIntValue()).isSignedIntN(16); 386}], NEGSIMM16, "S16Imm">; 387 388defm imm32zx16 : Immediate<i32, [{ 389 return N->getAPIntValue().isIntN(16); 390}], UIMM16, "U16Imm">; 391 392defm imm32sx16trunc : Immediate<i32, [{}], SIMM16, "S16Imm">; 393defm imm32zx16trunc : Immediate<i32, [{}], UIMM16, "U16Imm">; 394 395// Full 32-bit immediates. we need both signed and unsigned versions 396// because the assembler is picky. E.g. AFI requires signed operands 397// while NILF requires unsigned ones. 398defm simm32 : Immediate<i32, [{}], SIMM32, "S32Imm">; 399defm uimm32 : Immediate<i32, [{}], UIMM32, "U32Imm">; 400 401defm simm32n : Immediate<i32, [{ 402 auto SImm = N->getAPIntValue().trySExtValue(); 403 return SImm.has_value() && isInt<32>(-*SImm); 404}], NEGSIMM32, "S32Imm">; 405 406def imm32 : ImmLeaf<i32, [{}]>; 407 408//===----------------------------------------------------------------------===// 409// 64-bit immediates 410//===----------------------------------------------------------------------===// 411 412// Immediates for 16-bit chunks of an i64, with the other bits of the 413// i32 being zero. 414defm imm64ll16 : Immediate<i64, [{ 415 return N->getAPIntValue().isIntN(64) && SystemZ::isImmLL(N->getZExtValue()); 416}], LL16, "U16Imm">; 417 418defm imm64lh16 : Immediate<i64, [{ 419 return N->getAPIntValue().isIntN(64) && SystemZ::isImmLH(N->getZExtValue()); 420}], LH16, "U16Imm">; 421 422defm imm64hl16 : Immediate<i64, [{ 423 return N->getAPIntValue().isIntN(64) && SystemZ::isImmHL(N->getZExtValue()); 424}], HL16, "U16Imm">; 425 426defm imm64hh16 : Immediate<i64, [{ 427 return N->getAPIntValue().isIntN(64) && SystemZ::isImmHH(N->getZExtValue()); 428}], HH16, "U16Imm">; 429 430// Immediates for 16-bit chunks of an i64, with the other bits of the 431// i32 being one. 432defm imm64ll16c : Immediate<i64, [{ 433 return N->getAPIntValue().isIntN(64) && 434 SystemZ::isImmLL(uint64_t(~N->getZExtValue())); 435}], LL16, "U16Imm">; 436 437defm imm64lh16c : Immediate<i64, [{ 438 return N->getAPIntValue().isIntN(64) && 439 SystemZ::isImmLH(uint64_t(~N->getZExtValue())); 440}], LH16, "U16Imm">; 441 442defm imm64hl16c : Immediate<i64, [{ 443 return N->getAPIntValue().isIntN(64) && 444 SystemZ::isImmHL(uint64_t(~N->getZExtValue())); 445}], HL16, "U16Imm">; 446 447defm imm64hh16c : Immediate<i64, [{ 448 return N->getAPIntValue().isIntN(64) && 449 SystemZ::isImmHH(uint64_t(~N->getZExtValue())); 450}], HH16, "U16Imm">; 451 452// Immediates for the lower and upper 32 bits of an i64, with the other 453// bits of the i32 being zero. 454defm imm64lf32 : Immediate<i64, [{ 455 return N->getAPIntValue().isIntN(64) && SystemZ::isImmLF(N->getZExtValue()); 456}], LF32, "U32Imm">; 457 458defm imm64hf32 : Immediate<i64, [{ 459 return N->getAPIntValue().isIntN(64) && SystemZ::isImmHF(N->getZExtValue()); 460}], HF32, "U32Imm">; 461 462// Immediates for the lower and upper 32 bits of an i64, with the other 463// bits of the i32 being one. 464defm imm64lf32c : Immediate<i64, [{ 465 return N->getAPIntValue().isIntN(64) && 466 SystemZ::isImmLF(uint64_t(~N->getZExtValue())); 467}], LF32, "U32Imm">; 468 469defm imm64hf32c : Immediate<i64, [{ 470 return N->getAPIntValue().isIntN(64) && 471 SystemZ::isImmHF(uint64_t(~N->getZExtValue())); 472}], HF32, "U32Imm">; 473 474// Negated immediates that fit LF32 or LH16. 475defm imm64lh16n : Immediate<i64, [{ 476 return N->getAPIntValue().isIntN(64) && 477 SystemZ::isImmLH(uint64_t(-N->getZExtValue())); 478}], NEGLH16, "U16Imm">; 479 480defm imm64lf32n : Immediate<i64, [{ 481 return N->getAPIntValue().isIntN(64) && 482 SystemZ::isImmLF(uint64_t(-N->getZExtValue())); 483}], NEGLF32, "U32Imm">; 484 485// Short immediates. 486defm imm64sx8 : Immediate<i64, [{ 487 return N->getAPIntValue().isSignedIntN(8); 488}], SIMM8, "S8Imm">; 489 490defm imm64zx8 : Immediate<i64, [{ 491 return N->getAPIntValue().isIntN(8);; 492}], UIMM8, "U8Imm">; 493 494defm imm64sx16 : Immediate<i64, [{ 495 return N->getAPIntValue().isSignedIntN(16); 496}], SIMM16, "S16Imm">; 497 498defm imm64sx16n : Immediate<i64, [{ 499 return (-N->getAPIntValue()).isSignedIntN(16); 500}], NEGSIMM16, "S16Imm">; 501 502defm imm64zx16 : Immediate<i64, [{ 503 return N->getAPIntValue().isIntN(16); 504}], UIMM16, "U16Imm">; 505 506defm imm64sx32 : Immediate<i64, [{ 507 return N->getAPIntValue().isSignedIntN(32); 508}], SIMM32, "S32Imm">; 509 510defm imm64sx32n : Immediate<i64, [{ 511 return (-N->getAPIntValue()).isSignedIntN(32); 512}], NEGSIMM32, "S32Imm">; 513 514defm imm64zx32 : Immediate<i64, [{ 515 return N->getAPIntValue().isIntN(32); 516}], UIMM32, "U32Imm">; 517 518defm imm64zx32n : Immediate<i64, [{ 519 return (-N->getAPIntValue()).isIntN(32); 520}], NEGUIMM32, "U32Imm">; 521 522defm imm64zx48 : Immediate<i64, [{ 523 return N->getAPIntValue().isIntN(64); 524}], UIMM48, "U48Imm">; 525 526class Imm64 : ImmLeaf<i64, [{}]>, Operand<i64> { 527 let OperandType = "OPERAND_IMMEDIATE"; 528} 529def imm64 : Imm64; 530def len4imm64 : Imm64 { 531 let EncoderMethod = "getLenEncoding<SystemZ::FK_390_U4Imm>"; 532 let DecoderMethod = "decodeLenOperand<4>"; 533} 534def len8imm64 : Imm64 { 535 let EncoderMethod = "getLenEncoding<SystemZ::FK_390_U8Imm>"; 536 let DecoderMethod = "decodeLenOperand<8>"; 537} 538 539//===----------------------------------------------------------------------===// 540// Floating-point immediates 541//===----------------------------------------------------------------------===// 542 543// Floating-point zero. 544def fpimm0 : PatLeaf<(fpimm), [{ return N->isExactlyValue(+0.0); }]>; 545 546// Floating point negative zero. 547def fpimmneg0 : PatLeaf<(fpimm), [{ return N->isExactlyValue(-0.0); }]>; 548 549//===----------------------------------------------------------------------===// 550// Symbolic address operands 551//===----------------------------------------------------------------------===// 552 553// PC-relative asm operands. 554def PCRel12 : PCRelAsmOperand<"12">; 555def PCRel16 : PCRelAsmOperand<"16">; 556def PCRel24 : PCRelAsmOperand<"24">; 557def PCRel32 : PCRelAsmOperand<"32">; 558def PCRelTLS16 : PCRelTLSAsmOperand<"16">; 559def PCRelTLS32 : PCRelTLSAsmOperand<"32">; 560 561// PC-relative offsets of a basic block. The offset is sign-extended 562// and multiplied by 2. 563def brtarget16 : PCRelOperand<OtherVT, PCRel16> { 564 let EncoderMethod = "getPC16DBLEncoding"; 565 let DecoderMethod = "decodePC16DBLBranchOperand"; 566} 567def brtarget32 : PCRelOperand<OtherVT, PCRel32> { 568 let EncoderMethod = "getPC32DBLEncoding"; 569 let DecoderMethod = "decodePC32DBLBranchOperand"; 570} 571 572// Variants of brtarget for use with branch prediction preload. 573def brtarget12bpp : PCRelOperand<OtherVT, PCRel12> { 574 let EncoderMethod = "getPC12DBLBPPEncoding"; 575 let DecoderMethod = "decodePC12DBLBranchOperand"; 576} 577def brtarget16bpp : PCRelOperand<OtherVT, PCRel16> { 578 let EncoderMethod = "getPC16DBLBPPEncoding"; 579 let DecoderMethod = "decodePC16DBLBranchOperand"; 580} 581def brtarget24bpp : PCRelOperand<OtherVT, PCRel24> { 582 let EncoderMethod = "getPC24DBLBPPEncoding"; 583 let DecoderMethod = "decodePC24DBLBranchOperand"; 584} 585 586// Variants of brtarget16/32 with an optional additional TLS symbol. 587// These are used to annotate calls to __tls_get_offset. 588def tlssym : Operand<i64> { } 589def brtarget16tls : PCRelTLSOperand<OtherVT, PCRelTLS16> { 590 let MIOperandInfo = (ops brtarget16:$func, tlssym:$sym); 591 let EncoderMethod = "getPC16DBLTLSEncoding"; 592 let DecoderMethod = "decodePC16DBLBranchOperand"; 593} 594def brtarget32tls : PCRelTLSOperand<OtherVT, PCRelTLS32> { 595 let MIOperandInfo = (ops brtarget32:$func, tlssym:$sym); 596 let EncoderMethod = "getPC32DBLTLSEncoding"; 597 let DecoderMethod = "decodePC32DBLBranchOperand"; 598} 599 600// A PC-relative offset of a global value. The offset is sign-extended 601// and multiplied by 2. 602def pcrel32 : PCRelAddress<i64, "pcrel32", PCRel32> { 603 let EncoderMethod = "getPC32DBLEncoding"; 604 let DecoderMethod = "decodePC32DBLOperand"; 605} 606 607//===----------------------------------------------------------------------===// 608// Addressing modes 609//===----------------------------------------------------------------------===// 610 611class DispOp<ValueType vt, code pred> : Operand<vt>, PatLeaf<(vt imm), pred>; 612 613// 12-bit displacement operands. 614let EncoderMethod = "getImmOpValue<SystemZ::FK_390_U12Imm>", 615 DecoderMethod = "decodeU12ImmOperand" in { 616 def disp12imm32 : DispOp<i32, [{ return N->getAPIntValue().isIntN(12); }]>; 617 def disp12imm64 : DispOp<i64, [{ return N->getAPIntValue().isIntN(12); }]>; 618} 619 620// 20-bit displacement operands. 621let EncoderMethod = "getImmOpValue<SystemZ::FK_390_S20Imm>", 622 DecoderMethod = "decodeS20ImmOperand" in { 623 def disp20imm32 : DispOp<i32, [{ return N->getAPIntValue().isSignedIntN(20); }]>; 624 def disp20imm64 : DispOp<i64, [{ return N->getAPIntValue().isSignedIntN(20); }]>; 625} 626 627def BDAddr32Disp12 : AddressAsmOperand<"BDAddr", "32", "12">; 628def BDAddr32Disp20 : AddressAsmOperand<"BDAddr", "32", "20">; 629def BDAddr64Disp12 : AddressAsmOperand<"BDAddr", "64", "12">; 630def BDAddr64Disp20 : AddressAsmOperand<"BDAddr", "64", "20">; 631def BDXAddr64Disp12 : AddressAsmOperand<"BDXAddr", "64", "12">; 632def BDXAddr64Disp20 : AddressAsmOperand<"BDXAddr", "64", "20">; 633def BDLAddr64Disp12Len4 : AddressAsmOperand<"BDLAddr", "64", "12", "Len4">; 634def BDLAddr64Disp12Len8 : AddressAsmOperand<"BDLAddr", "64", "12", "Len8">; 635def BDRAddr64Disp12 : AddressAsmOperand<"BDRAddr", "64", "12">; 636def BDVAddr64Disp12 : AddressAsmOperand<"BDVAddr", "64", "12">; 637def LXAAddr64Disp20 : AddressAsmOperand<"LXAAddr", "64", "20">; 638 639// DAG patterns and operands for addressing modes. Each mode has 640// the form <type><range><group>[<len>] where: 641// 642// <type> is one of: 643// shift : base + displacement (32-bit) 644// bdaddr : base + displacement 645// mviaddr : like bdaddr, but reject cases with a natural index 646// bdxaddr : base + displacement + index 647// laaddr : like bdxaddr, but used for Load Address operations 648// lxaaddr : like bdxaddr, but used for Load (Logical) Indexed Address 649// dynalloc : base + displacement + index + ADJDYNALLOC 650// bdladdr : base + displacement with a length field 651// bdvaddr : base + displacement with a vector index 652// 653// <range> is one of: 654// 12 : the displacement is an unsigned 12-bit value 655// 20 : the displacement is a signed 20-bit value 656// 657// <group> is one of: 658// pair : used when there is an equivalent instruction with the opposite 659// range value (12 or 20) 660// only : used when there is no equivalent instruction with the opposite 661// range value 662// 663// <len> is one of: 664// 665// <empty> : there is no length field 666// len8 : the length field is 8 bits, with a range of [1, 0x100]. 667def shift12only : BDMode <"BDAddr", "32", "12", "Only">; 668def shift20only : BDMode <"BDAddr", "32", "20", "Only">; 669def bdaddr12only : BDMode <"BDAddr", "64", "12", "Only">; 670def bdaddr12pair : BDMode <"BDAddr", "64", "12", "Pair">; 671def bdaddr20only : BDMode <"BDAddr", "64", "20", "Only">; 672def bdaddr20pair : BDMode <"BDAddr", "64", "20", "Pair">; 673def mviaddr12pair : BDMode <"MVIAddr", "64", "12", "Pair">; 674def mviaddr20pair : BDMode <"MVIAddr", "64", "20", "Pair">; 675def bdxaddr12only : BDXMode<"BDXAddr", "64", "12", "Only">; 676def bdxaddr12pair : BDXMode<"BDXAddr", "64", "12", "Pair">; 677def bdxaddr20only : BDXMode<"BDXAddr", "64", "20", "Only">; 678def bdxaddr20only128 : BDXMode<"BDXAddr", "64", "20", "Only128">; 679def bdxaddr20pair : BDXMode<"BDXAddr", "64", "20", "Pair">; 680def dynalloc12only : BDXMode<"DynAlloc", "64", "12", "Only">; 681def laaddr12pair : BDXMode<"LAAddr", "64", "12", "Pair">; 682def laaddr20pair : BDXMode<"LAAddr", "64", "20", "Pair">; 683def lxaaddr20only : LXAMode< "64", "20">; 684def bdladdr12onlylen4 : BDLMode<"BDLAddr", "64", "12", "Only", "4">; 685def bdladdr12onlylen8 : BDLMode<"BDLAddr", "64", "12", "Only", "8">; 686def bdraddr12only : BDRMode<"BDRAddr", "64", "12", "Only">; 687def bdvaddr12only : BDVMode< "64", "12">; 688 689//===----------------------------------------------------------------------===// 690// Miscellaneous 691//===----------------------------------------------------------------------===// 692 693// A 4-bit condition-code mask. 694def cond4 : PatLeaf<(i32 timm), [{ return (N->getZExtValue() < 16); }]>, 695 Operand<i32> { 696 let PrintMethod = "printCond4Operand"; 697 let OperandType = "OPERAND_IMMEDIATE"; 698} 699