1 //===- SystemZInstrInfo.td - SystemZ Instruction defs ---------*- tblgen-*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the SystemZ instructions in TableGen format.
12 //===----------------------------------------------------------------------===//
14 include "SystemZInstrFormats.td"
16 //===----------------------------------------------------------------------===//
17 // SystemZ Specific Node Definitions.
18 //===----------------------------------------------------------------------===//
19 def SystemZretflag : SDNode<"SystemZISD::RET_FLAG", SDTNone,
20 [SDNPHasChain, SDNPOptInFlag]>;
22 let neverHasSideEffects = 1 in
23 def NOP : Pseudo<(outs), (ins), "# no-op", []>;
25 //===----------------------------------------------------------------------===//
26 // Instruction Pattern Stuff.
27 //===----------------------------------------------------------------------===//
28 def LL16 : SDNodeXForm<imm, [{
29 // Transformation function: return low 16 bits.
30 return getI16Imm(N->getZExtValue() & 0x000000000000FFFFULL);
33 def LH16 : SDNodeXForm<imm, [{
34 // Transformation function: return bits 16-31.
35 return getI16Imm((N->getZExtValue() & 0x00000000FFFF0000ULL) >> 16);
38 def HL16 : SDNodeXForm<imm, [{
39 // Transformation function: return bits 32-47.
40 return getI16Imm((N->getZExtValue() & 0x0000FFFF00000000ULL) >> 32);
43 def HH16 : SDNodeXForm<imm, [{
44 // Transformation function: return bits 48-63.
45 return getI16Imm((N->getZExtValue() & 0xFFFF000000000000ULL) >> 48);
48 def LO32 : SDNodeXForm<imm, [{
49 // Transformation function: return low 32 bits.
50 return getI32Imm(N->getZExtValue() & 0x00000000FFFFFFFFULL);
53 def HI32 : SDNodeXForm<imm, [{
54 // Transformation function: return bits 32-63.
55 return getI32Imm(N->getZExtValue() >> 32);
58 def i64ll16 : PatLeaf<(imm), [{
59 // i64ll16 predicate - true if the 64-bit immediate has only rightmost 16
61 return ((N->getZExtValue() & 0x000000000000FFFFULL) == N->getZExtValue());
64 def i64lh16 : PatLeaf<(imm), [{
65 // i64lh16 predicate - true if the 64-bit immediate has only bits 16-31 set.
66 return ((N->getZExtValue() & 0x00000000FFFF0000ULL) == N->getZExtValue());
69 def i64hl16 : PatLeaf<(i64 imm), [{
70 // i64hl16 predicate - true if the 64-bit immediate has only bits 32-47 set.
71 return ((N->getZExtValue() & 0x0000FFFF00000000ULL) == N->getZExtValue());
74 def i64hh16 : PatLeaf<(i64 imm), [{
75 // i64hh16 predicate - true if the 64-bit immediate has only bits 48-63 set.
76 return ((N->getZExtValue() & 0xFFFF000000000000ULL) == N->getZExtValue());
79 def immSExt16 : PatLeaf<(imm), [{
80 // immSExt16 predicate - true if the immediate fits in a 16-bit sign extended
82 if (N->getValueType(0) == MVT::i64) {
83 uint64_t val = N->getZExtValue();
84 return ((int64_t)val == (int16_t)val);
85 } else if (N->getValueType(0) == MVT::i32) {
86 uint32_t val = N->getZExtValue();
87 return ((int32_t)val == (int16_t)val);
93 def immSExt32 : PatLeaf<(i64 imm), [{
94 // immSExt32 predicate - true if the immediate fits in a 32-bit sign extended
96 uint64_t val = N->getZExtValue();
97 return ((int64_t)val == (int32_t)val);
100 def i64lo32 : PatLeaf<(i64 imm), [{
101 // i64lo32 predicate - true if the 64-bit immediate has only rightmost 32
103 return ((N->getZExtValue() & 0x00000000FFFFFFFFULL) == N->getZExtValue());
106 def i64hi32 : PatLeaf<(i64 imm), [{
107 // i64hi32 predicate - true if the 64-bit immediate has only bits 32-63 set.
108 return ((N->getZExtValue() & 0xFFFFFFFF00000000ULL) == N->getZExtValue());
111 //===----------------------------------------------------------------------===//
112 // SystemZ Operand Definitions.
113 //===----------------------------------------------------------------------===//
117 // riaddr := reg + imm
118 def riaddr32 : Operand<i32>,
119 ComplexPattern<i32, 2, "SelectAddrRI", []> {
120 let PrintMethod = "printRIAddrOperand";
121 let MIOperandInfo = (ops ADDR32:$base, i32imm:$disp);
124 def riaddr : Operand<i64>,
125 ComplexPattern<i64, 2, "SelectAddrRI", []> {
126 let PrintMethod = "printRIAddrOperand";
127 let MIOperandInfo = (ops ADDR64:$base, i32imm:$disp);
130 //===----------------------------------------------------------------------===//
132 //===----------------------------------------------------------------------===//
133 // Control Flow Instructions...
136 // FIXME: Provide proper encoding!
137 let isReturn = 1, isTerminator = 1 in {
138 def RET : Pseudo<(outs), (ins), "br\t%r14", [(SystemZretflag)]>;
141 //===----------------------------------------------------------------------===//
144 // FIXME: Provide proper encoding!
145 let neverHasSideEffects = 1 in {
146 def MOV32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src),
149 def MOV64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src),
154 def MOVSX64rr32 : Pseudo<(outs GR64:$dst), (ins GR32:$src),
155 "lgfr\t{$dst, $src}",
156 [(set GR64:$dst, (sext GR32:$src))]>;
157 def MOVZX64rr32 : Pseudo<(outs GR64:$dst), (ins GR32:$src),
158 "llgfr\t{$dst, $src}",
159 [(set GR64:$dst, (zext GR32:$src))]>;
161 // FIXME: Provide proper encoding!
162 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
163 def MOV32ri16 : Pseudo<(outs GR32:$dst), (ins i32imm:$src),
165 [(set GR32:$dst, immSExt16:$src)]>;
166 def MOV64ri16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
167 "lghi\t{$dst, $src}",
168 [(set GR64:$dst, immSExt16:$src)]>;
170 def MOV64rill16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
171 "llill\t{$dst, $src}",
172 [(set GR64:$dst, i64ll16:$src)]>;
173 def MOV64rilh16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
174 "llilh\t{$dst, $src}",
175 [(set GR64:$dst, i64lh16:$src)]>;
176 def MOV64rihl16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
177 "llihl\t{$dst, $src}",
178 [(set GR64:$dst, i64hl16:$src)]>;
179 def MOV64rihh16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
180 "llihh\t{$dst, $src}",
181 [(set GR64:$dst, i64hh16:$src)]>;
182 // FIXME: these 3 instructions seem to require extimm facility
183 def MOV64ri32 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
184 "lgfi\t{$dst, $src}",
185 [(set GR64:$dst, immSExt32:$src)]>;
186 def MOV64rilo32 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
187 "llilf\t{$dst, $src}",
188 [(set GR64:$dst, i64lo32:$src)]>;
189 def MOV64rihi32 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
190 "llihf\t{$dst, $src}",
191 [(set GR64:$dst, i64hi32:$src)]>;
194 //===----------------------------------------------------------------------===//
195 // Arithmetic Instructions
197 let isTwoAddress = 1 in {
199 let Defs = [PSW] in {
201 let isCommutable = 1 in { // X = ADD Y, Z == X = ADD Z, Y
202 // FIXME: Provide proper encoding!
203 def ADD32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
205 [(set GR32:$dst, (add GR32:$src1, GR32:$src2)),
207 def ADD64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
208 "agr\t{$dst, $src2}",
209 [(set GR64:$dst, (add GR64:$src1, GR64:$src2)),
213 // FIXME: Provide proper encoding!
214 def ADD32ri16 : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
215 "ahi\t{$dst, $src2}",
216 [(set GR32:$dst, (add GR32:$src1, immSExt16:$src2)),
218 def ADD32ri : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
219 "afi\t{$dst, $src2}",
220 [(set GR32:$dst, (add GR32:$src1, imm:$src2)),
222 def ADD64ri16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
223 "aghi\t{$dst, $src2}",
224 [(set GR64:$dst, (add GR64:$src1, immSExt16:$src2)),
226 def ADD64ri32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
227 "agfi\t{$dst, $src2}",
228 [(set GR64:$dst, (add GR64:$src1, immSExt32:$src2)),
231 let isCommutable = 1 in { // X = AND Y, Z == X = AND Z, Y
232 // FIXME: Provide proper encoding!
233 def AND32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
235 [(set GR32:$dst, (and GR32:$src1, GR32:$src2))]>;
236 def AND64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
237 "ngr\t{$dst, $src2}",
238 [(set GR64:$dst, (and GR64:$src1, GR64:$src2))]>;
241 // FIXME: Provide proper encoding!
242 def AND64rill16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
243 "nill\t{$dst, $src2}",
244 [(set GR64:$dst, (and GR64:$src1, i64ll16:$src2))]>;
245 def AND64rilh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
246 "nilh\t{$dst, $src2}",
247 [(set GR64:$dst, (and GR64:$src1, i64lh16:$src2))]>;
248 def AND64rihl16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
249 "nihl\t{$dst, $src2}",
250 [(set GR64:$dst, (and GR64:$src1, i64hl16:$src2))]>;
251 def AND64rihh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
252 "nihh\t{$dst, $src2}",
253 [(set GR64:$dst, (and GR64:$src1, i64hh16:$src2))]>;
254 // FIXME: these 2 instructions seem to require extimm facility
255 def AND64rilo32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
256 "nilf\t{$dst, $src2}",
257 [(set GR64:$dst, (and GR64:$src1, i64lo32:$src2))]>;
258 def AND64rihi32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
259 "nihf\t{$dst, $src2}",
260 [(set GR64:$dst, (and GR64:$src1, i64hi32:$src2))]>;
262 let isCommutable = 1 in { // X = OR Y, Z == X = OR Z, Y
263 // FIXME: Provide proper encoding!
264 def OR32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
266 [(set GR32:$dst, (or GR32:$src1, GR32:$src2))]>;
267 def OR64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
268 "ogr\t{$dst, $src2}",
269 [(set GR64:$dst, (or GR64:$src1, GR64:$src2))]>;
272 def OR32ri16 : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i16imm:$src2),
273 "oill\t{$dst, $src2}",
274 [(set GR32:$dst, (or GR32:$src1, i64ll16:$src2))]>;
275 def OR32ri16h : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i16imm:$src2),
276 "oilh\t{$dst, $src2}",
277 [(set GR32:$dst, (or GR32:$src1, i64lh16:$src2))]>;
278 def OR32ri : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
279 "oilf\t{$dst, $src2}",
280 [(set GR32:$dst, (or GR32:$src1, imm:$src2))]>;
282 def OR64rill16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
283 "oill\t{$dst, $src2}",
284 [(set GR64:$dst, (or GR64:$src1, i64ll16:$src2))]>;
285 def OR64rilh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
286 "oilh\t{$dst, $src2}",
287 [(set GR64:$dst, (or GR64:$src1, i64lh16:$src2))]>;
288 def OR64rihl16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
289 "oihl\t{$dst, $src2}",
290 [(set GR64:$dst, (or GR64:$src1, i64hl16:$src2))]>;
291 def OR64rihh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
292 "oihh\t{$dst, $src2}",
293 [(set GR64:$dst, (or GR64:$src1, i64hh16:$src2))]>;
294 // FIXME: these 2 instructions seem to require extimm facility
295 def OR64rilo32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
296 "oilf\t{$dst, $src2}",
297 [(set GR64:$dst, (or GR64:$src1, i64lo32:$src2))]>;
298 def OR64rihi32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
299 "oihf\t{$dst, $src2}",
300 [(set GR64:$dst, (or GR64:$src1, i64hi32:$src2))]>;
302 // FIXME: Provide proper encoding!
303 def SUB32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
305 [(set GR32:$dst, (sub GR32:$src1, GR32:$src2))]>;
306 def SUB64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
307 "sgr\t{$dst, $src2}",
308 [(set GR64:$dst, (sub GR64:$src1, GR64:$src2))]>;
311 let isCommutable = 1 in { // X = XOR Y, Z == X = XOR Z, Y
312 // FIXME: Provide proper encoding!
313 def XOR32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
315 [(set GR32:$dst, (xor GR32:$src1, GR32:$src2))]>;
316 def XOR64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
317 "xgr\t{$dst, $src2}",
318 [(set GR64:$dst, (xor GR64:$src1, GR64:$src2))]>;
321 def XOR32ri : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
322 "xilf\t{$dst, $src2}",
323 [(set GR32:$dst, (xor GR32:$src1, imm:$src2))]>;
325 // FIXME: these 2 instructions seem to require extimm facility
326 def XOR64rilo32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
327 "xilf\t{$dst, $src2}",
328 [(set GR64:$dst, (xor GR64:$src1, i64lo32:$src2))]>;
329 def XOR64rihi32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
330 "xihf\t{$dst, $src2}",
331 [(set GR64:$dst, (xor GR64:$src1, i64hi32:$src2))]>;
334 } // isTwoAddress = 1
336 //===----------------------------------------------------------------------===//
339 let isTwoAddress = 1 in
340 def SRL32rri : Pseudo<(outs GR32:$dst), (ins GR32:$src, riaddr32:$amt),
342 [(set GR32:$dst, (srl GR32:$src, riaddr32:$amt))]>;
343 def SRL64rri : Pseudo<(outs GR64:$dst), (ins GR64:$src, riaddr:$amt),
344 "srlg\t{$dst, $src, $amt}",
345 [(set GR64:$dst, (srl GR64:$src, (i32 (trunc riaddr:$amt))))]>;
346 def SRLA64ri : Pseudo<(outs GR64:$dst), (ins GR64:$src, i32imm:$amt),
347 "srlg\t{$dst, $src, $amt}",
348 [(set GR64:$dst, (srl GR64:$src, (i32 imm:$amt)))]>;
350 let isTwoAddress = 1 in
351 def SHL32rri : Pseudo<(outs GR32:$dst), (ins GR32:$src, riaddr32:$amt),
353 [(set GR32:$dst, (shl GR32:$src, riaddr32:$amt))]>;
354 def SHL64rri : Pseudo<(outs GR64:$dst), (ins GR64:$src, riaddr:$amt),
355 "sllg\t{$dst, $src, $amt}",
356 [(set GR64:$dst, (shl GR64:$src, (i32 (trunc riaddr:$amt))))]>;
357 def SHL64ri : Pseudo<(outs GR64:$dst), (ins GR64:$src, i32imm:$amt),
358 "sllg\t{$dst, $src, $amt}",
359 [(set GR64:$dst, (shl GR64:$src, (i32 imm:$amt)))]>;
362 let Defs = [PSW] in {
363 let isTwoAddress = 1 in
364 def SRA32rri : Pseudo<(outs GR32:$dst), (ins GR32:$src, riaddr32:$amt),
366 [(set GR32:$dst, (sra GR32:$src, riaddr32:$amt)),
368 def SRA64rri : Pseudo<(outs GR64:$dst), (ins GR64:$src, riaddr:$amt),
369 "srag\t{$dst, $src, $amt}",
370 [(set GR64:$dst, (sra GR64:$src, (i32 (trunc riaddr:$amt)))),
372 def SRA64ri : Pseudo<(outs GR64:$dst), (ins GR64:$src, i32imm:$amt),
373 "srag\t{$dst, $src, $amt}",
374 [(set GR64:$dst, (sra GR64:$src, (i32 imm:$amt))),
378 //===----------------------------------------------------------------------===//
379 // Non-Instruction Patterns.
380 //===----------------------------------------------------------------------===//
383 def : Pat<(i64 (anyext GR32:$src)),
384 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, subreg_32bit)>;
386 //===----------------------------------------------------------------------===//
388 //===----------------------------------------------------------------------===//
390 // FIXME: use add/sub tricks with 32678/-32768
393 def : Pat<(i32 (trunc GR64:$src)),
394 (EXTRACT_SUBREG GR64:$src, subreg_32bit)>;
396 // sext_inreg patterns
397 def : Pat<(sext_inreg GR64:$src, i32),
398 (MOVSX64rr32 (EXTRACT_SUBREG GR64:$src, subreg_32bit))>;