b28585bacf41246444a028a9503febe2059f3eb9
[oota-llvm.git] / lib / Target / SystemZ / SystemZInstrInfo.td
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
14 include "SystemZInstrFormats.td"
15
16 //===----------------------------------------------------------------------===//
17 // SystemZ Specific Node Definitions.
18 //===----------------------------------------------------------------------===//
19 def SystemZretflag : SDNode<"SystemZISD::RET_FLAG", SDTNone,
20                      [SDNPHasChain, SDNPOptInFlag]>;
21
22 let neverHasSideEffects = 1 in
23 def NOP : Pseudo<(outs), (ins), "# no-op", []>;
24
25 //===----------------------------------------------------------------------===//
26 // Instruction Pattern Stuff.
27 //===----------------------------------------------------------------------===//
28 def LL16 : SDNodeXForm<imm, [{
29   // Transformation function: return low 16 bits.
30   return getI16Imm(N->getZExtValue() & 0x000000000000FFFFULL);
31 }]>;
32
33 def LH16 : SDNodeXForm<imm, [{
34   // Transformation function: return bits 16-31.
35   return getI16Imm((N->getZExtValue() & 0x00000000FFFF0000ULL) >> 16);
36 }]>;
37
38 def HL16 : SDNodeXForm<imm, [{
39   // Transformation function: return bits 32-47.
40   return getI16Imm((N->getZExtValue() & 0x0000FFFF00000000ULL) >> 32);
41 }]>;
42
43 def HH16 : SDNodeXForm<imm, [{
44   // Transformation function: return bits 48-63.
45   return getI16Imm((N->getZExtValue() & 0xFFFF000000000000ULL) >> 48);
46 }]>;
47
48 def LO32 : SDNodeXForm<imm, [{
49   // Transformation function: return low 32 bits.
50   return getI32Imm(N->getZExtValue() & 0x00000000FFFFFFFFULL);
51 }]>;
52
53 def HI32 : SDNodeXForm<imm, [{
54   // Transformation function: return bits 32-63.
55   return getI32Imm(N->getZExtValue() >> 32);
56 }]>;
57
58 def 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
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());
67 }], LH16>;
68
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());
72 }], HL16>;
73
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());
77 }], HH16>;
78
79 def 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
93 def 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
100 def 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
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());
109 }], HI32>;
110
111 //===----------------------------------------------------------------------===//
112 // SystemZ Operand Definitions.
113 //===----------------------------------------------------------------------===//
114
115 // Address operands
116
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);
122 }
123
124 def 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!
137 let 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!
145 let neverHasSideEffects = 1 in {
146 def MOV32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src),
147                      "lr\t{$dst, $src}",
148                      []>;
149 def MOV64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src),
150                      "lgr\t{$dst, $src}",
151                      []>;
152 }
153
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))]>;
160
161 // FIXME: Provide proper encoding!
162 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
163 def MOV32ri16 : Pseudo<(outs GR32:$dst), (ins i32imm:$src),
164                        "lhi\t{$dst, $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)]>;
169
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)]>;
192 }
193
194 //===----------------------------------------------------------------------===//
195 // Arithmetic Instructions
196
197 let isTwoAddress = 1 in {
198
199 let Defs = [PSW] in {
200
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),
204                      "ar\t{$dst, $src2}",
205                      [(set GR32:$dst, (add GR32:$src1, GR32:$src2)),
206                       (implicit PSW)]>;
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)),
210                       (implicit PSW)]>;
211 }
212
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)),
217                         (implicit PSW)]>;
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)),
221                         (implicit PSW)]>;
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)),
225                         (implicit PSW)]>;
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)),
229                         (implicit PSW)]>;
230
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),
234                      "nr\t{$dst, $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))]>;
239 }
240
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))]>;
261
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),
265                     "or\t{$dst, $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))]>;
270 }
271
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))]>;
281
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))]>;
301
302 // FIXME: Provide proper encoding!
303 def SUB32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
304                      "sr\t{$dst, $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))]>;
309
310
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),
314                      "xr\t{$dst, $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))]>;
319 }
320
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))]>;
324
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))]>;
332
333 } // Defs = [PSW]
334 } // isTwoAddress = 1
335
336 //===----------------------------------------------------------------------===//
337 // Shifts
338
339 let isTwoAddress = 1 in
340 def SRL32rri : Pseudo<(outs GR32:$dst), (ins GR32:$src, riaddr32:$amt),
341                       "srl\t{$src, $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)))]>;
349
350 let isTwoAddress = 1 in
351 def SHL32rri : Pseudo<(outs GR32:$dst), (ins GR32:$src, riaddr32:$amt),
352                       "sll\t{$src, $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)))]>;
360
361
362 let Defs = [PSW] in {
363 let isTwoAddress = 1 in
364 def 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)]>;
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)))),
371                        (implicit PSW)]>;
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))),
375                        (implicit PSW)]>;
376 } // Defs = [PSW]
377
378 //===----------------------------------------------------------------------===//
379 // Non-Instruction Patterns.
380 //===----------------------------------------------------------------------===//
381
382 // anyext
383 def : 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
393 def : Pat<(i32 (trunc GR64:$src)),
394           (EXTRACT_SUBREG GR64:$src, subreg_32bit)>;
395
396 // sext_inreg patterns
397 def : Pat<(sext_inreg GR64:$src, i32),
398           (MOVSX64rr32 (EXTRACT_SUBREG GR64:$src, subreg_32bit))>;