SystemZInstrInfo.td revision a591ff53d91acb1232ed8500c646ce2af8a891e8
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, SDNPOptInFlag]>;
50def SystemZcall    : SDNode<"SystemZISD::CALL", SDT_SystemZCall,
51                     [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag, SDNPVariadic]>;
52def SystemZcallseq_start :
53                 SDNode<"ISD::CALLSEQ_START", SDT_SystemZCallSeqStart,
54                        [SDNPHasChain, SDNPOutFlag]>;
55def SystemZcallseq_end :
56                 SDNode<"ISD::CALLSEQ_END",   SDT_SystemZCallSeqEnd,
57                        [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
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 i64imm:$src),
233                      "llill\t{$dst, $src}",
234                      [(set GR64:$dst, i64ll16:$src)]>;
235def MOV64rilh16 : RII<0xEA5,
236                      (outs GR64:$dst), (ins i64imm:$src),
237                      "llilh\t{$dst, $src}",
238                      [(set GR64:$dst, i64lh16:$src)]>;
239def MOV64rihl16 : RII<0xDA5,
240                      (outs GR64:$dst), (ins i64imm:$src),
241                      "llihl\t{$dst, $src}",
242                      [(set GR64:$dst, i64hl16:$src)]>;
243def MOV64rihh16 : RII<0xCA5,
244                      (outs GR64:$dst), (ins i64imm:$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 i64imm:$src),
254                       "llilf\t{$dst, $src}",
255                       [(set GR64:$dst, i64lo32:$src)]>;
256def MOV64rihi32 : RILI<0xEC0, (outs GR64:$dst), (ins i64imm:$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, isAsCheapAsAMove = 1, isTwoAddress = 1 in {
482def MOV64Pr0_even : Pseudo<(outs GR64P:$dst), (ins GR64P:$src),
483                           "lhi\t${dst:subreg_even}, 0",
484                           []>;
485def MOV128r0_even : Pseudo<(outs GR128:$dst), (ins GR128:$src),
486                           "lghi\t${dst:subreg_even}, 0",
487                           []>;
488}
489
490// Byte swaps
491def BSWAP32rr : RREI<0xB91F,
492                     (outs GR32:$dst), (ins GR32:$src),
493                     "lrvr\t{$dst, $src}",
494                     [(set GR32:$dst, (bswap GR32:$src))]>;
495def BSWAP64rr : RREI<0xB90F,
496                     (outs GR64:$dst), (ins GR64:$src),
497                     "lrvgr\t{$dst, $src}",
498                     [(set GR64:$dst, (bswap GR64:$src))]>;
499
500// FIXME: this is invalid pattern for big-endian
501//def BSWAP16rm : RXYI<0x1FE3, (outs GR32:$dst), (ins rriaddr:$src),
502//                     "lrvh\t{$dst, $src}",
503//                     [(set GR32:$dst, (bswap (extloadi32i16 rriaddr:$src)))]>;
504def BSWAP32rm : RXYI<0x1EE3, (outs GR32:$dst), (ins rriaddr:$src),
505                     "lrv\t{$dst, $src}",
506                     [(set GR32:$dst, (bswap (load rriaddr:$src)))]>;
507def BSWAP64rm : RXYI<0x0FE3, (outs GR64:$dst), (ins rriaddr:$src),
508                     "lrvg\t{$dst, $src}",
509                     [(set GR64:$dst, (bswap (load rriaddr:$src)))]>;
510
511//def BSWAP16mr : RXYI<0xE33F, (outs), (ins rriaddr:$dst, GR32:$src),
512//                     "strvh\t{$src, $dst}",
513//                     [(truncstorei16 (bswap GR32:$src), rriaddr:$dst)]>;
514def BSWAP32mr : RXYI<0xE33E, (outs), (ins rriaddr:$dst, GR32:$src),
515                     "strv\t{$src, $dst}",
516                     [(store (bswap GR32:$src), rriaddr:$dst)]>;
517def BSWAP64mr : RXYI<0xE32F, (outs), (ins rriaddr:$dst, GR64:$src),
518                     "strvg\t{$src, $dst}",
519                     [(store (bswap GR64:$src), rriaddr:$dst)]>;
520
521//===----------------------------------------------------------------------===//
522// Arithmetic Instructions
523
524let Defs = [PSW] in {
525def NEG32rr : RRI<0x13,
526                  (outs GR32:$dst), (ins GR32:$src),
527                  "lcr\t{$dst, $src}",
528                  [(set GR32:$dst, (ineg GR32:$src)),
529                   (implicit PSW)]>;
530def NEG64rr : RREI<0xB903, (outs GR64:$dst), (ins GR64:$src),
531                   "lcgr\t{$dst, $src}",
532                   [(set GR64:$dst, (ineg GR64:$src)),
533                    (implicit PSW)]>;
534def NEG64rr32 : RREI<0xB913, (outs GR64:$dst), (ins GR32:$src),
535                     "lcgfr\t{$dst, $src}",
536                     [(set GR64:$dst, (ineg (sext GR32:$src))),
537                      (implicit PSW)]>;
538}
539
540let isTwoAddress = 1 in {
541
542let Defs = [PSW] in {
543
544let isCommutable = 1 in { // X = ADD Y, Z  == X = ADD Z, Y
545def ADD32rr : RRI<0x1A, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
546                  "ar\t{$dst, $src2}",
547                  [(set GR32:$dst, (add GR32:$src1, GR32:$src2)),
548                   (implicit PSW)]>;
549def ADD64rr : RREI<0xB908, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
550                   "agr\t{$dst, $src2}",
551                   [(set GR64:$dst, (add GR64:$src1, GR64:$src2)),
552                    (implicit PSW)]>;
553}
554
555def ADD32rm   : RXI<0x5A, (outs GR32:$dst), (ins GR32:$src1, rriaddr12:$src2),
556                    "a\t{$dst, $src2}",
557                    [(set GR32:$dst, (add GR32:$src1, (load rriaddr12:$src2))),
558                     (implicit PSW)]>;
559def ADD32rmy  : RXYI<0xE35A, (outs GR32:$dst), (ins GR32:$src1, rriaddr:$src2),
560                     "ay\t{$dst, $src2}",
561                     [(set GR32:$dst, (add GR32:$src1, (load rriaddr:$src2))),
562                      (implicit PSW)]>;
563def ADD64rm   : RXYI<0xE308, (outs GR64:$dst), (ins GR64:$src1, rriaddr:$src2),
564                     "ag\t{$dst, $src2}",
565                     [(set GR64:$dst, (add GR64:$src1, (load rriaddr:$src2))),
566                      (implicit PSW)]>;
567
568
569def ADD32ri16 : RII<0xA7A,
570                    (outs GR32:$dst), (ins GR32:$src1, s16imm:$src2),
571                    "ahi\t{$dst, $src2}",
572                    [(set GR32:$dst, (add GR32:$src1, immSExt16:$src2)),
573                     (implicit PSW)]>;
574def ADD32ri   : RILI<0xC29,
575                     (outs GR32:$dst), (ins GR32:$src1, s32imm:$src2),
576                     "afi\t{$dst, $src2}",
577                     [(set GR32:$dst, (add GR32:$src1, imm:$src2)),
578                      (implicit PSW)]>;
579def ADD64ri16 : RILI<0xA7B,
580                     (outs GR64:$dst), (ins GR64:$src1, s16imm64:$src2),
581                     "aghi\t{$dst, $src2}",
582                     [(set GR64:$dst, (add GR64:$src1, immSExt16:$src2)),
583                      (implicit PSW)]>;
584def ADD64ri32 : RILI<0xC28,
585                     (outs GR64:$dst), (ins GR64:$src1, s32imm64:$src2),
586                     "agfi\t{$dst, $src2}",
587                     [(set GR64:$dst, (add GR64:$src1, immSExt32:$src2)),
588                      (implicit PSW)]>;
589
590let isCommutable = 1 in { // X = ADC Y, Z  == X = ADC Z, Y
591def ADC32rr : RRI<0x1E, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
592                  "alr\t{$dst, $src2}",
593                  [(set GR32:$dst, (addc GR32:$src1, GR32:$src2))]>;
594def ADC64rr : RREI<0xB90A, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
595                   "algr\t{$dst, $src2}",
596                   [(set GR64:$dst, (addc GR64:$src1, GR64:$src2))]>;
597}
598
599def ADC32ri   : RILI<0xC2B,
600                     (outs GR32:$dst), (ins GR32:$src1, s32imm:$src2),
601                     "alfi\t{$dst, $src2}",
602                     [(set GR32:$dst, (addc GR32:$src1, imm:$src2))]>;
603def ADC64ri32 : RILI<0xC2A,
604                     (outs GR64:$dst), (ins GR64:$src1, s32imm64:$src2),
605                     "algfi\t{$dst, $src2}",
606                     [(set GR64:$dst, (addc GR64:$src1, immSExt32:$src2))]>;
607
608let Uses = [PSW] in {
609def ADDE32rr : RREI<0xB998, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
610                    "alcr\t{$dst, $src2}",
611                    [(set GR32:$dst, (adde GR32:$src1, GR32:$src2)),
612                     (implicit PSW)]>;
613def ADDE64rr : RREI<0xB988, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
614                    "alcgr\t{$dst, $src2}",
615                    [(set GR64:$dst, (adde GR64:$src1, GR64:$src2)),
616                     (implicit PSW)]>;
617}
618
619let isCommutable = 1 in { // X = AND Y, Z  == X = AND Z, Y
620def AND32rr : RRI<0x14,
621                  (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
622                  "nr\t{$dst, $src2}",
623                  [(set GR32:$dst, (and GR32:$src1, GR32:$src2))]>;
624def AND64rr : RREI<0xB980,
625                   (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
626                   "ngr\t{$dst, $src2}",
627                   [(set GR64:$dst, (and GR64:$src1, GR64:$src2))]>;
628}
629
630def AND32rm   : RXI<0x54, (outs GR32:$dst), (ins GR32:$src1, rriaddr12:$src2),
631                    "n\t{$dst, $src2}",
632                    [(set GR32:$dst, (and GR32:$src1, (load rriaddr12:$src2))),
633                     (implicit PSW)]>;
634def AND32rmy  : RXYI<0xE354, (outs GR32:$dst), (ins GR32:$src1, rriaddr:$src2),
635                     "ny\t{$dst, $src2}",
636                     [(set GR32:$dst, (and GR32:$src1, (load rriaddr:$src2))),
637                      (implicit PSW)]>;
638def AND64rm   : RXYI<0xE360, (outs GR64:$dst), (ins GR64:$src1, rriaddr:$src2),
639                     "ng\t{$dst, $src2}",
640                     [(set GR64:$dst, (and GR64:$src1, (load rriaddr:$src2))),
641                      (implicit PSW)]>;
642
643def AND32rill16 : RII<0xA57,
644                      (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
645                      "nill\t{$dst, $src2}",
646                      [(set GR32:$dst, (and GR32:$src1, i32ll16c:$src2))]>;
647def AND64rill16 : RII<0xA57,
648                      (outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
649                      "nill\t{$dst, $src2}",
650                      [(set GR64:$dst, (and GR64:$src1, i64ll16c:$src2))]>;
651
652def AND32rilh16 : RII<0xA56,
653                      (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
654                      "nilh\t{$dst, $src2}",
655                      [(set GR32:$dst, (and GR32:$src1, i32lh16c:$src2))]>;
656def AND64rilh16 : RII<0xA56,
657                      (outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
658                      "nilh\t{$dst, $src2}",
659                      [(set GR64:$dst, (and GR64:$src1, i64lh16c:$src2))]>;
660
661def AND64rihl16 : RII<0xA55,
662                      (outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
663                      "nihl\t{$dst, $src2}",
664                      [(set GR64:$dst, (and GR64:$src1, i64hl16c:$src2))]>;
665def AND64rihh16 : RII<0xA54,
666                      (outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
667                      "nihh\t{$dst, $src2}",
668                      [(set GR64:$dst, (and GR64:$src1, i64hh16c:$src2))]>;
669
670def AND32ri     : RILI<0xC0B,
671                       (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
672                       "nilf\t{$dst, $src2}",
673                       [(set GR32:$dst, (and GR32:$src1, imm:$src2))]>;
674def AND64rilo32 : RILI<0xC0B,
675                       (outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
676                       "nilf\t{$dst, $src2}",
677                       [(set GR64:$dst, (and GR64:$src1, i64lo32c:$src2))]>;
678def AND64rihi32 : RILI<0xC0A,
679                       (outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
680                       "nihf\t{$dst, $src2}",
681                       [(set GR64:$dst, (and GR64:$src1, i64hi32c:$src2))]>;
682
683let isCommutable = 1 in { // X = OR Y, Z  == X = OR Z, Y
684def OR32rr : RRI<0x16,
685                 (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
686                 "or\t{$dst, $src2}",
687                 [(set GR32:$dst, (or GR32:$src1, GR32:$src2))]>;
688def OR64rr : RREI<0xB981,
689                  (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
690                  "ogr\t{$dst, $src2}",
691                  [(set GR64:$dst, (or GR64:$src1, GR64:$src2))]>;
692}
693
694def OR32rm   : RXI<0x56, (outs GR32:$dst), (ins GR32:$src1, rriaddr12:$src2),
695                   "o\t{$dst, $src2}",
696                   [(set GR32:$dst, (or GR32:$src1, (load rriaddr12:$src2))),
697                    (implicit PSW)]>;
698def OR32rmy  : RXYI<0xE356, (outs GR32:$dst), (ins GR32:$src1, rriaddr:$src2),
699                    "oy\t{$dst, $src2}",
700                    [(set GR32:$dst, (or GR32:$src1, (load rriaddr:$src2))),
701                     (implicit PSW)]>;
702def OR64rm   : RXYI<0xE381, (outs GR64:$dst), (ins GR64:$src1, rriaddr:$src2),
703                    "og\t{$dst, $src2}",
704                    [(set GR64:$dst, (or GR64:$src1, (load rriaddr:$src2))),
705                     (implicit PSW)]>;
706
707 // FIXME: Provide proper encoding!
708def OR32ri16  : RII<0xA5B,
709                    (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
710                    "oill\t{$dst, $src2}",
711                    [(set GR32:$dst, (or GR32:$src1, i32ll16:$src2))]>;
712def OR32ri16h : RII<0xA5A,
713                    (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
714                    "oilh\t{$dst, $src2}",
715                    [(set GR32:$dst, (or GR32:$src1, i32lh16:$src2))]>;
716def OR32ri : RILI<0xC0D,
717                  (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
718                  "oilf\t{$dst, $src2}",
719                  [(set GR32:$dst, (or GR32:$src1, imm:$src2))]>;
720
721def OR64rill16 : RII<0xA5B,
722                     (outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
723                     "oill\t{$dst, $src2}",
724                     [(set GR64:$dst, (or GR64:$src1, i64ll16:$src2))]>;
725def OR64rilh16 : RII<0xA5A,
726                     (outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
727                     "oilh\t{$dst, $src2}",
728                     [(set GR64:$dst, (or GR64:$src1, i64lh16:$src2))]>;
729def OR64rihl16 : RII<0xA59,
730                     (outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
731                     "oihl\t{$dst, $src2}",
732                     [(set GR64:$dst, (or GR64:$src1, i64hl16:$src2))]>;
733def OR64rihh16 : RII<0xA58,
734                     (outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
735                     "oihh\t{$dst, $src2}",
736                     [(set GR64:$dst, (or GR64:$src1, i64hh16:$src2))]>;
737
738def OR64rilo32 : RILI<0xC0D,
739                      (outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
740                      "oilf\t{$dst, $src2}",
741                      [(set GR64:$dst, (or GR64:$src1, i64lo32:$src2))]>;
742def OR64rihi32 : RILI<0xC0C,
743                      (outs GR64:$dst), (ins GR64:$src1, i64imm:$src2),
744                      "oihf\t{$dst, $src2}",
745                      [(set GR64:$dst, (or GR64:$src1, i64hi32:$src2))]>;
746
747def SUB32rr : RRI<0x1B,
748                  (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
749                  "sr\t{$dst, $src2}",
750                  [(set GR32:$dst, (sub GR32:$src1, GR32:$src2))]>;
751def SUB64rr : RREI<0xB909,
752                   (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
753                   "sgr\t{$dst, $src2}",
754                   [(set GR64:$dst, (sub GR64:$src1, GR64:$src2))]>;
755
756def SUB32rm   : RXI<0x5B, (outs GR32:$dst), (ins GR32:$src1, rriaddr12:$src2),
757                    "s\t{$dst, $src2}",
758                    [(set GR32:$dst, (sub GR32:$src1, (load rriaddr12:$src2))),
759                     (implicit PSW)]>;
760def SUB32rmy  : RXYI<0xE35B, (outs GR32:$dst), (ins GR32:$src1, rriaddr:$src2),
761                     "sy\t{$dst, $src2}",
762                     [(set GR32:$dst, (sub GR32:$src1, (load rriaddr:$src2))),
763                      (implicit PSW)]>;
764def SUB64rm   : RXYI<0xE309, (outs GR64:$dst), (ins GR64:$src1, rriaddr:$src2),
765                     "sg\t{$dst, $src2}",
766                     [(set GR64:$dst, (sub GR64:$src1, (load rriaddr:$src2))),
767                      (implicit PSW)]>;
768 
769def SBC32rr : RRI<0x1F,
770                  (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
771                  "slr\t{$dst, $src2}",
772                  [(set GR32:$dst, (subc GR32:$src1, GR32:$src2))]>;
773def SBC64rr : RREI<0xB90B,
774                   (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
775                   "slgr\t{$dst, $src2}",
776                   [(set GR64:$dst, (subc GR64:$src1, GR64:$src2))]>;
777
778def SBC32ri   : RILI<0xC25,
779                     (outs GR32:$dst), (ins GR32:$src1, s32imm:$src2),
780                     "sllfi\t{$dst, $src2}",
781                     [(set GR32:$dst, (subc GR32:$src1, imm:$src2))]>;
782def SBC64ri32 : RILI<0xC24,
783                     (outs GR64:$dst), (ins GR64:$src1, s32imm64:$src2),
784                     "slgfi\t{$dst, $src2}",
785                     [(set GR64:$dst, (subc GR64:$src1, immSExt32:$src2))]>;
786
787let Uses = [PSW] in {
788def SUBE32rr : RREI<0xB999, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
789                    "slbr\t{$dst, $src2}",
790                    [(set GR32:$dst, (sube GR32:$src1, GR32:$src2)),
791                     (implicit PSW)]>;
792def SUBE64rr : RREI<0xB989, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
793                    "slbgr\t{$dst, $src2}",
794                    [(set GR64:$dst, (sube GR64:$src1, GR64:$src2)),
795                     (implicit PSW)]>;
796}
797
798let isCommutable = 1 in { // X = XOR Y, Z  == X = XOR Z, Y
799def XOR32rr : RRI<0x17,
800                  (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
801                  "xr\t{$dst, $src2}",
802                  [(set GR32:$dst, (xor GR32:$src1, GR32:$src2))]>;
803def XOR64rr : RREI<0xB982,
804                   (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
805                   "xgr\t{$dst, $src2}",
806                   [(set GR64:$dst, (xor GR64:$src1, GR64:$src2))]>;
807}
808
809def XOR32rm   : RXI<0x57,(outs GR32:$dst), (ins GR32:$src1, rriaddr12:$src2),
810                    "x\t{$dst, $src2}",
811                    [(set GR32:$dst, (xor GR32:$src1, (load rriaddr12:$src2))),
812                     (implicit PSW)]>;
813def XOR32rmy  : RXYI<0xE357, (outs GR32:$dst), (ins GR32:$src1, rriaddr:$src2),
814                     "xy\t{$dst, $src2}",
815                     [(set GR32:$dst, (xor GR32:$src1, (load rriaddr:$src2))),
816                      (implicit PSW)]>;
817def XOR64rm   : RXYI<0xE382, (outs GR64:$dst), (ins GR64:$src1, rriaddr:$src2),
818                     "xg\t{$dst, $src2}",
819                     [(set GR64:$dst, (xor GR64:$src1, (load rriaddr:$src2))),
820                      (implicit PSW)]>;
821
822def XOR32ri : RILI<0xC07,
823                   (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
824                   "xilf\t{$dst, $src2}",
825                   [(set GR32:$dst, (xor GR32:$src1, imm:$src2))]>;
826
827} // Defs = [PSW]
828
829let isCommutable = 1 in { // X = MUL Y, Z == X = MUL Z, Y
830def MUL32rr : RREI<0xB252,
831                   (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
832                   "msr\t{$dst, $src2}",
833                   [(set GR32:$dst, (mul GR32:$src1, GR32:$src2))]>;
834def MUL64rr : RREI<0xB90C,
835                   (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
836                   "msgr\t{$dst, $src2}",
837                   [(set GR64:$dst, (mul GR64:$src1, GR64:$src2))]>;
838}
839
840def MUL64rrP   : RRI<0x1C,
841                     (outs GR64P:$dst), (ins GR64P:$src1, GR32:$src2),
842                     "mr\t{$dst, $src2}",
843                     []>;
844def UMUL64rrP  : RREI<0xB996,
845                      (outs GR64P:$dst), (ins GR64P:$src1, GR32:$src2),
846                      "mlr\t{$dst, $src2}",
847                      []>;
848def UMUL128rrP : RREI<0xB986,
849                      (outs GR128:$dst), (ins GR128:$src1, GR64:$src2),
850                      "mlgr\t{$dst, $src2}",
851                      []>;
852
853def MUL32ri16   : RII<0xA7C,
854                      (outs GR32:$dst), (ins GR32:$src1, s16imm:$src2),
855                      "mhi\t{$dst, $src2}",
856                      [(set GR32:$dst, (mul GR32:$src1, i32immSExt16:$src2))]>;
857def MUL64ri16   : RII<0xA7D,
858                      (outs GR64:$dst), (ins GR64:$src1, s16imm64:$src2),
859                      "mghi\t{$dst, $src2}",
860                      [(set GR64:$dst, (mul GR64:$src1, immSExt16:$src2))]>;
861
862let AddedComplexity = 2 in {
863def MUL32ri     : RILI<0xC21,
864                       (outs GR32:$dst), (ins GR32:$src1, s32imm:$src2),
865                       "msfi\t{$dst, $src2}",
866                       [(set GR32:$dst, (mul GR32:$src1, imm:$src2))]>,
867                       Requires<[IsZ10]>;
868def MUL64ri32   : RILI<0xC20,
869                       (outs GR64:$dst), (ins GR64:$src1, s32imm64:$src2),
870                       "msgfi\t{$dst, $src2}",
871                       [(set GR64:$dst, (mul GR64:$src1, i64immSExt32:$src2))]>,
872                       Requires<[IsZ10]>;
873}
874
875def MUL32rm : RXI<0x71,
876                  (outs GR32:$dst), (ins GR32:$src1, rriaddr12:$src2),
877                  "ms\t{$dst, $src2}",
878                  [(set GR32:$dst, (mul GR32:$src1, (load rriaddr12:$src2)))]>;
879def MUL32rmy : RXYI<0xE351,
880                    (outs GR32:$dst), (ins GR32:$src1, rriaddr:$src2),
881                    "msy\t{$dst, $src2}",
882                    [(set GR32:$dst, (mul GR32:$src1, (load rriaddr:$src2)))]>;
883def MUL64rm  : RXYI<0xE30C,
884                    (outs GR64:$dst), (ins GR64:$src1, rriaddr:$src2),
885                    "msg\t{$dst, $src2}",
886                    [(set GR64:$dst, (mul GR64:$src1, (load rriaddr:$src2)))]>;
887
888def MULSX64rr32 : RREI<0xB91C,
889                       (outs GR64:$dst), (ins GR64:$src1, GR32:$src2),
890                       "msgfr\t{$dst, $src2}",
891                       [(set GR64:$dst, (mul GR64:$src1, (sext GR32:$src2)))]>;
892
893def SDIVREM32r : RREI<0xB91D,
894                      (outs GR128:$dst), (ins GR128:$src1, GR32:$src2),
895                      "dsgfr\t{$dst, $src2}",
896                      []>;
897def SDIVREM64r : RREI<0xB90D,
898                      (outs GR128:$dst), (ins GR128:$src1, GR64:$src2),
899                      "dsgr\t{$dst, $src2}",
900                      []>;
901
902def UDIVREM32r : RREI<0xB997,
903                      (outs GR64P:$dst), (ins GR64P:$src1, GR32:$src2),
904                      "dlr\t{$dst, $src2}",
905                      []>;
906def UDIVREM64r : RREI<0xB987,
907                      (outs GR128:$dst), (ins GR128:$src1, GR64:$src2),
908                      "dlgr\t{$dst, $src2}",
909                      []>;
910let mayLoad = 1 in {
911def SDIVREM32m : RXYI<0xE31D,
912                      (outs GR128:$dst), (ins GR128:$src1, rriaddr:$src2),
913                      "dsgf\t{$dst, $src2}",
914                      []>;
915def SDIVREM64m : RXYI<0xE30D,
916                      (outs GR128:$dst), (ins GR128:$src1, rriaddr:$src2),
917                      "dsg\t{$dst, $src2}",
918                      []>;
919
920def UDIVREM32m : RXYI<0xE397, (outs GR64P:$dst), (ins GR64P:$src1, rriaddr:$src2),
921                      "dl\t{$dst, $src2}",
922                      []>;
923def UDIVREM64m : RXYI<0xE387, (outs GR128:$dst), (ins GR128:$src1, rriaddr:$src2),
924                      "dlg\t{$dst, $src2}",
925                      []>;
926} // mayLoad
927} // isTwoAddress = 1
928
929//===----------------------------------------------------------------------===//
930// Shifts
931
932let isTwoAddress = 1 in
933def SRL32rri : RSI<0x88,
934                   (outs GR32:$dst), (ins GR32:$src, riaddr32:$amt),
935                   "srl\t{$src, $amt}",
936                   [(set GR32:$dst, (srl GR32:$src, riaddr32:$amt))]>;
937def SRL64rri : RSYI<0xEB0C,
938                    (outs GR64:$dst), (ins GR64:$src, riaddr:$amt),
939                    "srlg\t{$dst, $src, $amt}",
940                    [(set GR64:$dst, (srl GR64:$src, riaddr:$amt))]>;
941
942let isTwoAddress = 1 in
943def SHL32rri : RSI<0x89,
944                   (outs GR32:$dst), (ins GR32:$src, riaddr32:$amt),
945                   "sll\t{$src, $amt}",
946                   [(set GR32:$dst, (shl GR32:$src, riaddr32:$amt))]>;
947def SHL64rri : RSYI<0xEB0D,
948                    (outs GR64:$dst), (ins GR64:$src, riaddr:$amt),
949                    "sllg\t{$dst, $src, $amt}",
950                    [(set GR64:$dst, (shl GR64:$src, riaddr:$amt))]>;
951
952let Defs = [PSW] in {
953let isTwoAddress = 1 in
954def SRA32rri : RSI<0x8A,
955                   (outs GR32:$dst), (ins GR32:$src, riaddr32:$amt),
956                   "sra\t{$src, $amt}",
957                   [(set GR32:$dst, (sra GR32:$src, riaddr32:$amt)),
958                    (implicit PSW)]>;
959
960def SRA64rri : RSYI<0xEB0A,
961                    (outs GR64:$dst), (ins GR64:$src, riaddr:$amt),
962                    "srag\t{$dst, $src, $amt}",
963                    [(set GR64:$dst, (sra GR64:$src, riaddr:$amt)),
964                     (implicit PSW)]>;
965} // Defs = [PSW]
966
967def ROTL32rri : RSYI<0xEB1D,
968                     (outs GR32:$dst), (ins GR32:$src, riaddr32:$amt),
969                     "rll\t{$dst, $src, $amt}",
970                     [(set GR32:$dst, (rotl GR32:$src, riaddr32:$amt))]>;
971def ROTL64rri : RSYI<0xEB1C,
972                     (outs GR64:$dst), (ins GR64:$src, riaddr:$amt),
973                     "rllg\t{$dst, $src, $amt}",
974                     [(set GR64:$dst, (rotl GR64:$src, riaddr:$amt))]>;
975
976//===----------------------------------------------------------------------===//
977// Test instructions (like AND but do not produce any result)
978
979// Integer comparisons
980let Defs = [PSW] in {
981def CMP32rr : RRI<0x19,
982                  (outs), (ins GR32:$src1, GR32:$src2),
983                  "cr\t$src1, $src2",
984                  [(set PSW, (SystemZcmp GR32:$src1, GR32:$src2))]>; 
985def CMP64rr : RREI<0xB920,
986                   (outs), (ins GR64:$src1, GR64:$src2),
987                   "cgr\t$src1, $src2",
988                   [(set PSW, (SystemZcmp GR64:$src1, GR64:$src2))]>;
989
990def CMP32ri   : RILI<0xC2D,
991                     (outs), (ins GR32:$src1, s32imm:$src2),
992                     "cfi\t$src1, $src2",
993                     [(set PSW, (SystemZcmp GR32:$src1, imm:$src2))]>;
994def CMP64ri32 : RILI<0xC2C,
995                     (outs), (ins GR64:$src1, s32imm64:$src2),
996                     "cgfi\t$src1, $src2",
997                     [(set PSW, (SystemZcmp GR64:$src1, i64immSExt32:$src2))]>;
998
999def CMP32rm : RXI<0x59,
1000                  (outs), (ins GR32:$src1, rriaddr12:$src2),
1001                  "c\t$src1, $src2",
1002                  [(set PSW, (SystemZcmp GR32:$src1, (load rriaddr12:$src2)))]>;
1003def CMP32rmy : RXYI<0xE359,
1004                    (outs), (ins GR32:$src1, rriaddr:$src2),
1005                    "cy\t$src1, $src2",
1006                    [(set PSW, (SystemZcmp GR32:$src1, (load rriaddr:$src2)))]>;
1007def CMP64rm  : RXYI<0xE320,
1008                    (outs), (ins GR64:$src1, rriaddr:$src2),
1009                    "cg\t$src1, $src2",
1010                    [(set PSW, (SystemZcmp GR64:$src1, (load rriaddr:$src2)))]>;
1011
1012def UCMP32rr : RRI<0x15,
1013                   (outs), (ins GR32:$src1, GR32:$src2),
1014                   "clr\t$src1, $src2",
1015                   [(set PSW, (SystemZucmp GR32:$src1, GR32:$src2))]>;
1016def UCMP64rr : RREI<0xB921,
1017                    (outs), (ins GR64:$src1, GR64:$src2),
1018                    "clgr\t$src1, $src2",
1019                    [(set PSW, (SystemZucmp GR64:$src1, GR64:$src2))]>;
1020
1021def UCMP32ri   : RILI<0xC2F,
1022                      (outs), (ins GR32:$src1, i32imm:$src2),
1023                      "clfi\t$src1, $src2",
1024                      [(set PSW, (SystemZucmp GR32:$src1, imm:$src2))]>;
1025def UCMP64ri32 : RILI<0xC2E,
1026                      (outs), (ins GR64:$src1, i64i32imm:$src2),
1027                      "clgfi\t$src1, $src2",
1028                      [(set PSW,(SystemZucmp GR64:$src1, i64immZExt32:$src2))]>;
1029
1030def UCMP32rm  : RXI<0x55,
1031                    (outs), (ins GR32:$src1, rriaddr12:$src2),
1032                    "cl\t$src1, $src2",
1033                    [(set PSW, (SystemZucmp GR32:$src1,
1034                                            (load rriaddr12:$src2)))]>;
1035def UCMP32rmy : RXYI<0xE355,
1036                     (outs), (ins GR32:$src1, rriaddr:$src2),
1037                     "cly\t$src1, $src2",
1038                     [(set PSW, (SystemZucmp GR32:$src1,
1039                                             (load rriaddr:$src2)))]>;
1040def UCMP64rm  : RXYI<0xE351,
1041                     (outs), (ins GR64:$src1, rriaddr:$src2),
1042                     "clg\t$src1, $src2",
1043                     [(set PSW, (SystemZucmp GR64:$src1,
1044                                             (load rriaddr:$src2)))]>;
1045
1046def CMPSX64rr32  : RREI<0xB930,
1047                        (outs), (ins GR64:$src1, GR32:$src2),
1048                        "cgfr\t$src1, $src2",
1049                        [(set PSW, (SystemZucmp GR64:$src1,
1050                                                (sext GR32:$src2)))]>;
1051def UCMPZX64rr32 : RREI<0xB931,
1052                        (outs), (ins GR64:$src1, GR32:$src2),
1053                        "clgfr\t$src1, $src2",
1054                        [(set PSW, (SystemZucmp GR64:$src1,
1055                                                (zext GR32:$src2)))]>;
1056
1057def CMPSX64rm32   : RXYI<0xE330,
1058                         (outs), (ins GR64:$src1, rriaddr:$src2),
1059                         "cgf\t$src1, $src2",
1060                         [(set PSW, (SystemZucmp GR64:$src1,
1061                                             (sextloadi64i32 rriaddr:$src2)))]>;
1062def UCMPZX64rm32  : RXYI<0xE331,
1063                         (outs), (ins GR64:$src1, rriaddr:$src2),
1064                         "clgf\t$src1, $src2",
1065                         [(set PSW, (SystemZucmp GR64:$src1,
1066                                             (zextloadi64i32 rriaddr:$src2)))]>;
1067
1068// FIXME: Add other crazy ucmp forms
1069
1070} // Defs = [PSW]
1071
1072//===----------------------------------------------------------------------===//
1073// Other crazy stuff
1074let Defs = [PSW] in {
1075def FLOGR64 : RREI<0xB983,
1076                   (outs GR128:$dst), (ins GR64:$src),
1077                   "flogr\t{$dst, $src}",
1078                   []>;
1079} // Defs = [PSW]
1080
1081//===----------------------------------------------------------------------===//
1082// Non-Instruction Patterns.
1083//===----------------------------------------------------------------------===//
1084
1085// ConstPools, JumpTables
1086def : Pat<(SystemZpcrelwrapper tjumptable:$src), (LA64rm tjumptable:$src)>;
1087def : Pat<(SystemZpcrelwrapper tconstpool:$src), (LA64rm tconstpool:$src)>;
1088
1089// anyext
1090def : Pat<(i64 (anyext GR32:$src)),
1091          (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, subreg_32bit)>;
1092
1093// calls
1094def : Pat<(SystemZcall (i64 tglobaladdr:$dst)), (CALLi tglobaladdr:$dst)>;
1095def : Pat<(SystemZcall (i64 texternalsym:$dst)), (CALLi texternalsym:$dst)>;
1096
1097//===----------------------------------------------------------------------===//
1098// Peepholes.
1099//===----------------------------------------------------------------------===//
1100
1101// FIXME: use add/sub tricks with 32678/-32768
1102
1103// Arbitrary immediate support.
1104def : Pat<(i32 imm:$src),
1105          (EXTRACT_SUBREG (MOV64ri32 (GetI64FromI32 (i32 imm:$src))),
1106             subreg_32bit)>;
1107
1108// Implement in terms of LLIHF/OILF.
1109def : Pat<(i64 imm:$imm),
1110          (OR64rilo32 (MOV64rihi32 (HI32 imm:$imm)), (LO32 imm:$imm))>;
1111
1112// trunc patterns
1113def : Pat<(i32 (trunc GR64:$src)),
1114          (EXTRACT_SUBREG GR64:$src, subreg_32bit)>;
1115
1116// sext_inreg patterns
1117def : Pat<(sext_inreg GR64:$src, i32),
1118          (MOVSX64rr32 (EXTRACT_SUBREG GR64:$src, subreg_32bit))>;
1119
1120// extload patterns
1121def : Pat<(extloadi32i8  rriaddr:$src), (MOVZX32rm8  rriaddr:$src)>;
1122def : Pat<(extloadi32i16 rriaddr:$src), (MOVZX32rm16 rriaddr:$src)>;
1123def : Pat<(extloadi64i8  rriaddr:$src), (MOVZX64rm8  rriaddr:$src)>;
1124def : Pat<(extloadi64i16 rriaddr:$src), (MOVZX64rm16 rriaddr:$src)>;
1125def : Pat<(extloadi64i32 rriaddr:$src), (MOVZX64rm32 rriaddr:$src)>;
1126
1127// muls
1128def : Pat<(mulhs GR32:$src1, GR32:$src2),
1129          (EXTRACT_SUBREG (MUL64rrP (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)),
1130                                                   GR32:$src1, subreg_odd32),
1131                                    GR32:$src2),
1132                          subreg_even32)>;
1133
1134def : Pat<(mulhu GR32:$src1, GR32:$src2),
1135          (EXTRACT_SUBREG (UMUL64rrP (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)),
1136                                                    GR32:$src1, subreg_odd32),
1137                                     GR32:$src2),
1138                          subreg_even32)>;
1139def : Pat<(mulhu GR64:$src1, GR64:$src2),
1140          (EXTRACT_SUBREG (UMUL128rrP (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
1141                                                     GR64:$src1, subreg_odd),
1142                                      GR64:$src2),
1143                          subreg_even)>;
1144
1145def : Pat<(ctlz GR64:$src),
1146          (EXTRACT_SUBREG (FLOGR64 GR64:$src), subreg_even)>;
1147