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.
16def IsZ10 : Predicate<"Subtarget.isZ10()">;
17
18include "SystemZInstrFormats.td"
19
20//===----------------------------------------------------------------------===//
21// Type Constraints.
22//===----------------------------------------------------------------------===//
23class SDTCisI8<int OpNum> : SDTCisVT<OpNum, i8>;
24class SDTCisI16<int OpNum> : SDTCisVT<OpNum, i16>;
25class SDTCisI32<int OpNum> : SDTCisVT<OpNum, i32>;
26class SDTCisI64<int OpNum> : SDTCisVT<OpNum, i64>;
27
28//===----------------------------------------------------------------------===//
29// Type Profiles.
30//===----------------------------------------------------------------------===//
31def SDT_SystemZCall         : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>;
32def SDT_SystemZCallSeqStart : SDCallSeqStart<[SDTCisI64<0>]>;
33def SDT_SystemZCallSeqEnd   : SDCallSeqEnd<[SDTCisI64<0>, SDTCisI64<1>]>;
34def SDT_CmpTest             : SDTypeProfile<1, 2, [SDTCisI64<0>,
35                                                   SDTCisSameAs<1, 2>]>;
36def SDT_BrCond              : SDTypeProfile<0, 3,
37                                           [SDTCisVT<0, OtherVT>,
38                                            SDTCisI8<1>, SDTCisVT<2, i64>]>;
39def SDT_SelectCC            : SDTypeProfile<1, 4,
40                                           [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>,
41                                            SDTCisI8<3>, SDTCisVT<4, i64>]>;
42def SDT_Address             : SDTypeProfile<1, 1,
43                                            [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
44
45//===----------------------------------------------------------------------===//
46// SystemZ Specific Node Definitions.
47//===----------------------------------------------------------------------===//
48def SystemZretflag : SDNode<"SystemZISD::RET_FLAG", SDTNone,
49                     [SDNPHasChain, SDNPOptInGlue]>;
50def SystemZcall    : SDNode<"SystemZISD::CALL", SDT_SystemZCall,
51                     [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>;
52def SystemZcallseq_start :
53                 SDNode<"ISD::CALLSEQ_START", SDT_SystemZCallSeqStart,
54                        [SDNPHasChain, SDNPOutGlue]>;
55def SystemZcallseq_end :
56                 SDNode<"ISD::CALLSEQ_END",   SDT_SystemZCallSeqEnd,
57                        [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
58def SystemZcmp     : SDNode<"SystemZISD::CMP", SDT_CmpTest>;
59def SystemZucmp    : SDNode<"SystemZISD::UCMP", SDT_CmpTest>;
60def SystemZbrcond  : SDNode<"SystemZISD::BRCOND", SDT_BrCond,
61                            [SDNPHasChain]>;
62def SystemZselect  : SDNode<"SystemZISD::SELECT", SDT_SelectCC>;
63def SystemZpcrelwrapper : SDNode<"SystemZISD::PCRelativeWrapper", SDT_Address, []>;
64
65
66include "SystemZOperands.td"
67
68//===----------------------------------------------------------------------===//
69// Instruction list..
70
71def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i64imm:$amt),
72                              "#ADJCALLSTACKDOWN",
73                              [(SystemZcallseq_start timm:$amt)]>;
74def ADJCALLSTACKUP   : Pseudo<(outs), (ins i64imm:$amt1, i64imm:$amt2),
75                              "#ADJCALLSTACKUP",
76                              [(SystemZcallseq_end timm:$amt1, timm:$amt2)]>;
77
78let 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!
95let isReturn = 1, isTerminator = 1, isBarrier = 1, hasCtrlDep = 1 in {
96  def RET : Pseudo<(outs), (ins), "br\t%r14", [(SystemZretflag)]>;
97}
98
99let 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
157let 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
172let isReMaterializable = 1 in
173// FIXME: Provide imm12 variant
174// FIXME: Address should be halfword aligned...
175def LA64r  : RXI<0x47,
176                 (outs GR64:$dst), (ins laaddr:$src),
177                 "lay\t{$dst, $src}",
178                 [(set GR64:$dst, laaddr:$src)]>;
179def LA64rm : RXYI<0x71E3,
180                  (outs GR64:$dst), (ins i64imm:$src),
181                  "larl\t{$dst, $src}",
182                  [(set GR64:$dst,
183                        (SystemZpcrelwrapper tglobaladdr:$src))]>;
184
185let neverHasSideEffects = 1 in
186def NOP : Pseudo<(outs), (ins), "# no-op", []>;
187
188//===----------------------------------------------------------------------===//
189// Move Instructions
190
191let neverHasSideEffects = 1 in {
192def MOV32rr : RRI<0x18,
193                  (outs GR32:$dst), (ins GR32:$src),
194                  "lr\t{$dst, $src}",
195                  []>;
196def MOV64rr : RREI<0xB904,
197                   (outs GR64:$dst), (ins GR64:$src),
198                   "lgr\t{$dst, $src}",
199                   []>;
200def 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                     []>;
205def 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
212def MOVSX64rr32 : RREI<0xB914,
213                       (outs GR64:$dst), (ins GR32:$src),
214                       "lgfr\t{$dst, $src}",
215                       [(set GR64:$dst, (sext GR32:$src))]>;
216def MOVZX64rr32 : RREI<0xB916,
217                       (outs GR64:$dst), (ins GR32:$src),
218                       "llgfr\t{$dst, $src}",
219                       [(set GR64:$dst, (zext GR32:$src))]>;
220
221let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
222def MOV32ri16 : RII<0x8A7,
223                    (outs GR32:$dst), (ins s16imm:$src),
224                    "lhi\t{$dst, $src}",
225                    [(set GR32:$dst, immSExt16:$src)]>;
226def MOV64ri16 : RII<0x9A7,
227                    (outs GR64:$dst), (ins s16imm64:$src),
228                    "lghi\t{$dst, $src}",
229                    [(set GR64:$dst, immSExt16:$src)]>;
230
231def MOV64rill16 : RII<0xFA5,
232                      (outs GR64:$dst), (ins u16imm:$src),
233                      "llill\t{$dst, $src}",
234                      [(set GR64:$dst, i64ll16:$src)]>;
235def MOV64rilh16 : RII<0xEA5,
236                      (outs GR64:$dst), (ins u16imm:$src),
237                      "llilh\t{$dst, $src}",
238                      [(set GR64:$dst, i64lh16:$src)]>;
239def MOV64rihl16 : RII<0xDA5,
240                      (outs GR64:$dst), (ins u16imm:$src),
241                      "llihl\t{$dst, $src}",
242                      [(set GR64:$dst, i64hl16:$src)]>;
243def MOV64rihh16 : RII<0xCA5,
244                      (outs GR64:$dst), (ins u16imm:$src),
245                      "llihh\t{$dst, $src}",
246                      [(set GR64:$dst, i64hh16:$src)]>;
247
248def MOV64ri32 : RILI<0x1C0,
249                     (outs GR64:$dst), (ins s32imm64:$src),
250                     "lgfi\t{$dst, $src}",
251                     [(set GR64:$dst, immSExt32:$src)]>;
252def MOV64rilo32 : RILI<0xFC0,
253                       (outs GR64:$dst), (ins u32imm:$src),
254                       "llilf\t{$dst, $src}",
255                       [(set GR64:$dst, i64lo32:$src)]>;
256def MOV64rihi32 : RILI<0xEC0, (outs GR64:$dst), (ins u32imm:$src),
257                       "llihf\t{$dst, $src}",
258                       [(set GR64:$dst, i64hi32:$src)]>;
259}
260
261let canFoldAsLoad = 1, isReMaterializable = 1 in {
262def MOV32rm  : RXI<0x58,
263                   (outs GR32:$dst), (ins rriaddr12:$src),
264                   "l\t{$dst, $src}",
265                   [(set GR32:$dst, (load rriaddr12:$src))]>;
266def MOV32rmy : RXYI<0x58E3,
267                    (outs GR32:$dst), (ins rriaddr:$src),
268                    "ly\t{$dst, $src}",
269                    [(set GR32:$dst, (load rriaddr:$src))]>;
270def MOV64rm  : RXYI<0x04E3,
271                    (outs GR64:$dst), (ins rriaddr:$src),
272                    "lg\t{$dst, $src}",
273                    [(set GR64:$dst, (load rriaddr:$src))]>;
274def 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))]>;
279def 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))]>;
284def 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
291def MOV32mr  : RXI<0x50,
292                   (outs), (ins rriaddr12:$dst, GR32:$src),
293                   "st\t{$src, $dst}",
294                   [(store GR32:$src, rriaddr12:$dst)]>;
295def MOV32mry : RXYI<0x50E3,
296                    (outs), (ins rriaddr:$dst, GR32:$src),
297                    "sty\t{$src, $dst}",
298                    [(store GR32:$src, rriaddr:$dst)]>;
299def MOV64mr  : RXYI<0x24E3,
300                    (outs), (ins rriaddr:$dst, GR64:$src),
301                    "stg\t{$src, $dst}",
302                    [(store GR64:$src, rriaddr:$dst)]>;
303def 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)]>;
308def 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)]>;
313def 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
319def MOV8mi    : SII<0x92,
320                    (outs), (ins riaddr12:$dst, i32i8imm:$src),
321                    "mvi\t{$dst, $src}",
322                    [(truncstorei8 (i32 i32immSExt8:$src), riaddr12:$dst)]>;
323def MOV8miy   : SIYI<0x52EB,
324                     (outs), (ins riaddr:$dst, i32i8imm:$src),
325                     "mviy\t{$dst, $src}",
326                     [(truncstorei8 (i32 i32immSExt8:$src), riaddr:$dst)]>;
327
328let AddedComplexity = 2 in {
329def 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]>;
334def 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]>;
339def 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
347def MOVSX32rr8  : RREI<0xB926,
348                       (outs GR32:$dst), (ins GR32:$src),
349                       "lbr\t{$dst, $src}",
350                       [(set GR32:$dst, (sext_inreg GR32:$src, i8))]>;
351def MOVSX64rr8  : RREI<0xB906,
352                       (outs GR64:$dst), (ins GR64:$src),
353                       "lgbr\t{$dst, $src}",
354                       [(set GR64:$dst, (sext_inreg GR64:$src, i8))]>;
355def MOVSX32rr16 : RREI<0xB927,
356                       (outs GR32:$dst), (ins GR32:$src),
357                       "lhr\t{$dst, $src}",
358                       [(set GR32:$dst, (sext_inreg GR32:$src, i16))]>;
359def 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
365def MOVSX32rm8   : RXYI<0x76E3,
366                        (outs GR32:$dst), (ins rriaddr:$src),
367                        "lb\t{$dst, $src}",
368                        [(set GR32:$dst, (sextloadi32i8 rriaddr:$src))]>;
369def MOVSX32rm16  : RXI<0x48,
370                       (outs GR32:$dst), (ins rriaddr12:$src),
371                       "lh\t{$dst, $src}",
372                       [(set GR32:$dst, (sextloadi32i16 rriaddr12:$src))]>;
373def MOVSX32rm16y : RXYI<0x78E3,
374                        (outs GR32:$dst), (ins rriaddr:$src),
375                        "lhy\t{$dst, $src}",
376                        [(set GR32:$dst, (sextloadi32i16 rriaddr:$src))]>;
377def MOVSX64rm8   : RXYI<0x77E3,
378                        (outs GR64:$dst), (ins rriaddr:$src),
379                        "lgb\t{$dst, $src}",
380                        [(set GR64:$dst, (sextloadi64i8 rriaddr:$src))]>;
381def MOVSX64rm16  : RXYI<0x15E3,
382                        (outs GR64:$dst), (ins rriaddr:$src),
383                        "lgh\t{$dst, $src}",
384                        [(set GR64:$dst, (sextloadi64i16 rriaddr:$src))]>;
385def MOVSX64rm32  : RXYI<0x14E3,
386                        (outs GR64:$dst), (ins rriaddr:$src),
387                        "lgf\t{$dst, $src}",
388                        [(set GR64:$dst, (sextloadi64i32 rriaddr:$src))]>;
389
390def MOVZX32rm8  : RXYI<0x94E3,
391                       (outs GR32:$dst), (ins rriaddr:$src),
392                       "llc\t{$dst, $src}",
393                       [(set GR32:$dst, (zextloadi32i8 rriaddr:$src))]>;
394def MOVZX32rm16 : RXYI<0x95E3,
395                       (outs GR32:$dst), (ins rriaddr:$src),
396                       "llh\t{$dst, $src}",
397                       [(set GR32:$dst, (zextloadi32i16 rriaddr:$src))]>;
398def MOVZX64rm8  : RXYI<0x90E3,
399                       (outs GR64:$dst), (ins rriaddr:$src),
400                       "llgc\t{$dst, $src}",
401                       [(set GR64:$dst, (zextloadi64i8 rriaddr:$src))]>;
402def MOVZX64rm16 : RXYI<0x91E3,
403                       (outs GR64:$dst), (ins rriaddr:$src),
404                       "llgh\t{$dst, $src}",
405                       [(set GR64:$dst, (zextloadi64i16 rriaddr:$src))]>;
406def 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
412def MOV32m8r   : RXI<0x42,
413                     (outs), (ins rriaddr12:$dst, GR32:$src),
414                     "stc\t{$src, $dst}",
415                     [(truncstorei8 GR32:$src, rriaddr12:$dst)]>;
416
417def MOV32m8ry  : RXYI<0x72E3,
418                      (outs), (ins rriaddr:$dst, GR32:$src),
419                      "stcy\t{$src, $dst}",
420                      [(truncstorei8 GR32:$src, rriaddr:$dst)]>;
421
422def MOV32m16r  : RXI<0x40,
423                     (outs), (ins rriaddr12:$dst, GR32:$src),
424                     "sth\t{$src, $dst}",
425                     [(truncstorei16 GR32:$src, rriaddr12:$dst)]>;
426
427def MOV32m16ry : RXYI<0x70E3,
428                      (outs), (ins rriaddr:$dst, GR32:$src),
429                      "sthy\t{$src, $dst}",
430                      [(truncstorei16 GR32:$src, rriaddr:$dst)]>;
431
432def MOV64m8r   : RXI<0x42,
433                     (outs), (ins rriaddr12:$dst, GR64:$src),
434                     "stc\t{$src, $dst}",
435                     [(truncstorei8 GR64:$src, rriaddr12:$dst)]>;
436
437def MOV64m8ry  : RXYI<0x72E3,
438                      (outs), (ins rriaddr:$dst, GR64:$src),
439                      "stcy\t{$src, $dst}",
440                      [(truncstorei8 GR64:$src, rriaddr:$dst)]>;
441
442def MOV64m16r  : RXI<0x40,
443                     (outs), (ins rriaddr12:$dst, GR64:$src),
444                     "sth\t{$src, $dst}",
445                     [(truncstorei16 GR64:$src, rriaddr12:$dst)]>;
446
447def MOV64m16ry : RXYI<0x70E3,
448                      (outs), (ins rriaddr:$dst, GR64:$src),
449                      "sthy\t{$src, $dst}",
450                      [(truncstorei16 GR64:$src, rriaddr:$dst)]>;
451
452def MOV64m32r  : RXI<0x50,
453                     (outs), (ins rriaddr12:$dst, GR64:$src),
454                     "st\t{$src, $dst}",
455                     [(truncstorei32 GR64:$src, rriaddr12:$dst)]>;
456
457def 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?
464def MOV32mrm  : RSYI<0x90EB,
465                     (outs), (ins riaddr:$dst, GR32:$from, GR32:$to),
466                     "stmy\t{$from, $to, $dst}",
467                     []>;
468def MOV64mrm  : RSYI<0x24EB,
469                     (outs), (ins riaddr:$dst, GR64:$from, GR64:$to),
470                     "stmg\t{$from, $to, $dst}",
471                     []>;
472def MOV32rmm  : RSYI<0x90EB,
473                     (outs GR32:$from, GR32:$to), (ins riaddr:$dst),
474                     "lmy\t{$from, $to, $dst}",
475                     []>;
476def MOV64rmm  : RSYI<0x04EB,
477                     (outs GR64:$from, GR64:$to), (ins riaddr:$dst),
478                     "lmg\t{$from, $to, $dst}",
479                     []>;
480
481let isReMaterializable = 1, neverHasSideEffects = 1, isAsCheapAsAMove = 1,
482    Constraints = "$src = $dst" in {
483def MOV64Pr0_even : Pseudo<(outs GR64P:$dst), (ins GR64P:$src),
484                           "lhi\t${dst:subreg_even}, 0",
485                           []>;
486def MOV128r0_even : Pseudo<(outs GR128:$dst), (ins GR128:$src),
487                           "lghi\t${dst:subreg_even}, 0",
488                           []>;
489}
490
491// Byte swaps
492def BSWAP32rr : RREI<0xB91F,
493                     (outs GR32:$dst), (ins GR32:$src),
494                     "lrvr\t{$dst, $src}",
495                     [(set GR32:$dst, (bswap GR32:$src))]>;
496def 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)))]>;
505def BSWAP32rm : RXYI<0x1EE3, (outs GR32:$dst), (ins rriaddr:$src),
506                     "lrv\t{$dst, $src}",
507                     [(set GR32:$dst, (bswap (load rriaddr:$src)))]>;
508def 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)]>;
515def BSWAP32mr : RXYI<0xE33E, (outs), (ins rriaddr:$dst, GR32:$src),
516                     "strv\t{$src, $dst}",
517                     [(store (bswap GR32:$src), rriaddr:$dst)]>;
518def 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
525let Defs = [PSW] in {
526def 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)]>;
531def NEG64rr : RREI<0xB903, (outs GR64:$dst), (ins GR64:$src),
532                   "lcgr\t{$dst, $src}",
533                   [(set GR64:$dst, (ineg GR64:$src)),
534                    (implicit PSW)]>;
535def 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
541let Constraints = "$src1 = $dst" in {
542
543let Defs = [PSW] in {
544
545let isCommutable = 1 in { // X = ADD Y, Z  == X = ADD Z, Y
546def 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)]>;
550def 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
556def 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)]>;
560def 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)]>;
564def 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
570def 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)]>;
575def 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)]>;
580def 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)]>;
585def 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
591let isCommutable = 1 in { // X = ADC Y, Z  == X = ADC Z, Y
592def 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))]>;
595def 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
600def 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))]>;
604def 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
609let Uses = [PSW] in {
610def 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)]>;
614def 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
620let isCommutable = 1 in { // X = AND Y, Z  == X = AND Z, Y
621def 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))]>;
625def 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
631def 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)]>;
635def 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)]>;
639def 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
644def AND32rill16 : RII<0xA57,
645                      (outs GR32:$dst), (ins GR32:$src1, u16imm:$src2),
646                      "nill\t{$dst, $src2}",
647                      [(set GR32:$dst, (and GR32:$src1, i32ll16c:$src2))]>;
648def AND64rill16 : RII<0xA57,
649                      (outs GR64:$dst), (ins GR64:$src1, u16imm:$src2),
650                      "nill\t{$dst, $src2}",
651                      [(set GR64:$dst, (and GR64:$src1, i64ll16c:$src2))]>;
652
653def AND32rilh16 : RII<0xA56,
654                      (outs GR32:$dst), (ins GR32:$src1, u16imm:$src2),
655                      "nilh\t{$dst, $src2}",
656                      [(set GR32:$dst, (and GR32:$src1, i32lh16c:$src2))]>;
657def AND64rilh16 : RII<0xA56,
658                      (outs GR64:$dst), (ins GR64:$src1, u16imm:$src2),
659                      "nilh\t{$dst, $src2}",
660                      [(set GR64:$dst, (and GR64:$src1, i64lh16c:$src2))]>;
661
662def AND64rihl16 : RII<0xA55,
663                      (outs GR64:$dst), (ins GR64:$src1, u16imm:$src2),
664                      "nihl\t{$dst, $src2}",
665                      [(set GR64:$dst, (and GR64:$src1, i64hl16c:$src2))]>;
666def AND64rihh16 : RII<0xA54,
667                      (outs GR64:$dst), (ins GR64:$src1, u16imm:$src2),
668                      "nihh\t{$dst, $src2}",
669                      [(set GR64:$dst, (and GR64:$src1, i64hh16c:$src2))]>;
670
671def AND32ri     : RILI<0xC0B,
672                       (outs GR32:$dst), (ins GR32:$src1, u32imm:$src2),
673                       "nilf\t{$dst, $src2}",
674                       [(set GR32:$dst, (and GR32:$src1, imm:$src2))]>;
675def AND64rilo32 : RILI<0xC0B,
676                       (outs GR64:$dst), (ins GR64:$src1, u32imm:$src2),
677                       "nilf\t{$dst, $src2}",
678                       [(set GR64:$dst, (and GR64:$src1, i64lo32c:$src2))]>;
679def AND64rihi32 : RILI<0xC0A,
680                       (outs GR64:$dst), (ins GR64:$src1, u32imm:$src2),
681                       "nihf\t{$dst, $src2}",
682                       [(set GR64:$dst, (and GR64:$src1, i64hi32c:$src2))]>;
683
684let isCommutable = 1 in { // X = OR Y, Z  == X = OR Z, Y
685def 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))]>;
689def 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
695def 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)]>;
699def 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)]>;
703def 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!
709def OR32ri16  : RII<0xA5B,
710                    (outs GR32:$dst), (ins GR32:$src1, u32imm:$src2),
711                    "oill\t{$dst, $src2}",
712                    [(set GR32:$dst, (or GR32:$src1, i32ll16:$src2))]>;
713def OR32ri16h : RII<0xA5A,
714                    (outs GR32:$dst), (ins GR32:$src1, u32imm:$src2),
715                    "oilh\t{$dst, $src2}",
716                    [(set GR32:$dst, (or GR32:$src1, i32lh16:$src2))]>;
717def OR32ri : RILI<0xC0D,
718                  (outs GR32:$dst), (ins GR32:$src1, u32imm:$src2),
719                  "oilf\t{$dst, $src2}",
720                  [(set GR32:$dst, (or GR32:$src1, imm:$src2))]>;
721
722def OR64rill16 : RII<0xA5B,
723                     (outs GR64:$dst), (ins GR64:$src1, u16imm:$src2),
724                     "oill\t{$dst, $src2}",
725                     [(set GR64:$dst, (or GR64:$src1, i64ll16:$src2))]>;
726def OR64rilh16 : RII<0xA5A,
727                     (outs GR64:$dst), (ins GR64:$src1, u16imm:$src2),
728                     "oilh\t{$dst, $src2}",
729                     [(set GR64:$dst, (or GR64:$src1, i64lh16:$src2))]>;
730def OR64rihl16 : RII<0xA59,
731                     (outs GR64:$dst), (ins GR64:$src1, u16imm:$src2),
732                     "oihl\t{$dst, $src2}",
733                     [(set GR64:$dst, (or GR64:$src1, i64hl16:$src2))]>;
734def OR64rihh16 : RII<0xA58,
735                     (outs GR64:$dst), (ins GR64:$src1, u16imm:$src2),
736                     "oihh\t{$dst, $src2}",
737                     [(set GR64:$dst, (or GR64:$src1, i64hh16:$src2))]>;
738
739def OR64rilo32 : RILI<0xC0D,
740                      (outs GR64:$dst), (ins GR64:$src1, u32imm:$src2),
741                      "oilf\t{$dst, $src2}",
742                      [(set GR64:$dst, (or GR64:$src1, i64lo32:$src2))]>;
743def OR64rihi32 : RILI<0xC0C,
744                      (outs GR64:$dst), (ins GR64:$src1, u32imm:$src2),
745                      "oihf\t{$dst, $src2}",
746                      [(set GR64:$dst, (or GR64:$src1, i64hi32:$src2))]>;
747
748def 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))]>;
752def 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
757def 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)]>;
761def 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)]>;
765def 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
770def 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))]>;
774def 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
779def 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))]>;
783def 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
788let Uses = [PSW] in {
789def 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)]>;
793def 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
799let isCommutable = 1 in { // X = XOR Y, Z  == X = XOR Z, Y
800def 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))]>;
804def 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
810def 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)]>;
814def 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)]>;
818def 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
823def 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
830let isCommutable = 1 in { // X = MUL Y, Z == X = MUL Z, Y
831def 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))]>;
835def 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
841def MUL64rrP   : RRI<0x1C,
842                     (outs GR64P:$dst), (ins GR64P:$src1, GR32:$src2),
843                     "mr\t{$dst, $src2}",
844                     []>;
845def UMUL64rrP  : RREI<0xB996,
846                      (outs GR64P:$dst), (ins GR64P:$src1, GR32:$src2),
847                      "mlr\t{$dst, $src2}",
848                      []>;
849def UMUL128rrP : RREI<0xB986,
850                      (outs GR128:$dst), (ins GR128:$src1, GR64:$src2),
851                      "mlgr\t{$dst, $src2}",
852                      []>;
853
854def 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))]>;
858def 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
863let AddedComplexity = 2 in {
864def 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]>;
869def 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
876def 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)))]>;
880def 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)))]>;
884def 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
889def 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
894def SDIVREM32r : RREI<0xB91D,
895                      (outs GR128:$dst), (ins GR128:$src1, GR32:$src2),
896                      "dsgfr\t{$dst, $src2}",
897                      []>;
898def SDIVREM64r : RREI<0xB90D,
899                      (outs GR128:$dst), (ins GR128:$src1, GR64:$src2),
900                      "dsgr\t{$dst, $src2}",
901                      []>;
902
903def UDIVREM32r : RREI<0xB997,
904                      (outs GR64P:$dst), (ins GR64P:$src1, GR32:$src2),
905                      "dlr\t{$dst, $src2}",
906                      []>;
907def UDIVREM64r : RREI<0xB987,
908                      (outs GR128:$dst), (ins GR128:$src1, GR64:$src2),
909                      "dlgr\t{$dst, $src2}",
910                      []>;
911let mayLoad = 1 in {
912def SDIVREM32m : RXYI<0xE31D,
913                      (outs GR128:$dst), (ins GR128:$src1, rriaddr:$src2),
914                      "dsgf\t{$dst, $src2}",
915                      []>;
916def SDIVREM64m : RXYI<0xE30D,
917                      (outs GR128:$dst), (ins GR128:$src1, rriaddr:$src2),
918                      "dsg\t{$dst, $src2}",
919                      []>;
920
921def UDIVREM32m : RXYI<0xE397, (outs GR64P:$dst), (ins GR64P:$src1, rriaddr:$src2),
922                      "dl\t{$dst, $src2}",
923                      []>;
924def 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
933let Constraints = "$src = $dst" in
934def 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))]>;
938def 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
943let Constraints = "$src = $dst" in
944def 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))]>;
948def 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
953let Defs = [PSW] in {
954let Constraints = "$src = $dst" in
955def 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
961def 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
968def 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))]>;
972def 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
981let Defs = [PSW] in {
982def CMP32rr : RRI<0x19,
983                  (outs), (ins GR32:$src1, GR32:$src2),
984                  "cr\t$src1, $src2",
985                  [(set PSW, (SystemZcmp GR32:$src1, GR32:$src2))]>;
986def CMP64rr : RREI<0xB920,
987                   (outs), (ins GR64:$src1, GR64:$src2),
988                   "cgr\t$src1, $src2",
989                   [(set PSW, (SystemZcmp GR64:$src1, GR64:$src2))]>;
990
991def CMP32ri   : RILI<0xC2D,
992                     (outs), (ins GR32:$src1, s32imm:$src2),
993                     "cfi\t$src1, $src2",
994                     [(set PSW, (SystemZcmp GR32:$src1, imm:$src2))]>;
995def CMP64ri32 : RILI<0xC2C,
996                     (outs), (ins GR64:$src1, s32imm64:$src2),
997                     "cgfi\t$src1, $src2",
998                     [(set PSW, (SystemZcmp GR64:$src1, i64immSExt32:$src2))]>;
999
1000def CMP32rm : RXI<0x59,
1001                  (outs), (ins GR32:$src1, rriaddr12:$src2),
1002                  "c\t$src1, $src2",
1003                  [(set PSW, (SystemZcmp GR32:$src1, (load rriaddr12:$src2)))]>;
1004def CMP32rmy : RXYI<0xE359,
1005                    (outs), (ins GR32:$src1, rriaddr:$src2),
1006                    "cy\t$src1, $src2",
1007                    [(set PSW, (SystemZcmp GR32:$src1, (load rriaddr:$src2)))]>;
1008def 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
1013def UCMP32rr : RRI<0x15,
1014                   (outs), (ins GR32:$src1, GR32:$src2),
1015                   "clr\t$src1, $src2",
1016                   [(set PSW, (SystemZucmp GR32:$src1, GR32:$src2))]>;
1017def UCMP64rr : RREI<0xB921,
1018                    (outs), (ins GR64:$src1, GR64:$src2),
1019                    "clgr\t$src1, $src2",
1020                    [(set PSW, (SystemZucmp GR64:$src1, GR64:$src2))]>;
1021
1022def UCMP32ri   : RILI<0xC2F,
1023                      (outs), (ins GR32:$src1, i32imm:$src2),
1024                      "clfi\t$src1, $src2",
1025                      [(set PSW, (SystemZucmp GR32:$src1, imm:$src2))]>;
1026def UCMP64ri32 : RILI<0xC2E,
1027                      (outs), (ins GR64:$src1, i64i32imm:$src2),
1028                      "clgfi\t$src1, $src2",
1029                      [(set PSW,(SystemZucmp GR64:$src1, i64immZExt32:$src2))]>;
1030
1031def 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)))]>;
1036def 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)))]>;
1041def 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
1047def 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)))]>;
1052def 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
1058def 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)))]>;
1063def 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
1075let Defs = [PSW] in {
1076def 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
1087def : Pat<(SystemZpcrelwrapper tjumptable:$src), (LA64rm tjumptable:$src)>;
1088def : Pat<(SystemZpcrelwrapper tconstpool:$src), (LA64rm tconstpool:$src)>;
1089
1090// anyext
1091def : Pat<(i64 (anyext GR32:$src)),
1092          (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, subreg_32bit)>;
1093
1094// calls
1095def : Pat<(SystemZcall (i64 tglobaladdr:$dst)), (CALLi tglobaladdr:$dst)>;
1096def : 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.
1105def : Pat<(i32 imm:$src),
1106          (EXTRACT_SUBREG (MOV64ri32 (GetI64FromI32 (i32 imm:$src))),
1107             subreg_32bit)>;
1108
1109// Implement in terms of LLIHF/OILF.
1110def : Pat<(i64 imm:$imm),
1111          (OR64rilo32 (MOV64rihi32 (HI32 imm:$imm)), (LO32 imm:$imm))>;
1112
1113// trunc patterns
1114def : Pat<(i32 (trunc GR64:$src)),
1115          (EXTRACT_SUBREG GR64:$src, subreg_32bit)>;
1116
1117// sext_inreg patterns
1118def : Pat<(sext_inreg GR64:$src, i32),
1119          (MOVSX64rr32 (EXTRACT_SUBREG GR64:$src, subreg_32bit))>;
1120
1121// extload patterns
1122def : Pat<(extloadi32i8  rriaddr:$src), (MOVZX32rm8  rriaddr:$src)>;
1123def : Pat<(extloadi32i16 rriaddr:$src), (MOVZX32rm16 rriaddr:$src)>;
1124def : Pat<(extloadi64i8  rriaddr:$src), (MOVZX64rm8  rriaddr:$src)>;
1125def : Pat<(extloadi64i16 rriaddr:$src), (MOVZX64rm16 rriaddr:$src)>;
1126def : Pat<(extloadi64i32 rriaddr:$src), (MOVZX64rm32 rriaddr:$src)>;
1127
1128// muls
1129def : 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
1135def : 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)>;
1140def : 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
1146def : Pat<(ctlz GR64:$src),
1147          (EXTRACT_SUBREG (FLOGR64 GR64:$src), subreg_even)>;
1148