Add bunch of 32-bit patterns... Uffff :)
[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 //  Control Flow Instructions...
113 //
114
115 // FIXME: Provide proper encoding!
116 let 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!
124 let neverHasSideEffects = 1 in {
125 def MOV32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src),
126                      "lr\t{$dst, $src}",
127                      []>;
128 def MOV64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src),
129                      "lgr\t{$dst, $src}",
130                      []>;
131 }
132
133 def MOVSX64rr32 : Pseudo<(outs GR64:$dst), (ins GR32:$src),
134                          "lgfr\t{$dst, $src}",
135                          [(set GR64:$dst, (sext GR32:$src))]>;
136 def 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!
141 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
142 def MOV32ri16 : Pseudo<(outs GR32:$dst), (ins i32imm:$src),
143                        "lhi\t{$dst, $src}",
144                        [(set GR32:$dst, immSExt16:$src)]>;
145 def MOV64ri16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
146                        "lghi\t{$dst, $src}",
147                        [(set GR64:$dst, immSExt16:$src)]>;
148
149 def MOV64rill16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
150                          "llill\t{$dst, $src}",
151                          [(set GR64:$dst, i64ll16:$src)]>;
152 def MOV64rilh16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
153                          "llilh\t{$dst, $src}",
154                          [(set GR64:$dst, i64lh16:$src)]>;
155 def MOV64rihl16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
156                          "llihl\t{$dst, $src}",
157                          [(set GR64:$dst, i64hl16:$src)]>;
158 def 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
162 def MOV64ri32 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
163                        "lgfi\t{$dst, $src}",
164                        [(set GR64:$dst, immSExt32:$src)]>;
165 def MOV64rilo32 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
166                          "llilf\t{$dst, $src}",
167                          [(set GR64:$dst, i64lo32:$src)]>;
168 def 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
176 let isTwoAddress = 1 in {
177
178 let Defs = [PSW] in {
179
180 let isCommutable = 1 in { // X = ADD Y, Z  == X = ADD Z, Y
181 // FIXME: Provide proper encoding!
182 def 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)]>;
186 def 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!
193 def 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)]>;
197 def 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)]>;
201 def 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)]>;
205 def 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
210 let isCommutable = 1 in { // X = AND Y, Z  == X = AND Z, Y
211 // FIXME: Provide proper encoding!
212 def AND32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
213                      "nr\t{$dst, $src2}",
214                      [(set GR32:$dst, (and GR32:$src1, GR32:$src2))]>;
215 def 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!
221 def AND64rill16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
222                          "nill\t{$dst, $src2}",
223                          [(set GR64:$dst, (and GR64:$src1, i64ll16:$src2))]>;
224 def AND64rilh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
225                          "nilh\t{$dst, $src2}",
226                          [(set GR64:$dst, (and GR64:$src1, i64lh16:$src2))]>;
227 def AND64rihl16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
228                          "nihl\t{$dst, $src2}",
229                          [(set GR64:$dst, (and GR64:$src1, i64hl16:$src2))]>;
230 def 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
234 def AND64rilo32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
235                          "nilf\t{$dst, $src2}",
236                          [(set GR64:$dst, (and GR64:$src1, i64lo32:$src2))]>;
237 def 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
241 let isCommutable = 1 in { // X = OR Y, Z  == X = OR Z, Y
242 // FIXME: Provide proper encoding!
243 def OR32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
244                     "or\t{$dst, $src2}",
245                     [(set GR32:$dst, (or GR32:$src1, GR32:$src2))]>;
246 def 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
251 def OR32ri16  : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i16imm:$src2),
252                       "oill\t{$dst, $src2}",
253                       [(set GR32:$dst, (or GR32:$src1, i64ll16:$src2))]>;
254 def OR32ri16h : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i16imm:$src2),
255                       "oilh\t{$dst, $src2}",
256                       [(set GR32:$dst, (or GR32:$src1, i64lh16:$src2))]>;
257 def 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
261 def OR64rill16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
262                         "oill\t{$dst, $src2}",
263                         [(set GR64:$dst, (or GR64:$src1, i64ll16:$src2))]>;
264 def OR64rilh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
265                         "oilh\t{$dst, $src2}",
266                         [(set GR64:$dst, (or GR64:$src1, i64lh16:$src2))]>;
267 def OR64rihl16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
268                         "oihl\t{$dst, $src2}",
269                         [(set GR64:$dst, (or GR64:$src1, i64hl16:$src2))]>;
270 def 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
274 def OR64rilo32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
275                         "oilf\t{$dst, $src2}",
276                         [(set GR64:$dst, (or GR64:$src1, i64lo32:$src2))]>;
277 def 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!
282 def SUB32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
283                      "sr\t{$dst, $src2}",
284                      [(set GR32:$dst, (sub GR32:$src1, GR32:$src2))]>;
285 def 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
290 let isCommutable = 1 in { // X = XOR Y, Z  == X = XOR Z, Y
291 // FIXME: Provide proper encoding!
292 def XOR32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
293                      "xr\t{$dst, $src2}",
294                      [(set GR32:$dst, (xor GR32:$src1, GR32:$src2))]>;
295 def 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
300 def 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
305 def XOR64rilo32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
306                          "xilf\t{$dst, $src2}",
307                          [(set GR64:$dst, (xor GR64:$src1, i64lo32:$src2))]>;
308 def 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
320 def : 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
330 def : Pat<(i32 (trunc GR64:$src)),
331           (EXTRACT_SUBREG GR64:$src, subreg_32bit)>;
332
333 // sext_inreg patterns
334 def : Pat<(sext_inreg GR64:$src, i32),
335           (MOVSX64rr32 (EXTRACT_SUBREG GR64:$src, subreg_32bit))>;