xref: /llvm-project/llvm/lib/Target/SystemZ/SystemZOperands.td (revision 8424bf207efd89eacf2fe893b67be98d535e1db6)
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