446e426abfea58d419be915a54f0e64dc8ae34ea
[oota-llvm.git] / lib / Target / SystemZ / SystemZOperands.td
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.
20 def SYSTEMZ_COND_E  : PatLeaf<(i8 0)>;
21 def SYSTEMZ_COND_NE : PatLeaf<(i8 1)>;
22 def SYSTEMZ_COND_H  : PatLeaf<(i8 2)>;
23 def SYSTEMZ_COND_L  : PatLeaf<(i8 3)>;
24 def SYSTEMZ_COND_HE : PatLeaf<(i8 4)>;
25 def SYSTEMZ_COND_LE : PatLeaf<(i8 5)>;
26
27 def LL16 : SDNodeXForm<imm, [{
28   // Transformation function: return low 16 bits.
29   return getI16Imm(N->getZExtValue() & 0x000000000000FFFFULL);
30 }]>;
31
32 def LH16 : SDNodeXForm<imm, [{
33   // Transformation function: return bits 16-31.
34   return getI16Imm((N->getZExtValue() & 0x00000000FFFF0000ULL) >> 16);
35 }]>;
36
37 def HL16 : SDNodeXForm<imm, [{
38   // Transformation function: return bits 32-47.
39   return getI16Imm((N->getZExtValue() & 0x0000FFFF00000000ULL) >> 32);
40 }]>;
41
42 def HH16 : SDNodeXForm<imm, [{
43   // Transformation function: return bits 48-63.
44   return getI16Imm((N->getZExtValue() & 0xFFFF000000000000ULL) >> 48);
45 }]>;
46
47 def LO32 : SDNodeXForm<imm, [{
48   // Transformation function: return low 32 bits.
49   return getI32Imm(N->getZExtValue() & 0x00000000FFFFFFFFULL);
50 }]>;
51
52 def HI32 : SDNodeXForm<imm, [{
53   // Transformation function: return bits 32-63.
54   return getI32Imm(N->getZExtValue() >> 32);
55 }]>;
56
57 def i32ll16 : PatLeaf<(i32 imm), [{
58   // i32ll16 predicate - true if the 32-bit immediate has only rightmost 16
59   // bits set.
60   return ((N->getZExtValue() & 0x000000000000FFFFULL) == N->getZExtValue());
61 }], LL16>;
62
63 def i32lh16 : PatLeaf<(i32 imm), [{
64   // i32lh16 predicate - true if the 32-bit immediate has only bits 16-31 set.
65   return ((N->getZExtValue() & 0x00000000FFFF0000ULL) == N->getZExtValue());
66 }], LH16>;
67
68 def i32ll16c : PatLeaf<(i32 imm), [{
69   // i32ll16c predicate - true if the 32-bit immediate has all bits 16-31 set.
70   return ((N->getZExtValue() | 0x00000000FFFF0000ULL) == N->getZExtValue());
71 }], LL16>;
72
73 def i32lh16c : PatLeaf<(i32 imm), [{
74   // i32lh16c predicate - true if the 32-bit immediate has all rightmost 16
75   //  bits set.
76   return ((N->getZExtValue() | 0x000000000000FFFFULL) == N->getZExtValue());
77 }], LH16>;
78
79 def i64ll16 : PatLeaf<(i64 imm), [{  
80   // i64ll16 predicate - true if the 64-bit immediate has only rightmost 16
81   // bits set.
82   return ((N->getZExtValue() & 0x000000000000FFFFULL) == N->getZExtValue());
83 }], LL16>;
84
85 def i64lh16 : PatLeaf<(i64 imm), [{  
86   // i64lh16 predicate - true if the 64-bit immediate has only bits 16-31 set.
87   return ((N->getZExtValue() & 0x00000000FFFF0000ULL) == N->getZExtValue());
88 }], LH16>;
89
90 def i64hl16 : PatLeaf<(i64 imm), [{  
91   // i64hl16 predicate - true if the 64-bit immediate has only bits 32-47 set.
92   return ((N->getZExtValue() & 0x0000FFFF00000000ULL) == N->getZExtValue());
93 }], HL16>;
94
95 def i64hh16 : PatLeaf<(i64 imm), [{  
96   // i64hh16 predicate - true if the 64-bit immediate has only bits 48-63 set.
97   return ((N->getZExtValue() & 0xFFFF000000000000ULL) == N->getZExtValue());
98 }], HH16>;
99
100 def i64ll16c : PatLeaf<(i64 imm), [{  
101   // i64ll16c predicate - true if the 64-bit immediate has only rightmost 16
102   // bits set.
103   return ((N->getZExtValue() | 0xFFFFFFFFFFFF0000ULL) == N->getZExtValue());
104 }], LL16>;
105
106 def i64lh16c : PatLeaf<(i64 imm), [{  
107   // i64lh16c predicate - true if the 64-bit immediate has only bits 16-31 set.
108   return ((N->getZExtValue() | 0xFFFFFFFF0000FFFFULL) == N->getZExtValue());
109 }], LH16>;
110
111 def i64hl16c : PatLeaf<(i64 imm), [{  
112   // i64hl16c predicate - true if the 64-bit immediate has only bits 32-47 set.
113   return ((N->getZExtValue() | 0xFFFF0000FFFFFFFFULL) == N->getZExtValue());
114 }], HL16>;
115
116 def i64hh16c : PatLeaf<(i64 imm), [{  
117   // i64hh16c predicate - true if the 64-bit immediate has only bits 48-63 set.
118   return ((N->getZExtValue() | 0x0000FFFFFFFFFFFFULL) == N->getZExtValue());
119 }], HH16>;
120
121 def immSExt16 : PatLeaf<(imm), [{
122   // immSExt16 predicate - true if the immediate fits in a 16-bit sign extended
123   // field.
124   if (N->getValueType(0) == MVT::i64) {
125     uint64_t val = N->getZExtValue();
126     return ((int64_t)val == (int16_t)val);
127   } else if (N->getValueType(0) == MVT::i32) {
128     uint32_t val = N->getZExtValue();
129     return ((int32_t)val == (int16_t)val);
130   }
131
132   return false;
133 }]>;
134
135 def immSExt32 : PatLeaf<(i64 imm), [{
136   // immSExt32 predicate - true if the immediate fits in a 32-bit sign extended
137   // field.
138   uint64_t val = N->getZExtValue();
139   return ((int64_t)val == (int32_t)val);
140 }]>;
141
142 def i64lo32 : PatLeaf<(i64 imm), [{
143   // i64lo32 predicate - true if the 64-bit immediate has only rightmost 32
144   // bits set.
145   return ((N->getZExtValue() & 0x00000000FFFFFFFFULL) == N->getZExtValue());
146 }], LO32>;
147
148 def i64hi32 : PatLeaf<(i64 imm), [{
149   // i64hi32 predicate - true if the 64-bit immediate has only bits 32-63 set.
150   return ((N->getZExtValue() & 0xFFFFFFFF00000000ULL) == N->getZExtValue());
151 }], HI32>;
152
153 def i64lo32c : PatLeaf<(i64 imm), [{
154   // i64lo32 predicate - true if the 64-bit immediate has only rightmost 32
155   // bits set.
156   return ((N->getZExtValue() | 0xFFFFFFFF00000000ULL) == N->getZExtValue());
157 }], LO32>;
158
159 def i64hi32c : PatLeaf<(i64 imm), [{
160   // i64hi32 predicate - true if the 64-bit immediate has only bits 32-63 set.
161   return ((N->getZExtValue() | 0x00000000FFFFFFFFULL) == N->getZExtValue());
162 }], HI32>;
163
164 def i32immSExt8  : PatLeaf<(i32 imm), [{
165   // i32immSExt8 predicate - True if the 32-bit immediate fits in a 8-bit
166   // sign extended field.
167   return (int32_t)N->getZExtValue() == (int8_t)N->getZExtValue();
168 }]>;
169
170 def i32immSExt16 : PatLeaf<(i32 imm), [{
171   // i32immSExt16 predicate - True if the 32-bit immediate fits in a 16-bit
172   // sign extended field.
173   return (int32_t)N->getZExtValue() == (int16_t)N->getZExtValue();
174 }]>;
175
176 def i64immSExt32 : PatLeaf<(i64 imm), [{
177   // i64immSExt32 predicate - True if the 64-bit immediate fits in a 32-bit
178   // sign extended field.
179   return (int64_t)N->getZExtValue() == (int32_t)N->getZExtValue();
180 }]>;
181
182 def i64immZExt32 : PatLeaf<(i64 imm), [{
183   // i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
184   // zero extended field.
185   return (uint64_t)N->getZExtValue() == (uint32_t)N->getZExtValue();
186 }]>;
187
188 // extloads
189 def extloadi32i8   : PatFrag<(ops node:$ptr), (i32 (extloadi8  node:$ptr))>;
190 def extloadi32i16  : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>;
191 def extloadi64i8   : PatFrag<(ops node:$ptr), (i64 (extloadi8  node:$ptr))>;
192 def extloadi64i16  : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
193 def extloadi64i32  : PatFrag<(ops node:$ptr), (i64 (extloadi32 node:$ptr))>;
194
195 def sextloadi32i8   : PatFrag<(ops node:$ptr), (i32 (sextloadi8  node:$ptr))>;
196 def sextloadi32i16  : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>;
197 def sextloadi64i8   : PatFrag<(ops node:$ptr), (i64 (sextloadi8  node:$ptr))>;
198 def sextloadi64i16  : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
199 def sextloadi64i32  : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>;
200
201 def zextloadi32i8   : PatFrag<(ops node:$ptr), (i32 (zextloadi8  node:$ptr))>;
202 def zextloadi32i16  : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>;
203 def zextloadi64i8   : PatFrag<(ops node:$ptr), (i64 (zextloadi8  node:$ptr))>;
204 def zextloadi64i16  : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>;
205 def zextloadi64i32  : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
206
207 // A couple of more descriptive operand definitions.
208 // 32-bits but only 8 bits are significant.
209 def i32i8imm  : Operand<i32>;
210 // 32-bits but only 16 bits are significant.
211 def i32i16imm : Operand<i32>;
212 // 64-bits but only 32 bits are significant.
213 def i64i32imm : Operand<i64>;
214 // Branch targets have OtherVT type.
215 def brtarget : Operand<OtherVT>;
216
217 // Unigned i12
218 def u12imm : Operand<i32> {
219   let PrintMethod = "printU16ImmOperand";
220 }
221 // Signed i16
222 def s16imm : Operand<i32> {
223   let PrintMethod = "printS16ImmOperand";
224 }
225 def s16imm64 : Operand<i64> {
226   let PrintMethod = "printS16ImmOperand";
227 }
228 // Signed i20
229 def s20imm : Operand<i32> {
230   let PrintMethod = "printS20ImmOperand";
231 }
232 def s20imm64 : Operand<i64> {
233   let PrintMethod = "printS20ImmOperand";
234 }
235 // Signed i32
236 def s32imm : Operand<i32> {
237   let PrintMethod = "printS32ImmOperand";
238 }
239 def s32imm64 : Operand<i64> {
240   let PrintMethod = "printS32ImmOperand";
241 }
242
243 //===----------------------------------------------------------------------===//
244 // SystemZ Operand Definitions.
245 //===----------------------------------------------------------------------===//
246
247 // Address operands
248
249 // riaddr := reg + imm
250 def riaddr32 : Operand<i32>,
251                ComplexPattern<i32, 2, "SelectAddrRI32", []> {
252   let PrintMethod = "printRIAddrOperand";
253   let MIOperandInfo = (ops ADDR32:$base, u12imm:$disp);
254 }
255
256 def riaddr : Operand<i64>,
257              ComplexPattern<i64, 2, "SelectAddrRI", []> {
258   let PrintMethod = "printRIAddrOperand";
259   let MIOperandInfo = (ops ADDR64:$base, s20imm64:$disp);
260 }
261
262 //===----------------------------------------------------------------------===//
263
264 // rriaddr := reg + reg + imm
265 def rriaddr : Operand<i64>,
266               ComplexPattern<i64, 3, "SelectAddrRRI", [], []> {
267   let PrintMethod = "printRRIAddrOperand";
268   let MIOperandInfo = (ops ADDR64:$base, s20imm64:$disp, ADDR64:$index);
269 }
270 def laaddr : Operand<i64>,
271              ComplexPattern<i64, 3, "SelectLAAddr", [add, sub, or, frameindex], []> {
272   let PrintMethod = "printRRIAddrOperand";
273   let MIOperandInfo = (ops ADDR64:$base, s20imm64:$disp, ADDR64:$index);
274 }