SystemZInstrInfo.td revision 9e4816e09f50e3c4ef7368a188966944b8167ab4
1//===- SystemZInstrInfo.td - SystemZ Instruction 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 SystemZ instructions in TableGen format.
11//
12//===----------------------------------------------------------------------===//
13
14include "SystemZInstrFormats.td"
15
16//===----------------------------------------------------------------------===//
17// SystemZ Specific Node Definitions.
18//===----------------------------------------------------------------------===//
19def SystemZretflag : SDNode<"SystemZISD::RET_FLAG", SDTNone,
20                     [SDNPHasChain, SDNPOptInFlag]>;
21
22let neverHasSideEffects = 1 in
23def NOP : Pseudo<(outs), (ins), "# no-op", []>;
24
25//===----------------------------------------------------------------------===//
26// Instruction Pattern Stuff.
27//===----------------------------------------------------------------------===//
28def LL16 : SDNodeXForm<imm, [{
29  // Transformation function: return low 16 bits.
30  return getI16Imm(N->getZExtValue() & 0x000000000000FFFFULL);
31}]>;
32
33def LH16 : SDNodeXForm<imm, [{
34  // Transformation function: return bits 16-31.
35  return getI16Imm((N->getZExtValue() & 0x00000000FFFF0000ULL) >> 16);
36}]>;
37
38def HL16 : SDNodeXForm<imm, [{
39  // Transformation function: return bits 32-47.
40  return getI16Imm((N->getZExtValue() & 0x0000FFFF00000000ULL) >> 32);
41}]>;
42
43def HH16 : SDNodeXForm<imm, [{
44  // Transformation function: return bits 48-63.
45  return getI16Imm((N->getZExtValue() & 0xFFFF000000000000ULL) >> 48);
46}]>;
47
48def LO32 : SDNodeXForm<imm, [{
49  // Transformation function: return low 32 bits.
50  return getI32Imm(N->getZExtValue() & 0x00000000FFFFFFFFULL);
51}]>;
52
53def HI32 : SDNodeXForm<imm, [{
54  // Transformation function: return bits 32-63.
55  return getI32Imm(N->getZExtValue() >> 32);
56}]>;
57
58def i64ll16 : PatLeaf<(imm), [{  
59  // i64ll16 predicate - true if the 64-bit immediate has only rightmost 16
60  // bits set.
61  return ((N->getZExtValue() & 0x000000000000FFFFULL) == N->getZExtValue());
62}], LL16>;
63
64def 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());
67}], LH16>;
68
69def 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());
72}], HL16>;
73
74def 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());
77}], HH16>;
78
79def immSExt16 : PatLeaf<(imm), [{
80  // immSExt16 predicate - true if the immediate fits in a 16-bit sign extended
81  // field.
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);
88  }
89
90  return false;
91}]>;
92
93def immSExt32 : PatLeaf<(i64 imm), [{
94  // immSExt32 predicate - true if the immediate fits in a 32-bit sign extended
95  // field.
96  uint64_t val = N->getZExtValue();
97  return ((int64_t)val == (int32_t)val);
98}]>;
99
100def i64lo32 : PatLeaf<(i64 imm), [{
101  // i64lo32 predicate - true if the 64-bit immediate has only rightmost 32
102  // bits set.
103  return ((N->getZExtValue() & 0x00000000FFFFFFFFULL) == N->getZExtValue());
104}], LO32>;
105
106def 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());
109}], HI32>;
110
111//===----------------------------------------------------------------------===//
112// SystemZ Operand Definitions.
113//===----------------------------------------------------------------------===//
114
115// Address operands
116
117// riaddr := reg + imm
118def riaddr32 : Operand<i32>,
119               ComplexPattern<i32, 2, "SelectAddrRI", []> {
120  let PrintMethod = "printRIAddrOperand";
121  let MIOperandInfo = (ops ADDR32:$base, i32imm:$disp);
122}
123
124def riaddr : Operand<i64>,
125             ComplexPattern<i64, 2, "SelectAddrRI", []> {
126  let PrintMethod = "printRIAddrOperand";
127  let MIOperandInfo = (ops ADDR64:$base, i32imm:$disp);
128}
129
130//===----------------------------------------------------------------------===//
131
132//===----------------------------------------------------------------------===//
133//  Control Flow Instructions...
134//
135
136// FIXME: Provide proper encoding!
137let isReturn = 1, isTerminator = 1 in {
138  def RET : Pseudo<(outs), (ins), "br\t%r14", [(SystemZretflag)]>;
139}
140
141//===----------------------------------------------------------------------===//
142// Move Instructions
143
144// FIXME: Provide proper encoding!
145let neverHasSideEffects = 1 in {
146def MOV32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src),
147                     "lr\t{$dst, $src}",
148                     []>;
149def MOV64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src),
150                     "lgr\t{$dst, $src}",
151                     []>;
152}
153
154def MOVSX64rr32 : Pseudo<(outs GR64:$dst), (ins GR32:$src),
155                         "lgfr\t{$dst, $src}",
156                         [(set GR64:$dst, (sext GR32:$src))]>;
157def MOVZX64rr32 : Pseudo<(outs GR64:$dst), (ins GR32:$src),
158                         "llgfr\t{$dst, $src}",
159                         [(set GR64:$dst, (zext GR32:$src))]>;
160
161// FIXME: Provide proper encoding!
162let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
163def MOV32ri16 : Pseudo<(outs GR32:$dst), (ins i32imm:$src),
164                       "lhi\t{$dst, $src}",
165                       [(set GR32:$dst, immSExt16:$src)]>;
166def MOV64ri16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
167                       "lghi\t{$dst, $src}",
168                       [(set GR64:$dst, immSExt16:$src)]>;
169
170def MOV64rill16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
171                         "llill\t{$dst, $src}",
172                         [(set GR64:$dst, i64ll16:$src)]>;
173def MOV64rilh16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
174                         "llilh\t{$dst, $src}",
175                         [(set GR64:$dst, i64lh16:$src)]>;
176def MOV64rihl16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
177                         "llihl\t{$dst, $src}",
178                         [(set GR64:$dst, i64hl16:$src)]>;
179def 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
183def MOV64ri32 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
184                       "lgfi\t{$dst, $src}",
185                       [(set GR64:$dst, immSExt32:$src)]>;
186def MOV64rilo32 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
187                         "llilf\t{$dst, $src}",
188                         [(set GR64:$dst, i64lo32:$src)]>;
189def MOV64rihi32 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
190                         "llihf\t{$dst, $src}",
191                         [(set GR64:$dst, i64hi32:$src)]>;
192}
193
194//===----------------------------------------------------------------------===//
195// Arithmetic Instructions
196
197let isTwoAddress = 1 in {
198
199let Defs = [PSW] in {
200
201let isCommutable = 1 in { // X = ADD Y, Z  == X = ADD Z, Y
202// FIXME: Provide proper encoding!
203def ADD32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
204                     "ar\t{$dst, $src2}",
205                     [(set GR32:$dst, (add GR32:$src1, GR32:$src2)),
206                      (implicit PSW)]>;
207def ADD64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
208                     "agr\t{$dst, $src2}",
209                     [(set GR64:$dst, (add GR64:$src1, GR64:$src2)),
210                      (implicit PSW)]>;
211}
212
213// FIXME: Provide proper encoding!
214def ADD32ri16 : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
215                       "ahi\t{$dst, $src2}",
216                       [(set GR32:$dst, (add GR32:$src1, immSExt16:$src2)),
217                        (implicit PSW)]>;
218def ADD32ri   : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
219                       "afi\t{$dst, $src2}",
220                       [(set GR32:$dst, (add GR32:$src1, imm:$src2)),
221                        (implicit PSW)]>;
222def ADD64ri16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
223                       "aghi\t{$dst, $src2}",
224                       [(set GR64:$dst, (add GR64:$src1, immSExt16:$src2)),
225                        (implicit PSW)]>;
226def ADD64ri32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
227                       "agfi\t{$dst, $src2}",
228                       [(set GR64:$dst, (add GR64:$src1, immSExt32:$src2)),
229                        (implicit PSW)]>;
230
231let isCommutable = 1 in { // X = AND Y, Z  == X = AND Z, Y
232// FIXME: Provide proper encoding!
233def AND32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
234                     "nr\t{$dst, $src2}",
235                     [(set GR32:$dst, (and GR32:$src1, GR32:$src2))]>;
236def AND64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
237                     "ngr\t{$dst, $src2}",
238                     [(set GR64:$dst, (and GR64:$src1, GR64:$src2))]>;
239}
240
241// FIXME: Provide proper encoding!
242def AND64rill16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
243                         "nill\t{$dst, $src2}",
244                         [(set GR64:$dst, (and GR64:$src1, i64ll16:$src2))]>;
245def AND64rilh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
246                         "nilh\t{$dst, $src2}",
247                         [(set GR64:$dst, (and GR64:$src1, i64lh16:$src2))]>;
248def AND64rihl16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
249                         "nihl\t{$dst, $src2}",
250                         [(set GR64:$dst, (and GR64:$src1, i64hl16:$src2))]>;
251def 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
255def AND64rilo32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
256                         "nilf\t{$dst, $src2}",
257                         [(set GR64:$dst, (and GR64:$src1, i64lo32:$src2))]>;
258def AND64rihi32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
259                         "nihf\t{$dst, $src2}",
260                         [(set GR64:$dst, (and GR64:$src1, i64hi32:$src2))]>;
261
262let isCommutable = 1 in { // X = OR Y, Z  == X = OR Z, Y
263// FIXME: Provide proper encoding!
264def OR32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
265                    "or\t{$dst, $src2}",
266                    [(set GR32:$dst, (or GR32:$src1, GR32:$src2))]>;
267def OR64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
268                    "ogr\t{$dst, $src2}",
269                    [(set GR64:$dst, (or GR64:$src1, GR64:$src2))]>;
270}
271
272def OR32ri16  : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i16imm:$src2),
273                      "oill\t{$dst, $src2}",
274                      [(set GR32:$dst, (or GR32:$src1, i64ll16:$src2))]>;
275def OR32ri16h : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i16imm:$src2),
276                      "oilh\t{$dst, $src2}",
277                      [(set GR32:$dst, (or GR32:$src1, i64lh16:$src2))]>;
278def OR32ri : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
279                    "oilf\t{$dst, $src2}",
280                    [(set GR32:$dst, (or GR32:$src1, imm:$src2))]>;
281
282def OR64rill16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
283                        "oill\t{$dst, $src2}",
284                        [(set GR64:$dst, (or GR64:$src1, i64ll16:$src2))]>;
285def OR64rilh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
286                        "oilh\t{$dst, $src2}",
287                        [(set GR64:$dst, (or GR64:$src1, i64lh16:$src2))]>;
288def OR64rihl16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
289                        "oihl\t{$dst, $src2}",
290                        [(set GR64:$dst, (or GR64:$src1, i64hl16:$src2))]>;
291def 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
295def OR64rilo32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
296                        "oilf\t{$dst, $src2}",
297                        [(set GR64:$dst, (or GR64:$src1, i64lo32:$src2))]>;
298def OR64rihi32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
299                        "oihf\t{$dst, $src2}",
300                        [(set GR64:$dst, (or GR64:$src1, i64hi32:$src2))]>;
301
302// FIXME: Provide proper encoding!
303def SUB32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
304                     "sr\t{$dst, $src2}",
305                     [(set GR32:$dst, (sub GR32:$src1, GR32:$src2))]>;
306def SUB64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
307                     "sgr\t{$dst, $src2}",
308                     [(set GR64:$dst, (sub GR64:$src1, GR64:$src2))]>;
309
310
311let isCommutable = 1 in { // X = XOR Y, Z  == X = XOR Z, Y
312// FIXME: Provide proper encoding!
313def XOR32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
314                     "xr\t{$dst, $src2}",
315                     [(set GR32:$dst, (xor GR32:$src1, GR32:$src2))]>;
316def XOR64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
317                     "xgr\t{$dst, $src2}",
318                     [(set GR64:$dst, (xor GR64:$src1, GR64:$src2))]>;
319}
320
321def XOR32ri : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
322                     "xilf\t{$dst, $src2}",
323                     [(set GR32:$dst, (xor GR32:$src1, imm:$src2))]>;
324
325// FIXME: these 2 instructions seem to require extimm facility
326def XOR64rilo32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
327                         "xilf\t{$dst, $src2}",
328                         [(set GR64:$dst, (xor GR64:$src1, i64lo32:$src2))]>;
329def XOR64rihi32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
330                         "xihf\t{$dst, $src2}",
331                         [(set GR64:$dst, (xor GR64:$src1, i64hi32:$src2))]>;
332
333} // Defs = [PSW]
334} // isTwoAddress = 1
335
336//===----------------------------------------------------------------------===//
337// Shifts
338
339let isTwoAddress = 1 in
340def SRL32rri : Pseudo<(outs GR32:$dst), (ins GR32:$src, riaddr32:$amt),
341                      "srl\t{$src, $amt}",
342                      [(set GR32:$dst, (srl GR32:$src, riaddr32:$amt))]>;
343def 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))))]>;
346def 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)))]>;
349
350let isTwoAddress = 1 in
351def SHL32rri : Pseudo<(outs GR32:$dst), (ins GR32:$src, riaddr32:$amt),
352                      "sll\t{$src, $amt}",
353                      [(set GR32:$dst, (shl GR32:$src, riaddr32:$amt))]>;
354def 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))))]>;
357def 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)))]>;
360
361
362let Defs = [PSW] in {
363let isTwoAddress = 1 in
364def SRA32rri : Pseudo<(outs GR32:$dst), (ins GR32:$src, riaddr32:$amt),
365                      "sra\t{$src, $amt}",
366                      [(set GR32:$dst, (sra GR32:$src, riaddr32:$amt)),
367                       (implicit PSW)]>;
368def 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)))),
371                       (implicit PSW)]>;
372def 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))),
375                       (implicit PSW)]>;
376} // Defs = [PSW]
377
378//===----------------------------------------------------------------------===//
379// Non-Instruction Patterns.
380//===----------------------------------------------------------------------===//
381
382// anyext
383def : Pat<(i64 (anyext GR32:$src)),
384          (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, subreg_32bit)>;
385
386//===----------------------------------------------------------------------===//
387// Peepholes.
388//===----------------------------------------------------------------------===//
389
390// FIXME: use add/sub tricks with 32678/-32768
391
392// trunc patterns
393def : Pat<(i32 (trunc GR64:$src)),
394          (EXTRACT_SUBREG GR64:$src, subreg_32bit)>;
395
396// sext_inreg patterns
397def : Pat<(sext_inreg GR64:$src, i32),
398          (MOVSX64rr32 (EXTRACT_SUBREG GR64:$src, subreg_32bit))>;
399