80171542a3def5ee104e66c6ec4975c1637a2e90
[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 // rriaddr := reg + reg + imm
133 def rriaddr : Operand<i64>,
134               ComplexPattern<i64, 3, "SelectAddrRRI", []> {
135   let PrintMethod = "printRRIAddrOperand";
136   let MIOperandInfo = (ops ADDR64:$base, ADDR64:$index, i32imm:$disp);
137 }
138
139 //===----------------------------------------------------------------------===//
140 //  Control Flow Instructions...
141 //
142
143 // FIXME: Provide proper encoding!
144 let isReturn = 1, isTerminator = 1 in {
145   def RET : Pseudo<(outs), (ins), "br\t%r14", [(SystemZretflag)]>;
146 }
147
148 //===----------------------------------------------------------------------===//
149 // Move Instructions
150
151 // FIXME: Provide proper encoding!
152 let neverHasSideEffects = 1 in {
153 def MOV32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src),
154                      "lr\t{$dst, $src}",
155                      []>;
156 def MOV64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src),
157                      "lgr\t{$dst, $src}",
158                      []>;
159 }
160
161 def MOVSX64rr32 : Pseudo<(outs GR64:$dst), (ins GR32:$src),
162                          "lgfr\t{$dst, $src}",
163                          [(set GR64:$dst, (sext GR32:$src))]>;
164 def MOVZX64rr32 : Pseudo<(outs GR64:$dst), (ins GR32:$src),
165                          "llgfr\t{$dst, $src}",
166                          [(set GR64:$dst, (zext GR32:$src))]>;
167
168 // FIXME: Provide proper encoding!
169 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
170 def MOV32ri16 : Pseudo<(outs GR32:$dst), (ins i32imm:$src),
171                        "lhi\t{$dst, $src}",
172                        [(set GR32:$dst, immSExt16:$src)]>;
173 def MOV64ri16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
174                        "lghi\t{$dst, $src}",
175                        [(set GR64:$dst, immSExt16:$src)]>;
176
177 def MOV64rill16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
178                          "llill\t{$dst, $src}",
179                          [(set GR64:$dst, i64ll16:$src)]>;
180 def MOV64rilh16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
181                          "llilh\t{$dst, $src}",
182                          [(set GR64:$dst, i64lh16:$src)]>;
183 def MOV64rihl16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
184                          "llihl\t{$dst, $src}",
185                          [(set GR64:$dst, i64hl16:$src)]>;
186 def MOV64rihh16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
187                          "llihh\t{$dst, $src}",
188                          [(set GR64:$dst, i64hh16:$src)]>;
189 // FIXME: these 3 instructions seem to require extimm facility
190 def MOV64ri32 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
191                        "lgfi\t{$dst, $src}",
192                        [(set GR64:$dst, immSExt32:$src)]>;
193 def MOV64rilo32 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
194                          "llilf\t{$dst, $src}",
195                          [(set GR64:$dst, i64lo32:$src)]>;
196 def MOV64rihi32 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
197                          "llihf\t{$dst, $src}",
198                          [(set GR64:$dst, i64hi32:$src)]>;
199 }
200
201 let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in {
202 def MOV64rm : Pseudo<(outs GR64:$dst), (ins rriaddr:$src),
203                      "lgr\t{$dst, $src}",
204                      [(set GR64:$dst, (load rriaddr:$src))]>;
205 }
206
207
208 //===----------------------------------------------------------------------===//
209 // Arithmetic Instructions
210
211 let isTwoAddress = 1 in {
212
213 let Defs = [PSW] in {
214
215 let isCommutable = 1 in { // X = ADD Y, Z  == X = ADD Z, Y
216 // FIXME: Provide proper encoding!
217 def ADD32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
218                      "ar\t{$dst, $src2}",
219                      [(set GR32:$dst, (add GR32:$src1, GR32:$src2)),
220                       (implicit PSW)]>;
221 def ADD64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
222                      "agr\t{$dst, $src2}",
223                      [(set GR64:$dst, (add GR64:$src1, GR64:$src2)),
224                       (implicit PSW)]>;
225 }
226
227 // FIXME: Provide proper encoding!
228 def ADD32ri16 : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
229                        "ahi\t{$dst, $src2}",
230                        [(set GR32:$dst, (add GR32:$src1, immSExt16:$src2)),
231                         (implicit PSW)]>;
232 def ADD32ri   : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
233                        "afi\t{$dst, $src2}",
234                        [(set GR32:$dst, (add GR32:$src1, imm:$src2)),
235                         (implicit PSW)]>;
236 def ADD64ri16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
237                        "aghi\t{$dst, $src2}",
238                        [(set GR64:$dst, (add GR64:$src1, immSExt16:$src2)),
239                         (implicit PSW)]>;
240 def ADD64ri32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
241                        "agfi\t{$dst, $src2}",
242                        [(set GR64:$dst, (add GR64:$src1, immSExt32:$src2)),
243                         (implicit PSW)]>;
244
245 let isCommutable = 1 in { // X = AND Y, Z  == X = AND Z, Y
246 // FIXME: Provide proper encoding!
247 def AND32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
248                      "nr\t{$dst, $src2}",
249                      [(set GR32:$dst, (and GR32:$src1, GR32:$src2))]>;
250 def AND64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
251                      "ngr\t{$dst, $src2}",
252                      [(set GR64:$dst, (and GR64:$src1, GR64:$src2))]>;
253 }
254
255 // FIXME: Provide proper encoding!
256 def AND64rill16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
257                          "nill\t{$dst, $src2}",
258                          [(set GR64:$dst, (and GR64:$src1, i64ll16:$src2))]>;
259 def AND64rilh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
260                          "nilh\t{$dst, $src2}",
261                          [(set GR64:$dst, (and GR64:$src1, i64lh16:$src2))]>;
262 def AND64rihl16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
263                          "nihl\t{$dst, $src2}",
264                          [(set GR64:$dst, (and GR64:$src1, i64hl16:$src2))]>;
265 def AND64rihh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
266                          "nihh\t{$dst, $src2}",
267                          [(set GR64:$dst, (and GR64:$src1, i64hh16:$src2))]>;
268 // FIXME: these 2 instructions seem to require extimm facility
269 def AND64rilo32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
270                          "nilf\t{$dst, $src2}",
271                          [(set GR64:$dst, (and GR64:$src1, i64lo32:$src2))]>;
272 def AND64rihi32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
273                          "nihf\t{$dst, $src2}",
274                          [(set GR64:$dst, (and GR64:$src1, i64hi32:$src2))]>;
275
276 let isCommutable = 1 in { // X = OR Y, Z  == X = OR Z, Y
277 // FIXME: Provide proper encoding!
278 def OR32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
279                     "or\t{$dst, $src2}",
280                     [(set GR32:$dst, (or GR32:$src1, GR32:$src2))]>;
281 def OR64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
282                     "ogr\t{$dst, $src2}",
283                     [(set GR64:$dst, (or GR64:$src1, GR64:$src2))]>;
284 }
285
286 def OR32ri16  : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i16imm:$src2),
287                       "oill\t{$dst, $src2}",
288                       [(set GR32:$dst, (or GR32:$src1, i64ll16:$src2))]>;
289 def OR32ri16h : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i16imm:$src2),
290                       "oilh\t{$dst, $src2}",
291                       [(set GR32:$dst, (or GR32:$src1, i64lh16:$src2))]>;
292 def OR32ri : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
293                     "oilf\t{$dst, $src2}",
294                     [(set GR32:$dst, (or GR32:$src1, imm:$src2))]>;
295
296 def OR64rill16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
297                         "oill\t{$dst, $src2}",
298                         [(set GR64:$dst, (or GR64:$src1, i64ll16:$src2))]>;
299 def OR64rilh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
300                         "oilh\t{$dst, $src2}",
301                         [(set GR64:$dst, (or GR64:$src1, i64lh16:$src2))]>;
302 def OR64rihl16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
303                         "oihl\t{$dst, $src2}",
304                         [(set GR64:$dst, (or GR64:$src1, i64hl16:$src2))]>;
305 def OR64rihh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
306                         "oihh\t{$dst, $src2}",
307                         [(set GR64:$dst, (or GR64:$src1, i64hh16:$src2))]>;
308 // FIXME: these 2 instructions seem to require extimm facility
309 def OR64rilo32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
310                         "oilf\t{$dst, $src2}",
311                         [(set GR64:$dst, (or GR64:$src1, i64lo32:$src2))]>;
312 def OR64rihi32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
313                         "oihf\t{$dst, $src2}",
314                         [(set GR64:$dst, (or GR64:$src1, i64hi32:$src2))]>;
315
316 // FIXME: Provide proper encoding!
317 def SUB32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
318                      "sr\t{$dst, $src2}",
319                      [(set GR32:$dst, (sub GR32:$src1, GR32:$src2))]>;
320 def SUB64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
321                      "sgr\t{$dst, $src2}",
322                      [(set GR64:$dst, (sub GR64:$src1, GR64:$src2))]>;
323
324
325 let isCommutable = 1 in { // X = XOR Y, Z  == X = XOR Z, Y
326 // FIXME: Provide proper encoding!
327 def XOR32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
328                      "xr\t{$dst, $src2}",
329                      [(set GR32:$dst, (xor GR32:$src1, GR32:$src2))]>;
330 def XOR64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
331                      "xgr\t{$dst, $src2}",
332                      [(set GR64:$dst, (xor GR64:$src1, GR64:$src2))]>;
333 }
334
335 def XOR32ri : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
336                      "xilf\t{$dst, $src2}",
337                      [(set GR32:$dst, (xor GR32:$src1, imm:$src2))]>;
338
339 // FIXME: these 2 instructions seem to require extimm facility
340 def XOR64rilo32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
341                          "xilf\t{$dst, $src2}",
342                          [(set GR64:$dst, (xor GR64:$src1, i64lo32:$src2))]>;
343 def XOR64rihi32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
344                          "xihf\t{$dst, $src2}",
345                          [(set GR64:$dst, (xor GR64:$src1, i64hi32:$src2))]>;
346
347 } // Defs = [PSW]
348 } // isTwoAddress = 1
349
350 //===----------------------------------------------------------------------===//
351 // Shifts
352
353 let isTwoAddress = 1 in
354 def SRL32rri : Pseudo<(outs GR32:$dst), (ins GR32:$src, riaddr32:$amt),
355                       "srl\t{$src, $amt}",
356                       [(set GR32:$dst, (srl GR32:$src, riaddr32:$amt))]>;
357 def SRL64rri : Pseudo<(outs GR64:$dst), (ins GR64:$src, riaddr:$amt),
358                       "srlg\t{$dst, $src, $amt}",
359                       [(set GR64:$dst, (srl GR64:$src, (i32 (trunc riaddr:$amt))))]>;
360 def SRLA64ri  : Pseudo<(outs GR64:$dst), (ins GR64:$src, i32imm:$amt),
361                       "srlg\t{$dst, $src, $amt}",
362                       [(set GR64:$dst, (srl GR64:$src, (i32 imm:$amt)))]>;
363
364 let isTwoAddress = 1 in
365 def SHL32rri : Pseudo<(outs GR32:$dst), (ins GR32:$src, riaddr32:$amt),
366                       "sll\t{$src, $amt}",
367                       [(set GR32:$dst, (shl GR32:$src, riaddr32:$amt))]>;
368 def SHL64rri : Pseudo<(outs GR64:$dst), (ins GR64:$src, riaddr:$amt),
369                       "sllg\t{$dst, $src, $amt}",
370                       [(set GR64:$dst, (shl GR64:$src, (i32 (trunc riaddr:$amt))))]>;
371 def SHL64ri  : Pseudo<(outs GR64:$dst), (ins GR64:$src, i32imm:$amt),
372                       "sllg\t{$dst, $src, $amt}",
373                       [(set GR64:$dst, (shl GR64:$src, (i32 imm:$amt)))]>;
374
375
376 let Defs = [PSW] in {
377 let isTwoAddress = 1 in
378 def SRA32rri : Pseudo<(outs GR32:$dst), (ins GR32:$src, riaddr32:$amt),
379                       "sra\t{$src, $amt}",
380                       [(set GR32:$dst, (sra GR32:$src, riaddr32:$amt)),
381                        (implicit PSW)]>;
382 def SRA64rri : Pseudo<(outs GR64:$dst), (ins GR64:$src, riaddr:$amt),
383                       "srag\t{$dst, $src, $amt}",
384                       [(set GR64:$dst, (sra GR64:$src, (i32 (trunc riaddr:$amt)))),
385                        (implicit PSW)]>;
386 def SRA64ri  : Pseudo<(outs GR64:$dst), (ins GR64:$src, i32imm:$amt),
387                       "srag\t{$dst, $src, $amt}",
388                       [(set GR64:$dst, (sra GR64:$src, (i32 imm:$amt))),
389                        (implicit PSW)]>;
390 } // Defs = [PSW]
391
392 //===----------------------------------------------------------------------===//
393 // Non-Instruction Patterns.
394 //===----------------------------------------------------------------------===//
395
396 // anyext
397 def : Pat<(i64 (anyext GR32:$src)),
398           (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, subreg_32bit)>;
399
400 //===----------------------------------------------------------------------===//
401 // Peepholes.
402 //===----------------------------------------------------------------------===//
403
404 // FIXME: use add/sub tricks with 32678/-32768
405
406 // trunc patterns
407 def : Pat<(i32 (trunc GR64:$src)),
408           (EXTRACT_SUBREG GR64:$src, subreg_32bit)>;
409
410 // sext_inreg patterns
411 def : Pat<(sext_inreg GR64:$src, i32),
412           (MOVSX64rr32 (EXTRACT_SUBREG GR64:$src, subreg_32bit))>;