ca849bfcc9ef25cddc0a2d85ccac96016b41c7ab
[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 //===----------------------------------------------------------------------===//
15 // SystemZ Instruction Predicate Definitions.
16 def IsZ10 : Predicate<"Subtarget.isZ10()">;
17
18 include "SystemZInstrFormats.td"
19
20 //===----------------------------------------------------------------------===//
21 // Type Constraints.
22 //===----------------------------------------------------------------------===//
23 class SDTCisI8<int OpNum> : SDTCisVT<OpNum, i8>;
24 class SDTCisI16<int OpNum> : SDTCisVT<OpNum, i16>;
25 class SDTCisI32<int OpNum> : SDTCisVT<OpNum, i32>;
26 class SDTCisI64<int OpNum> : SDTCisVT<OpNum, i64>;
27
28 //===----------------------------------------------------------------------===//
29 // Type Profiles.
30 //===----------------------------------------------------------------------===//
31 def SDT_SystemZCall         : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>;
32 def SDT_SystemZCallSeqStart : SDCallSeqStart<[SDTCisI64<0>]>;
33 def SDT_SystemZCallSeqEnd   : SDCallSeqEnd<[SDTCisI64<0>, SDTCisI64<1>]>;
34 def SDT_CmpTest             : SDTypeProfile<1, 2, [SDTCisI64<0>,
35                                                    SDTCisSameAs<1, 2>]>;
36 def SDT_BrCond              : SDTypeProfile<0, 3,
37                                            [SDTCisVT<0, OtherVT>,
38                                             SDTCisI8<1>, SDTCisVT<2, i64>]>;
39 def SDT_SelectCC            : SDTypeProfile<1, 4,
40                                            [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>,
41                                             SDTCisI8<3>, SDTCisVT<4, i64>]>;
42 def SDT_Address             : SDTypeProfile<1, 1,
43                                             [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
44
45 //===----------------------------------------------------------------------===//
46 // SystemZ Specific Node Definitions.
47 //===----------------------------------------------------------------------===//
48 def SystemZretflag : SDNode<"SystemZISD::RET_FLAG", SDTNone,
49                      [SDNPHasChain, SDNPOptInGlue]>;
50 def SystemZcall    : SDNode<"SystemZISD::CALL", SDT_SystemZCall,
51                      [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>;
52 def SystemZcallseq_start :
53                  SDNode<"ISD::CALLSEQ_START", SDT_SystemZCallSeqStart,
54                         [SDNPHasChain, SDNPOutGlue]>;
55 def SystemZcallseq_end :
56                  SDNode<"ISD::CALLSEQ_END",   SDT_SystemZCallSeqEnd,
57                         [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
58 def SystemZcmp     : SDNode<"SystemZISD::CMP", SDT_CmpTest>;
59 def SystemZucmp    : SDNode<"SystemZISD::UCMP", SDT_CmpTest>;
60 def SystemZbrcond  : SDNode<"SystemZISD::BRCOND", SDT_BrCond,
61                             [SDNPHasChain]>;
62 def SystemZselect  : SDNode<"SystemZISD::SELECT", SDT_SelectCC>;
63 def SystemZpcrelwrapper : SDNode<"SystemZISD::PCRelativeWrapper", SDT_Address, []>;
64
65
66 include "SystemZOperands.td"
67
68 //===----------------------------------------------------------------------===//
69 // Instruction list..
70
71 def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i64imm:$amt),
72                               "#ADJCALLSTACKDOWN",
73                               [(SystemZcallseq_start timm:$amt)]>;
74 def ADJCALLSTACKUP   : Pseudo<(outs), (ins i64imm:$amt1, i64imm:$amt2),
75                               "#ADJCALLSTACKUP",
76                               [(SystemZcallseq_end timm:$amt1, timm:$amt2)]>;
77
78 let Uses = [PSW], usesCustomInserter = 1 in {
79   def Select32 : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2, i8imm:$cc),
80                         "# Select32 PSEUDO",
81                         [(set GR32:$dst,
82                               (SystemZselect GR32:$src1, GR32:$src2, imm:$cc, PSW))]>;
83   def Select64 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2, i8imm:$cc),
84                         "# Select64 PSEUDO",
85                         [(set GR64:$dst,
86                               (SystemZselect GR64:$src1, GR64:$src2, imm:$cc, PSW))]>;
87 }
88
89
90 //===----------------------------------------------------------------------===//
91 //  Control Flow Instructions...
92 //
93
94 // FIXME: Provide proper encoding!
95 let isReturn = 1, isTerminator = 1, isBarrier = 1, hasCtrlDep = 1 in {
96   def RET : Pseudo<(outs), (ins), "br\t%r14", [(SystemZretflag)]>;
97 }
98
99 let isBranch = 1, isTerminator = 1 in {
100   let isBarrier = 1 in {
101     def JMP  : Pseudo<(outs), (ins brtarget:$dst), "j\t{$dst}", [(br bb:$dst)]>;
102
103     let isIndirectBranch = 1 in
104       def JMPr   : Pseudo<(outs), (ins GR64:$dst), "br\t{$dst}", [(brind GR64:$dst)]>;
105   }
106
107   let Uses = [PSW] in {
108     def JO  : Pseudo<(outs), (ins brtarget:$dst),
109                      "jo\t$dst",
110                      [(SystemZbrcond bb:$dst, SYSTEMZ_COND_O, PSW)]>;
111     def JH  : Pseudo<(outs), (ins brtarget:$dst),
112                      "jh\t$dst",
113                      [(SystemZbrcond bb:$dst, SYSTEMZ_COND_H, PSW)]>;
114     def JNLE: Pseudo<(outs), (ins brtarget:$dst),
115                      "jnle\t$dst",
116                      [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NLE, PSW)]>;
117     def JL  : Pseudo<(outs), (ins brtarget:$dst),
118                      "jl\t$dst",
119                      [(SystemZbrcond bb:$dst, SYSTEMZ_COND_L, PSW)]>;
120     def JNHE: Pseudo<(outs), (ins brtarget:$dst),
121                      "jnhe\t$dst",
122                      [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NHE, PSW)]>;
123     def JLH : Pseudo<(outs), (ins brtarget:$dst),
124                      "jlh\t$dst",
125                      [(SystemZbrcond bb:$dst, SYSTEMZ_COND_LH, PSW)]>;
126     def JNE : Pseudo<(outs), (ins brtarget:$dst),
127                      "jne\t$dst",
128                      [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NE, PSW)]>;
129     def JE  : Pseudo<(outs), (ins brtarget:$dst),
130                      "je\t$dst",
131                      [(SystemZbrcond bb:$dst, SYSTEMZ_COND_E, PSW)]>;
132     def JNLH: Pseudo<(outs), (ins brtarget:$dst),
133                      "jnlh\t$dst",
134                      [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NLH, PSW)]>;
135     def JHE : Pseudo<(outs), (ins brtarget:$dst),
136                      "jhe\t$dst",
137                      [(SystemZbrcond bb:$dst, SYSTEMZ_COND_HE, PSW)]>;
138     def JNL : Pseudo<(outs), (ins brtarget:$dst),
139                      "jnl\t$dst",
140                      [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NL, PSW)]>;
141     def JLE : Pseudo<(outs), (ins brtarget:$dst),
142                      "jle\t$dst",
143                      [(SystemZbrcond bb:$dst, SYSTEMZ_COND_LE, PSW)]>;
144     def JNH : Pseudo<(outs), (ins brtarget:$dst),
145                      "jnh\t$dst",
146                      [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NH, PSW)]>;
147     def JNO : Pseudo<(outs), (ins brtarget:$dst),
148                      "jno\t$dst",
149                      [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NO, PSW)]>;
150   } // Uses = [PSW]
151 } // isBranch = 1
152
153 //===----------------------------------------------------------------------===//
154 //  Call Instructions...
155 //
156
157 let isCall = 1 in
158   // All calls clobber the non-callee saved registers. Uses for argument
159   // registers are added manually.
160   let Defs = [R0D, R1D, R2D, R3D, R4D, R5D, R14D,
161               F0L, F1L, F2L, F3L, F4L, F5L, F6L, F7L] in {
162     def CALLi     : Pseudo<(outs), (ins imm_pcrel:$dst, variable_ops),
163                            "brasl\t%r14, $dst", [(SystemZcall imm:$dst)]>;
164     def CALLr     : Pseudo<(outs), (ins ADDR64:$dst, variable_ops),
165                            "basr\t%r14, $dst", [(SystemZcall ADDR64:$dst)]>;
166   }
167
168 //===----------------------------------------------------------------------===//
169 //  Miscellaneous Instructions.
170 //
171
172 let isReMaterializable = 1 in
173 // FIXME: Provide imm12 variant
174 // FIXME: Address should be halfword aligned...
175 def LA64r  : RXI<0x47,
176                  (outs GR64:$dst), (ins laaddr:$src),
177                  "lay\t{$dst, $src}",
178                  [(set GR64:$dst, laaddr:$src)]>;
179 def LA64rm : RXYI<0x71E3,
180                   (outs GR64:$dst), (ins i64imm:$src),
181                   "larl\t{$dst, $src}",
182                   [(set GR64:$dst,
183                         (SystemZpcrelwrapper tglobaladdr:$src))]>;
184
185 let neverHasSideEffects = 1 in
186 def NOP : Pseudo<(outs), (ins), "# no-op", []>;
187
188 //===----------------------------------------------------------------------===//
189 // Move Instructions
190
191 let neverHasSideEffects = 1 in {
192 def MOV32rr : RRI<0x18,
193                   (outs GR32:$dst), (ins GR32:$src),
194                   "lr\t{$dst, $src}",
195                   []>;
196 def MOV64rr : RREI<0xB904,
197                    (outs GR64:$dst), (ins GR64:$src),
198                    "lgr\t{$dst, $src}",
199                    []>;
200 def MOV128rr : Pseudo<(outs GR128:$dst), (ins GR128:$src),
201                      "# MOV128 PSEUDO!\n"
202                      "\tlgr\t${dst:subreg_odd}, ${src:subreg_odd}\n"
203                      "\tlgr\t${dst:subreg_even}, ${src:subreg_even}",
204                      []>;
205 def MOV64rrP : Pseudo<(outs GR64P:$dst), (ins GR64P:$src),
206                      "# MOV64P PSEUDO!\n"
207                      "\tlr\t${dst:subreg_odd}, ${src:subreg_odd}\n"
208                      "\tlr\t${dst:subreg_even}, ${src:subreg_even}",
209                      []>;
210 }
211
212 def MOVSX64rr32 : RREI<0xB914,
213                        (outs GR64:$dst), (ins GR32:$src),
214                        "lgfr\t{$dst, $src}",
215                        [(set GR64:$dst, (sext GR32:$src))]>;
216 def MOVZX64rr32 : RREI<0xB916,
217                        (outs GR64:$dst), (ins GR32:$src),
218                        "llgfr\t{$dst, $src}",
219                        [(set GR64:$dst, (zext GR32:$src))]>;
220
221 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
222 def MOV32ri16 : RII<0x8A7,
223                     (outs GR32:$dst), (ins s16imm:$src),
224                     "lhi\t{$dst, $src}",
225                     [(set GR32:$dst, immSExt16:$src)]>;
226 def MOV64ri16 : RII<0x9A7,
227                     (outs GR64:$dst), (ins s16imm64:$src),
228                     "lghi\t{$dst, $src}",
229                     [(set GR64:$dst, immSExt16:$src)]>;
230
231 def MOV64rill16 : RII<0xFA5,
232                       (outs GR64:$dst), (ins i64imm:$src),
233                       "llill\t{$dst, $src}",
234                       [(set GR64:$dst, i64ll16:$src)]>;
235 def MOV64rilh16 : RII<0xEA5,
236                       (outs GR64:$dst), (ins i64imm:$src),
237                       "llilh\t{$dst, $src}",
238                       [(set GR64:$dst, i64lh16:$src)]>;
239 def MOV64rihl16 : RII<0xDA5,
240                       (outs GR64:$dst), (ins i64imm:$src),
241                       "llihl\t{$dst, $src}",
242                       [(set GR64:$dst, i64hl16:$src)]>;
243 def MOV64rihh16 : RII<0xCA5,
244                       (outs GR64:$dst), (ins i64imm:$src),
245                       "llihh\t{$dst, $src}",
246                       [(set GR64:$dst, i64hh16:$src)]>;
247
248 def MOV64ri32 : RILI<0x1C0,
249                      (outs GR64:$dst), (ins s32imm64:$src),
250                      "lgfi\t{$dst, $src}",
251                      [(set GR64:$dst, immSExt32:$src)]>;
252 def MOV64rilo32 : RILI<0xFC0,
253                        (outs GR64:$dst), (ins i64imm:$src),
254                        "llilf\t{$dst, $src}",
255                        [(set GR64:$dst, i64lo32:$src)]>;
256 def MOV64rihi32 : RILI<0xEC0, (outs GR64:$dst), (ins i64imm:$src),
257                        "llihf\t{$dst, $src}",
258                        [(set GR64:$dst, i64hi32:$src)]>;
259 }
260
261 let canFoldAsLoad = 1, isReMaterializable = 1 in {
262 def MOV32rm  : RXI<0x58,
263                    (outs GR32:$dst), (ins rriaddr12:$src),
264                    "l\t{$dst, $src}",
265                    [(set GR32:$dst, (load rriaddr12:$src))]>;
266 def MOV32rmy : RXYI<0x58E3,
267                     (outs GR32:$dst), (ins rriaddr:$src),
268                     "ly\t{$dst, $src}",
269                     [(set GR32:$dst, (load rriaddr:$src))]>;
270 def MOV64rm  : RXYI<0x04E3,
271                     (outs GR64:$dst), (ins rriaddr:$src),
272                     "lg\t{$dst, $src}",
273                     [(set GR64:$dst, (load rriaddr:$src))]>;
274 def MOV64Prm : Pseudo<(outs GR64P:$dst), (ins rriaddr12:$src),
275                       "# MOV64P PSEUDO!\n"
276                       "\tl\t${dst:subreg_odd},  $src\n"
277                       "\tl\t${dst:subreg_even}, 4+$src",
278                       [(set GR64P:$dst, (load rriaddr12:$src))]>;
279 def MOV64Prmy : Pseudo<(outs GR64P:$dst), (ins rriaddr:$src),
280                        "# MOV64P PSEUDO!\n"
281                        "\tly\t${dst:subreg_odd},  $src\n"
282                        "\tly\t${dst:subreg_even}, 4+$src",
283                        [(set GR64P:$dst, (load rriaddr:$src))]>;
284 def MOV128rm : Pseudo<(outs GR128:$dst), (ins rriaddr:$src),
285                       "# MOV128 PSEUDO!\n"
286                       "\tlg\t${dst:subreg_odd},  $src\n"
287                       "\tlg\t${dst:subreg_even}, 8+$src",
288                       [(set GR128:$dst, (load rriaddr:$src))]>;
289 }
290
291 def MOV32mr  : RXI<0x50,
292                    (outs), (ins rriaddr12:$dst, GR32:$src),
293                    "st\t{$src, $dst}",
294                    [(store GR32:$src, rriaddr12:$dst)]>;
295 def MOV32mry : RXYI<0x50E3,
296                     (outs), (ins rriaddr:$dst, GR32:$src),
297                     "sty\t{$src, $dst}",
298                     [(store GR32:$src, rriaddr:$dst)]>;
299 def MOV64mr  : RXYI<0x24E3,
300                     (outs), (ins rriaddr:$dst, GR64:$src),
301                     "stg\t{$src, $dst}",
302                     [(store GR64:$src, rriaddr:$dst)]>;
303 def MOV64Pmr : Pseudo<(outs), (ins rriaddr12:$dst, GR64P:$src),
304                       "# MOV64P PSEUDO!\n"
305                       "\tst\t${src:subreg_odd}, $dst\n"
306                       "\tst\t${src:subreg_even}, 4+$dst",
307                       [(store GR64P:$src, rriaddr12:$dst)]>;
308 def MOV64Pmry : Pseudo<(outs), (ins rriaddr:$dst, GR64P:$src),
309                        "# MOV64P PSEUDO!\n"
310                        "\tsty\t${src:subreg_odd}, $dst\n"
311                        "\tsty\t${src:subreg_even}, 4+$dst",
312                        [(store GR64P:$src, rriaddr:$dst)]>;
313 def MOV128mr : Pseudo<(outs), (ins rriaddr:$dst, GR128:$src),
314                       "# MOV128 PSEUDO!\n"
315                       "\tstg\t${src:subreg_odd}, $dst\n"
316                       "\tstg\t${src:subreg_even}, 8+$dst",
317                       [(store GR128:$src, rriaddr:$dst)]>;
318
319 def MOV8mi    : SII<0x92,
320                     (outs), (ins riaddr12:$dst, i32i8imm:$src),
321                     "mvi\t{$dst, $src}",
322                     [(truncstorei8 (i32 i32immSExt8:$src), riaddr12:$dst)]>;
323 def MOV8miy   : SIYI<0x52EB,
324                      (outs), (ins riaddr:$dst, i32i8imm:$src),
325                      "mviy\t{$dst, $src}",
326                      [(truncstorei8 (i32 i32immSExt8:$src), riaddr:$dst)]>;
327
328 let AddedComplexity = 2 in {
329 def MOV16mi   : SILI<0xE544,
330                      (outs), (ins riaddr12:$dst, s16imm:$src),
331                      "mvhhi\t{$dst, $src}",
332                      [(truncstorei16 (i32 i32immSExt16:$src), riaddr12:$dst)]>,
333                      Requires<[IsZ10]>;
334 def MOV32mi16 : SILI<0xE54C,
335                      (outs), (ins riaddr12:$dst, s32imm:$src),
336                      "mvhi\t{$dst, $src}",
337                      [(store (i32 immSExt16:$src), riaddr12:$dst)]>,
338                      Requires<[IsZ10]>;
339 def MOV64mi16 : SILI<0xE548,
340                      (outs), (ins riaddr12:$dst, s32imm64:$src),
341                      "mvghi\t{$dst, $src}",
342                      [(store (i64 immSExt16:$src), riaddr12:$dst)]>,
343                      Requires<[IsZ10]>;
344 }
345
346 // sexts
347 def MOVSX32rr8  : RREI<0xB926,
348                        (outs GR32:$dst), (ins GR32:$src),
349                        "lbr\t{$dst, $src}",
350                        [(set GR32:$dst, (sext_inreg GR32:$src, i8))]>;
351 def MOVSX64rr8  : RREI<0xB906,
352                        (outs GR64:$dst), (ins GR64:$src),
353                        "lgbr\t{$dst, $src}",
354                        [(set GR64:$dst, (sext_inreg GR64:$src, i8))]>;
355 def MOVSX32rr16 : RREI<0xB927,
356                        (outs GR32:$dst), (ins GR32:$src),
357                        "lhr\t{$dst, $src}",
358                        [(set GR32:$dst, (sext_inreg GR32:$src, i16))]>;
359 def MOVSX64rr16 : RREI<0xB907,
360                        (outs GR64:$dst), (ins GR64:$src),
361                        "lghr\t{$dst, $src}",
362                        [(set GR64:$dst, (sext_inreg GR64:$src, i16))]>;
363
364 // extloads
365 def MOVSX32rm8   : RXYI<0x76E3,
366                         (outs GR32:$dst), (ins rriaddr:$src),
367                         "lb\t{$dst, $src}",
368                         [(set GR32:$dst, (sextloadi32i8 rriaddr:$src))]>;
369 def MOVSX32rm16  : RXI<0x48,
370                        (outs GR32:$dst), (ins rriaddr12:$src),
371                        "lh\t{$dst, $src}",
372                        [(set GR32:$dst, (sextloadi32i16 rriaddr12:$src))]>;
373 def MOVSX32rm16y : RXYI<0x78E3,
374                         (outs GR32:$dst), (ins rriaddr:$src),
375                         "lhy\t{$dst, $src}",
376                         [(set GR32:$dst, (sextloadi32i16 rriaddr:$src))]>;
377 def MOVSX64rm8   : RXYI<0x77E3,
378                         (outs GR64:$dst), (ins rriaddr:$src),
379                         "lgb\t{$dst, $src}",
380                         [(set GR64:$dst, (sextloadi64i8 rriaddr:$src))]>;
381 def MOVSX64rm16  : RXYI<0x15E3,
382                         (outs GR64:$dst), (ins rriaddr:$src),
383                         "lgh\t{$dst, $src}",
384                         [(set GR64:$dst, (sextloadi64i16 rriaddr:$src))]>;
385 def MOVSX64rm32  : RXYI<0x14E3,
386                         (outs GR64:$dst), (ins rriaddr:$src),
387                         "lgf\t{$dst, $src}",
388                         [(set GR64:$dst, (sextloadi64i32 rriaddr:$src))]>;
389
390 def MOVZX32rm8  : RXYI<0x94E3,
391                        (outs GR32:$dst), (ins rriaddr:$src),
392                        "llc\t{$dst, $src}",
393                        [(set GR32:$dst, (zextloadi32i8 rriaddr:$src))]>;
394 def MOVZX32rm16 : RXYI<0x95E3,
395                        (outs GR32:$dst), (ins rriaddr:$src),
396                        "llh\t{$dst, $src}",
397                        [(set GR32:$dst, (zextloadi32i16 rriaddr:$src))]>;
398 def MOVZX64rm8  : RXYI<0x90E3,
399                        (outs GR64:$dst), (ins rriaddr:$src),
400                        "llgc\t{$dst, $src}",
401                        [(set GR64:$dst, (zextloadi64i8 rriaddr:$src))]>;
402 def MOVZX64rm16 : RXYI<0x91E3,
403                        (outs GR64:$dst), (ins rriaddr:$src),
404                        "llgh\t{$dst, $src}",
405                        [(set GR64:$dst, (zextloadi64i16 rriaddr:$src))]>;
406 def MOVZX64rm32 : RXYI<0x16E3,
407                        (outs GR64:$dst), (ins rriaddr:$src),
408                        "llgf\t{$dst, $src}",
409                        [(set GR64:$dst, (zextloadi64i32 rriaddr:$src))]>;
410
411 // truncstores
412 def MOV32m8r   : RXI<0x42,
413                      (outs), (ins rriaddr12:$dst, GR32:$src),
414                      "stc\t{$src, $dst}",
415                      [(truncstorei8 GR32:$src, rriaddr12:$dst)]>;
416
417 def MOV32m8ry  : RXYI<0x72E3,
418                       (outs), (ins rriaddr:$dst, GR32:$src),
419                       "stcy\t{$src, $dst}",
420                       [(truncstorei8 GR32:$src, rriaddr:$dst)]>;
421
422 def MOV32m16r  : RXI<0x40,
423                      (outs), (ins rriaddr12:$dst, GR32:$src),
424                      "sth\t{$src, $dst}",
425                      [(truncstorei16 GR32:$src, rriaddr12:$dst)]>;
426
427 def MOV32m16ry : RXYI<0x70E3,
428                       (outs), (ins rriaddr:$dst, GR32:$src),
429                       "sthy\t{$src, $dst}",
430                       [(truncstorei16 GR32:$src, rriaddr:$dst)]>;
431
432 def MOV64m8r   : RXI<0x42,
433                      (outs), (ins rriaddr12:$dst, GR64:$src),
434                      "stc\t{$src, $dst}",
435                      [(truncstorei8 GR64:$src, rriaddr12:$dst)]>;
436
437 def MOV64m8ry  : RXYI<0x72E3,
438                       (outs), (ins rriaddr:$dst, GR64:$src),
439                       "stcy\t{$src, $dst}",
440                       [(truncstorei8 GR64:$src, rriaddr:$dst)]>;
441
442 def MOV64m16r  : RXI<0x40,
443                      (outs), (ins rriaddr12:$dst, GR64:$src),
444                      "sth\t{$src, $dst}",
445                      [(truncstorei16 GR64:$src, rriaddr12:$dst)]>;
446
447 def MOV64m16ry : RXYI<0x70E3,
448                       (outs), (ins rriaddr:$dst, GR64:$src),
449                       "sthy\t{$src, $dst}",
450                       [(truncstorei16 GR64:$src, rriaddr:$dst)]>;
451
452 def MOV64m32r  : RXI<0x50,
453                      (outs), (ins rriaddr12:$dst, GR64:$src),
454                      "st\t{$src, $dst}",
455                      [(truncstorei32 GR64:$src, rriaddr12:$dst)]>;
456
457 def MOV64m32ry : RXYI<0x50E3,
458                       (outs), (ins rriaddr:$dst, GR64:$src),
459                       "sty\t{$src, $dst}",
460                       [(truncstorei32 GR64:$src, rriaddr:$dst)]>;
461
462 // multiple regs moves
463 // FIXME: should we use multiple arg nodes?
464 def MOV32mrm  : RSYI<0x90EB,
465                      (outs), (ins riaddr:$dst, GR32:$from, GR32:$to),
466                      "stmy\t{$from, $to, $dst}",
467                      []>;
468 def MOV64mrm  : RSYI<0x24EB,
469                      (outs), (ins riaddr:$dst, GR64:$from, GR64:$to),
470                      "stmg\t{$from, $to, $dst}",
471                      []>;
472 def MOV32rmm  : RSYI<0x90EB,
473                      (outs GR32:$from, GR32:$to), (ins riaddr:$dst),
474                      "lmy\t{$from, $to, $dst}",
475                      []>;
476 def MOV64rmm  : RSYI<0x04EB,
477                      (outs GR64:$from, GR64:$to), (ins riaddr:$dst),
478                      "lmg\t{$from, $to, $dst}",
479                      []>;
480
481 let isReMaterializable = 1, isAsCheapAsAMove = 1,
482     Constraints = "$src = $dst" in {
483 def MOV64Pr0_even : Pseudo<(outs GR64P:$dst), (ins GR64P:$src),
484                            "lhi\t${dst:subreg_even}, 0",
485                            []>;
486 def MOV128r0_even : Pseudo<(outs GR128:$dst), (ins GR128:$src),
487                            "lghi\t${dst:subreg_even}, 0",
488                            []>;
489 }
490
491 // Byte swaps
492 def BSWAP32rr : RREI<0xB91F,
493                      (outs GR32:$dst), (ins GR32:$src),
494                      "lrvr\t{$dst, $src}",
495                      [(set GR32:$dst, (bswap GR32:$src))]>;
496 def BSWAP64rr : RREI<0xB90F,
497                      (outs GR64:$dst), (ins GR64:$src),
498                      "lrvgr\t{$dst, $src}",
499                      [(set GR64:$dst, (bswap GR64:$src))]>;
500
501 // FIXME: this is invalid pattern for big-endian
502 //def BSWAP16rm : RXYI<0x1FE3, (outs GR32:$dst), (ins rriaddr:$src),
503 //                     "lrvh\t{$dst, $src}",
504 //                     [(set GR32:$dst, (bswap (extloadi32i16 rriaddr:$src)))]>;
505 def BSWAP32rm : RXYI<0x1EE3, (outs GR32:$dst), (ins rriaddr:$src),
506                      "lrv\t{$dst, $src}",
507                      [(set GR32:$dst, (bswap (load rriaddr:$src)))]>;
508 def BSWAP64rm : RXYI<0x0FE3, (outs GR64:$dst), (ins rriaddr:$src),
509                      "lrvg\t{$dst, $src}",
510                      [(set GR64:$dst, (bswap (load rriaddr:$src)))]>;
511
512 //def BSWAP16mr : RXYI<0xE33F, (outs), (ins rriaddr:$dst, GR32:$src),
513 //                     "strvh\t{$src, $dst}",
514 //                     [(truncstorei16 (bswap GR32:$src), rriaddr:$dst)]>;
515 def BSWAP32mr : RXYI<0xE33E, (outs), (ins rriaddr:$dst, GR32:$src),
516                      "strv\t{$src, $dst}",
517                      [(store (bswap GR32:$src), rriaddr:$dst)]>;
518 def BSWAP64mr : RXYI<0xE32F, (outs), (ins rriaddr:$dst, GR64:$src),
519                      "strvg\t{$src, $dst}",
520                      [(store (bswap GR64:$src), rriaddr:$dst)]>;
521
522 //===----------------------------------------------------------------------===//
523 // Arithmetic Instructions
524
525 let Defs = [PSW] in {
526 def NEG32rr : RRI<0x13,
527                   (outs GR32:$dst), (ins GR32:$src),
528                   "lcr\t{$dst, $src}",
529                   [(set GR32:$dst, (ineg GR32:$src)),
530                    (implicit PSW)]>;
531 def NEG64rr : RREI<0xB903, (outs GR64:$dst), (ins GR64:$src),
532                    "lcgr\t{$dst, $src}",
533                    [(set GR64:$dst, (ineg GR64:$src)),
534                     (implicit PSW)]>;
535 def NEG64rr32 : RREI<0xB913, (outs GR64:$dst), (ins GR32:$src),
536                      "lcgfr\t{$dst, $src}",
537                      [(set GR64:$dst, (ineg (sext GR32:$src))),
538                       (implicit PSW)]>;
539 }
540
541 let Constraints = "$src1 = $dst" in {
542
543 let Defs = [PSW] in {
544
545 let isCommutable = 1 in { // X = ADD Y, Z  == X = ADD Z, Y
546 def ADD32rr : RRI<0x1A, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
547                   "ar\t{$dst, $src2}",
548                   [(set GR32:$dst, (add GR32:$src1, GR32:$src2)),
549                    (implicit PSW)]>;
550 def ADD64rr : RREI<0xB908, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
551                    "agr\t{$dst, $src2}",
552                    [(set GR64:$dst, (add GR64:$src1, GR64:$src2)),
553                     (implicit PSW)]>;
554 }
555
556 def ADD32rm   : RXI<0x5A, (outs GR32:$dst), (ins GR32:$src1, rriaddr12:$src2),
557                     "a\t{$dst, $src2}",
558                     [(set GR32:$dst, (add GR32:$src1, (load rriaddr12:$src2))),
559                      (implicit PSW)]>;
560 def ADD32rmy  : RXYI<0xE35A, (outs GR32:$dst), (ins GR32:$src1, rriaddr:$src2),
561                      "ay\t{$dst, $src2}",
562                      [(set GR32:$dst, (add GR32:$src1, (load rriaddr:$src2))),
563                       (implicit PSW)]>;
564 def ADD64rm   : RXYI<0xE308, (outs GR64:$dst), (ins GR64:$src1, rriaddr:$src2),
565                      "ag\t{$dst, $src2}",
566                      [(set GR64:$dst, (add GR64:$src1, (load rriaddr:$src2))),
567                       (implicit PSW)]>;
568
569
570 def ADD32ri16 : RII<0xA7A,
571                     (outs GR32:$dst), (ins GR32:$src1, s16imm:$src2),
572                     "ahi\t{$dst, $src2}",
573                     [(set GR32:$dst, (add GR32:$src1, immSExt16:$src2)),
574                      (implicit PSW)]>;
575 def ADD32ri   : RILI<0xC29,
576                      (outs GR32:$dst), (ins GR32:$src1, s32imm:$src2),
577                      "afi\t{$dst, $src2}",
578                      [(set GR32:$dst, (add GR32:$src1, imm:$src2)),
579                       (implicit PSW)]>;
580 def ADD64ri16 : RILI<0xA7B,
581                      (outs GR64:$dst), (ins GR64:$src1, s16imm64:$src2),
582                      "aghi\t{$dst, $src2}",
583                      [(set GR64:$dst, (add GR64:$src1, immSExt16:$src2)),
584                       (implicit PSW)]>;
585 def ADD64ri32 : RILI<0xC28,
586                      (outs GR64:$dst), (ins GR64:$src1, s32imm64:$src2),
587                      "agfi\t{$dst, $src2}",
588                      [(set GR64:$dst, (add GR64:$src1, immSExt32:$src2)),
589                       (implicit PSW)]>;
590
591 let isCommutable = 1 in { // X = ADC Y, Z  == X = ADC Z, Y
592 def ADC32rr : RRI<0x1E, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
593                   "alr\t{$dst, $src2}",
594                   [(set GR32:$dst, (addc GR32:$src1, GR32:$src2))]>;
595 def ADC64rr : RREI<0xB90A, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
596                    "algr\t{$dst, $src2}",
597                    [(set GR64:$dst, (addc GR64:$src1, GR64:$src2))]>;
598 }
599
600 def ADC32ri   : RILI<0xC2B,
601                      (outs GR32:$dst), (ins GR32:$src1, s32imm:$src2),
602                      "alfi\t{$dst, $src2}",
603                      [(set GR32:$dst, (addc GR32:$src1, imm:$src2))]>;
604 def ADC64ri32 : RILI<0xC2A,
605                      (outs GR64:$dst), (ins GR64:$src1, s32imm64:$src2),
606                      "algfi\t{$dst, $src2}",
607                      [(set GR64:$dst, (addc GR64:$src1, immSExt32:$src2))]>;
608
609 let Uses = [PSW] in {
610 def ADDE32rr : RREI<0xB998, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
611                     "alcr\t{$dst, $src2}",
612                     [(set GR32:$dst, (adde GR32:$src1, GR32:$src2)),
613                      (implicit PSW)]>;
614 def ADDE64rr : RREI<0xB988, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
615                     "alcgr\t{$dst, $src2}",
616                     [(set GR64:$dst, (adde GR64:$src1, GR64:$src2)),
617                      (implicit PSW)]>;
618 }
619
620 let isCommutable = 1 in { // X = AND Y, Z  == X = AND Z, Y
621 def AND32rr : RRI<0x14,
622                   (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
623                   "nr\t{$dst, $src2}",
624                   [(set GR32:$dst, (and GR32:$src1, GR32:$src2))]>;
625 def AND64rr : RREI<0xB980,
626                    (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
627                    "ngr\t{$dst, $src2}",
628                    [(set GR64:$dst, (and GR64:$src1, GR64:$src2))]>;
629 }
630
631 def AND32rm   : RXI<0x54, (outs GR32:$dst), (ins GR32:$src1, rriaddr12:$src2),
632                     "n\t{$dst, $src2}",
633                     [(set GR32:$dst, (and GR32:$src1, (load rriaddr12:$src2))),
634                      (implicit PSW)]>;
635 def AND32rmy  : RXYI<0xE354, (outs GR32:$dst), (ins GR32:$src1, rriaddr:$src2),
636                      "ny\t{$dst, $src2}",
637                      [(set GR32:$dst, (and GR32:$src1, (load rriaddr:$src2))),
638                       (implicit PSW)]>;
639 def AND64rm   : RXYI<0xE360, (outs GR64:$dst), (ins GR64:$src1, rriaddr:$src2),
640                      "ng\t{$dst, $src2}",
641                      [(set GR64:$dst, (and GR64:$src1, (load rriaddr:$src2))),
642                       (implicit PSW)]>;
643
644 def AND32rill16 : RII<0xA57,
645                       (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
646                       "nill\t{$dst, $src2}",
647                       [(set GR32:$dst, (and GR32:$src1, i32ll16c:$src2))]>;
648 def AND64rill16 : RII<0xA57,
649                       (outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
650                       "nill\t{$dst, $src2}",
651                       [(set GR64:$dst, (and GR64:$src1, i64ll16c:$src2))]>;
652
653 def AND32rilh16 : RII<0xA56,
654                       (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
655                       "nilh\t{$dst, $src2}",
656                       [(set GR32:$dst, (and GR32:$src1, i32lh16c:$src2))]>;
657 def AND64rilh16 : RII<0xA56,
658                       (outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
659                       "nilh\t{$dst, $src2}",
660                       [(set GR64:$dst, (and GR64:$src1, i64lh16c:$src2))]>;
661
662 def AND64rihl16 : RII<0xA55,
663                       (outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
664                       "nihl\t{$dst, $src2}",
665                       [(set GR64:$dst, (and GR64:$src1, i64hl16c:$src2))]>;
666 def AND64rihh16 : RII<0xA54,
667                       (outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
668                       "nihh\t{$dst, $src2}",
669                       [(set GR64:$dst, (and GR64:$src1, i64hh16c:$src2))]>;
670
671 def AND32ri     : RILI<0xC0B,
672                        (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
673                        "nilf\t{$dst, $src2}",
674                        [(set GR32:$dst, (and GR32:$src1, imm:$src2))]>;
675 def AND64rilo32 : RILI<0xC0B,
676                        (outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
677                        "nilf\t{$dst, $src2}",
678                        [(set GR64:$dst, (and GR64:$src1, i64lo32c:$src2))]>;
679 def AND64rihi32 : RILI<0xC0A,
680                        (outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
681                        "nihf\t{$dst, $src2}",
682                        [(set GR64:$dst, (and GR64:$src1, i64hi32c:$src2))]>;
683
684 let isCommutable = 1 in { // X = OR Y, Z  == X = OR Z, Y
685 def OR32rr : RRI<0x16,
686                  (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
687                  "or\t{$dst, $src2}",
688                  [(set GR32:$dst, (or GR32:$src1, GR32:$src2))]>;
689 def OR64rr : RREI<0xB981,
690                   (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
691                   "ogr\t{$dst, $src2}",
692                   [(set GR64:$dst, (or GR64:$src1, GR64:$src2))]>;
693 }
694
695 def OR32rm   : RXI<0x56, (outs GR32:$dst), (ins GR32:$src1, rriaddr12:$src2),
696                    "o\t{$dst, $src2}",
697                    [(set GR32:$dst, (or GR32:$src1, (load rriaddr12:$src2))),
698                     (implicit PSW)]>;
699 def OR32rmy  : RXYI<0xE356, (outs GR32:$dst), (ins GR32:$src1, rriaddr:$src2),
700                     "oy\t{$dst, $src2}",
701                     [(set GR32:$dst, (or GR32:$src1, (load rriaddr:$src2))),
702                      (implicit PSW)]>;
703 def OR64rm   : RXYI<0xE381, (outs GR64:$dst), (ins GR64:$src1, rriaddr:$src2),
704                     "og\t{$dst, $src2}",
705                     [(set GR64:$dst, (or GR64:$src1, (load rriaddr:$src2))),
706                      (implicit PSW)]>;
707
708  // FIXME: Provide proper encoding!
709 def OR32ri16  : RII<0xA5B,
710                     (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
711                     "oill\t{$dst, $src2}",
712                     [(set GR32:$dst, (or GR32:$src1, i32ll16:$src2))]>;
713 def OR32ri16h : RII<0xA5A,
714                     (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
715                     "oilh\t{$dst, $src2}",
716                     [(set GR32:$dst, (or GR32:$src1, i32lh16:$src2))]>;
717 def OR32ri : RILI<0xC0D,
718                   (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
719                   "oilf\t{$dst, $src2}",
720                   [(set GR32:$dst, (or GR32:$src1, imm:$src2))]>;
721
722 def OR64rill16 : RII<0xA5B,
723                      (outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
724                      "oill\t{$dst, $src2}",
725                      [(set GR64:$dst, (or GR64:$src1, i64ll16:$src2))]>;
726 def OR64rilh16 : RII<0xA5A,
727                      (outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
728                      "oilh\t{$dst, $src2}",
729                      [(set GR64:$dst, (or GR64:$src1, i64lh16:$src2))]>;
730 def OR64rihl16 : RII<0xA59,
731                      (outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
732                      "oihl\t{$dst, $src2}",
733                      [(set GR64:$dst, (or GR64:$src1, i64hl16:$src2))]>;
734 def OR64rihh16 : RII<0xA58,
735                      (outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
736                      "oihh\t{$dst, $src2}",
737                      [(set GR64:$dst, (or GR64:$src1, i64hh16:$src2))]>;
738
739 def OR64rilo32 : RILI<0xC0D,
740                       (outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
741                       "oilf\t{$dst, $src2}",
742                       [(set GR64:$dst, (or GR64:$src1, i64lo32:$src2))]>;
743 def OR64rihi32 : RILI<0xC0C,
744                       (outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
745                       "oihf\t{$dst, $src2}",
746                       [(set GR64:$dst, (or GR64:$src1, i64hi32:$src2))]>;
747
748 def SUB32rr : RRI<0x1B,
749                   (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
750                   "sr\t{$dst, $src2}",
751                   [(set GR32:$dst, (sub GR32:$src1, GR32:$src2))]>;
752 def SUB64rr : RREI<0xB909,
753                    (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
754                    "sgr\t{$dst, $src2}",
755                    [(set GR64:$dst, (sub GR64:$src1, GR64:$src2))]>;
756
757 def SUB32rm   : RXI<0x5B, (outs GR32:$dst), (ins GR32:$src1, rriaddr12:$src2),
758                     "s\t{$dst, $src2}",
759                     [(set GR32:$dst, (sub GR32:$src1, (load rriaddr12:$src2))),
760                      (implicit PSW)]>;
761 def SUB32rmy  : RXYI<0xE35B, (outs GR32:$dst), (ins GR32:$src1, rriaddr:$src2),
762                      "sy\t{$dst, $src2}",
763                      [(set GR32:$dst, (sub GR32:$src1, (load rriaddr:$src2))),
764                       (implicit PSW)]>;
765 def SUB64rm   : RXYI<0xE309, (outs GR64:$dst), (ins GR64:$src1, rriaddr:$src2),
766                      "sg\t{$dst, $src2}",
767                      [(set GR64:$dst, (sub GR64:$src1, (load rriaddr:$src2))),
768                       (implicit PSW)]>;
769  
770 def SBC32rr : RRI<0x1F,
771                   (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
772                   "slr\t{$dst, $src2}",
773                   [(set GR32:$dst, (subc GR32:$src1, GR32:$src2))]>;
774 def SBC64rr : RREI<0xB90B,
775                    (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
776                    "slgr\t{$dst, $src2}",
777                    [(set GR64:$dst, (subc GR64:$src1, GR64:$src2))]>;
778
779 def SBC32ri   : RILI<0xC25,
780                      (outs GR32:$dst), (ins GR32:$src1, s32imm:$src2),
781                      "sllfi\t{$dst, $src2}",
782                      [(set GR32:$dst, (subc GR32:$src1, imm:$src2))]>;
783 def SBC64ri32 : RILI<0xC24,
784                      (outs GR64:$dst), (ins GR64:$src1, s32imm64:$src2),
785                      "slgfi\t{$dst, $src2}",
786                      [(set GR64:$dst, (subc GR64:$src1, immSExt32:$src2))]>;
787
788 let Uses = [PSW] in {
789 def SUBE32rr : RREI<0xB999, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
790                     "slbr\t{$dst, $src2}",
791                     [(set GR32:$dst, (sube GR32:$src1, GR32:$src2)),
792                      (implicit PSW)]>;
793 def SUBE64rr : RREI<0xB989, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
794                     "slbgr\t{$dst, $src2}",
795                     [(set GR64:$dst, (sube GR64:$src1, GR64:$src2)),
796                      (implicit PSW)]>;
797 }
798
799 let isCommutable = 1 in { // X = XOR Y, Z  == X = XOR Z, Y
800 def XOR32rr : RRI<0x17,
801                   (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
802                   "xr\t{$dst, $src2}",
803                   [(set GR32:$dst, (xor GR32:$src1, GR32:$src2))]>;
804 def XOR64rr : RREI<0xB982,
805                    (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
806                    "xgr\t{$dst, $src2}",
807                    [(set GR64:$dst, (xor GR64:$src1, GR64:$src2))]>;
808 }
809
810 def XOR32rm   : RXI<0x57,(outs GR32:$dst), (ins GR32:$src1, rriaddr12:$src2),
811                     "x\t{$dst, $src2}",
812                     [(set GR32:$dst, (xor GR32:$src1, (load rriaddr12:$src2))),
813                      (implicit PSW)]>;
814 def XOR32rmy  : RXYI<0xE357, (outs GR32:$dst), (ins GR32:$src1, rriaddr:$src2),
815                      "xy\t{$dst, $src2}",
816                      [(set GR32:$dst, (xor GR32:$src1, (load rriaddr:$src2))),
817                       (implicit PSW)]>;
818 def XOR64rm   : RXYI<0xE382, (outs GR64:$dst), (ins GR64:$src1, rriaddr:$src2),
819                      "xg\t{$dst, $src2}",
820                      [(set GR64:$dst, (xor GR64:$src1, (load rriaddr:$src2))),
821                       (implicit PSW)]>;
822
823 def XOR32ri : RILI<0xC07,
824                    (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
825                    "xilf\t{$dst, $src2}",
826                    [(set GR32:$dst, (xor GR32:$src1, imm:$src2))]>;
827
828 } // Defs = [PSW]
829
830 let isCommutable = 1 in { // X = MUL Y, Z == X = MUL Z, Y
831 def MUL32rr : RREI<0xB252,
832                    (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
833                    "msr\t{$dst, $src2}",
834                    [(set GR32:$dst, (mul GR32:$src1, GR32:$src2))]>;
835 def MUL64rr : RREI<0xB90C,
836                    (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
837                    "msgr\t{$dst, $src2}",
838                    [(set GR64:$dst, (mul GR64:$src1, GR64:$src2))]>;
839 }
840
841 def MUL64rrP   : RRI<0x1C,
842                      (outs GR64P:$dst), (ins GR64P:$src1, GR32:$src2),
843                      "mr\t{$dst, $src2}",
844                      []>;
845 def UMUL64rrP  : RREI<0xB996,
846                       (outs GR64P:$dst), (ins GR64P:$src1, GR32:$src2),
847                       "mlr\t{$dst, $src2}",
848                       []>;
849 def UMUL128rrP : RREI<0xB986,
850                       (outs GR128:$dst), (ins GR128:$src1, GR64:$src2),
851                       "mlgr\t{$dst, $src2}",
852                       []>;
853
854 def MUL32ri16   : RII<0xA7C,
855                       (outs GR32:$dst), (ins GR32:$src1, s16imm:$src2),
856                       "mhi\t{$dst, $src2}",
857                       [(set GR32:$dst, (mul GR32:$src1, i32immSExt16:$src2))]>;
858 def MUL64ri16   : RII<0xA7D,
859                       (outs GR64:$dst), (ins GR64:$src1, s16imm64:$src2),
860                       "mghi\t{$dst, $src2}",
861                       [(set GR64:$dst, (mul GR64:$src1, immSExt16:$src2))]>;
862
863 let AddedComplexity = 2 in {
864 def MUL32ri     : RILI<0xC21,
865                        (outs GR32:$dst), (ins GR32:$src1, s32imm:$src2),
866                        "msfi\t{$dst, $src2}",
867                        [(set GR32:$dst, (mul GR32:$src1, imm:$src2))]>,
868                        Requires<[IsZ10]>;
869 def MUL64ri32   : RILI<0xC20,
870                        (outs GR64:$dst), (ins GR64:$src1, s32imm64:$src2),
871                        "msgfi\t{$dst, $src2}",
872                        [(set GR64:$dst, (mul GR64:$src1, i64immSExt32:$src2))]>,
873                        Requires<[IsZ10]>;
874 }
875
876 def MUL32rm : RXI<0x71,
877                   (outs GR32:$dst), (ins GR32:$src1, rriaddr12:$src2),
878                   "ms\t{$dst, $src2}",
879                   [(set GR32:$dst, (mul GR32:$src1, (load rriaddr12:$src2)))]>;
880 def MUL32rmy : RXYI<0xE351,
881                     (outs GR32:$dst), (ins GR32:$src1, rriaddr:$src2),
882                     "msy\t{$dst, $src2}",
883                     [(set GR32:$dst, (mul GR32:$src1, (load rriaddr:$src2)))]>;
884 def MUL64rm  : RXYI<0xE30C,
885                     (outs GR64:$dst), (ins GR64:$src1, rriaddr:$src2),
886                     "msg\t{$dst, $src2}",
887                     [(set GR64:$dst, (mul GR64:$src1, (load rriaddr:$src2)))]>;
888
889 def MULSX64rr32 : RREI<0xB91C,
890                        (outs GR64:$dst), (ins GR64:$src1, GR32:$src2),
891                        "msgfr\t{$dst, $src2}",
892                        [(set GR64:$dst, (mul GR64:$src1, (sext GR32:$src2)))]>;
893
894 def SDIVREM32r : RREI<0xB91D,
895                       (outs GR128:$dst), (ins GR128:$src1, GR32:$src2),
896                       "dsgfr\t{$dst, $src2}",
897                       []>;
898 def SDIVREM64r : RREI<0xB90D,
899                       (outs GR128:$dst), (ins GR128:$src1, GR64:$src2),
900                       "dsgr\t{$dst, $src2}",
901                       []>;
902
903 def UDIVREM32r : RREI<0xB997,
904                       (outs GR64P:$dst), (ins GR64P:$src1, GR32:$src2),
905                       "dlr\t{$dst, $src2}",
906                       []>;
907 def UDIVREM64r : RREI<0xB987,
908                       (outs GR128:$dst), (ins GR128:$src1, GR64:$src2),
909                       "dlgr\t{$dst, $src2}",
910                       []>;
911 let mayLoad = 1 in {
912 def SDIVREM32m : RXYI<0xE31D,
913                       (outs GR128:$dst), (ins GR128:$src1, rriaddr:$src2),
914                       "dsgf\t{$dst, $src2}",
915                       []>;
916 def SDIVREM64m : RXYI<0xE30D,
917                       (outs GR128:$dst), (ins GR128:$src1, rriaddr:$src2),
918                       "dsg\t{$dst, $src2}",
919                       []>;
920
921 def UDIVREM32m : RXYI<0xE397, (outs GR64P:$dst), (ins GR64P:$src1, rriaddr:$src2),
922                       "dl\t{$dst, $src2}",
923                       []>;
924 def UDIVREM64m : RXYI<0xE387, (outs GR128:$dst), (ins GR128:$src1, rriaddr:$src2),
925                       "dlg\t{$dst, $src2}",
926                       []>;
927 } // mayLoad
928 } // Constraints = "$src1 = $dst"
929
930 //===----------------------------------------------------------------------===//
931 // Shifts
932
933 let Constraints = "$src = $dst" in
934 def SRL32rri : RSI<0x88,
935                    (outs GR32:$dst), (ins GR32:$src, riaddr32:$amt),
936                    "srl\t{$src, $amt}",
937                    [(set GR32:$dst, (srl GR32:$src, riaddr32:$amt))]>;
938 def SRL64rri : RSYI<0xEB0C,
939                     (outs GR64:$dst), (ins GR64:$src, riaddr:$amt),
940                     "srlg\t{$dst, $src, $amt}",
941                     [(set GR64:$dst, (srl GR64:$src, riaddr:$amt))]>;
942
943 let Constraints = "$src = $dst" in
944 def SHL32rri : RSI<0x89,
945                    (outs GR32:$dst), (ins GR32:$src, riaddr32:$amt),
946                    "sll\t{$src, $amt}",
947                    [(set GR32:$dst, (shl GR32:$src, riaddr32:$amt))]>;
948 def SHL64rri : RSYI<0xEB0D,
949                     (outs GR64:$dst), (ins GR64:$src, riaddr:$amt),
950                     "sllg\t{$dst, $src, $amt}",
951                     [(set GR64:$dst, (shl GR64:$src, riaddr:$amt))]>;
952
953 let Defs = [PSW] in {
954 let Constraints = "$src = $dst" in
955 def SRA32rri : RSI<0x8A,
956                    (outs GR32:$dst), (ins GR32:$src, riaddr32:$amt),
957                    "sra\t{$src, $amt}",
958                    [(set GR32:$dst, (sra GR32:$src, riaddr32:$amt)),
959                     (implicit PSW)]>;
960
961 def SRA64rri : RSYI<0xEB0A,
962                     (outs GR64:$dst), (ins GR64:$src, riaddr:$amt),
963                     "srag\t{$dst, $src, $amt}",
964                     [(set GR64:$dst, (sra GR64:$src, riaddr:$amt)),
965                      (implicit PSW)]>;
966 } // Defs = [PSW]
967
968 def ROTL32rri : RSYI<0xEB1D,
969                      (outs GR32:$dst), (ins GR32:$src, riaddr32:$amt),
970                      "rll\t{$dst, $src, $amt}",
971                      [(set GR32:$dst, (rotl GR32:$src, riaddr32:$amt))]>;
972 def ROTL64rri : RSYI<0xEB1C,
973                      (outs GR64:$dst), (ins GR64:$src, riaddr:$amt),
974                      "rllg\t{$dst, $src, $amt}",
975                      [(set GR64:$dst, (rotl GR64:$src, riaddr:$amt))]>;
976
977 //===----------------------------------------------------------------------===//
978 // Test instructions (like AND but do not produce any result)
979
980 // Integer comparisons
981 let Defs = [PSW] in {
982 def CMP32rr : RRI<0x19,
983                   (outs), (ins GR32:$src1, GR32:$src2),
984                   "cr\t$src1, $src2",
985                   [(set PSW, (SystemZcmp GR32:$src1, GR32:$src2))]>; 
986 def CMP64rr : RREI<0xB920,
987                    (outs), (ins GR64:$src1, GR64:$src2),
988                    "cgr\t$src1, $src2",
989                    [(set PSW, (SystemZcmp GR64:$src1, GR64:$src2))]>;
990
991 def CMP32ri   : RILI<0xC2D,
992                      (outs), (ins GR32:$src1, s32imm:$src2),
993                      "cfi\t$src1, $src2",
994                      [(set PSW, (SystemZcmp GR32:$src1, imm:$src2))]>;
995 def CMP64ri32 : RILI<0xC2C,
996                      (outs), (ins GR64:$src1, s32imm64:$src2),
997                      "cgfi\t$src1, $src2",
998                      [(set PSW, (SystemZcmp GR64:$src1, i64immSExt32:$src2))]>;
999
1000 def CMP32rm : RXI<0x59,
1001                   (outs), (ins GR32:$src1, rriaddr12:$src2),
1002                   "c\t$src1, $src2",
1003                   [(set PSW, (SystemZcmp GR32:$src1, (load rriaddr12:$src2)))]>;
1004 def CMP32rmy : RXYI<0xE359,
1005                     (outs), (ins GR32:$src1, rriaddr:$src2),
1006                     "cy\t$src1, $src2",
1007                     [(set PSW, (SystemZcmp GR32:$src1, (load rriaddr:$src2)))]>;
1008 def CMP64rm  : RXYI<0xE320,
1009                     (outs), (ins GR64:$src1, rriaddr:$src2),
1010                     "cg\t$src1, $src2",
1011                     [(set PSW, (SystemZcmp GR64:$src1, (load rriaddr:$src2)))]>;
1012
1013 def UCMP32rr : RRI<0x15,
1014                    (outs), (ins GR32:$src1, GR32:$src2),
1015                    "clr\t$src1, $src2",
1016                    [(set PSW, (SystemZucmp GR32:$src1, GR32:$src2))]>;
1017 def UCMP64rr : RREI<0xB921,
1018                     (outs), (ins GR64:$src1, GR64:$src2),
1019                     "clgr\t$src1, $src2",
1020                     [(set PSW, (SystemZucmp GR64:$src1, GR64:$src2))]>;
1021
1022 def UCMP32ri   : RILI<0xC2F,
1023                       (outs), (ins GR32:$src1, i32imm:$src2),
1024                       "clfi\t$src1, $src2",
1025                       [(set PSW, (SystemZucmp GR32:$src1, imm:$src2))]>;
1026 def UCMP64ri32 : RILI<0xC2E,
1027                       (outs), (ins GR64:$src1, i64i32imm:$src2),
1028                       "clgfi\t$src1, $src2",
1029                       [(set PSW,(SystemZucmp GR64:$src1, i64immZExt32:$src2))]>;
1030
1031 def UCMP32rm  : RXI<0x55,
1032                     (outs), (ins GR32:$src1, rriaddr12:$src2),
1033                     "cl\t$src1, $src2",
1034                     [(set PSW, (SystemZucmp GR32:$src1,
1035                                             (load rriaddr12:$src2)))]>;
1036 def UCMP32rmy : RXYI<0xE355,
1037                      (outs), (ins GR32:$src1, rriaddr:$src2),
1038                      "cly\t$src1, $src2",
1039                      [(set PSW, (SystemZucmp GR32:$src1,
1040                                              (load rriaddr:$src2)))]>;
1041 def UCMP64rm  : RXYI<0xE351,
1042                      (outs), (ins GR64:$src1, rriaddr:$src2),
1043                      "clg\t$src1, $src2",
1044                      [(set PSW, (SystemZucmp GR64:$src1,
1045                                              (load rriaddr:$src2)))]>;
1046
1047 def CMPSX64rr32  : RREI<0xB930,
1048                         (outs), (ins GR64:$src1, GR32:$src2),
1049                         "cgfr\t$src1, $src2",
1050                         [(set PSW, (SystemZucmp GR64:$src1,
1051                                                 (sext GR32:$src2)))]>;
1052 def UCMPZX64rr32 : RREI<0xB931,
1053                         (outs), (ins GR64:$src1, GR32:$src2),
1054                         "clgfr\t$src1, $src2",
1055                         [(set PSW, (SystemZucmp GR64:$src1,
1056                                                 (zext GR32:$src2)))]>;
1057
1058 def CMPSX64rm32   : RXYI<0xE330,
1059                          (outs), (ins GR64:$src1, rriaddr:$src2),
1060                          "cgf\t$src1, $src2",
1061                          [(set PSW, (SystemZucmp GR64:$src1,
1062                                              (sextloadi64i32 rriaddr:$src2)))]>;
1063 def UCMPZX64rm32  : RXYI<0xE331,
1064                          (outs), (ins GR64:$src1, rriaddr:$src2),
1065                          "clgf\t$src1, $src2",
1066                          [(set PSW, (SystemZucmp GR64:$src1,
1067                                              (zextloadi64i32 rriaddr:$src2)))]>;
1068
1069 // FIXME: Add other crazy ucmp forms
1070
1071 } // Defs = [PSW]
1072
1073 //===----------------------------------------------------------------------===//
1074 // Other crazy stuff
1075 let Defs = [PSW] in {
1076 def FLOGR64 : RREI<0xB983,
1077                    (outs GR128:$dst), (ins GR64:$src),
1078                    "flogr\t{$dst, $src}",
1079                    []>;
1080 } // Defs = [PSW]
1081
1082 //===----------------------------------------------------------------------===//
1083 // Non-Instruction Patterns.
1084 //===----------------------------------------------------------------------===//
1085
1086 // ConstPools, JumpTables
1087 def : Pat<(SystemZpcrelwrapper tjumptable:$src), (LA64rm tjumptable:$src)>;
1088 def : Pat<(SystemZpcrelwrapper tconstpool:$src), (LA64rm tconstpool:$src)>;
1089
1090 // anyext
1091 def : Pat<(i64 (anyext GR32:$src)),
1092           (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, subreg_32bit)>;
1093
1094 // calls
1095 def : Pat<(SystemZcall (i64 tglobaladdr:$dst)), (CALLi tglobaladdr:$dst)>;
1096 def : Pat<(SystemZcall (i64 texternalsym:$dst)), (CALLi texternalsym:$dst)>;
1097
1098 //===----------------------------------------------------------------------===//
1099 // Peepholes.
1100 //===----------------------------------------------------------------------===//
1101
1102 // FIXME: use add/sub tricks with 32678/-32768
1103
1104 // Arbitrary immediate support.
1105 def : Pat<(i32 imm:$src),
1106           (EXTRACT_SUBREG (MOV64ri32 (GetI64FromI32 (i32 imm:$src))),
1107              subreg_32bit)>;
1108
1109 // Implement in terms of LLIHF/OILF.
1110 def : Pat<(i64 imm:$imm),
1111           (OR64rilo32 (MOV64rihi32 (HI32 imm:$imm)), (LO32 imm:$imm))>;
1112
1113 // trunc patterns
1114 def : Pat<(i32 (trunc GR64:$src)),
1115           (EXTRACT_SUBREG GR64:$src, subreg_32bit)>;
1116
1117 // sext_inreg patterns
1118 def : Pat<(sext_inreg GR64:$src, i32),
1119           (MOVSX64rr32 (EXTRACT_SUBREG GR64:$src, subreg_32bit))>;
1120
1121 // extload patterns
1122 def : Pat<(extloadi32i8  rriaddr:$src), (MOVZX32rm8  rriaddr:$src)>;
1123 def : Pat<(extloadi32i16 rriaddr:$src), (MOVZX32rm16 rriaddr:$src)>;
1124 def : Pat<(extloadi64i8  rriaddr:$src), (MOVZX64rm8  rriaddr:$src)>;
1125 def : Pat<(extloadi64i16 rriaddr:$src), (MOVZX64rm16 rriaddr:$src)>;
1126 def : Pat<(extloadi64i32 rriaddr:$src), (MOVZX64rm32 rriaddr:$src)>;
1127
1128 // muls
1129 def : Pat<(mulhs GR32:$src1, GR32:$src2),
1130           (EXTRACT_SUBREG (MUL64rrP (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)),
1131                                                    GR32:$src1, subreg_odd32),
1132                                     GR32:$src2),
1133                           subreg_32bit)>;
1134
1135 def : Pat<(mulhu GR32:$src1, GR32:$src2),
1136           (EXTRACT_SUBREG (UMUL64rrP (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)),
1137                                                     GR32:$src1, subreg_odd32),
1138                                      GR32:$src2),
1139                           subreg_32bit)>;
1140 def : Pat<(mulhu GR64:$src1, GR64:$src2),
1141           (EXTRACT_SUBREG (UMUL128rrP (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
1142                                                      GR64:$src1, subreg_odd),
1143                                       GR64:$src2),
1144                           subreg_even)>;
1145
1146 def : Pat<(ctlz GR64:$src),
1147           (EXTRACT_SUBREG (FLOGR64 GR64:$src), subreg_even)>;