SystemZInstrInfo.td revision a51752cbea5d57956f177470f463baeeee33f3d7
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//  Control Flow Instructions...
113//
114
115// FIXME: Provide proper encoding!
116let isReturn = 1, isTerminator = 1 in {
117  def RET : Pseudo<(outs), (ins), "br\t%r14", [(SystemZretflag)]>;
118}
119
120//===----------------------------------------------------------------------===//
121// Move Instructions
122
123// FIXME: Provide proper encoding!
124let neverHasSideEffects = 1 in {
125def MOV32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src),
126                     "lr\t{$dst, $src}",
127                     []>;
128def MOV64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src),
129                     "lgr\t{$dst, $src}",
130                     []>;
131}
132
133def MOVSX64rr32 : Pseudo<(outs GR64:$dst), (ins GR32:$src),
134                         "lgfr\t{$dst, $src}",
135                         [(set GR64:$dst, (sext GR32:$src))]>;
136def MOVZX64rr32 : Pseudo<(outs GR64:$dst), (ins GR32:$src),
137                         "llgfr\t{$dst, $src}",
138                         [(set GR64:$dst, (zext GR32:$src))]>;
139
140// FIXME: Provide proper encoding!
141let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
142def MOV32ri16 : Pseudo<(outs GR32:$dst), (ins i32imm:$src),
143                       "lhi\t{$dst, $src}",
144                       [(set GR32:$dst, immSExt16:$src)]>;
145def MOV64ri16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
146                       "lghi\t{$dst, $src}",
147                       [(set GR64:$dst, immSExt16:$src)]>;
148
149def MOV64rill16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
150                         "llill\t{$dst, $src}",
151                         [(set GR64:$dst, i64ll16:$src)]>;
152def MOV64rilh16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
153                         "llilh\t{$dst, $src}",
154                         [(set GR64:$dst, i64lh16:$src)]>;
155def MOV64rihl16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
156                         "llihl\t{$dst, $src}",
157                         [(set GR64:$dst, i64hl16:$src)]>;
158def MOV64rihh16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
159                         "llihh\t{$dst, $src}",
160                         [(set GR64:$dst, i64hh16:$src)]>;
161// FIXME: these 3 instructions seem to require extimm facility
162def MOV64ri32 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
163                       "lgfi\t{$dst, $src}",
164                       [(set GR64:$dst, immSExt32:$src)]>;
165def MOV64rilo32 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
166                         "llilf\t{$dst, $src}",
167                         [(set GR64:$dst, i64lo32:$src)]>;
168def MOV64rihi32 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
169                         "llihf\t{$dst, $src}",
170                         [(set GR64:$dst, i64hi32:$src)]>;
171}
172
173//===----------------------------------------------------------------------===//
174// Arithmetic Instructions
175
176let isTwoAddress = 1 in {
177
178let Defs = [PSW] in {
179
180let isCommutable = 1 in { // X = ADD Y, Z  == X = ADD Z, Y
181// FIXME: Provide proper encoding!
182def ADD32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
183                     "ar\t{$dst, $src2}",
184                     [(set GR32:$dst, (add GR32:$src1, GR32:$src2)),
185                      (implicit PSW)]>;
186def ADD64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
187                     "agr\t{$dst, $src2}",
188                     [(set GR64:$dst, (add GR64:$src1, GR64:$src2)),
189                      (implicit PSW)]>;
190}
191
192// FIXME: Provide proper encoding!
193def ADD32ri16 : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
194                       "ahi\t{$dst, $src2}",
195                       [(set GR32:$dst, (add GR32:$src1, immSExt16:$src2)),
196                        (implicit PSW)]>;
197def ADD32ri   : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
198                       "afi\t{$dst, $src2}",
199                       [(set GR32:$dst, (add GR32:$src1, imm:$src2)),
200                        (implicit PSW)]>;
201def ADD64ri16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
202                       "aghi\t{$dst, $src2}",
203                       [(set GR64:$dst, (add GR64:$src1, immSExt16:$src2)),
204                        (implicit PSW)]>;
205def ADD64ri32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
206                       "agfi\t{$dst, $src2}",
207                       [(set GR64:$dst, (add GR64:$src1, immSExt32:$src2)),
208                        (implicit PSW)]>;
209
210let isCommutable = 1 in { // X = AND Y, Z  == X = AND Z, Y
211// FIXME: Provide proper encoding!
212def AND32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
213                     "nr\t{$dst, $src2}",
214                     [(set GR32:$dst, (and GR32:$src1, GR32:$src2))]>;
215def AND64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
216                     "ngr\t{$dst, $src2}",
217                     [(set GR64:$dst, (and GR64:$src1, GR64:$src2))]>;
218}
219
220// FIXME: Provide proper encoding!
221def AND64rill16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
222                         "nill\t{$dst, $src2}",
223                         [(set GR64:$dst, (and GR64:$src1, i64ll16:$src2))]>;
224def AND64rilh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
225                         "nilh\t{$dst, $src2}",
226                         [(set GR64:$dst, (and GR64:$src1, i64lh16:$src2))]>;
227def AND64rihl16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
228                         "nihl\t{$dst, $src2}",
229                         [(set GR64:$dst, (and GR64:$src1, i64hl16:$src2))]>;
230def AND64rihh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
231                         "nihh\t{$dst, $src2}",
232                         [(set GR64:$dst, (and GR64:$src1, i64hh16:$src2))]>;
233// FIXME: these 2 instructions seem to require extimm facility
234def AND64rilo32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
235                         "nilf\t{$dst, $src2}",
236                         [(set GR64:$dst, (and GR64:$src1, i64lo32:$src2))]>;
237def AND64rihi32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
238                         "nihf\t{$dst, $src2}",
239                         [(set GR64:$dst, (and GR64:$src1, i64hi32:$src2))]>;
240
241let isCommutable = 1 in { // X = OR Y, Z  == X = OR Z, Y
242// FIXME: Provide proper encoding!
243def OR32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
244                    "or\t{$dst, $src2}",
245                    [(set GR32:$dst, (or GR32:$src1, GR32:$src2))]>;
246def OR64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
247                    "ogr\t{$dst, $src2}",
248                    [(set GR64:$dst, (or GR64:$src1, GR64:$src2))]>;
249}
250
251def OR32ri16  : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i16imm:$src2),
252                      "oill\t{$dst, $src2}",
253                      [(set GR32:$dst, (or GR32:$src1, i64ll16:$src2))]>;
254def OR32ri16h : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i16imm:$src2),
255                      "oilh\t{$dst, $src2}",
256                      [(set GR32:$dst, (or GR32:$src1, i64lh16:$src2))]>;
257def OR32ri : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
258                    "oilf\t{$dst, $src2}",
259                    [(set GR32:$dst, (or GR32:$src1, imm:$src2))]>;
260
261def OR64rill16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
262                        "oill\t{$dst, $src2}",
263                        [(set GR64:$dst, (or GR64:$src1, i64ll16:$src2))]>;
264def OR64rilh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
265                        "oilh\t{$dst, $src2}",
266                        [(set GR64:$dst, (or GR64:$src1, i64lh16:$src2))]>;
267def OR64rihl16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
268                        "oihl\t{$dst, $src2}",
269                        [(set GR64:$dst, (or GR64:$src1, i64hl16:$src2))]>;
270def OR64rihh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
271                        "oihh\t{$dst, $src2}",
272                        [(set GR64:$dst, (or GR64:$src1, i64hh16:$src2))]>;
273// FIXME: these 2 instructions seem to require extimm facility
274def OR64rilo32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
275                        "oilf\t{$dst, $src2}",
276                        [(set GR64:$dst, (or GR64:$src1, i64lo32:$src2))]>;
277def OR64rihi32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
278                        "oihf\t{$dst, $src2}",
279                        [(set GR64:$dst, (or GR64:$src1, i64hi32:$src2))]>;
280
281// FIXME: Provide proper encoding!
282def SUB32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
283                     "sr\t{$dst, $src2}",
284                     [(set GR32:$dst, (sub GR32:$src1, GR32:$src2))]>;
285def SUB64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
286                     "sgr\t{$dst, $src2}",
287                     [(set GR64:$dst, (sub GR64:$src1, GR64:$src2))]>;
288
289
290let isCommutable = 1 in { // X = XOR Y, Z  == X = XOR Z, Y
291// FIXME: Provide proper encoding!
292def XOR32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
293                     "xr\t{$dst, $src2}",
294                     [(set GR32:$dst, (xor GR32:$src1, GR32:$src2))]>;
295def XOR64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
296                     "xgr\t{$dst, $src2}",
297                     [(set GR64:$dst, (xor GR64:$src1, GR64:$src2))]>;
298}
299
300def XOR32ri : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
301                     "xilf\t{$dst, $src2}",
302                     [(set GR32:$dst, (xor GR32:$src1, imm:$src2))]>;
303
304// FIXME: these 2 instructions seem to require extimm facility
305def XOR64rilo32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
306                         "xilf\t{$dst, $src2}",
307                         [(set GR64:$dst, (xor GR64:$src1, i64lo32:$src2))]>;
308def XOR64rihi32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
309                         "xihf\t{$dst, $src2}",
310                         [(set GR64:$dst, (xor GR64:$src1, i64hi32:$src2))]>;
311
312} // Defs = [PSW]
313} // isTwoAddress = 1
314
315//===----------------------------------------------------------------------===//
316// Non-Instruction Patterns.
317//===----------------------------------------------------------------------===//
318
319// anyext
320def : Pat<(i64 (anyext GR32:$src)),
321          (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, subreg_32bit)>;
322
323//===----------------------------------------------------------------------===//
324// Peepholes.
325//===----------------------------------------------------------------------===//
326
327// FIXME: use add/sub tricks with 32678/-32768
328
329// trunc patterns
330def : Pat<(i32 (trunc GR64:$src)),
331          (EXTRACT_SUBREG GR64:$src, subreg_32bit)>;
332
333// sext_inreg patterns
334def : Pat<(sext_inreg GR64:$src, i32),
335          (MOVSX64rr32 (EXTRACT_SUBREG GR64:$src, subreg_32bit))>;
336