Add address computation stuff
[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 def i32immSExt8  : PatLeaf<(i32 imm), [{
112   // i32immSExt8 predicate - True if the 32-bit immediate fits in a 8-bit
113   // sign extended field.
114   return (int32_t)N->getZExtValue() == (int8_t)N->getZExtValue();
115 }]>;
116
117 def i32immSExt16 : PatLeaf<(i32 imm), [{
118   // i32immSExt16 predicate - True if the 32-bit immediate fits in a 16-bit
119   // sign extended field.
120   return (int32_t)N->getZExtValue() == (int16_t)N->getZExtValue();
121 }]>;
122
123 // extloads
124 def extloadi64i8   : PatFrag<(ops node:$ptr), (i64 (extloadi8  node:$ptr))>;
125 def extloadi64i16  : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
126 def extloadi64i32  : PatFrag<(ops node:$ptr), (i64 (extloadi32 node:$ptr))>;
127
128 def sextloadi64i8   : PatFrag<(ops node:$ptr), (i64 (sextloadi8  node:$ptr))>;
129 def sextloadi64i16  : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
130 def sextloadi64i32  : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>;
131
132 def zextloadi64i8   : PatFrag<(ops node:$ptr), (i64 (zextloadi8  node:$ptr))>;
133 def zextloadi64i16  : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>;
134 def zextloadi64i32  : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
135
136 // A couple of more descriptive operand definitions.
137 // 32-bits but only 8 bits are significant.
138 def i32i8imm  : Operand<i32>;
139 // 32-bits but only 16 bits are significant.
140 def i32i16imm : Operand<i32>;
141
142 //===----------------------------------------------------------------------===//
143 // SystemZ Operand Definitions.
144 //===----------------------------------------------------------------------===//
145
146 // Address operands
147
148 // riaddr := reg + imm
149 def riaddr32 : Operand<i32>,
150                ComplexPattern<i32, 2, "SelectAddrRI", []> {
151   let PrintMethod = "printRIAddrOperand";
152   let MIOperandInfo = (ops ADDR32:$base, i32imm:$disp);
153 }
154
155 def riaddr : Operand<i64>,
156              ComplexPattern<i64, 2, "SelectAddrRI", []> {
157   let PrintMethod = "printRIAddrOperand";
158   let MIOperandInfo = (ops ADDR64:$base, i32imm:$disp);
159 }
160
161 //===----------------------------------------------------------------------===//
162
163 // rriaddr := reg + reg + imm
164 def rriaddr : Operand<i64>,
165               ComplexPattern<i64, 3, "SelectAddrRRI", [], []> {
166   let PrintMethod = "printRRIAddrOperand";
167   let MIOperandInfo = (ops ADDR64:$base, ADDR64:$index, i32imm:$disp);
168 }
169 def laaddr : Operand<i64>,
170              ComplexPattern<i64, 3, "SelectLAAddr", [add, sub, or, frameindex], []> {
171   let PrintMethod = "printRRIAddrOperand";
172   let MIOperandInfo = (ops ADDR64:$base, ADDR64:$index, i32imm:$disp);
173 }
174
175
176 //===----------------------------------------------------------------------===//
177 //  Control Flow Instructions...
178 //
179
180 // FIXME: Provide proper encoding!
181 let isReturn = 1, isTerminator = 1 in {
182   def RET : Pseudo<(outs), (ins), "br\t%r14", [(SystemZretflag)]>;
183 }
184
185
186 //===----------------------------------------------------------------------===//
187 //  Miscellaneous Instructions.
188 //
189
190 let isReMaterializable = 1 in
191 // FIXME: Provide imm12 variant
192 def LA64r  : Pseudo<(outs GR64:$dst), (ins laaddr:$src),
193                     "lay\t{$dst, $src}",
194                     [(set GR64:$dst, laaddr:$src)]>;
195
196
197 //===----------------------------------------------------------------------===//
198 // Move Instructions
199
200 // FIXME: Provide proper encoding!
201 let neverHasSideEffects = 1 in {
202 def MOV32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src),
203                      "lr\t{$dst, $src}",
204                      []>;
205 def MOV64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src),
206                      "lgr\t{$dst, $src}",
207                      []>;
208 }
209
210 def MOVSX64rr32 : Pseudo<(outs GR64:$dst), (ins GR32:$src),
211                          "lgfr\t{$dst, $src}",
212                          [(set GR64:$dst, (sext GR32:$src))]>;
213 def MOVZX64rr32 : Pseudo<(outs GR64:$dst), (ins GR32:$src),
214                          "llgfr\t{$dst, $src}",
215                          [(set GR64:$dst, (zext GR32:$src))]>;
216
217 // FIXME: Provide proper encoding!
218 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
219 def MOV32ri16 : Pseudo<(outs GR32:$dst), (ins i32imm:$src),
220                        "lhi\t{$dst, $src}",
221                        [(set GR32:$dst, immSExt16:$src)]>;
222 def MOV64ri16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
223                        "lghi\t{$dst, $src}",
224                        [(set GR64:$dst, immSExt16:$src)]>;
225
226 def MOV64rill16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
227                          "llill\t{$dst, $src}",
228                          [(set GR64:$dst, i64ll16:$src)]>;
229 def MOV64rilh16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
230                          "llilh\t{$dst, $src}",
231                          [(set GR64:$dst, i64lh16:$src)]>;
232 def MOV64rihl16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
233                          "llihl\t{$dst, $src}",
234                          [(set GR64:$dst, i64hl16:$src)]>;
235 def MOV64rihh16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
236                          "llihh\t{$dst, $src}",
237                          [(set GR64:$dst, i64hh16:$src)]>;
238 // FIXME: these 3 instructions seem to require extimm facility
239 def MOV64ri32 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
240                        "lgfi\t{$dst, $src}",
241                        [(set GR64:$dst, immSExt32:$src)]>;
242 def MOV64rilo32 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
243                          "llilf\t{$dst, $src}",
244                          [(set GR64:$dst, i64lo32:$src)]>;
245 def MOV64rihi32 : Pseudo<(outs GR64:$dst), (ins i64imm:$src),
246                          "llihf\t{$dst, $src}",
247                          [(set GR64:$dst, i64hi32:$src)]>;
248 }
249
250 let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in {
251 def MOV64rm : Pseudo<(outs GR64:$dst), (ins rriaddr:$src),
252                      "lg\t{$dst, $src}",
253                      [(set GR64:$dst, (load rriaddr:$src))]>;
254
255 }
256
257 def MOV64mr : Pseudo<(outs), (ins rriaddr:$dst, GR64:$src),
258                      "stg\t{$src, $dst}",
259                      [(store GR64:$src, rriaddr:$dst)]>;
260
261 // FIXME: displacements here are really 12 bit, not 20!
262 def MOV8mi    : Pseudo<(outs), (ins riaddr:$dst, i32i8imm:$src),
263                        "mvi\t{$dst, $src}",
264                        [(truncstorei8 (i32 i32immSExt8:$src), riaddr:$dst)]>;
265 def MOV16mi   : Pseudo<(outs), (ins riaddr:$dst, i32i16imm:$src),
266                        "mvhhi\t{$dst, $src}",
267                        [(truncstorei16 (i32 i32immSExt16:$src), riaddr:$dst)]>;
268 def MOV32mi16 : Pseudo<(outs), (ins riaddr:$dst, i32imm:$src),
269                        "mvhi\t{$dst, $src}",
270                        [(store (i32 immSExt16:$src), riaddr:$dst)]>;
271 def MOV64mi16 : Pseudo<(outs), (ins riaddr:$dst, i64imm:$src),
272                        "mvghi\t{$dst, $src}",
273                        [(store (i64 immSExt16:$src), riaddr:$dst)]>;
274
275 // extloads
276 def MOVSX64rm8  : Pseudo<(outs GR64:$dst), (ins rriaddr:$src),
277                          "lgb\t{$dst, $src}",
278                          [(set GR64:$dst, (sextloadi64i8 rriaddr:$src))]>;
279 def MOVSX64rm16 : Pseudo<(outs GR64:$dst), (ins rriaddr:$src),
280                          "lgh\t{$dst, $src}",
281                          [(set GR64:$dst, (sextloadi64i16 rriaddr:$src))]>;
282 def MOVSX64rm32 : Pseudo<(outs GR64:$dst), (ins rriaddr:$src),
283                          "lgf\t{$dst, $src}",
284                          [(set GR64:$dst, (sextloadi64i32 rriaddr:$src))]>;
285
286 def MOVZX64rm8  : Pseudo<(outs GR64:$dst), (ins rriaddr:$src),
287                          "llgc\t{$dst, $src}",
288                          [(set GR64:$dst, (zextloadi64i8 rriaddr:$src))]>;
289 def MOVZX64rm16 : Pseudo<(outs GR64:$dst), (ins rriaddr:$src),
290                          "llgh\t{$dst, $src}",
291                          [(set GR64:$dst, (zextloadi64i16 rriaddr:$src))]>;
292 def MOVZX64rm32 : Pseudo<(outs GR64:$dst), (ins rriaddr:$src),
293                          "llgf\t{$dst, $src}",
294                          [(set GR64:$dst, (zextloadi64i32 rriaddr:$src))]>;
295
296 // truncstores
297 // FIXME: Implement 12-bit displacement stuff someday
298 def MOV32m8r  : Pseudo<(outs), (ins rriaddr:$dst, GR32:$src),
299                        "stcy\t{$src, $dst}",
300                        [(truncstorei8 GR32:$src, rriaddr:$dst)]>;
301
302 def MOV32m16r : Pseudo<(outs), (ins rriaddr:$dst, GR32:$src),
303                        "sthy\t{$src, $dst}",
304                        [(truncstorei16 GR32:$src, rriaddr:$dst)]>;
305
306 def MOV64m8r  : Pseudo<(outs), (ins rriaddr:$dst, GR64:$src),
307                        "stcy\t{$src, $dst}",
308                        [(truncstorei8 GR64:$src, rriaddr:$dst)]>;
309
310 def MOV64m16r : Pseudo<(outs), (ins rriaddr:$dst, GR64:$src),
311                        "sthy\t{$src, $dst}",
312                        [(truncstorei16 GR64:$src, rriaddr:$dst)]>;
313
314 def MOV64m32r : Pseudo<(outs), (ins rriaddr:$dst, GR64:$src),
315                        "sty\t{$src, $dst}",
316                        [(truncstorei32 GR64:$src, rriaddr:$dst)]>;
317
318 //===----------------------------------------------------------------------===//
319 // Arithmetic Instructions
320
321 let isTwoAddress = 1 in {
322
323 let Defs = [PSW] in {
324
325 let isCommutable = 1 in { // X = ADD Y, Z  == X = ADD Z, Y
326 // FIXME: Provide proper encoding!
327 def ADD32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
328                      "ar\t{$dst, $src2}",
329                      [(set GR32:$dst, (add GR32:$src1, GR32:$src2)),
330                       (implicit PSW)]>;
331 def ADD64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
332                      "agr\t{$dst, $src2}",
333                      [(set GR64:$dst, (add GR64:$src1, GR64:$src2)),
334                       (implicit PSW)]>;
335 }
336
337 // FIXME: Provide proper encoding!
338 def ADD32ri16 : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
339                        "ahi\t{$dst, $src2}",
340                        [(set GR32:$dst, (add GR32:$src1, immSExt16:$src2)),
341                         (implicit PSW)]>;
342 def ADD32ri   : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
343                        "afi\t{$dst, $src2}",
344                        [(set GR32:$dst, (add GR32:$src1, imm:$src2)),
345                         (implicit PSW)]>;
346 def ADD64ri16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
347                        "aghi\t{$dst, $src2}",
348                        [(set GR64:$dst, (add GR64:$src1, immSExt16:$src2)),
349                         (implicit PSW)]>;
350 def ADD64ri32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
351                        "agfi\t{$dst, $src2}",
352                        [(set GR64:$dst, (add GR64:$src1, immSExt32:$src2)),
353                         (implicit PSW)]>;
354
355 let isCommutable = 1 in { // X = AND Y, Z  == X = AND Z, Y
356 // FIXME: Provide proper encoding!
357 def AND32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
358                      "nr\t{$dst, $src2}",
359                      [(set GR32:$dst, (and GR32:$src1, GR32:$src2))]>;
360 def AND64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
361                      "ngr\t{$dst, $src2}",
362                      [(set GR64:$dst, (and GR64:$src1, GR64:$src2))]>;
363 }
364
365 // FIXME: Provide proper encoding!
366 def AND64rill16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
367                          "nill\t{$dst, $src2}",
368                          [(set GR64:$dst, (and GR64:$src1, i64ll16:$src2))]>;
369 def AND64rilh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
370                          "nilh\t{$dst, $src2}",
371                          [(set GR64:$dst, (and GR64:$src1, i64lh16:$src2))]>;
372 def AND64rihl16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
373                          "nihl\t{$dst, $src2}",
374                          [(set GR64:$dst, (and GR64:$src1, i64hl16:$src2))]>;
375 def AND64rihh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
376                          "nihh\t{$dst, $src2}",
377                          [(set GR64:$dst, (and GR64:$src1, i64hh16:$src2))]>;
378 // FIXME: these 2 instructions seem to require extimm facility
379 def AND64rilo32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
380                          "nilf\t{$dst, $src2}",
381                          [(set GR64:$dst, (and GR64:$src1, i64lo32:$src2))]>;
382 def AND64rihi32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
383                          "nihf\t{$dst, $src2}",
384                          [(set GR64:$dst, (and GR64:$src1, i64hi32:$src2))]>;
385
386 let isCommutable = 1 in { // X = OR Y, Z  == X = OR Z, Y
387 // FIXME: Provide proper encoding!
388 def OR32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
389                     "or\t{$dst, $src2}",
390                     [(set GR32:$dst, (or GR32:$src1, GR32:$src2))]>;
391 def OR64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
392                     "ogr\t{$dst, $src2}",
393                     [(set GR64:$dst, (or GR64:$src1, GR64:$src2))]>;
394 }
395
396 def OR32ri16  : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i16imm:$src2),
397                       "oill\t{$dst, $src2}",
398                       [(set GR32:$dst, (or GR32:$src1, i64ll16:$src2))]>;
399 def OR32ri16h : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i16imm:$src2),
400                       "oilh\t{$dst, $src2}",
401                       [(set GR32:$dst, (or GR32:$src1, i64lh16:$src2))]>;
402 def OR32ri : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
403                     "oilf\t{$dst, $src2}",
404                     [(set GR32:$dst, (or GR32:$src1, imm:$src2))]>;
405
406 def OR64rill16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
407                         "oill\t{$dst, $src2}",
408                         [(set GR64:$dst, (or GR64:$src1, i64ll16:$src2))]>;
409 def OR64rilh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
410                         "oilh\t{$dst, $src2}",
411                         [(set GR64:$dst, (or GR64:$src1, i64lh16:$src2))]>;
412 def OR64rihl16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
413                         "oihl\t{$dst, $src2}",
414                         [(set GR64:$dst, (or GR64:$src1, i64hl16:$src2))]>;
415 def OR64rihh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
416                         "oihh\t{$dst, $src2}",
417                         [(set GR64:$dst, (or GR64:$src1, i64hh16:$src2))]>;
418 // FIXME: these 2 instructions seem to require extimm facility
419 def OR64rilo32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
420                         "oilf\t{$dst, $src2}",
421                         [(set GR64:$dst, (or GR64:$src1, i64lo32:$src2))]>;
422 def OR64rihi32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
423                         "oihf\t{$dst, $src2}",
424                         [(set GR64:$dst, (or GR64:$src1, i64hi32:$src2))]>;
425
426 // FIXME: Provide proper encoding!
427 def SUB32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
428                      "sr\t{$dst, $src2}",
429                      [(set GR32:$dst, (sub GR32:$src1, GR32:$src2))]>;
430 def SUB64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
431                      "sgr\t{$dst, $src2}",
432                      [(set GR64:$dst, (sub GR64:$src1, GR64:$src2))]>;
433
434
435 let isCommutable = 1 in { // X = XOR Y, Z  == X = XOR Z, Y
436 // FIXME: Provide proper encoding!
437 def XOR32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
438                      "xr\t{$dst, $src2}",
439                      [(set GR32:$dst, (xor GR32:$src1, GR32:$src2))]>;
440 def XOR64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
441                      "xgr\t{$dst, $src2}",
442                      [(set GR64:$dst, (xor GR64:$src1, GR64:$src2))]>;
443 }
444
445 def XOR32ri : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
446                      "xilf\t{$dst, $src2}",
447                      [(set GR32:$dst, (xor GR32:$src1, imm:$src2))]>;
448
449 // FIXME: these 2 instructions seem to require extimm facility
450 def XOR64rilo32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
451                          "xilf\t{$dst, $src2}",
452                          [(set GR64:$dst, (xor GR64:$src1, i64lo32:$src2))]>;
453 def XOR64rihi32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
454                          "xihf\t{$dst, $src2}",
455                          [(set GR64:$dst, (xor GR64:$src1, i64hi32:$src2))]>;
456
457 } // Defs = [PSW]
458 } // isTwoAddress = 1
459
460 //===----------------------------------------------------------------------===//
461 // Shifts
462
463 let isTwoAddress = 1 in
464 def SRL32rri : Pseudo<(outs GR32:$dst), (ins GR32:$src, riaddr32:$amt),
465                       "srl\t{$src, $amt}",
466                       [(set GR32:$dst, (srl GR32:$src, riaddr32:$amt))]>;
467 def SRL64rri : Pseudo<(outs GR64:$dst), (ins GR64:$src, riaddr:$amt),
468                       "srlg\t{$dst, $src, $amt}",
469                       [(set GR64:$dst, (srl GR64:$src, (i32 (trunc riaddr:$amt))))]>;
470 def SRLA64ri  : Pseudo<(outs GR64:$dst), (ins GR64:$src, i32imm:$amt),
471                       "srlg\t{$dst, $src, $amt}",
472                       [(set GR64:$dst, (srl GR64:$src, (i32 imm:$amt)))]>;
473
474 let isTwoAddress = 1 in
475 def SHL32rri : Pseudo<(outs GR32:$dst), (ins GR32:$src, riaddr32:$amt),
476                       "sll\t{$src, $amt}",
477                       [(set GR32:$dst, (shl GR32:$src, riaddr32:$amt))]>;
478 def SHL64rri : Pseudo<(outs GR64:$dst), (ins GR64:$src, riaddr:$amt),
479                       "sllg\t{$dst, $src, $amt}",
480                       [(set GR64:$dst, (shl GR64:$src, (i32 (trunc riaddr:$amt))))]>;
481 def SHL64ri  : Pseudo<(outs GR64:$dst), (ins GR64:$src, i32imm:$amt),
482                       "sllg\t{$dst, $src, $amt}",
483                       [(set GR64:$dst, (shl GR64:$src, (i32 imm:$amt)))]>;
484
485
486 let Defs = [PSW] in {
487 let isTwoAddress = 1 in
488 def SRA32rri : Pseudo<(outs GR32:$dst), (ins GR32:$src, riaddr32:$amt),
489                       "sra\t{$src, $amt}",
490                       [(set GR32:$dst, (sra GR32:$src, riaddr32:$amt)),
491                        (implicit PSW)]>;
492 def SRA64rri : Pseudo<(outs GR64:$dst), (ins GR64:$src, riaddr:$amt),
493                       "srag\t{$dst, $src, $amt}",
494                       [(set GR64:$dst, (sra GR64:$src, (i32 (trunc riaddr:$amt)))),
495                        (implicit PSW)]>;
496 def SRA64ri  : Pseudo<(outs GR64:$dst), (ins GR64:$src, i32imm:$amt),
497                       "srag\t{$dst, $src, $amt}",
498                       [(set GR64:$dst, (sra GR64:$src, (i32 imm:$amt))),
499                        (implicit PSW)]>;
500 } // Defs = [PSW]
501
502 //===----------------------------------------------------------------------===//
503 // Non-Instruction Patterns.
504 //===----------------------------------------------------------------------===//
505
506 // anyext
507 def : Pat<(i64 (anyext GR32:$src)),
508           (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, subreg_32bit)>;
509
510 //===----------------------------------------------------------------------===//
511 // Peepholes.
512 //===----------------------------------------------------------------------===//
513
514 // FIXME: use add/sub tricks with 32678/-32768
515
516 // trunc patterns
517 def : Pat<(i32 (trunc GR64:$src)),
518           (EXTRACT_SUBREG GR64:$src, subreg_32bit)>;
519
520 // sext_inreg patterns
521 def : Pat<(sext_inreg GR64:$src, i32),
522           (MOVSX64rr32 (EXTRACT_SUBREG GR64:$src, subreg_32bit))>;
523
524 // extload patterns
525 def : Pat<(extloadi64i8  rriaddr:$src), (MOVZX64rm8  rriaddr:$src)>;
526 def : Pat<(extloadi64i16 rriaddr:$src), (MOVZX64rm16 rriaddr:$src)>;
527 def : Pat<(extloadi64i32 rriaddr:$src), (MOVZX64rm32 rriaddr:$src)>;