SystemZOperands.td revision cf2cdc9cae27a25deb50013b1337abb0c522c354
1//=====- SystemZOperands.td - SystemZ Operands defs ---------*- tblgen-*-=====//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source 
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file describes the various SystemZ instruction operands.
11//
12//===----------------------------------------------------------------------===//
13
14//===----------------------------------------------------------------------===//
15// Instruction Pattern Stuff.
16//===----------------------------------------------------------------------===//
17
18// SystemZ specific condition code. These correspond to CondCode in
19// SystemZ.h. They must be kept in synch.
20def SYSTEMZ_COND_O   : PatLeaf<(i8 0)>;
21def SYSTEMZ_COND_H   : PatLeaf<(i8 1)>;
22def SYSTEMZ_COND_NLE : PatLeaf<(i8 2)>;
23def SYSTEMZ_COND_L   : PatLeaf<(i8 3)>;
24def SYSTEMZ_COND_NHE : PatLeaf<(i8 4)>;
25def SYSTEMZ_COND_LH  : PatLeaf<(i8 5)>;
26def SYSTEMZ_COND_NE  : PatLeaf<(i8 6)>;
27def SYSTEMZ_COND_E   : PatLeaf<(i8 7)>;
28def SYSTEMZ_COND_NLH : PatLeaf<(i8 8)>;
29def SYSTEMZ_COND_HE  : PatLeaf<(i8 9)>;
30def SYSTEMZ_COND_NL  : PatLeaf<(i8 10)>;
31def SYSTEMZ_COND_LE  : PatLeaf<(i8 11)>;
32def SYSTEMZ_COND_NH  : PatLeaf<(i8 12)>;
33def SYSTEMZ_COND_NO  : PatLeaf<(i8 13)>;
34
35def LO8 : SDNodeXForm<imm, [{
36  // Transformation function: return low 8 bits.
37  return getI8Imm(N->getZExtValue() & 0x00000000000000FFULL);
38}]>;
39
40def LL16 : SDNodeXForm<imm, [{
41  // Transformation function: return low 16 bits.
42  return getI16Imm(N->getZExtValue() & 0x000000000000FFFFULL);
43}]>;
44
45def LH16 : SDNodeXForm<imm, [{
46  // Transformation function: return bits 16-31.
47  return getI16Imm((N->getZExtValue() & 0x00000000FFFF0000ULL) >> 16);
48}]>;
49
50def HL16 : SDNodeXForm<imm, [{
51  // Transformation function: return bits 32-47.
52  return getI16Imm((N->getZExtValue() & 0x0000FFFF00000000ULL) >> 32);
53}]>;
54
55def HH16 : SDNodeXForm<imm, [{
56  // Transformation function: return bits 48-63.
57  return getI16Imm((N->getZExtValue() & 0xFFFF000000000000ULL) >> 48);
58}]>;
59
60def LO32 : SDNodeXForm<imm, [{
61  // Transformation function: return low 32 bits.
62  return getI32Imm(N->getZExtValue() & 0x00000000FFFFFFFFULL);
63}]>;
64
65def HI32 : SDNodeXForm<imm, [{
66  // Transformation function: return bits 32-63.
67  return getI32Imm(N->getZExtValue() >> 32);
68}]>;
69
70def GetI64FromI32 : SDNodeXForm<imm, [{
71  return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i64);
72}]>;
73
74def i32ll16 : PatLeaf<(i32 imm), [{
75  // i32ll16 predicate - true if the 32-bit immediate has only rightmost 16
76  // bits set.
77  return ((N->getZExtValue() & 0x000000000000FFFFULL) == N->getZExtValue());
78}], LL16>;
79
80def i32lh16 : PatLeaf<(i32 imm), [{
81  // i32lh16 predicate - true if the 32-bit immediate has only bits 16-31 set.
82  return ((N->getZExtValue() & 0x00000000FFFF0000ULL) == N->getZExtValue());
83}], LH16>;
84
85def i32ll16c : PatLeaf<(i32 imm), [{
86  // i32ll16c predicate - true if the 32-bit immediate has all bits 16-31 set.
87  return ((N->getZExtValue() | 0x00000000FFFF0000ULL) == N->getZExtValue());
88}], LL16>;
89
90def i32lh16c : PatLeaf<(i32 imm), [{
91  // i32lh16c predicate - true if the 32-bit immediate has all rightmost 16
92  //  bits set.
93  return ((N->getZExtValue() | 0x000000000000FFFFULL) == N->getZExtValue());
94}], LH16>;
95
96def i64ll16 : PatLeaf<(i64 imm), [{  
97  // i64ll16 predicate - true if the 64-bit immediate has only rightmost 16
98  // bits set.
99  return ((N->getZExtValue() & 0x000000000000FFFFULL) == N->getZExtValue());
100}], LL16>;
101
102def i64lh16 : PatLeaf<(i64 imm), [{  
103  // i64lh16 predicate - true if the 64-bit immediate has only bits 16-31 set.
104  return ((N->getZExtValue() & 0x00000000FFFF0000ULL) == N->getZExtValue());
105}], LH16>;
106
107def i64hl16 : PatLeaf<(i64 imm), [{  
108  // i64hl16 predicate - true if the 64-bit immediate has only bits 32-47 set.
109  return ((N->getZExtValue() & 0x0000FFFF00000000ULL) == N->getZExtValue());
110}], HL16>;
111
112def i64hh16 : PatLeaf<(i64 imm), [{  
113  // i64hh16 predicate - true if the 64-bit immediate has only bits 48-63 set.
114  return ((N->getZExtValue() & 0xFFFF000000000000ULL) == N->getZExtValue());
115}], HH16>;
116
117def i64ll16c : PatLeaf<(i64 imm), [{  
118  // i64ll16c predicate - true if the 64-bit immediate has only rightmost 16
119  // bits set.
120  return ((N->getZExtValue() | 0xFFFFFFFFFFFF0000ULL) == N->getZExtValue());
121}], LL16>;
122
123def i64lh16c : PatLeaf<(i64 imm), [{  
124  // i64lh16c predicate - true if the 64-bit immediate has only bits 16-31 set.
125  return ((N->getZExtValue() | 0xFFFFFFFF0000FFFFULL) == N->getZExtValue());
126}], LH16>;
127
128def i64hl16c : PatLeaf<(i64 imm), [{  
129  // i64hl16c predicate - true if the 64-bit immediate has only bits 32-47 set.
130  return ((N->getZExtValue() | 0xFFFF0000FFFFFFFFULL) == N->getZExtValue());
131}], HL16>;
132
133def i64hh16c : PatLeaf<(i64 imm), [{  
134  // i64hh16c predicate - true if the 64-bit immediate has only bits 48-63 set.
135  return ((N->getZExtValue() | 0x0000FFFFFFFFFFFFULL) == N->getZExtValue());
136}], HH16>;
137
138def immSExt16 : PatLeaf<(imm), [{
139  // immSExt16 predicate - true if the immediate fits in a 16-bit sign extended
140  // field.
141  if (N->getValueType(0) == MVT::i64) {
142    uint64_t val = N->getZExtValue();
143    return ((int64_t)val == (int16_t)val);
144  } else if (N->getValueType(0) == MVT::i32) {
145    uint32_t val = N->getZExtValue();
146    return ((int32_t)val == (int16_t)val);
147  }
148
149  return false;
150}], LL16>;
151
152def immSExt32 : PatLeaf<(i64 imm), [{
153  // immSExt32 predicate - true if the immediate fits in a 32-bit sign extended
154  // field.
155  uint64_t val = N->getZExtValue();
156  return ((int64_t)val == (int32_t)val);
157}], LO32>;
158
159def i64lo32 : PatLeaf<(i64 imm), [{
160  // i64lo32 predicate - true if the 64-bit immediate has only rightmost 32
161  // bits set.
162  return ((N->getZExtValue() & 0x00000000FFFFFFFFULL) == N->getZExtValue());
163}], LO32>;
164
165def i64hi32 : PatLeaf<(i64 imm), [{
166  // i64hi32 predicate - true if the 64-bit immediate has only bits 32-63 set.
167  return ((N->getZExtValue() & 0xFFFFFFFF00000000ULL) == N->getZExtValue());
168}], HI32>;
169
170def i64lo32c : PatLeaf<(i64 imm), [{
171  // i64lo32 predicate - true if the 64-bit immediate has only rightmost 32
172  // bits set.
173  return ((N->getZExtValue() | 0xFFFFFFFF00000000ULL) == N->getZExtValue());
174}], LO32>;
175
176def i64hi32c : PatLeaf<(i64 imm), [{
177  // i64hi32 predicate - true if the 64-bit immediate has only bits 32-63 set.
178  return ((N->getZExtValue() | 0x00000000FFFFFFFFULL) == N->getZExtValue());
179}], HI32>;
180
181def i32immSExt8  : PatLeaf<(i32 imm), [{
182  // i32immSExt8 predicate - True if the 32-bit immediate fits in a 8-bit
183  // sign extended field.
184  return (int32_t)N->getZExtValue() == (int8_t)N->getZExtValue();
185}], LO8>;
186
187def i32immSExt16 : PatLeaf<(i32 imm), [{
188  // i32immSExt16 predicate - True if the 32-bit immediate fits in a 16-bit
189  // sign extended field.
190  return (int32_t)N->getZExtValue() == (int16_t)N->getZExtValue();
191}], LL16>;
192
193def i64immSExt32 : PatLeaf<(i64 imm), [{
194  // i64immSExt32 predicate - True if the 64-bit immediate fits in a 32-bit
195  // sign extended field.
196  return (int64_t)N->getZExtValue() == (int32_t)N->getZExtValue();
197}], LO32>;
198
199def i64immZExt32 : PatLeaf<(i64 imm), [{
200  // i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
201  // zero extended field.
202  return (uint64_t)N->getZExtValue() == (uint32_t)N->getZExtValue();
203}], LO32>;
204
205// extloads
206def extloadi32i8   : PatFrag<(ops node:$ptr), (i32 (extloadi8  node:$ptr))>;
207def extloadi32i16  : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>;
208def extloadi64i8   : PatFrag<(ops node:$ptr), (i64 (extloadi8  node:$ptr))>;
209def extloadi64i16  : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
210def extloadi64i32  : PatFrag<(ops node:$ptr), (i64 (extloadi32 node:$ptr))>;
211
212def sextloadi32i8   : PatFrag<(ops node:$ptr), (i32 (sextloadi8  node:$ptr))>;
213def sextloadi32i16  : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>;
214def sextloadi64i8   : PatFrag<(ops node:$ptr), (i64 (sextloadi8  node:$ptr))>;
215def sextloadi64i16  : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
216def sextloadi64i32  : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>;
217
218def zextloadi32i8   : PatFrag<(ops node:$ptr), (i32 (zextloadi8  node:$ptr))>;
219def zextloadi32i16  : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>;
220def zextloadi64i8   : PatFrag<(ops node:$ptr), (i64 (zextloadi8  node:$ptr))>;
221def zextloadi64i16  : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>;
222def zextloadi64i32  : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
223
224// A couple of more descriptive operand definitions.
225// 32-bits but only 8 bits are significant.
226def i32i8imm  : Operand<i32>;
227// 32-bits but only 16 bits are significant.
228def i32i16imm : Operand<i32>;
229// 64-bits but only 32 bits are significant.
230def i64i32imm : Operand<i64>;
231// Branch targets have OtherVT type.
232def brtarget : Operand<OtherVT>;
233
234// Unsigned i12
235def u12imm : Operand<i32> {
236  let PrintMethod = "printU12ImmOperand";
237}
238def u12imm64 : Operand<i64> {
239  let PrintMethod = "printU12ImmOperand";
240}
241
242// Signed i16
243def s16imm : Operand<i32> {
244  let PrintMethod = "printS16ImmOperand";
245}
246def s16imm64 : Operand<i64> {
247  let PrintMethod = "printS16ImmOperand";
248}
249// Unsigned i16
250def u16imm : Operand<i32> {
251  let PrintMethod = "printU16ImmOperand";
252}
253def u16imm64 : Operand<i64> {
254  let PrintMethod = "printU16ImmOperand";
255}
256
257// Signed i20
258def s20imm : Operand<i32> {
259  let PrintMethod = "printS20ImmOperand";
260}
261def s20imm64 : Operand<i64> {
262  let PrintMethod = "printS20ImmOperand";
263}
264// Signed i32
265def s32imm : Operand<i32> {
266  let PrintMethod = "printS32ImmOperand";
267}
268def s32imm64 : Operand<i64> {
269  let PrintMethod = "printS32ImmOperand";
270}
271// Unsigned i32
272def u32imm : Operand<i32> {
273  let PrintMethod = "printU32ImmOperand";
274}
275def u32imm64 : Operand<i64> {
276  let PrintMethod = "printU32ImmOperand";
277}
278
279def imm_pcrel : Operand<i64> {
280  let PrintMethod = "printPCRelImmOperand";
281}
282
283//===----------------------------------------------------------------------===//
284// SystemZ Operand Definitions.
285//===----------------------------------------------------------------------===//
286
287// Address operands
288
289// riaddr := reg + imm
290def riaddr32 : Operand<i64>,
291               ComplexPattern<i64, 2, "SelectAddrRI12Only", []> {
292  let PrintMethod = "printRIAddrOperand";
293  let MIOperandInfo = (ops ADDR64:$base, u12imm:$disp);
294}
295
296def riaddr12 : Operand<i64>,
297               ComplexPattern<i64, 2, "SelectAddrRI12", []> {
298  let PrintMethod = "printRIAddrOperand";
299  let MIOperandInfo = (ops ADDR64:$base, u12imm64:$disp);
300}
301
302def riaddr : Operand<i64>,
303             ComplexPattern<i64, 2, "SelectAddrRI", []> {
304  let PrintMethod = "printRIAddrOperand";
305  let MIOperandInfo = (ops ADDR64:$base, s20imm64:$disp);
306}
307
308//===----------------------------------------------------------------------===//
309
310// rriaddr := reg + reg + imm
311def rriaddr12 : Operand<i64>,
312                ComplexPattern<i64, 3, "SelectAddrRRI12", [], []> {
313  let PrintMethod = "printRRIAddrOperand";
314  let MIOperandInfo = (ops ADDR64:$base, u12imm64:$disp, ADDR64:$index);
315}
316def rriaddr : Operand<i64>,
317              ComplexPattern<i64, 3, "SelectAddrRRI20", [], []> {
318  let PrintMethod = "printRRIAddrOperand";
319  let MIOperandInfo = (ops ADDR64:$base, s20imm64:$disp, ADDR64:$index);
320}
321def laaddr : Operand<i64>,
322             ComplexPattern<i64, 3, "SelectLAAddr", [add, sub, or, frameindex], []> {
323  let PrintMethod = "printRRIAddrOperand";
324  let MIOperandInfo = (ops ADDR64:$base, s20imm64:$disp, ADDR64:$index);
325}
326