1234353Sdim//===-- PPCInstr64Bit.td - The PowerPC 64-bit Support ------*- tablegen -*-===//
2234353Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6193323Sed//
7193323Sed//===----------------------------------------------------------------------===//
8193323Sed//
9193323Sed// This file describes the PowerPC 64-bit instructions.  These patterns are used
10193323Sed// both when in ppc64 mode and when in "use 64-bit extensions in 32-bit" mode.
11193323Sed//
12193323Sed//===----------------------------------------------------------------------===//
13193323Sed
14193323Sed//===----------------------------------------------------------------------===//
15193323Sed// 64-bit operands.
16193323Sed//
17193323Seddef s16imm64 : Operand<i64> {
18193323Sed  let PrintMethod = "printS16ImmOperand";
19261991Sdim  let EncoderMethod = "getImm16Encoding";
20251662Sdim  let ParserMatchClass = PPCS16ImmAsmOperand;
21276479Sdim  let DecoderMethod = "decodeSImmOperand<16>";
22193323Sed}
23193323Seddef u16imm64 : Operand<i64> {
24193323Sed  let PrintMethod = "printU16ImmOperand";
25261991Sdim  let EncoderMethod = "getImm16Encoding";
26251662Sdim  let ParserMatchClass = PPCU16ImmAsmOperand;
27276479Sdim  let DecoderMethod = "decodeUImmOperand<16>";
28193323Sed}
29261991Sdimdef s17imm64 : Operand<i64> {
30261991Sdim  // This operand type is used for addis/lis to allow the assembler parser
31261991Sdim  // to accept immediates in the range -65536..65535 for compatibility with
32261991Sdim  // the GNU assembler.  The operand is treated as 16-bit otherwise.
33261991Sdim  let PrintMethod = "printS16ImmOperand";
34261991Sdim  let EncoderMethod = "getImm16Encoding";
35261991Sdim  let ParserMatchClass = PPCS17ImmAsmOperand;
36276479Sdim  let DecoderMethod = "decodeSImmOperand<16>";
37193323Sed}
38243830Sdimdef tocentry : Operand<iPTR> {
39249423Sdim  let MIOperandInfo = (ops i64imm:$imm);
40243830Sdim}
41249423Sdimdef tlsreg : Operand<i64> {
42249423Sdim  let EncoderMethod = "getTLSRegEncoding";
43261991Sdim  let ParserMatchClass = PPCTLSRegOperand;
44249423Sdim}
45249423Sdimdef tlsgd : Operand<i64> {}
46261991Sdimdef tlscall : Operand<i64> {
47261991Sdim  let PrintMethod = "printTLSCall";
48261991Sdim  let MIOperandInfo = (ops calltarget:$func, tlsgd:$sym);
49261991Sdim  let EncoderMethod = "getTLSCallEncoding";
50261991Sdim}
51193323Sed
52193323Sed//===----------------------------------------------------------------------===//
53193323Sed// 64-bit transformation functions.
54193323Sed//
55193323Sed
56193323Seddef SHL64 : SDNodeXForm<imm, [{
57193323Sed  // Transformation function: 63 - imm
58288943Sdim  return getI32Imm(63 - N->getZExtValue(), SDLoc(N));
59193323Sed}]>;
60193323Sed
61193323Seddef SRL64 : SDNodeXForm<imm, [{
62193323Sed  // Transformation function: 64 - imm
63288943Sdim  return N->getZExtValue() ? getI32Imm(64 - N->getZExtValue(), SDLoc(N))
64288943Sdim                           : getI32Imm(0, SDLoc(N));
65193323Sed}]>;
66193323Sed
67193323Sed
68193323Sed//===----------------------------------------------------------------------===//
69193323Sed// Calls.
70193323Sed//
71193323Sed
72276479Sdimlet Interpretation64Bit = 1, isCodeGenOnly = 1 in {
73249423Sdimlet isTerminator = 1, isBarrier = 1, PPC970_Unit = 7 in {
74360784Sdim  let isReturn = 1, isPredicable = 1, Uses = [LR8, RM] in
75280031Sdim    def BLR8 : XLForm_2_ext<19, 16, 20, 0, 0, (outs), (ins), "blr", IIC_BrB,
76280031Sdim                            [(retflag)]>, Requires<[In64BitMode]>;
77251662Sdim  let isBranch = 1, isIndirectBranch = 1, Uses = [CTR8] in {
78360784Sdim    let isPredicable = 1 in
79360784Sdim      def BCTR8 : XLForm_2_ext<19, 528, 20, 0, 0, (outs), (ins), "bctr", IIC_BrB,
80360784Sdim                               []>,
81360784Sdim          Requires<[In64BitMode]>;
82276479Sdim    def BCCCTR8 : XLForm_2_br<19, 528, 0, (outs), (ins pred:$cond),
83276479Sdim                              "b${cond:cc}ctr${cond:pm} ${cond:reg}", IIC_BrB,
84276479Sdim                              []>,
85276479Sdim        Requires<[In64BitMode]>;
86251662Sdim
87276479Sdim    def BCCTR8  : XLForm_2_br2<19, 528, 12, 0, (outs), (ins crbitrc:$bi),
88276479Sdim                               "bcctr 12, $bi, 0", IIC_BrB, []>,
89251662Sdim        Requires<[In64BitMode]>;
90276479Sdim    def BCCTR8n : XLForm_2_br2<19, 528, 4, 0, (outs), (ins crbitrc:$bi),
91276479Sdim                               "bcctr 4, $bi, 0", IIC_BrB, []>,
92276479Sdim        Requires<[In64BitMode]>;
93251662Sdim  }
94249423Sdim}
95249423Sdim
96193323Sedlet Defs = [LR8] in
97344779Sdim  def MovePCtoLR8 : PPCEmitTimePseudo<(outs), (ins), "#MovePCtoLR8", []>,
98193323Sed                    PPC970_Unit_BRU;
99193323Sed
100249423Sdimlet isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7 in {
101249423Sdim  let Defs = [CTR8], Uses = [CTR8] in {
102249423Sdim    def BDZ8  : BForm_1<16, 18, 0, 0, (outs), (ins condbrtarget:$dst),
103249423Sdim                        "bdz $dst">;
104249423Sdim    def BDNZ8 : BForm_1<16, 16, 0, 0, (outs), (ins condbrtarget:$dst),
105249423Sdim                        "bdnz $dst">;
106193323Sed  }
107251662Sdim
108251662Sdim  let isReturn = 1, Defs = [CTR8], Uses = [CTR8, LR8, RM] in {
109251662Sdim    def BDZLR8  : XLForm_2_ext<19, 16, 18, 0, 0, (outs), (ins),
110276479Sdim                              "bdzlr", IIC_BrB, []>;
111251662Sdim    def BDNZLR8 : XLForm_2_ext<19, 16, 16, 0, 0, (outs), (ins),
112276479Sdim                              "bdnzlr", IIC_BrB, []>;
113251662Sdim  }
114193323Sed}
115193323Sed
116251662Sdim
117251662Sdim
118234353Sdimlet isCall = 1, PPC970_Unit = 7, Defs = [LR8] in {
119193323Sed  // Convenient aliases for call instructions
120193323Sed  let Uses = [RM] in {
121249423Sdim    def BL8  : IForm<18, 0, 1, (outs), (ins calltarget:$func),
122276479Sdim                     "bl $func", IIC_BrB, []>;  // See Pat patterns below.
123234353Sdim
124261991Sdim    def BL8_TLS  : IForm<18, 0, 1, (outs), (ins tlscall:$func),
125276479Sdim                         "bl $func", IIC_BrB, []>;
126261991Sdim
127261991Sdim    def BLA8 : IForm<18, 1, 1, (outs), (ins abscalltarget:$func),
128276479Sdim                     "bla $func", IIC_BrB, [(PPCcall (i64 imm:$func))]>;
129249423Sdim  }
130249423Sdim  let Uses = [RM], isCodeGenOnly = 1 in {
131249423Sdim    def BL8_NOP  : IForm_and_DForm_4_zero<18, 0, 1, 24,
132239462Sdim                             (outs), (ins calltarget:$func),
133276479Sdim                             "bl $func\n\tnop", IIC_BrB, []>;
134234353Sdim
135261991Sdim    def BL8_NOP_TLS : IForm_and_DForm_4_zero<18, 0, 1, 24,
136261991Sdim                                  (outs), (ins tlscall:$func),
137276479Sdim                                  "bl $func\n\tnop", IIC_BrB, []>;
138234353Sdim
139249423Sdim    def BLA8_NOP : IForm_and_DForm_4_zero<18, 1, 1, 24,
140261991Sdim                             (outs), (ins abscalltarget:$func),
141276479Sdim                             "bla $func\n\tnop", IIC_BrB,
142249423Sdim                             [(PPCcall_nop (i64 imm:$func))]>;
143193323Sed  }
144249423Sdim  let Uses = [CTR8, RM] in {
145360784Sdim    let isPredicable = 1 in
146360784Sdim      def BCTRL8 : XLForm_2_ext<19, 528, 20, 0, 1, (outs), (ins),
147360784Sdim                                "bctrl", IIC_BrB, [(PPCbctrl)]>,
148360784Sdim                   Requires<[In64BitMode]>;
149251662Sdim
150276479Sdim    let isCodeGenOnly = 1 in {
151276479Sdim      def BCCCTRL8 : XLForm_2_br<19, 528, 1, (outs), (ins pred:$cond),
152276479Sdim                                 "b${cond:cc}ctrl${cond:pm} ${cond:reg}", IIC_BrB,
153276479Sdim                                 []>,
154276479Sdim          Requires<[In64BitMode]>;
155276479Sdim
156276479Sdim      def BCCTRL8  : XLForm_2_br2<19, 528, 12, 1, (outs), (ins crbitrc:$bi),
157276479Sdim                                  "bcctrl 12, $bi, 0", IIC_BrB, []>,
158276479Sdim          Requires<[In64BitMode]>;
159276479Sdim      def BCCTRL8n : XLForm_2_br2<19, 528, 4, 1, (outs), (ins crbitrc:$bi),
160276479Sdim                                  "bcctrl 4, $bi, 0", IIC_BrB, []>,
161276479Sdim          Requires<[In64BitMode]>;
162276479Sdim    }
163193323Sed  }
164193323Sed}
165280031Sdim
166280031Sdimlet isCall = 1, PPC970_Unit = 7, isCodeGenOnly = 1,
167280031Sdim    Defs = [LR8, X2], Uses = [CTR8, RM], RST = 2 in {
168280031Sdim  def BCTRL8_LDinto_toc :
169280031Sdim    XLForm_2_ext_and_DSForm_1<19, 528, 20, 0, 1, 58, 0, (outs),
170280031Sdim                              (ins memrix:$src),
171280031Sdim                              "bctrl\n\tld 2, $src", IIC_BrB,
172353358Sdim                              [(PPCbctrl_load_toc iaddrX4:$src)]>,
173280031Sdim    Requires<[In64BitMode]>;
174280031Sdim}
175280031Sdim
176251662Sdim} // Interpretation64Bit
177193323Sed
178276479Sdim// FIXME: Duplicating this for the asm parser should be unnecessary, but the
179276479Sdim// previous definition must be marked as CodeGen only to prevent decoding
180276479Sdim// conflicts.
181276479Sdimlet Interpretation64Bit = 1, isAsmParserOnly = 1 in
182276479Sdimlet isCall = 1, PPC970_Unit = 7, Defs = [LR8], Uses = [RM] in
183276479Sdimdef BL8_TLS_ : IForm<18, 0, 1, (outs), (ins tlscall:$func),
184276479Sdim                     "bl $func", IIC_BrB, []>;
185276479Sdim
186193323Sed// Calls
187249423Sdimdef : Pat<(PPCcall (i64 tglobaladdr:$dst)),
188249423Sdim          (BL8 tglobaladdr:$dst)>;
189249423Sdimdef : Pat<(PPCcall_nop (i64 tglobaladdr:$dst)),
190249423Sdim          (BL8_NOP tglobaladdr:$dst)>;
191193323Sed
192249423Sdimdef : Pat<(PPCcall (i64 texternalsym:$dst)),
193249423Sdim          (BL8 texternalsym:$dst)>;
194249423Sdimdef : Pat<(PPCcall_nop (i64 texternalsym:$dst)),
195249423Sdim          (BL8_NOP texternalsym:$dst)>;
196234353Sdim
197353358Sdim// Calls for AIX
198353358Sdimdef : Pat<(PPCcall (i64 mcsym:$dst)),
199353358Sdim          (BL8 mcsym:$dst)>;
200353358Sdimdef : Pat<(PPCcall_nop (i64 mcsym:$dst)),
201353358Sdim          (BL8_NOP mcsym:$dst)>;
202353358Sdim
203193323Sed// Atomic operations
204327952Sdim// FIXME: some of these might be used with constant operands. This will result
205327952Sdim// in constant materialization instructions that may be redundant. We currently
206327952Sdim// clean this up in PPCMIPeephole with calls to
207327952Sdim// PPCInstrInfo::convertToImmediateForm() but we should probably not emit them
208327952Sdim// in the first place.
209344779Sdimlet Defs = [CR0] in {
210344779Sdim  def ATOMIC_LOAD_ADD_I64 : PPCCustomInserterPseudo<
211344779Sdim    (outs g8rc:$dst), (ins memrr:$ptr, g8rc:$incr), "#ATOMIC_LOAD_ADD_I64",
212344779Sdim    [(set i64:$dst, (atomic_load_add_64 xoaddr:$ptr, i64:$incr))]>;
213344779Sdim  def ATOMIC_LOAD_SUB_I64 : PPCCustomInserterPseudo<
214344779Sdim    (outs g8rc:$dst), (ins memrr:$ptr, g8rc:$incr), "#ATOMIC_LOAD_SUB_I64",
215344779Sdim    [(set i64:$dst, (atomic_load_sub_64 xoaddr:$ptr, i64:$incr))]>;
216344779Sdim  def ATOMIC_LOAD_OR_I64 : PPCCustomInserterPseudo<
217344779Sdim    (outs g8rc:$dst), (ins memrr:$ptr, g8rc:$incr), "#ATOMIC_LOAD_OR_I64",
218344779Sdim    [(set i64:$dst, (atomic_load_or_64 xoaddr:$ptr, i64:$incr))]>;
219344779Sdim  def ATOMIC_LOAD_XOR_I64 : PPCCustomInserterPseudo<
220344779Sdim    (outs g8rc:$dst), (ins memrr:$ptr, g8rc:$incr), "#ATOMIC_LOAD_XOR_I64",
221344779Sdim    [(set i64:$dst, (atomic_load_xor_64 xoaddr:$ptr, i64:$incr))]>;
222344779Sdim  def ATOMIC_LOAD_AND_I64 : PPCCustomInserterPseudo<
223344779Sdim    (outs g8rc:$dst), (ins memrr:$ptr, g8rc:$incr), "#ATOMIC_LOAD_AND_i64",
224344779Sdim    [(set i64:$dst, (atomic_load_and_64 xoaddr:$ptr, i64:$incr))]>;
225344779Sdim  def ATOMIC_LOAD_NAND_I64 : PPCCustomInserterPseudo<
226344779Sdim    (outs g8rc:$dst), (ins memrr:$ptr, g8rc:$incr), "#ATOMIC_LOAD_NAND_I64",
227344779Sdim    [(set i64:$dst, (atomic_load_nand_64 xoaddr:$ptr, i64:$incr))]>;
228344779Sdim  def ATOMIC_LOAD_MIN_I64 : PPCCustomInserterPseudo<
229344779Sdim    (outs g8rc:$dst), (ins memrr:$ptr, g8rc:$incr), "#ATOMIC_LOAD_MIN_I64",
230344779Sdim    [(set i64:$dst, (atomic_load_min_64 xoaddr:$ptr, i64:$incr))]>;
231344779Sdim  def ATOMIC_LOAD_MAX_I64 : PPCCustomInserterPseudo<
232344779Sdim    (outs g8rc:$dst), (ins memrr:$ptr, g8rc:$incr), "#ATOMIC_LOAD_MAX_I64",
233344779Sdim    [(set i64:$dst, (atomic_load_max_64 xoaddr:$ptr, i64:$incr))]>;
234344779Sdim  def ATOMIC_LOAD_UMIN_I64 : PPCCustomInserterPseudo<
235344779Sdim    (outs g8rc:$dst), (ins memrr:$ptr, g8rc:$incr), "#ATOMIC_LOAD_UMIN_I64",
236344779Sdim    [(set i64:$dst, (atomic_load_umin_64 xoaddr:$ptr, i64:$incr))]>;
237344779Sdim  def ATOMIC_LOAD_UMAX_I64 : PPCCustomInserterPseudo<
238344779Sdim    (outs g8rc:$dst), (ins memrr:$ptr, g8rc:$incr), "#ATOMIC_LOAD_UMAX_I64",
239344779Sdim    [(set i64:$dst, (atomic_load_umax_64 xoaddr:$ptr, i64:$incr))]>;
240193323Sed
241344779Sdim  def ATOMIC_CMP_SWAP_I64 : PPCCustomInserterPseudo<
242344779Sdim    (outs g8rc:$dst), (ins memrr:$ptr, g8rc:$old, g8rc:$new), "#ATOMIC_CMP_SWAP_I64",
243344779Sdim    [(set i64:$dst, (atomic_cmp_swap_64 xoaddr:$ptr, i64:$old, i64:$new))]>;
244193323Sed
245344779Sdim  def ATOMIC_SWAP_I64 : PPCCustomInserterPseudo<
246344779Sdim    (outs g8rc:$dst), (ins memrr:$ptr, g8rc:$new), "#ATOMIC_SWAP_I64",
247344779Sdim    [(set i64:$dst, (atomic_swap_64 xoaddr:$ptr, i64:$new))]>;
248193323Sed}
249193323Sed
250193323Sed// Instructions to support atomic operations
251288943Sdimlet mayLoad = 1, hasSideEffects = 0 in {
252341825Sdimdef LDARX : XForm_1_memOp<31,  84, (outs g8rc:$rD), (ins memrr:$ptr),
253341825Sdim                          "ldarx $rD, $ptr", IIC_LdStLDARX, []>;
254193323Sed
255288943Sdim// Instruction to support lock versions of atomics
256288943Sdim// (EH=1 - see Power ISA 2.07 Book II 4.4.2)
257288943Sdimdef LDARXL : XForm_1<31,  84, (outs g8rc:$rD), (ins memrr:$ptr),
258360784Sdim                     "ldarx $rD, $ptr, 1", IIC_LdStLDARX, []>, isRecordForm;
259309124Sdim
260309124Sdimlet hasExtraDefRegAllocReq = 1 in
261309124Sdimdef LDAT : X_RD5_RS5_IM5<31, 614, (outs g8rc:$rD), (ins g8rc:$rA, u5imm:$FC),
262309124Sdim                         "ldat $rD, $rA, $FC", IIC_LdStLoad>, isPPC64,
263309124Sdim           Requires<[IsISA3_0]>;
264288943Sdim}
265288943Sdim
266321369Sdimlet Defs = [CR0], mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
267341825Sdimdef STDCX : XForm_1_memOp<31, 214, (outs), (ins g8rc:$rS, memrr:$dst),
268360784Sdim                          "stdcx. $rS, $dst", IIC_LdStSTDCX, []>, isRecordForm;
269193323Sed
270321369Sdimlet mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
271309124Sdimdef STDAT : X_RD5_RS5_IM5<31, 742, (outs), (ins g8rc:$rS, g8rc:$rA, u5imm:$FC),
272309124Sdim                          "stdat $rS, $rA, $FC", IIC_LdStStore>, isPPC64,
273309124Sdim            Requires<[IsISA3_0]>;
274309124Sdim
275276479Sdimlet Interpretation64Bit = 1, isCodeGenOnly = 1 in {
276193323Sedlet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [RM] in
277344779Sdimdef TCRETURNdi8 :PPCEmitTimePseudo< (outs),
278239462Sdim                        (ins calltarget:$dst, i32imm:$offset),
279193323Sed                 "#TC_RETURNd8 $dst $offset",
280193323Sed                 []>;
281193323Sed
282193323Sedlet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [RM] in
283344779Sdimdef TCRETURNai8 :PPCEmitTimePseudo<(outs), (ins abscalltarget:$func, i32imm:$offset),
284193323Sed                 "#TC_RETURNa8 $func $offset",
285193323Sed                 [(PPCtc_return (i64 imm:$func), imm:$offset)]>;
286193323Sed
287193323Sedlet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [RM] in
288344779Sdimdef TCRETURNri8 : PPCEmitTimePseudo<(outs), (ins CTRRC8:$dst, i32imm:$offset),
289193323Sed                 "#TC_RETURNr8 $dst $offset",
290193323Sed                 []>;
291193323Sed
292193323Sedlet isTerminator = 1, isBarrier = 1, PPC970_Unit = 7, isBranch = 1,
293249423Sdim    isIndirectBranch = 1, isCall = 1, isReturn = 1, Uses = [CTR8, RM] in
294276479Sdimdef TAILBCTR8 : XLForm_2_ext<19, 528, 20, 0, 0, (outs), (ins), "bctr", IIC_BrB,
295276479Sdim                             []>,
296249423Sdim    Requires<[In64BitMode]>;
297193323Sed
298193323Sedlet isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7,
299193323Sed    isBarrier = 1, isCall = 1, isReturn = 1, Uses = [RM] in
300193323Seddef TAILB8   : IForm<18, 0, 0, (outs), (ins calltarget:$dst),
301276479Sdim                  "b $dst", IIC_BrB,
302193323Sed                  []>;
303193323Sed
304193323Sedlet isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7,
305193323Sed    isBarrier = 1, isCall = 1, isReturn = 1, Uses = [RM] in
306261991Sdimdef TAILBA8   : IForm<18, 0, 0, (outs), (ins abscalltarget:$dst),
307276479Sdim                  "ba $dst", IIC_BrB,
308193323Sed                  []>;
309251662Sdim} // Interpretation64Bit
310249423Sdim
311193323Seddef : Pat<(PPCtc_return (i64 tglobaladdr:$dst),  imm:$imm),
312193323Sed          (TCRETURNdi8 tglobaladdr:$dst, imm:$imm)>;
313193323Sed
314193323Seddef : Pat<(PPCtc_return (i64 texternalsym:$dst), imm:$imm),
315193323Sed          (TCRETURNdi8 texternalsym:$dst, imm:$imm)>;
316193323Sed
317193323Seddef : Pat<(PPCtc_return CTRRC8:$dst, imm:$imm),
318193323Sed          (TCRETURNri8 CTRRC8:$dst, imm:$imm)>;
319193323Sed
320239462Sdim
321249423Sdim// 64-bit CR instructions
322276479Sdimlet Interpretation64Bit = 1, isCodeGenOnly = 1 in {
323280031Sdimlet hasSideEffects = 0 in {
324296417Sdim// mtocrf's input needs to be prepared by shifting by an amount dependent
325296417Sdim// on the cr register selected. Thus, post-ra anti-dep breaking must not
326296417Sdim// later change that register assignment.
327296417Sdimlet hasExtraDefRegAllocReq = 1 in {
328261991Sdimdef MTOCRF8: XFXForm_5a<31, 144, (outs crbitm:$FXM), (ins g8rc:$ST),
329276479Sdim                        "mtocrf $FXM, $ST", IIC_BrMCRX>,
330261991Sdim            PPC970_DGroup_First, PPC970_Unit_CRU;
331261991Sdim
332296417Sdim// Similarly to mtocrf, the mask for mtcrf must be prepared in a way that
333296417Sdim// is dependent on the cr fields being set.
334261991Sdimdef MTCRF8 : XFXForm_5<31, 144, (outs), (ins i32imm:$FXM, g8rc:$rS),
335276479Sdim                      "mtcrf $FXM, $rS", IIC_BrMCRX>,
336234353Sdim            PPC970_MicroCode, PPC970_Unit_CRU;
337296417Sdim} // hasExtraDefRegAllocReq = 1
338193323Sed
339296417Sdim// mfocrf's input needs to be prepared by shifting by an amount dependent
340296417Sdim// on the cr register selected. Thus, post-ra anti-dep breaking must not
341296417Sdim// later change that register assignment.
342296417Sdimlet hasExtraSrcRegAllocReq = 1 in {
343261991Sdimdef MFOCRF8: XFXForm_5a<31, 19, (outs g8rc:$rT), (ins crbitm:$FXM),
344276479Sdim                        "mfocrf $rT, $FXM", IIC_SprMFCRF>,
345261991Sdim             PPC970_DGroup_First, PPC970_Unit_CRU;
346251662Sdim
347296417Sdim// Similarly to mfocrf, the mask for mfcrf must be prepared in a way that
348296417Sdim// is dependent on the cr fields being copied.
349251662Sdimdef MFCR8 : XFXForm_3<31, 19, (outs g8rc:$rT), (ins),
350276479Sdim                     "mfcr $rT", IIC_SprMFCR>,
351234353Sdim                     PPC970_MicroCode, PPC970_Unit_CRU;
352296417Sdim} // hasExtraSrcRegAllocReq = 1
353280031Sdim} // hasSideEffects = 0
354234353Sdim
355344779Sdim// While longjmp is a control-flow barrier (fallthrough isn't allowed), setjmp
356344779Sdim// is not.
357344779Sdimlet hasSideEffects = 1 in {
358261991Sdim  let Defs = [CTR8] in
359344779Sdim  def EH_SjLj_SetJmp64  : PPCCustomInserterPseudo<(outs gprc:$dst), (ins memr:$buf),
360249423Sdim                            "#EH_SJLJ_SETJMP64",
361249423Sdim                            [(set i32:$dst, (PPCeh_sjlj_setjmp addr:$buf))]>,
362249423Sdim                          Requires<[In64BitMode]>;
363344779Sdim}
364344779Sdim
365344779Sdimlet hasSideEffects = 1, isBarrier = 1 in {
366249423Sdim  let isTerminator = 1 in
367344779Sdim  def EH_SjLj_LongJmp64 : PPCCustomInserterPseudo<(outs), (ins memr:$buf),
368249423Sdim                            "#EH_SJLJ_LONGJMP64",
369249423Sdim                            [(PPCeh_sjlj_longjmp addr:$buf)]>,
370249423Sdim                          Requires<[In64BitMode]>;
371249423Sdim}
372249423Sdim
373288943Sdimdef MFSPR8 : XFXForm_1<31, 339, (outs g8rc:$RT), (ins i32imm:$SPR),
374288943Sdim                       "mfspr $RT, $SPR", IIC_SprMFSPR>;
375288943Sdimdef MTSPR8 : XFXForm_1<31, 467, (outs), (ins i32imm:$SPR, g8rc:$RT),
376288943Sdim                       "mtspr $SPR, $RT", IIC_SprMTSPR>;
377288943Sdim
378288943Sdim
379193323Sed//===----------------------------------------------------------------------===//
380193323Sed// 64-bit SPR manipulation instrs.
381193323Sed
382193323Sedlet Uses = [CTR8] in {
383251662Sdimdef MFCTR8 : XFXForm_1_ext<31, 339, 9, (outs g8rc:$rT), (ins),
384276479Sdim                           "mfctr $rT", IIC_SprMFSPR>,
385193323Sed             PPC970_DGroup_First, PPC970_Unit_FXU;
386193323Sed}
387249423Sdimlet Pattern = [(PPCmtctr i64:$rS)], Defs = [CTR8] in {
388251662Sdimdef MTCTR8 : XFXForm_7_ext<31, 467, 9, (outs), (ins g8rc:$rS),
389276479Sdim                           "mtctr $rS", IIC_SprMTSPR>,
390193323Sed             PPC970_DGroup_First, PPC970_Unit_FXU;
391193323Sed}
392276479Sdimlet hasSideEffects = 1, Defs = [CTR8] in {
393353358Sdimlet Pattern = [(int_set_loop_iterations i64:$rS)] in
394261991Sdimdef MTCTR8loop : XFXForm_7_ext<31, 467, 9, (outs), (ins g8rc:$rS),
395276479Sdim                               "mtctr $rS", IIC_SprMTSPR>,
396261991Sdim                 PPC970_DGroup_First, PPC970_Unit_FXU;
397261991Sdim}
398193323Sed
399276479Sdimlet Pattern = [(set i64:$rT, readcyclecounter)] in
400251662Sdimdef MFTB8 : XFXForm_1_ext<31, 339, 268, (outs g8rc:$rT), (ins),
401276479Sdim                          "mfspr $rT, 268", IIC_SprMFTB>,
402239462Sdim            PPC970_DGroup_First, PPC970_Unit_FXU;
403239462Sdim// Note that encoding mftb using mfspr is now the preferred form,
404239462Sdim// and has been since at least ISA v2.03. The mftb instruction has
405239462Sdim// now been phased out. Using mfspr, however, is known not to work on
406239462Sdim// the POWER3.
407239462Sdim
408193323Sedlet Defs = [X1], Uses = [X1] in
409344779Sdimdef DYNALLOC8 : PPCEmitTimePseudo<(outs g8rc:$result), (ins g8rc:$negsize, memri:$fpsi),"#DYNALLOC8",
410249423Sdim                       [(set i64:$result,
411249423Sdim                             (PPCdynalloc i64:$negsize, iaddr:$fpsi))]>;
412344779Sdimdef DYNAREAOFFSET8 : PPCEmitTimePseudo<(outs i64imm:$result), (ins memri:$fpsi), "#DYNAREAOFFSET8",
413296417Sdim                       [(set i64:$result, (PPCdynareaoffset iaddr:$fpsi))]>;
414193323Sed
415360784Sdimlet hasSideEffects = 0 in {
416193323Sedlet Defs = [LR8] in {
417251662Sdimdef MTLR8  : XFXForm_7_ext<31, 467, 8, (outs), (ins g8rc:$rS),
418276479Sdim                           "mtlr $rS", IIC_SprMTSPR>,
419193323Sed             PPC970_DGroup_First, PPC970_Unit_FXU;
420193323Sed}
421193323Sedlet Uses = [LR8] in {
422251662Sdimdef MFLR8  : XFXForm_1_ext<31, 339, 8, (outs g8rc:$rT), (ins),
423276479Sdim                           "mflr $rT", IIC_SprMFSPR>,
424193323Sed             PPC970_DGroup_First, PPC970_Unit_FXU;
425193323Sed}
426251662Sdim} // Interpretation64Bit
427360784Sdim}
428193323Sed
429193323Sed//===----------------------------------------------------------------------===//
430193323Sed// Fixed point instructions.
431193323Sed//
432193323Sed
433193323Sedlet PPC970_Unit = 1 in {  // FXU Operations.
434251662Sdimlet Interpretation64Bit = 1 in {
435280031Sdimlet hasSideEffects = 0 in {
436276479Sdimlet isCodeGenOnly = 1 in {
437193323Sed
438243830Sdimlet isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in {
439261991Sdimdef LI8  : DForm_2_r0<14, (outs g8rc:$rD), (ins s16imm64:$imm),
440276479Sdim                      "li $rD, $imm", IIC_IntSimple,
441261991Sdim                      [(set i64:$rD, imm64SExt16:$imm)]>;
442261991Sdimdef LIS8 : DForm_2_r0<15, (outs g8rc:$rD), (ins s17imm64:$imm),
443276479Sdim                      "lis $rD, $imm", IIC_IntSimple,
444249423Sdim                      [(set i64:$rD, imm16ShiftedSExt:$imm)]>;
445243830Sdim}
446193323Sed
447193323Sed// Logical ops.
448276479Sdimlet isCommutable = 1 in {
449251662Sdimdefm NAND8: XForm_6r<31, 476, (outs g8rc:$rA), (ins g8rc:$rS, g8rc:$rB),
450276479Sdim                     "nand", "$rA, $rS, $rB", IIC_IntSimple,
451251662Sdim                     [(set i64:$rA, (not (and i64:$rS, i64:$rB)))]>;
452251662Sdimdefm AND8 : XForm_6r<31,  28, (outs g8rc:$rA), (ins g8rc:$rS, g8rc:$rB),
453276479Sdim                     "and", "$rA, $rS, $rB", IIC_IntSimple,
454251662Sdim                     [(set i64:$rA, (and i64:$rS, i64:$rB))]>;
455276479Sdim} // isCommutable
456251662Sdimdefm ANDC8: XForm_6r<31,  60, (outs g8rc:$rA), (ins g8rc:$rS, g8rc:$rB),
457276479Sdim                     "andc", "$rA, $rS, $rB", IIC_IntSimple,
458251662Sdim                     [(set i64:$rA, (and i64:$rS, (not i64:$rB)))]>;
459276479Sdimlet isCommutable = 1 in {
460251662Sdimdefm OR8  : XForm_6r<31, 444, (outs g8rc:$rA), (ins g8rc:$rS, g8rc:$rB),
461276479Sdim                     "or", "$rA, $rS, $rB", IIC_IntSimple,
462251662Sdim                     [(set i64:$rA, (or i64:$rS, i64:$rB))]>;
463251662Sdimdefm NOR8 : XForm_6r<31, 124, (outs g8rc:$rA), (ins g8rc:$rS, g8rc:$rB),
464276479Sdim                     "nor", "$rA, $rS, $rB", IIC_IntSimple,
465251662Sdim                     [(set i64:$rA, (not (or i64:$rS, i64:$rB)))]>;
466276479Sdim} // isCommutable
467251662Sdimdefm ORC8 : XForm_6r<31, 412, (outs g8rc:$rA), (ins g8rc:$rS, g8rc:$rB),
468276479Sdim                     "orc", "$rA, $rS, $rB", IIC_IntSimple,
469251662Sdim                     [(set i64:$rA, (or i64:$rS, (not i64:$rB)))]>;
470276479Sdimlet isCommutable = 1 in {
471251662Sdimdefm EQV8 : XForm_6r<31, 284, (outs g8rc:$rA), (ins g8rc:$rS, g8rc:$rB),
472276479Sdim                     "eqv", "$rA, $rS, $rB", IIC_IntSimple,
473251662Sdim                     [(set i64:$rA, (not (xor i64:$rS, i64:$rB)))]>;
474251662Sdimdefm XOR8 : XForm_6r<31, 316, (outs g8rc:$rA), (ins g8rc:$rS, g8rc:$rB),
475276479Sdim                     "xor", "$rA, $rS, $rB", IIC_IntSimple,
476251662Sdim                     [(set i64:$rA, (xor i64:$rS, i64:$rB))]>;
477276479Sdim} // let isCommutable = 1
478193323Sed
479193323Sed// Logical ops with immediate.
480251662Sdimlet Defs = [CR0] in {
481360784Sdimdef ANDI8_rec  : DForm_4<28, (outs g8rc:$dst), (ins g8rc:$src1, u16imm64:$src2),
482276479Sdim                      "andi. $dst, $src1, $src2", IIC_IntGeneral,
483249423Sdim                      [(set i64:$dst, (and i64:$src1, immZExt16:$src2))]>,
484360784Sdim                      isRecordForm;
485360784Sdimdef ANDIS8_rec : DForm_4<29, (outs g8rc:$dst), (ins g8rc:$src1, u16imm64:$src2),
486276479Sdim                     "andis. $dst, $src1, $src2", IIC_IntGeneral,
487249423Sdim                    [(set i64:$dst, (and i64:$src1, imm16ShiftedZExt:$src2))]>,
488360784Sdim                     isRecordForm;
489251662Sdim}
490276479Sdimdef ORI8    : DForm_4<24, (outs g8rc:$dst), (ins g8rc:$src1, u16imm64:$src2),
491276479Sdim                      "ori $dst, $src1, $src2", IIC_IntSimple,
492249423Sdim                      [(set i64:$dst, (or i64:$src1, immZExt16:$src2))]>;
493276479Sdimdef ORIS8   : DForm_4<25, (outs g8rc:$dst), (ins g8rc:$src1, u16imm64:$src2),
494276479Sdim                      "oris $dst, $src1, $src2", IIC_IntSimple,
495249423Sdim                    [(set i64:$dst, (or i64:$src1, imm16ShiftedZExt:$src2))]>;
496276479Sdimdef XORI8   : DForm_4<26, (outs g8rc:$dst), (ins g8rc:$src1, u16imm64:$src2),
497276479Sdim                      "xori $dst, $src1, $src2", IIC_IntSimple,
498249423Sdim                      [(set i64:$dst, (xor i64:$src1, immZExt16:$src2))]>;
499276479Sdimdef XORIS8  : DForm_4<27, (outs g8rc:$dst), (ins g8rc:$src1, u16imm64:$src2),
500276479Sdim                      "xoris $dst, $src1, $src2", IIC_IntSimple,
501249423Sdim                   [(set i64:$dst, (xor i64:$src1, imm16ShiftedZExt:$src2))]>;
502193323Sed
503276479Sdimlet isCommutable = 1 in
504360661Sdimdefm ADD8  : XOForm_1rx<31, 266, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB),
505360661Sdim                        "add", "$rT, $rA, $rB", IIC_IntSimple,
506360661Sdim                        [(set i64:$rT, (add i64:$rA, i64:$rB))]>;
507249423Sdim// ADD8 has a special form: reg = ADD8(reg, sym@tls) for use by the
508309124Sdim// initial-exec thread-local storage model.  We need to forbid r0 here -
509309124Sdim// while it works for add just fine, the linker can relax this to local-exec
510309124Sdim// addi, which won't work for r0.
511309124Sdimdef ADD8TLS  : XOForm_1<31, 266, 0, (outs g8rc:$rT), (ins g8rc_nox0:$rA, tlsreg:$rB),
512276479Sdim                        "add $rT, $rA, $rB", IIC_IntSimple,
513249423Sdim                        [(set i64:$rT, (add i64:$rA, tglobaltlsaddr:$rB))]>;
514341825Sdimlet mayLoad = 1 in {
515341825Sdimdef LBZXTLS : XForm_1<31,  87, (outs g8rc:$rD), (ins ptr_rc_nor0:$rA, tlsreg:$rB),
516341825Sdim                      "lbzx $rD, $rA, $rB", IIC_LdStLoad, []>;
517341825Sdimdef LHZXTLS : XForm_1<31, 279, (outs g8rc:$rD), (ins ptr_rc_nor0:$rA, tlsreg:$rB),
518341825Sdim                      "lhzx $rD, $rA, $rB", IIC_LdStLoad, []>;
519341825Sdimdef LWZXTLS : XForm_1<31,  23, (outs g8rc:$rD), (ins ptr_rc_nor0:$rA, tlsreg:$rB),
520341825Sdim                      "lwzx $rD, $rA, $rB", IIC_LdStLoad, []>;
521341825Sdimdef LDXTLS  : XForm_1<31,  21, (outs g8rc:$rD), (ins ptr_rc_nor0:$rA, tlsreg:$rB),
522341825Sdim                      "ldx $rD, $rA, $rB", IIC_LdStLD, []>, isPPC64;
523341825Sdimdef LBZXTLS_32 : XForm_1<31,  87, (outs gprc:$rD), (ins ptr_rc_nor0:$rA, tlsreg:$rB),
524341825Sdim                         "lbzx $rD, $rA, $rB", IIC_LdStLoad, []>;
525341825Sdimdef LHZXTLS_32 : XForm_1<31, 279, (outs gprc:$rD), (ins ptr_rc_nor0:$rA, tlsreg:$rB),
526341825Sdim                         "lhzx $rD, $rA, $rB", IIC_LdStLoad, []>;
527341825Sdimdef LWZXTLS_32 : XForm_1<31,  23, (outs gprc:$rD), (ins ptr_rc_nor0:$rA, tlsreg:$rB),
528341825Sdim                         "lwzx $rD, $rA, $rB", IIC_LdStLoad, []>;
529341825Sdim
530341825Sdim}
531341825Sdim
532341825Sdimlet mayStore = 1 in {
533341825Sdimdef STBXTLS : XForm_8<31, 215, (outs), (ins g8rc:$rS, ptr_rc_nor0:$rA, tlsreg:$rB),
534341825Sdim                      "stbx $rS, $rA, $rB", IIC_LdStStore, []>,
535341825Sdim                      PPC970_DGroup_Cracked;
536341825Sdimdef STHXTLS : XForm_8<31, 407, (outs), (ins g8rc:$rS, ptr_rc_nor0:$rA, tlsreg:$rB),
537341825Sdim                      "sthx $rS, $rA, $rB", IIC_LdStStore, []>,
538341825Sdim                      PPC970_DGroup_Cracked;
539341825Sdimdef STWXTLS : XForm_8<31, 151, (outs), (ins g8rc:$rS, ptr_rc_nor0:$rA, tlsreg:$rB),
540341825Sdim                      "stwx $rS, $rA, $rB", IIC_LdStStore, []>,
541341825Sdim                      PPC970_DGroup_Cracked;
542341825Sdimdef STDXTLS  : XForm_8<31, 149, (outs), (ins g8rc:$rS, ptr_rc_nor0:$rA, tlsreg:$rB),
543341825Sdim                       "stdx $rS, $rA, $rB", IIC_LdStSTD, []>, isPPC64,
544341825Sdim                       PPC970_DGroup_Cracked;
545341825Sdimdef STBXTLS_32 : XForm_8<31, 215, (outs), (ins gprc:$rS, ptr_rc_nor0:$rA, tlsreg:$rB),
546341825Sdim                         "stbx $rS, $rA, $rB", IIC_LdStStore, []>,
547341825Sdim                         PPC970_DGroup_Cracked;
548341825Sdimdef STHXTLS_32 : XForm_8<31, 407, (outs), (ins gprc:$rS, ptr_rc_nor0:$rA, tlsreg:$rB),
549341825Sdim                         "sthx $rS, $rA, $rB", IIC_LdStStore, []>,
550341825Sdim                         PPC970_DGroup_Cracked;
551341825Sdimdef STWXTLS_32 : XForm_8<31, 151, (outs), (ins gprc:$rS, ptr_rc_nor0:$rA, tlsreg:$rB),
552341825Sdim                         "stwx $rS, $rA, $rB", IIC_LdStStore, []>,
553341825Sdim                         PPC970_DGroup_Cracked;
554341825Sdim
555341825Sdim}
556341825Sdim
557276479Sdimlet isCommutable = 1 in
558251662Sdimdefm ADDC8 : XOForm_1rc<31, 10, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB),
559276479Sdim                        "addc", "$rT, $rA, $rB", IIC_IntGeneral,
560251662Sdim                        [(set i64:$rT, (addc i64:$rA, i64:$rB))]>,
561251662Sdim                        PPC970_DGroup_Cracked;
562276479Sdim
563251662Sdimlet Defs = [CARRY] in
564251662Sdimdef ADDIC8 : DForm_2<12, (outs g8rc:$rD), (ins g8rc:$rA, s16imm64:$imm),
565276479Sdim                     "addic $rD, $rA, $imm", IIC_IntGeneral,
566261991Sdim                     [(set i64:$rD, (addc i64:$rA, imm64SExt16:$imm))]>;
567261991Sdimdef ADDI8  : DForm_2<14, (outs g8rc:$rD), (ins g8rc_nox0:$rA, s16imm64:$imm),
568276479Sdim                     "addi $rD, $rA, $imm", IIC_IntSimple,
569261991Sdim                     [(set i64:$rD, (add i64:$rA, imm64SExt16:$imm))]>;
570261991Sdimdef ADDIS8 : DForm_2<15, (outs g8rc:$rD), (ins g8rc_nox0:$rA, s17imm64:$imm),
571276479Sdim                     "addis $rD, $rA, $imm", IIC_IntSimple,
572249423Sdim                     [(set i64:$rD, (add i64:$rA, imm16ShiftedSExt:$imm))]>;
573193323Sed
574198090Srdivackylet Defs = [CARRY] in {
575251662Sdimdef SUBFIC8: DForm_2< 8, (outs g8rc:$rD), (ins g8rc:$rA, s16imm64:$imm),
576276479Sdim                     "subfic $rD, $rA, $imm", IIC_IntGeneral,
577261991Sdim                     [(set i64:$rD, (subc imm64SExt16:$imm, i64:$rA))]>;
578309124Sdim}
579309124Sdimdefm SUBFC8 : XOForm_1rc<31, 8, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB),
580276479Sdim                        "subfc", "$rT, $rA, $rB", IIC_IntGeneral,
581251662Sdim                        [(set i64:$rT, (subc i64:$rB, i64:$rA))]>,
582251662Sdim                        PPC970_DGroup_Cracked;
583360661Sdimdefm SUBF8 : XOForm_1rx<31, 40, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB),
584360661Sdim                        "subf", "$rT, $rA, $rB", IIC_IntGeneral,
585360661Sdim                        [(set i64:$rT, (sub i64:$rB, i64:$rA))]>;
586251662Sdimdefm NEG8    : XOForm_3r<31, 104, 0, (outs g8rc:$rT), (ins g8rc:$rA),
587276479Sdim                        "neg", "$rT, $rA", IIC_IntSimple,
588251662Sdim                        [(set i64:$rT, (ineg i64:$rA))]>;
589251662Sdimlet Uses = [CARRY] in {
590276479Sdimlet isCommutable = 1 in
591251662Sdimdefm ADDE8   : XOForm_1rc<31, 138, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB),
592276479Sdim                          "adde", "$rT, $rA, $rB", IIC_IntGeneral,
593251662Sdim                          [(set i64:$rT, (adde i64:$rA, i64:$rB))]>;
594251662Sdimdefm ADDME8  : XOForm_3rc<31, 234, 0, (outs g8rc:$rT), (ins g8rc:$rA),
595276479Sdim                          "addme", "$rT, $rA", IIC_IntGeneral,
596251662Sdim                          [(set i64:$rT, (adde i64:$rA, -1))]>;
597251662Sdimdefm ADDZE8  : XOForm_3rc<31, 202, 0, (outs g8rc:$rT), (ins g8rc:$rA),
598276479Sdim                          "addze", "$rT, $rA", IIC_IntGeneral,
599251662Sdim                          [(set i64:$rT, (adde i64:$rA, 0))]>;
600251662Sdimdefm SUBFE8  : XOForm_1rc<31, 136, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB),
601276479Sdim                          "subfe", "$rT, $rA, $rB", IIC_IntGeneral,
602251662Sdim                          [(set i64:$rT, (sube i64:$rB, i64:$rA))]>;
603251662Sdimdefm SUBFME8 : XOForm_3rc<31, 232, 0, (outs g8rc:$rT), (ins g8rc:$rA),
604276479Sdim                          "subfme", "$rT, $rA", IIC_IntGeneral,
605251662Sdim                          [(set i64:$rT, (sube -1, i64:$rA))]>;
606251662Sdimdefm SUBFZE8 : XOForm_3rc<31, 200, 0, (outs g8rc:$rT), (ins g8rc:$rA),
607276479Sdim                          "subfze", "$rT, $rA", IIC_IntGeneral,
608251662Sdim                          [(set i64:$rT, (sube 0, i64:$rA))]>;
609198090Srdivacky}
610276479Sdim} // isCodeGenOnly
611193323Sed
612276479Sdim// FIXME: Duplicating this for the asm parser should be unnecessary, but the
613276479Sdim// previous definition must be marked as CodeGen only to prevent decoding
614276479Sdim// conflicts.
615341825Sdimlet isAsmParserOnly = 1 in {
616276479Sdimdef ADD8TLS_ : XOForm_1<31, 266, 0, (outs g8rc:$rT), (ins g8rc:$rA, tlsreg:$rB),
617276479Sdim                        "add $rT, $rA, $rB", IIC_IntSimple, []>;
618193323Sed
619341825Sdimlet mayLoad = 1 in {
620341825Sdimdef LBZXTLS_ : XForm_1<31,  87, (outs g8rc:$rD), (ins ptr_rc_nor0:$rA, tlsreg:$rB),
621341825Sdim                      "lbzx $rD, $rA, $rB", IIC_LdStLoad, []>;
622341825Sdimdef LHZXTLS_ : XForm_1<31, 279, (outs g8rc:$rD), (ins ptr_rc_nor0:$rA, tlsreg:$rB),
623341825Sdim                      "lhzx $rD, $rA, $rB", IIC_LdStLoad, []>;
624341825Sdimdef LWZXTLS_ : XForm_1<31,  23, (outs g8rc:$rD), (ins ptr_rc_nor0:$rA, tlsreg:$rB),
625341825Sdim                      "lwzx $rD, $rA, $rB", IIC_LdStLoad, []>;
626341825Sdimdef LDXTLS_  : XForm_1<31,  21, (outs g8rc:$rD), (ins ptr_rc_nor0:$rA, tlsreg:$rB),
627341825Sdim                      "ldx $rD, $rA, $rB", IIC_LdStLD, []>, isPPC64;
628341825Sdim}
629341825Sdim
630341825Sdimlet mayStore = 1 in {
631341825Sdimdef STBXTLS_ : XForm_8<31, 215, (outs), (ins g8rc:$rS, ptr_rc_nor0:$rA, tlsreg:$rB),
632341825Sdim                      "stbx $rS, $rA, $rB", IIC_LdStStore, []>,
633341825Sdim                      PPC970_DGroup_Cracked;
634341825Sdimdef STHXTLS_ : XForm_8<31, 407, (outs), (ins g8rc:$rS, ptr_rc_nor0:$rA, tlsreg:$rB),
635341825Sdim                      "sthx $rS, $rA, $rB", IIC_LdStStore, []>,
636341825Sdim                      PPC970_DGroup_Cracked;
637341825Sdimdef STWXTLS_ : XForm_8<31, 151, (outs), (ins g8rc:$rS, ptr_rc_nor0:$rA, tlsreg:$rB),
638341825Sdim                      "stwx $rS, $rA, $rB", IIC_LdStStore, []>,
639341825Sdim                      PPC970_DGroup_Cracked;
640341825Sdimdef STDXTLS_  : XForm_8<31, 149, (outs), (ins g8rc:$rS, ptr_rc_nor0:$rA, tlsreg:$rB),
641341825Sdim                       "stdx $rS, $rA, $rB", IIC_LdStSTD, []>, isPPC64,
642341825Sdim                       PPC970_DGroup_Cracked;
643341825Sdim}
644341825Sdim}
645341825Sdim
646276479Sdimlet isCommutable = 1 in {
647251662Sdimdefm MULHD : XOForm_1r<31, 73, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB),
648276479Sdim                       "mulhd", "$rT, $rA, $rB", IIC_IntMulHW,
649251662Sdim                       [(set i64:$rT, (mulhs i64:$rA, i64:$rB))]>;
650251662Sdimdefm MULHDU : XOForm_1r<31, 9, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB),
651276479Sdim                       "mulhdu", "$rT, $rA, $rB", IIC_IntMulHWU,
652251662Sdim                       [(set i64:$rT, (mulhu i64:$rA, i64:$rB))]>;
653276479Sdim} // isCommutable
654251662Sdim}
655251662Sdim} // Interpretation64Bit
656193323Sed
657280031Sdimlet isCompare = 1, hasSideEffects = 0 in {
658251662Sdim  def CMPD   : XForm_16_ext<31, 0, (outs crrc:$crD), (ins g8rc:$rA, g8rc:$rB),
659276479Sdim                            "cmpd $crD, $rA, $rB", IIC_IntCompare>, isPPC64;
660251662Sdim  def CMPLD  : XForm_16_ext<31, 32, (outs crrc:$crD), (ins g8rc:$rA, g8rc:$rB),
661276479Sdim                            "cmpld $crD, $rA, $rB", IIC_IntCompare>, isPPC64;
662276479Sdim  def CMPDI  : DForm_5_ext<11, (outs crrc:$crD), (ins g8rc:$rA, s16imm64:$imm),
663276479Sdim                           "cmpdi $crD, $rA, $imm", IIC_IntCompare>, isPPC64;
664276479Sdim  def CMPLDI : DForm_6_ext<10, (outs crrc:$dst), (ins g8rc:$src1, u16imm64:$src2),
665276479Sdim                           "cmpldi $dst, $src1, $src2",
666276479Sdim                           IIC_IntCompare>, isPPC64;
667309124Sdim  let Interpretation64Bit = 1, isCodeGenOnly = 1 in
668309124Sdim  def CMPRB8 : X_BF3_L1_RS5_RS5<31, 192, (outs crbitrc:$BF),
669309124Sdim                                (ins u1imm:$L, g8rc:$rA, g8rc:$rB),
670309124Sdim                                "cmprb $BF, $L, $rA, $rB", IIC_IntCompare, []>,
671309124Sdim               Requires<[IsISA3_0]>;
672309124Sdim  def CMPEQB : X_BF3_RS5_RS5<31, 224, (outs crbitrc:$BF),
673309124Sdim                             (ins g8rc:$rA, g8rc:$rB), "cmpeqb $BF, $rA, $rB",
674309124Sdim                             IIC_IntCompare, []>, Requires<[IsISA3_0]>;
675198090Srdivacky}
676193323Sed
677280031Sdimlet hasSideEffects = 0 in {
678251662Sdimdefm SLD  : XForm_6r<31,  27, (outs g8rc:$rA), (ins g8rc:$rS, gprc:$rB),
679276479Sdim                     "sld", "$rA, $rS, $rB", IIC_IntRotateD,
680251662Sdim                     [(set i64:$rA, (PPCshl i64:$rS, i32:$rB))]>, isPPC64;
681251662Sdimdefm SRD  : XForm_6r<31, 539, (outs g8rc:$rA), (ins g8rc:$rS, gprc:$rB),
682276479Sdim                     "srd", "$rA, $rS, $rB", IIC_IntRotateD,
683251662Sdim                     [(set i64:$rA, (PPCsrl i64:$rS, i32:$rB))]>, isPPC64;
684251662Sdimdefm SRAD : XForm_6rc<31, 794, (outs g8rc:$rA), (ins g8rc:$rS, gprc:$rB),
685276479Sdim                      "srad", "$rA, $rS, $rB", IIC_IntRotateD,
686251662Sdim                      [(set i64:$rA, (PPCsra i64:$rS, i32:$rB))]>, isPPC64;
687193323Sed
688280031Sdimlet Interpretation64Bit = 1, isCodeGenOnly = 1 in {
689280031Sdimdefm CNTLZW8 : XForm_11r<31,  26, (outs g8rc:$rA), (ins g8rc:$rS),
690280031Sdim                        "cntlzw", "$rA, $rS", IIC_IntGeneral, []>;
691309124Sdimdefm CNTTZW8 : XForm_11r<31, 538, (outs g8rc:$rA), (ins g8rc:$rS),
692309124Sdim                        "cnttzw", "$rA, $rS", IIC_IntGeneral, []>,
693309124Sdim               Requires<[IsISA3_0]>;
694280031Sdim
695251662Sdimdefm EXTSB8 : XForm_11r<31, 954, (outs g8rc:$rA), (ins g8rc:$rS),
696276479Sdim                        "extsb", "$rA, $rS", IIC_IntSimple,
697251662Sdim                        [(set i64:$rA, (sext_inreg i64:$rS, i8))]>;
698251662Sdimdefm EXTSH8 : XForm_11r<31, 922, (outs g8rc:$rA), (ins g8rc:$rS),
699276479Sdim                        "extsh", "$rA, $rS", IIC_IntSimple,
700251662Sdim                        [(set i64:$rA, (sext_inreg i64:$rS, i16))]>;
701280031Sdim
702280031Sdimdefm SLW8  : XForm_6r<31,  24, (outs g8rc:$rA), (ins g8rc:$rS, g8rc:$rB),
703280031Sdim                      "slw", "$rA, $rS, $rB", IIC_IntGeneral, []>;
704280031Sdimdefm SRW8  : XForm_6r<31, 536, (outs g8rc:$rA), (ins g8rc:$rS, g8rc:$rB),
705280031Sdim                      "srw", "$rA, $rS, $rB", IIC_IntGeneral, []>;
706251662Sdim} // Interpretation64Bit
707193323Sed
708261991Sdim// For fast-isel:
709261991Sdimlet isCodeGenOnly = 1 in {
710261991Sdimdef EXTSB8_32_64 : XForm_11<31, 954, (outs g8rc:$rA), (ins gprc:$rS),
711276479Sdim                           "extsb $rA, $rS", IIC_IntSimple, []>, isPPC64;
712261991Sdimdef EXTSH8_32_64 : XForm_11<31, 922, (outs g8rc:$rA), (ins gprc:$rS),
713276479Sdim                           "extsh $rA, $rS", IIC_IntSimple, []>, isPPC64;
714261991Sdim} // isCodeGenOnly for fast-isel
715261991Sdim
716251662Sdimdefm EXTSW  : XForm_11r<31, 986, (outs g8rc:$rA), (ins g8rc:$rS),
717276479Sdim                        "extsw", "$rA, $rS", IIC_IntSimple,
718251662Sdim                        [(set i64:$rA, (sext_inreg i64:$rS, i32))]>, isPPC64;
719276479Sdimlet Interpretation64Bit = 1, isCodeGenOnly = 1 in
720251662Sdimdefm EXTSW_32_64 : XForm_11r<31, 986, (outs g8rc:$rA), (ins gprc:$rS),
721276479Sdim                             "extsw", "$rA, $rS", IIC_IntSimple,
722251662Sdim                             [(set i64:$rA, (sext i32:$rS))]>, isPPC64;
723321369Sdimlet isCodeGenOnly = 1 in
724321369Sdimdef EXTSW_32 : XForm_11<31, 986, (outs gprc:$rA), (ins gprc:$rS),
725321369Sdim                        "extsw $rA, $rS", IIC_IntSimple,
726321369Sdim                        []>, isPPC64;
727251662Sdim
728251662Sdimdefm SRADI  : XSForm_1rc<31, 413, (outs g8rc:$rA), (ins g8rc:$rS, u6imm:$SH),
729276479Sdim                         "sradi", "$rA, $rS, $SH", IIC_IntRotateDI,
730251662Sdim                         [(set i64:$rA, (sra i64:$rS, (i32 imm:$SH)))]>, isPPC64;
731327952Sdim
732353358Sdimlet Interpretation64Bit = 1, isCodeGenOnly = 1 in
733353358Sdimdefm EXTSWSLI_32_64 : XSForm_1r<31, 445, (outs g8rc:$rA),
734353358Sdim                                (ins gprc:$rS, u6imm:$SH),
735353358Sdim                                "extswsli", "$rA, $rS, $SH", IIC_IntRotateDI,
736353358Sdim                                [(set i64:$rA,
737353358Sdim                                      (PPCextswsli i32:$rS, (i32 imm:$SH)))]>,
738353358Sdim                                isPPC64, Requires<[IsISA3_0]>;
739327952Sdim
740353358Sdimdefm EXTSWSLI : XSForm_1rc<31, 445, (outs g8rc:$rA), (ins g8rc:$rS, u6imm:$SH),
741353358Sdim                           "extswsli", "$rA, $rS, $SH", IIC_IntRotateDI,
742353358Sdim                           []>, isPPC64, Requires<[IsISA3_0]>;
743353358Sdim
744321369Sdim// For fast-isel:
745327952Sdimlet isCodeGenOnly = 1, Defs = [CARRY] in
746321369Sdimdef SRADI_32  : XSForm_1<31, 413, (outs gprc:$rA), (ins gprc:$rS, u6imm:$SH),
747321369Sdim                         "sradi $rA, $rS, $SH", IIC_IntRotateDI, []>, isPPC64;
748321369Sdim
749309124Sdimdefm CNTLZD : XForm_11r<31,  58, (outs g8rc:$rA), (ins g8rc:$rS),
750276479Sdim                        "cntlzd", "$rA, $rS", IIC_IntGeneral,
751251662Sdim                        [(set i64:$rA, (ctlz i64:$rS))]>;
752309124Sdimdefm CNTTZD : XForm_11r<31, 570, (outs g8rc:$rA), (ins g8rc:$rS),
753309124Sdim                        "cnttzd", "$rA, $rS", IIC_IntGeneral,
754309124Sdim                        [(set i64:$rA, (cttz i64:$rS))]>, Requires<[IsISA3_0]>;
755261991Sdimdef POPCNTD : XForm_11<31, 506, (outs g8rc:$rA), (ins g8rc:$rS),
756276479Sdim                       "popcntd $rA, $rS", IIC_IntGeneral,
757261991Sdim                       [(set i64:$rA, (ctpop i64:$rS))]>;
758288943Sdimdef BPERMD : XForm_6<31, 252, (outs g8rc:$rA), (ins g8rc:$rS, g8rc:$rB),
759288943Sdim                     "bpermd $rA, $rS, $rB", IIC_IntGeneral,
760288943Sdim                     [(set i64:$rA, (int_ppc_bpermd g8rc:$rS, g8rc:$rB))]>,
761288943Sdim                     isPPC64, Requires<[HasBPERMD]>;
762251662Sdim
763280031Sdimlet isCodeGenOnly = 1, isCommutable = 1 in
764280031Sdimdef CMPB8 : XForm_6<31, 508, (outs g8rc:$rA), (ins g8rc:$rS, g8rc:$rB),
765280031Sdim                    "cmpb $rA, $rS, $rB", IIC_IntGeneral,
766280031Sdim                    [(set i64:$rA, (PPCcmpb i64:$rS, i64:$rB))]>;
767280031Sdim
768249423Sdim// popcntw also does a population count on the high 32 bits (storing the
769249423Sdim// results in the high 32-bits of the output). We'll ignore that here (which is
770249423Sdim// safe because we never separately use the high part of the 64-bit registers).
771261991Sdimdef POPCNTW : XForm_11<31, 378, (outs gprc:$rA), (ins gprc:$rS),
772276479Sdim                       "popcntw $rA, $rS", IIC_IntGeneral,
773261991Sdim                       [(set i32:$rA, (ctpop i32:$rS))]>;
774249423Sdim
775327952Sdimdef POPCNTB : XForm_11<31, 122, (outs gprc:$rA), (ins gprc:$rS),
776327952Sdim                       "popcntb $rA, $rS", IIC_IntGeneral, []>;
777327952Sdim
778288943Sdimdefm DIVD  : XOForm_1rcr<31, 489, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB),
779288943Sdim                          "divd", "$rT, $rA, $rB", IIC_IntDivD,
780288943Sdim                          [(set i64:$rT, (sdiv i64:$rA, i64:$rB))]>, isPPC64;
781288943Sdimdefm DIVDU : XOForm_1rcr<31, 457, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB),
782288943Sdim                          "divdu", "$rT, $rA, $rB", IIC_IntDivD,
783288943Sdim                          [(set i64:$rT, (udiv i64:$rA, i64:$rB))]>, isPPC64;
784360661Sdimdefm DIVDE : XOForm_1rcr<31, 425, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB),
785360661Sdim                         "divde", "$rT, $rA, $rB", IIC_IntDivD,
786360661Sdim                         [(set i64:$rT, (int_ppc_divde g8rc:$rA, g8rc:$rB))]>,
787360661Sdim                         isPPC64, Requires<[HasExtDiv]>;
788321369Sdim
789321369Sdimlet Predicates = [IsISA3_0] in {
790327952Sdimdef MADDHD : VAForm_1a<48, (outs g8rc :$RT), (ins g8rc:$RA, g8rc:$RB, g8rc:$RC),
791327952Sdim                       "maddhd $RT, $RA, $RB, $RC", IIC_IntMulHD, []>, isPPC64;
792353358Sdimdef MADDHDU : VAForm_1a<49, 
793353358Sdim                       (outs g8rc :$RT), (ins g8rc:$RA, g8rc:$RB, g8rc:$RC),
794327952Sdim                       "maddhdu $RT, $RA, $RB, $RC", IIC_IntMulHD, []>, isPPC64;
795353358Sdimdef MADDLD : VAForm_1a<51, (outs gprc :$RT), (ins gprc:$RA, gprc:$RB, gprc:$RC),
796353358Sdim                       "maddld $RT, $RA, $RB, $RC", IIC_IntMulHD,
797353358Sdim                       [(set i32:$RT, (add_without_simm16 (mul_without_simm16 i32:$RA, i32:$RB), i32:$RC))]>,
798353358Sdim                       isPPC64;
799344779Sdimdef SETB : XForm_44<31, 128, (outs gprc:$RT), (ins crrc:$BFA),
800344779Sdim                       "setb $RT, $BFA", IIC_IntGeneral>, isPPC64;
801344779Sdimlet Interpretation64Bit = 1, isCodeGenOnly = 1 in {
802353358Sdim  def MADDLD8 : VAForm_1a<51, 
803353358Sdim                       (outs g8rc :$RT), (ins g8rc:$RA, g8rc:$RB, g8rc:$RC),
804353358Sdim                       "maddld $RT, $RA, $RB, $RC", IIC_IntMulHD,
805353358Sdim                       [(set i64:$RT, (add_without_simm16 (mul_without_simm16 i64:$RA, i64:$RB), i64:$RC))]>,
806353358Sdim                       isPPC64;
807344779Sdim  def SETB8 : XForm_44<31, 128, (outs g8rc:$RT), (ins crrc:$BFA),
808344779Sdim                       "setb $RT, $BFA", IIC_IntGeneral>, isPPC64;
809344779Sdim}
810327952Sdimdef DARN : XForm_45<31, 755, (outs g8rc:$RT), (ins i32imm:$L),
811327952Sdim                     "darn $RT, $L", IIC_LdStLD>, isPPC64;
812327952Sdimdef ADDPCIS : DXForm<19, 2, (outs g8rc:$RT), (ins i32imm:$D),
813327952Sdim                     "addpcis $RT, $D", IIC_BrB, []>, isPPC64;
814321369Sdimdef MODSD : XForm_8<31, 777, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB),
815321369Sdim                        "modsd $rT, $rA, $rB", IIC_IntDivW,
816321369Sdim                        [(set i64:$rT, (srem i64:$rA, i64:$rB))]>;
817321369Sdimdef MODUD : XForm_8<31, 265, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB),
818321369Sdim                        "modud $rT, $rA, $rB", IIC_IntDivW,
819321369Sdim                        [(set i64:$rT, (urem i64:$rA, i64:$rB))]>;
820321369Sdim}
821321369Sdim
822360661Sdimdefm DIVDEU : XOForm_1rcr<31, 393, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB),
823360661Sdim                          "divdeu", "$rT, $rA, $rB", IIC_IntDivD,
824360661Sdim                          [(set i64:$rT, (int_ppc_divdeu g8rc:$rA, g8rc:$rB))]>,
825360661Sdim                          isPPC64, Requires<[HasExtDiv]>;
826276479Sdimlet isCommutable = 1 in
827360661Sdimdefm MULLD : XOForm_1rx<31, 233, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB),
828360661Sdim                        "mulld", "$rT, $rA, $rB", IIC_IntMulHD,
829360661Sdim                        [(set i64:$rT, (mul i64:$rA, i64:$rB))]>, isPPC64;
830276479Sdimlet Interpretation64Bit = 1, isCodeGenOnly = 1 in
831261991Sdimdef MULLI8 : DForm_2<7, (outs g8rc:$rD), (ins g8rc:$rA, s16imm64:$imm),
832276479Sdim                       "mulli $rD, $rA, $imm", IIC_IntMulLI,
833261991Sdim                       [(set i64:$rD, (mul i64:$rA, imm64SExt16:$imm))]>;
834251662Sdim}
835193323Sed
836280031Sdimlet hasSideEffects = 0 in {
837251662Sdimdefm RLDIMI : MDForm_1r<30, 3, (outs g8rc:$rA),
838251662Sdim                        (ins g8rc:$rSi, g8rc:$rS, u6imm:$SH, u6imm:$MBE),
839276479Sdim                        "rldimi", "$rA, $rS, $SH, $MBE", IIC_IntRotateDI,
840251662Sdim                        []>, isPPC64, RegConstraint<"$rSi = $rA">,
841251662Sdim                        NoEncode<"$rSi">;
842193323Sed
843193323Sed// Rotate instructions.
844251662Sdimdefm RLDCL  : MDSForm_1r<30, 8,
845251662Sdim                        (outs g8rc:$rA), (ins g8rc:$rS, gprc:$rB, u6imm:$MBE),
846276479Sdim                        "rldcl", "$rA, $rS, $rB, $MBE", IIC_IntRotateD,
847251662Sdim                        []>, isPPC64;
848261991Sdimdefm RLDCR  : MDSForm_1r<30, 9,
849261991Sdim                        (outs g8rc:$rA), (ins g8rc:$rS, gprc:$rB, u6imm:$MBE),
850276479Sdim                        "rldcr", "$rA, $rS, $rB, $MBE", IIC_IntRotateD,
851261991Sdim                        []>, isPPC64;
852251662Sdimdefm RLDICL : MDForm_1r<30, 0,
853251662Sdim                        (outs g8rc:$rA), (ins g8rc:$rS, u6imm:$SH, u6imm:$MBE),
854276479Sdim                        "rldicl", "$rA, $rS, $SH, $MBE", IIC_IntRotateDI,
855251662Sdim                        []>, isPPC64;
856261991Sdim// For fast-isel:
857261991Sdimlet isCodeGenOnly = 1 in
858261991Sdimdef RLDICL_32_64 : MDForm_1<30, 0,
859321369Sdim                            (outs g8rc:$rA),
860321369Sdim                            (ins gprc:$rS, u6imm:$SH, u6imm:$MBE),
861321369Sdim                            "rldicl $rA, $rS, $SH, $MBE", IIC_IntRotateDI,
862321369Sdim                            []>, isPPC64;
863321369Sdim// End fast-isel.
864321369Sdimlet Interpretation64Bit = 1, isCodeGenOnly = 1 in
865321369Sdimdefm RLDICL_32 : MDForm_1r<30, 0,
866321369Sdim                           (outs gprc:$rA),
867261991Sdim                           (ins gprc:$rS, u6imm:$SH, u6imm:$MBE),
868321369Sdim                           "rldicl", "$rA, $rS, $SH, $MBE", IIC_IntRotateDI,
869261991Sdim                           []>, isPPC64;
870251662Sdimdefm RLDICR : MDForm_1r<30, 1,
871251662Sdim                        (outs g8rc:$rA), (ins g8rc:$rS, u6imm:$SH, u6imm:$MBE),
872276479Sdim                        "rldicr", "$rA, $rS, $SH, $MBE", IIC_IntRotateDI,
873251662Sdim                        []>, isPPC64;
874321369Sdimlet isCodeGenOnly = 1 in
875321369Sdimdef RLDICR_32 : MDForm_1<30, 1,
876321369Sdim                         (outs gprc:$rA), (ins gprc:$rS, u6imm:$SH, u6imm:$MBE),
877321369Sdim                         "rldicr $rA, $rS, $SH, $MBE", IIC_IntRotateDI,
878321369Sdim                         []>, isPPC64;
879261991Sdimdefm RLDIC  : MDForm_1r<30, 2,
880261991Sdim                        (outs g8rc:$rA), (ins g8rc:$rS, u6imm:$SH, u6imm:$MBE),
881276479Sdim                        "rldic", "$rA, $rS, $SH, $MBE", IIC_IntRotateDI,
882261991Sdim                        []>, isPPC64;
883234353Sdim
884276479Sdimlet Interpretation64Bit = 1, isCodeGenOnly = 1 in {
885251662Sdimdefm RLWINM8 : MForm_2r<21, (outs g8rc:$rA),
886251662Sdim                        (ins g8rc:$rS, u5imm:$SH, u5imm:$MB, u5imm:$ME),
887276479Sdim                        "rlwinm", "$rA, $rS, $SH, $MB, $ME", IIC_IntGeneral,
888251662Sdim                        []>;
889234353Sdim
890280031Sdimdefm RLWNM8  : MForm_2r<23, (outs g8rc:$rA),
891280031Sdim                        (ins g8rc:$rS, g8rc:$rB, u5imm:$MB, u5imm:$ME),
892280031Sdim                        "rlwnm", "$rA, $rS, $rB, $MB, $ME", IIC_IntGeneral,
893280031Sdim                        []>;
894280031Sdim
895276479Sdim// RLWIMI can be commuted if the rotate amount is zero.
896276479Sdimlet Interpretation64Bit = 1, isCodeGenOnly = 1 in
897276479Sdimdefm RLWIMI8 : MForm_2r<20, (outs g8rc:$rA),
898276479Sdim                        (ins g8rc:$rSi, g8rc:$rS, u5imm:$SH, u5imm:$MB,
899276479Sdim                        u5imm:$ME), "rlwimi", "$rA, $rS, $SH, $MB, $ME",
900276479Sdim                        IIC_IntRotate, []>, PPC970_DGroup_Cracked,
901276479Sdim                        RegConstraint<"$rSi = $rA">, NoEncode<"$rSi">;
902276479Sdim
903251662Sdimlet isSelect = 1 in
904243830Sdimdef ISEL8   : AForm_4<31, 15,
905251662Sdim                     (outs g8rc:$rT), (ins g8rc_nox0:$rA, g8rc:$rB, crbitrc:$cond),
906288943Sdim                     "isel $rT, $rA, $rB, $cond", IIC_IntISEL,
907239462Sdim                     []>;
908251662Sdim}  // Interpretation64Bit
909280031Sdim}  // hasSideEffects = 0
910193323Sed}  // End FXU Operations.
911193323Sed
912193323Sed
913193323Sed//===----------------------------------------------------------------------===//
914193323Sed// Load/Store instructions.
915193323Sed//
916193323Sed
917193323Sed
918193323Sed// Sign extending loads.
919288943Sdimlet PPC970_Unit = 2 in {
920276479Sdimlet Interpretation64Bit = 1, isCodeGenOnly = 1 in
921251662Sdimdef LHA8: DForm_1<42, (outs g8rc:$rD), (ins memri:$src),
922276479Sdim                  "lha $rD, $src", IIC_LdStLHA,
923249423Sdim                  [(set i64:$rD, (sextloadi16 iaddr:$src))]>,
924193323Sed                  PPC970_DGroup_Cracked;
925251662Sdimdef LWA  : DSForm_1<58, 2, (outs g8rc:$rD), (ins memrix:$src),
926276479Sdim                    "lwa $rD, $src", IIC_LdStLWA,
927249423Sdim                    [(set i64:$rD,
928353358Sdim                          (aligned4sextloadi32 iaddrX4:$src))]>, isPPC64,
929193323Sed                    PPC970_DGroup_Cracked;
930276479Sdimlet Interpretation64Bit = 1, isCodeGenOnly = 1 in
931341825Sdimdef LHAX8: XForm_1_memOp<31, 343, (outs g8rc:$rD), (ins memrr:$src),
932341825Sdim                        "lhax $rD, $src", IIC_LdStLHA,
933341825Sdim                        [(set i64:$rD, (sextloadi16 xaddr:$src))]>,
934341825Sdim                        PPC970_DGroup_Cracked;
935341825Sdimdef LWAX : XForm_1_memOp<31, 341, (outs g8rc:$rD), (ins memrr:$src),
936341825Sdim                        "lwax $rD, $src", IIC_LdStLHA,
937353358Sdim                        [(set i64:$rD, (sextloadi32 xaddrX4:$src))]>, isPPC64,
938341825Sdim                        PPC970_DGroup_Cracked;
939261991Sdim// For fast-isel:
940360784Sdimlet isCodeGenOnly = 1, mayLoad = 1, hasSideEffects = 0 in {
941261991Sdimdef LWA_32  : DSForm_1<58, 2, (outs gprc:$rD), (ins memrix:$src),
942276479Sdim                      "lwa $rD, $src", IIC_LdStLWA, []>, isPPC64,
943261991Sdim                      PPC970_DGroup_Cracked;
944341825Sdimdef LWAX_32 : XForm_1_memOp<31, 341, (outs gprc:$rD), (ins memrr:$src),
945341825Sdim                            "lwax $rD, $src", IIC_LdStLHA, []>, isPPC64,
946341825Sdim                            PPC970_DGroup_Cracked;
947261991Sdim} // end fast-isel isCodeGenOnly
948193323Sed
949193323Sed// Update forms.
950280031Sdimlet mayLoad = 1, hasSideEffects = 0 in {
951276479Sdimlet Interpretation64Bit = 1, isCodeGenOnly = 1 in
952251662Sdimdef LHAU8 : DForm_1<43, (outs g8rc:$rD, ptr_rc_nor0:$ea_result),
953249423Sdim                    (ins memri:$addr),
954276479Sdim                    "lhau $rD, $addr", IIC_LdStLHAU,
955249423Sdim                    []>, RegConstraint<"$addr.reg = $ea_result">,
956193323Sed                    NoEncode<"$ea_result">;
957193323Sed// NO LWAU!
958193323Sed
959276479Sdimlet Interpretation64Bit = 1, isCodeGenOnly = 1 in
960341825Sdimdef LHAUX8 : XForm_1_memOp<31, 375, (outs g8rc:$rD, ptr_rc_nor0:$ea_result),
961341825Sdim                          (ins memrr:$addr),
962341825Sdim                          "lhaux $rD, $addr", IIC_LdStLHAUX,
963341825Sdim                          []>, RegConstraint<"$addr.ptrreg = $ea_result">,
964341825Sdim                          NoEncode<"$ea_result">;
965341825Sdimdef LWAUX : XForm_1_memOp<31, 373, (outs g8rc:$rD, ptr_rc_nor0:$ea_result),
966341825Sdim                          (ins memrr:$addr),
967341825Sdim                          "lwaux $rD, $addr", IIC_LdStLHAUX,
968341825Sdim                          []>, RegConstraint<"$addr.ptrreg = $ea_result">,
969341825Sdim                          NoEncode<"$ea_result">, isPPC64;
970193323Sed}
971249423Sdim}
972193323Sed
973276479Sdimlet Interpretation64Bit = 1, isCodeGenOnly = 1 in {
974193323Sed// Zero extending loads.
975288943Sdimlet PPC970_Unit = 2 in {
976251662Sdimdef LBZ8 : DForm_1<34, (outs g8rc:$rD), (ins memri:$src),
977276479Sdim                  "lbz $rD, $src", IIC_LdStLoad,
978249423Sdim                  [(set i64:$rD, (zextloadi8 iaddr:$src))]>;
979251662Sdimdef LHZ8 : DForm_1<40, (outs g8rc:$rD), (ins memri:$src),
980276479Sdim                  "lhz $rD, $src", IIC_LdStLoad,
981249423Sdim                  [(set i64:$rD, (zextloadi16 iaddr:$src))]>;
982251662Sdimdef LWZ8 : DForm_1<32, (outs g8rc:$rD), (ins memri:$src),
983276479Sdim                  "lwz $rD, $src", IIC_LdStLoad,
984249423Sdim                  [(set i64:$rD, (zextloadi32 iaddr:$src))]>, isPPC64;
985193323Sed
986341825Sdimdef LBZX8 : XForm_1_memOp<31,  87, (outs g8rc:$rD), (ins memrr:$src),
987341825Sdim                          "lbzx $rD, $src", IIC_LdStLoad,
988341825Sdim                          [(set i64:$rD, (zextloadi8 xaddr:$src))]>;
989341825Sdimdef LHZX8 : XForm_1_memOp<31, 279, (outs g8rc:$rD), (ins memrr:$src),
990341825Sdim                          "lhzx $rD, $src", IIC_LdStLoad,
991341825Sdim                          [(set i64:$rD, (zextloadi16 xaddr:$src))]>;
992341825Sdimdef LWZX8 : XForm_1_memOp<31,  23, (outs g8rc:$rD), (ins memrr:$src),
993341825Sdim                          "lwzx $rD, $src", IIC_LdStLoad,
994341825Sdim                          [(set i64:$rD, (zextloadi32 xaddr:$src))]>;
995193323Sed                   
996193323Sed                   
997193323Sed// Update forms.
998280031Sdimlet mayLoad = 1, hasSideEffects = 0 in {
999341825Sdimdef LBZU8 : DForm_1<35, (outs g8rc:$rD, ptr_rc_nor0:$ea_result),
1000341825Sdim                    (ins memri:$addr),
1001276479Sdim                    "lbzu $rD, $addr", IIC_LdStLoadUpd,
1002193323Sed                    []>, RegConstraint<"$addr.reg = $ea_result">,
1003193323Sed                    NoEncode<"$ea_result">;
1004341825Sdimdef LHZU8 : DForm_1<41, (outs g8rc:$rD, ptr_rc_nor0:$ea_result),
1005341825Sdim                    (ins memri:$addr),
1006276479Sdim                    "lhzu $rD, $addr", IIC_LdStLoadUpd,
1007193323Sed                    []>, RegConstraint<"$addr.reg = $ea_result">,
1008193323Sed                    NoEncode<"$ea_result">;
1009341825Sdimdef LWZU8 : DForm_1<33, (outs g8rc:$rD, ptr_rc_nor0:$ea_result),
1010341825Sdim                    (ins memri:$addr),
1011276479Sdim                    "lwzu $rD, $addr", IIC_LdStLoadUpd,
1012193323Sed                    []>, RegConstraint<"$addr.reg = $ea_result">,
1013193323Sed                    NoEncode<"$ea_result">;
1014239462Sdim
1015341825Sdimdef LBZUX8 : XForm_1_memOp<31, 119, (outs g8rc:$rD, ptr_rc_nor0:$ea_result),
1016341825Sdim                          (ins memrr:$addr),
1017341825Sdim                          "lbzux $rD, $addr", IIC_LdStLoadUpdX,
1018341825Sdim                          []>, RegConstraint<"$addr.ptrreg = $ea_result">,
1019341825Sdim                          NoEncode<"$ea_result">;
1020341825Sdimdef LHZUX8 : XForm_1_memOp<31, 311, (outs g8rc:$rD, ptr_rc_nor0:$ea_result),
1021341825Sdim                          (ins memrr:$addr),
1022341825Sdim                          "lhzux $rD, $addr", IIC_LdStLoadUpdX,
1023341825Sdim                          []>, RegConstraint<"$addr.ptrreg = $ea_result">,
1024341825Sdim                          NoEncode<"$ea_result">;
1025341825Sdimdef LWZUX8 : XForm_1_memOp<31, 55, (outs g8rc:$rD, ptr_rc_nor0:$ea_result),
1026341825Sdim                          (ins memrr:$addr),
1027341825Sdim                          "lwzux $rD, $addr", IIC_LdStLoadUpdX,
1028341825Sdim                          []>, RegConstraint<"$addr.ptrreg = $ea_result">,
1029341825Sdim                          NoEncode<"$ea_result">;
1030193323Sed}
1031193323Sed}
1032251662Sdim} // Interpretation64Bit
1033193323Sed
1034193323Sed
1035193323Sed// Full 8-byte loads.
1036288943Sdimlet PPC970_Unit = 2 in {
1037251662Sdimdef LD   : DSForm_1<58, 0, (outs g8rc:$rD), (ins memrix:$src),
1038276479Sdim                    "ld $rD, $src", IIC_LdStLD,
1039353358Sdim                    [(set i64:$rD, (aligned4load iaddrX4:$src))]>, isPPC64;
1040277320Sdim// The following four definitions are selected for small code model only.
1041249423Sdim// Otherwise, we need to create two instructions to form a 32-bit offset,
1042249423Sdim// so we have a custom matcher for TOC_ENTRY in PPCDAGToDAGIsel::Select().
1043344779Sdimdef LDtoc: PPCEmitTimePseudo<(outs g8rc:$rD), (ins tocentry:$disp, g8rc:$reg),
1044243830Sdim                  "#LDtoc",
1045249423Sdim                  [(set i64:$rD,
1046249423Sdim                     (PPCtoc_entry tglobaladdr:$disp, i64:$reg))]>, isPPC64;
1047344779Sdimdef LDtocJTI: PPCEmitTimePseudo<(outs g8rc:$rD), (ins tocentry:$disp, g8rc:$reg),
1048243830Sdim                  "#LDtocJTI",
1049249423Sdim                  [(set i64:$rD,
1050249423Sdim                     (PPCtoc_entry tjumptable:$disp, i64:$reg))]>, isPPC64;
1051344779Sdimdef LDtocCPT: PPCEmitTimePseudo<(outs g8rc:$rD), (ins tocentry:$disp, g8rc:$reg),
1052243830Sdim                  "#LDtocCPT",
1053249423Sdim                  [(set i64:$rD,
1054249423Sdim                     (PPCtoc_entry tconstpool:$disp, i64:$reg))]>, isPPC64;
1055344779Sdimdef LDtocBA: PPCEmitTimePseudo<(outs g8rc:$rD), (ins tocentry:$disp, g8rc:$reg),
1056277320Sdim                  "#LDtocCPT",
1057277320Sdim                  [(set i64:$rD,
1058277320Sdim                     (PPCtoc_entry tblockaddress:$disp, i64:$reg))]>, isPPC64;
1059234353Sdim
1060341825Sdimdef LDX  : XForm_1_memOp<31,  21, (outs g8rc:$rD), (ins memrr:$src),
1061341825Sdim                        "ldx $rD, $src", IIC_LdStLD,
1062353358Sdim                        [(set i64:$rD, (load xaddrX4:$src))]>, isPPC64;
1063341825Sdimdef LDBRX : XForm_1_memOp<31,  532, (outs g8rc:$rD), (ins memrr:$src),
1064341825Sdim                          "ldbrx $rD, $src", IIC_LdStLoad,
1065341825Sdim                          [(set i64:$rD, (PPClbrx xoaddr:$src, i64))]>, isPPC64;
1066249423Sdim
1067280031Sdimlet mayLoad = 1, hasSideEffects = 0, isCodeGenOnly = 1 in {
1068341825Sdimdef LHBRX8 : XForm_1_memOp<31, 790, (outs g8rc:$rD), (ins memrr:$src),
1069341825Sdim                          "lhbrx $rD, $src", IIC_LdStLoad, []>;
1070341825Sdimdef LWBRX8 : XForm_1_memOp<31,  534, (outs g8rc:$rD), (ins memrr:$src),
1071341825Sdim                          "lwbrx $rD, $src", IIC_LdStLoad, []>;
1072280031Sdim}
1073280031Sdim
1074280031Sdimlet mayLoad = 1, hasSideEffects = 0 in {
1075341825Sdimdef LDU  : DSForm_1<58, 1, (outs g8rc:$rD, ptr_rc_nor0:$ea_result),
1076341825Sdim                    (ins memrix:$addr),
1077276479Sdim                    "ldu $rD, $addr", IIC_LdStLDU,
1078193323Sed                    []>, RegConstraint<"$addr.reg = $ea_result">, isPPC64,
1079193323Sed                    NoEncode<"$ea_result">;
1080193323Sed
1081341825Sdimdef LDUX : XForm_1_memOp<31, 53, (outs g8rc:$rD, ptr_rc_nor0:$ea_result),
1082341825Sdim                        (ins memrr:$addr),
1083341825Sdim                        "ldux $rD, $addr", IIC_LdStLDUX,
1084341825Sdim                        []>, RegConstraint<"$addr.ptrreg = $ea_result">,
1085341825Sdim                        NoEncode<"$ea_result">, isPPC64;
1086309124Sdim
1087309124Sdimdef LDMX : XForm_1<31, 309, (outs g8rc:$rD), (ins memrr:$src),
1088309124Sdim                   "ldmx $rD, $src", IIC_LdStLD, []>, isPPC64,
1089341825Sdim                   Requires<[IsISA3_0]>;
1090193323Sed}
1091251662Sdim}
1092193323Sed
1093249423Sdim// Support for medium and large code model.
1094288943Sdimlet hasSideEffects = 0 in {
1095321369Sdimlet isReMaterializable = 1 in {
1096360784Sdimdef ADDIStocHA8: PPCEmitTimePseudo<(outs g8rc:$rD), (ins g8rc_nox0:$reg, tocentry:$disp),
1097360784Sdim                       "#ADDIStocHA8", []>, isPPC64;
1098344779Sdimdef ADDItocL: PPCEmitTimePseudo<(outs g8rc:$rD), (ins g8rc_nox0:$reg, tocentry:$disp),
1099321369Sdim                     "#ADDItocL", []>, isPPC64;
1100321369Sdim}
1101288943Sdimlet mayLoad = 1 in
1102344779Sdimdef LDtocL: PPCEmitTimePseudo<(outs g8rc:$rD), (ins tocentry:$disp, g8rc_nox0:$reg),
1103288943Sdim                   "#LDtocL", []>, isPPC64;
1104288943Sdim}
1105249423Sdim
1106249423Sdim// Support for thread-local storage.
1107344779Sdimdef ADDISgotTprelHA: PPCEmitTimePseudo<(outs g8rc:$rD), (ins g8rc_nox0:$reg, s16imm64:$disp),
1108249423Sdim                         "#ADDISgotTprelHA",
1109249423Sdim                         [(set i64:$rD,
1110249423Sdim                           (PPCaddisGotTprelHA i64:$reg,
1111249423Sdim                                               tglobaltlsaddr:$disp))]>,
1112249423Sdim                  isPPC64;
1113360784Sdimdef LDgotTprelL: PPCEmitTimePseudo<(outs g8rc_nox0:$rD), (ins s16imm64:$disp, g8rc_nox0:$reg),
1114249423Sdim                        "#LDgotTprelL",
1115249423Sdim                        [(set i64:$rD,
1116249423Sdim                          (PPCldGotTprelL tglobaltlsaddr:$disp, i64:$reg))]>,
1117249423Sdim                 isPPC64;
1118321369Sdim
1119344779Sdimlet Defs = [CR7], Itinerary = IIC_LdStSync in
1120344779Sdimdef CFENCE8 : PPCPostRAExpPseudo<(outs), (ins g8rc:$cr), "#CFENCE8", []>;
1121321369Sdim
1122249423Sdimdef : Pat<(PPCaddTls i64:$in, tglobaltlsaddr:$g),
1123249423Sdim          (ADD8TLS $in, tglobaltlsaddr:$g)>;
1124344779Sdimdef ADDIStlsgdHA: PPCEmitTimePseudo<(outs g8rc:$rD), (ins g8rc_nox0:$reg, s16imm64:$disp),
1125249423Sdim                         "#ADDIStlsgdHA",
1126249423Sdim                         [(set i64:$rD,
1127249423Sdim                           (PPCaddisTlsgdHA i64:$reg, tglobaltlsaddr:$disp))]>,
1128249423Sdim                  isPPC64;
1129344779Sdimdef ADDItlsgdL : PPCEmitTimePseudo<(outs g8rc:$rD), (ins g8rc_nox0:$reg, s16imm64:$disp),
1130249423Sdim                       "#ADDItlsgdL",
1131249423Sdim                       [(set i64:$rD,
1132249423Sdim                         (PPCaddiTlsgdL i64:$reg, tglobaltlsaddr:$disp))]>,
1133249423Sdim                 isPPC64;
1134288943Sdim// LR8 is a true define, while the rest of the Defs are clobbers.  X3 is
1135288943Sdim// explicitly defined when this op is created, so not mentioned here.
1136321369Sdim// This is lowered to BL8_NOP_TLS by the assembly printer, so the size must be
1137321369Sdim// correct because the branch select pass is relying on it.
1138321369Sdimlet hasExtraSrcRegAllocReq = 1, hasExtraDefRegAllocReq = 1, Size = 8,
1139288943Sdim    Defs = [X0,X4,X5,X6,X7,X8,X9,X10,X11,X12,LR8,CTR8,CR0,CR1,CR5,CR6,CR7] in
1140344779Sdimdef GETtlsADDR : PPCEmitTimePseudo<(outs g8rc:$rD), (ins g8rc:$reg, tlsgd:$sym),
1141288943Sdim                        "#GETtlsADDR",
1142288943Sdim                        [(set i64:$rD,
1143288943Sdim                          (PPCgetTlsAddr i64:$reg, tglobaltlsaddr:$sym))]>,
1144288943Sdim                 isPPC64;
1145288943Sdim// Combined op for ADDItlsgdL and GETtlsADDR, late expanded.  X3 and LR8
1146288943Sdim// are true defines while the rest of the Defs are clobbers.
1147288943Sdimlet hasExtraSrcRegAllocReq = 1, hasExtraDefRegAllocReq = 1,
1148288943Sdim    Defs = [X0,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12,LR8,CTR8,CR0,CR1,CR5,CR6,CR7]
1149288943Sdim    in
1150344779Sdimdef ADDItlsgdLADDR : PPCEmitTimePseudo<(outs g8rc:$rD),
1151288943Sdim                            (ins g8rc_nox0:$reg, s16imm64:$disp, tlsgd:$sym),
1152288943Sdim                            "#ADDItlsgdLADDR",
1153288943Sdim                            [(set i64:$rD,
1154288943Sdim                              (PPCaddiTlsgdLAddr i64:$reg,
1155288943Sdim                                                 tglobaltlsaddr:$disp,
1156288943Sdim                                                 tglobaltlsaddr:$sym))]>,
1157288943Sdim                     isPPC64;
1158344779Sdimdef ADDIStlsldHA: PPCEmitTimePseudo<(outs g8rc:$rD), (ins g8rc_nox0:$reg, s16imm64:$disp),
1159249423Sdim                         "#ADDIStlsldHA",
1160249423Sdim                         [(set i64:$rD,
1161249423Sdim                           (PPCaddisTlsldHA i64:$reg, tglobaltlsaddr:$disp))]>,
1162249423Sdim                  isPPC64;
1163344779Sdimdef ADDItlsldL : PPCEmitTimePseudo<(outs g8rc:$rD), (ins g8rc_nox0:$reg, s16imm64:$disp),
1164249423Sdim                       "#ADDItlsldL",
1165249423Sdim                       [(set i64:$rD,
1166249423Sdim                         (PPCaddiTlsldL i64:$reg, tglobaltlsaddr:$disp))]>,
1167249423Sdim                 isPPC64;
1168288943Sdim// LR8 is a true define, while the rest of the Defs are clobbers.  X3 is
1169288943Sdim// explicitly defined when this op is created, so not mentioned here.
1170288943Sdimlet hasExtraSrcRegAllocReq = 1, hasExtraDefRegAllocReq = 1,
1171288943Sdim    Defs = [X0,X4,X5,X6,X7,X8,X9,X10,X11,X12,LR8,CTR8,CR0,CR1,CR5,CR6,CR7] in
1172344779Sdimdef GETtlsldADDR : PPCEmitTimePseudo<(outs g8rc:$rD), (ins g8rc:$reg, tlsgd:$sym),
1173288943Sdim                          "#GETtlsldADDR",
1174288943Sdim                          [(set i64:$rD,
1175288943Sdim                            (PPCgetTlsldAddr i64:$reg, tglobaltlsaddr:$sym))]>,
1176288943Sdim                   isPPC64;
1177288943Sdim// Combined op for ADDItlsldL and GETtlsADDR, late expanded.  X3 and LR8
1178288943Sdim// are true defines, while the rest of the Defs are clobbers.
1179288943Sdimlet hasExtraSrcRegAllocReq = 1, hasExtraDefRegAllocReq = 1,
1180288943Sdim    Defs = [X0,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12,LR8,CTR8,CR0,CR1,CR5,CR6,CR7]
1181288943Sdim    in
1182344779Sdimdef ADDItlsldLADDR : PPCEmitTimePseudo<(outs g8rc:$rD),
1183288943Sdim                            (ins g8rc_nox0:$reg, s16imm64:$disp, tlsgd:$sym),
1184288943Sdim                            "#ADDItlsldLADDR",
1185288943Sdim                            [(set i64:$rD,
1186288943Sdim                              (PPCaddiTlsldLAddr i64:$reg,
1187288943Sdim                                                 tglobaltlsaddr:$disp,
1188288943Sdim                                                 tglobaltlsaddr:$sym))]>,
1189288943Sdim                     isPPC64;
1190344779Sdimdef ADDISdtprelHA: PPCEmitTimePseudo<(outs g8rc:$rD), (ins g8rc_nox0:$reg, s16imm64:$disp),
1191249423Sdim                          "#ADDISdtprelHA",
1192249423Sdim                          [(set i64:$rD,
1193249423Sdim                            (PPCaddisDtprelHA i64:$reg,
1194249423Sdim                                              tglobaltlsaddr:$disp))]>,
1195249423Sdim                   isPPC64;
1196344779Sdimdef ADDIdtprelL : PPCEmitTimePseudo<(outs g8rc:$rD), (ins g8rc_nox0:$reg, s16imm64:$disp),
1197249423Sdim                         "#ADDIdtprelL",
1198249423Sdim                         [(set i64:$rD,
1199249423Sdim                           (PPCaddiDtprelL i64:$reg, tglobaltlsaddr:$disp))]>,
1200249423Sdim                  isPPC64;
1201249423Sdim
1202193323Sedlet PPC970_Unit = 2 in {
1203276479Sdimlet Interpretation64Bit = 1, isCodeGenOnly = 1 in {
1204193323Sed// Truncating stores.                       
1205251662Sdimdef STB8 : DForm_1<38, (outs), (ins g8rc:$rS, memri:$src),
1206276479Sdim                   "stb $rS, $src", IIC_LdStStore,
1207249423Sdim                   [(truncstorei8 i64:$rS, iaddr:$src)]>;
1208251662Sdimdef STH8 : DForm_1<44, (outs), (ins g8rc:$rS, memri:$src),
1209276479Sdim                   "sth $rS, $src", IIC_LdStStore,
1210249423Sdim                   [(truncstorei16 i64:$rS, iaddr:$src)]>;
1211251662Sdimdef STW8 : DForm_1<36, (outs), (ins g8rc:$rS, memri:$src),
1212276479Sdim                   "stw $rS, $src", IIC_LdStStore,
1213249423Sdim                   [(truncstorei32 i64:$rS, iaddr:$src)]>;
1214341825Sdimdef STBX8 : XForm_8_memOp<31, 215, (outs), (ins g8rc:$rS, memrr:$dst),
1215341825Sdim                          "stbx $rS, $dst", IIC_LdStStore,
1216341825Sdim                          [(truncstorei8 i64:$rS, xaddr:$dst)]>,
1217341825Sdim                          PPC970_DGroup_Cracked;
1218341825Sdimdef STHX8 : XForm_8_memOp<31, 407, (outs), (ins g8rc:$rS, memrr:$dst),
1219341825Sdim                          "sthx $rS, $dst", IIC_LdStStore,
1220341825Sdim                          [(truncstorei16 i64:$rS, xaddr:$dst)]>,
1221341825Sdim                          PPC970_DGroup_Cracked;
1222341825Sdimdef STWX8 : XForm_8_memOp<31, 151, (outs), (ins g8rc:$rS, memrr:$dst),
1223341825Sdim                          "stwx $rS, $dst", IIC_LdStStore,
1224341825Sdim                          [(truncstorei32 i64:$rS, xaddr:$dst)]>,
1225341825Sdim                          PPC970_DGroup_Cracked;
1226251662Sdim} // Interpretation64Bit
1227251662Sdim
1228193323Sed// Normal 8-byte stores.
1229251662Sdimdef STD  : DSForm_1<62, 0, (outs), (ins g8rc:$rS, memrix:$dst),
1230276479Sdim                    "std $rS, $dst", IIC_LdStSTD,
1231353358Sdim                    [(aligned4store i64:$rS, iaddrX4:$dst)]>, isPPC64;
1232341825Sdimdef STDX  : XForm_8_memOp<31, 149, (outs), (ins g8rc:$rS, memrr:$dst),
1233341825Sdim                          "stdx $rS, $dst", IIC_LdStSTD,
1234353358Sdim                          [(store i64:$rS, xaddrX4:$dst)]>, isPPC64,
1235341825Sdim                          PPC970_DGroup_Cracked;
1236341825Sdimdef STDBRX: XForm_8_memOp<31, 660, (outs), (ins g8rc:$rS, memrr:$dst),
1237341825Sdim                          "stdbrx $rS, $dst", IIC_LdStStore,
1238341825Sdim                          [(PPCstbrx i64:$rS, xoaddr:$dst, i64)]>, isPPC64,
1239341825Sdim                          PPC970_DGroup_Cracked;
1240193323Sed}
1241193323Sed
1242249423Sdim// Stores with Update (pre-inc).
1243321369Sdimlet PPC970_Unit = 2, mayStore = 1, mayLoad = 0 in {
1244276479Sdimlet Interpretation64Bit = 1, isCodeGenOnly = 1 in {
1245251662Sdimdef STBU8 : DForm_1<39, (outs ptr_rc_nor0:$ea_res), (ins g8rc:$rS, memri:$dst),
1246344779Sdim                   "stbu $rS, $dst", IIC_LdStSTU, []>,
1247249423Sdim                   RegConstraint<"$dst.reg = $ea_res">, NoEncode<"$ea_res">;
1248251662Sdimdef STHU8 : DForm_1<45, (outs ptr_rc_nor0:$ea_res), (ins g8rc:$rS, memri:$dst),
1249344779Sdim                   "sthu $rS, $dst", IIC_LdStSTU, []>,
1250249423Sdim                   RegConstraint<"$dst.reg = $ea_res">, NoEncode<"$ea_res">;
1251251662Sdimdef STWU8 : DForm_1<37, (outs ptr_rc_nor0:$ea_res), (ins g8rc:$rS, memri:$dst),
1252344779Sdim                   "stwu $rS, $dst", IIC_LdStSTU, []>,
1253249423Sdim                   RegConstraint<"$dst.reg = $ea_res">, NoEncode<"$ea_res">;
1254193323Sed
1255341825Sdimdef STBUX8: XForm_8_memOp<31, 247, (outs ptr_rc_nor0:$ea_res),
1256341825Sdim                          (ins g8rc:$rS, memrr:$dst),
1257344779Sdim                          "stbux $rS, $dst", IIC_LdStSTUX, []>,
1258341825Sdim                          RegConstraint<"$dst.ptrreg = $ea_res">,
1259341825Sdim                          NoEncode<"$ea_res">,
1260341825Sdim                          PPC970_DGroup_Cracked;
1261341825Sdimdef STHUX8: XForm_8_memOp<31, 439, (outs ptr_rc_nor0:$ea_res),
1262341825Sdim                          (ins g8rc:$rS, memrr:$dst),
1263344779Sdim                          "sthux $rS, $dst", IIC_LdStSTUX, []>,
1264341825Sdim                          RegConstraint<"$dst.ptrreg = $ea_res">,
1265341825Sdim                          NoEncode<"$ea_res">,
1266341825Sdim                          PPC970_DGroup_Cracked;
1267341825Sdimdef STWUX8: XForm_8_memOp<31, 183, (outs ptr_rc_nor0:$ea_res),
1268341825Sdim                          (ins g8rc:$rS, memrr:$dst),
1269344779Sdim                          "stwux $rS, $dst", IIC_LdStSTUX, []>,
1270341825Sdim                          RegConstraint<"$dst.ptrreg = $ea_res">,
1271341825Sdim                          NoEncode<"$ea_res">,
1272341825Sdim                          PPC970_DGroup_Cracked;
1273251662Sdim} // Interpretation64Bit
1274251662Sdim
1275341825Sdimdef STDU : DSForm_1<62, 1, (outs ptr_rc_nor0:$ea_res),
1276341825Sdim                   (ins g8rc:$rS, memrix:$dst),
1277344779Sdim                   "stdu $rS, $dst", IIC_LdStSTU, []>,
1278276479Sdim                   RegConstraint<"$dst.reg = $ea_res">, NoEncode<"$ea_res">,
1279276479Sdim                   isPPC64;
1280276479Sdim
1281341825Sdimdef STDUX : XForm_8_memOp<31, 181, (outs ptr_rc_nor0:$ea_res),
1282341825Sdim                          (ins g8rc:$rS, memrr:$dst),
1283344779Sdim                          "stdux $rS, $dst", IIC_LdStSTUX, []>,
1284341825Sdim                          RegConstraint<"$dst.ptrreg = $ea_res">,
1285341825Sdim                          NoEncode<"$ea_res">,
1286341825Sdim                          PPC970_DGroup_Cracked, isPPC64;
1287193323Sed}
1288193323Sed
1289249423Sdim// Patterns to match the pre-inc stores.  We can't put the patterns on
1290249423Sdim// the instruction definitions directly as ISel wants the address base
1291249423Sdim// and offset to be separate operands, not a single complex operand.
1292249423Sdimdef : Pat<(pre_truncsti8 i64:$rS, iPTR:$ptrreg, iaddroff:$ptroff),
1293249423Sdim          (STBU8 $rS, iaddroff:$ptroff, $ptrreg)>;
1294249423Sdimdef : Pat<(pre_truncsti16 i64:$rS, iPTR:$ptrreg, iaddroff:$ptroff),
1295249423Sdim          (STHU8 $rS, iaddroff:$ptroff, $ptrreg)>;
1296249423Sdimdef : Pat<(pre_truncsti32 i64:$rS, iPTR:$ptrreg, iaddroff:$ptroff),
1297249423Sdim          (STWU8 $rS, iaddroff:$ptroff, $ptrreg)>;
1298249423Sdimdef : Pat<(aligned4pre_store i64:$rS, iPTR:$ptrreg, iaddroff:$ptroff),
1299249423Sdim          (STDU $rS, iaddroff:$ptroff, $ptrreg)>;
1300193323Sed
1301249423Sdimdef : Pat<(pre_truncsti8 i64:$rS, iPTR:$ptrreg, iPTR:$ptroff),
1302249423Sdim          (STBUX8 $rS, $ptrreg, $ptroff)>;
1303249423Sdimdef : Pat<(pre_truncsti16 i64:$rS, iPTR:$ptrreg, iPTR:$ptroff),
1304249423Sdim          (STHUX8 $rS, $ptrreg, $ptroff)>;
1305249423Sdimdef : Pat<(pre_truncsti32 i64:$rS, iPTR:$ptrreg, iPTR:$ptroff),
1306249423Sdim          (STWUX8 $rS, $ptrreg, $ptroff)>;
1307249423Sdimdef : Pat<(pre_store i64:$rS, iPTR:$ptrreg, iPTR:$ptroff),
1308249423Sdim          (STDUX $rS, $ptrreg, $ptroff)>;
1309193323Sed
1310249423Sdim
1311193323Sed//===----------------------------------------------------------------------===//
1312193323Sed// Floating point instructions.
1313193323Sed//
1314193323Sed
1315193323Sed
1316280031Sdimlet PPC970_Unit = 3, hasSideEffects = 0,
1317251662Sdim    Uses = [RM] in {  // FPU Operations.
1318251662Sdimdefm FCFID  : XForm_26r<63, 846, (outs f8rc:$frD), (ins f8rc:$frB),
1319276479Sdim                        "fcfid", "$frD, $frB", IIC_FPGeneral,
1320251662Sdim                        [(set f64:$frD, (PPCfcfid f64:$frB))]>, isPPC64;
1321261991Sdimdefm FCTID  : XForm_26r<63, 814, (outs f8rc:$frD), (ins f8rc:$frB),
1322276479Sdim                        "fctid", "$frD, $frB", IIC_FPGeneral,
1323261991Sdim                        []>, isPPC64;
1324314564Sdimdefm FCTIDU : XForm_26r<63, 942, (outs f8rc:$frD), (ins f8rc:$frB),
1325314564Sdim                        "fctidu", "$frD, $frB", IIC_FPGeneral,
1326314564Sdim                        []>, isPPC64;
1327251662Sdimdefm FCTIDZ : XForm_26r<63, 815, (outs f8rc:$frD), (ins f8rc:$frB),
1328276479Sdim                        "fctidz", "$frD, $frB", IIC_FPGeneral,
1329251662Sdim                        [(set f64:$frD, (PPCfctidz f64:$frB))]>, isPPC64;
1330249423Sdim
1331251662Sdimdefm FCFIDU  : XForm_26r<63, 974, (outs f8rc:$frD), (ins f8rc:$frB),
1332276479Sdim                        "fcfidu", "$frD, $frB", IIC_FPGeneral,
1333251662Sdim                        [(set f64:$frD, (PPCfcfidu f64:$frB))]>, isPPC64;
1334251662Sdimdefm FCFIDS  : XForm_26r<59, 846, (outs f4rc:$frD), (ins f8rc:$frB),
1335276479Sdim                        "fcfids", "$frD, $frB", IIC_FPGeneral,
1336251662Sdim                        [(set f32:$frD, (PPCfcfids f64:$frB))]>, isPPC64;
1337251662Sdimdefm FCFIDUS : XForm_26r<59, 974, (outs f4rc:$frD), (ins f8rc:$frB),
1338276479Sdim                        "fcfidus", "$frD, $frB", IIC_FPGeneral,
1339251662Sdim                        [(set f32:$frD, (PPCfcfidus f64:$frB))]>, isPPC64;
1340251662Sdimdefm FCTIDUZ : XForm_26r<63, 943, (outs f8rc:$frD), (ins f8rc:$frB),
1341276479Sdim                        "fctiduz", "$frD, $frB", IIC_FPGeneral,
1342251662Sdim                        [(set f64:$frD, (PPCfctiduz f64:$frB))]>, isPPC64;
1343251662Sdimdefm FCTIWUZ : XForm_26r<63, 143, (outs f8rc:$frD), (ins f8rc:$frB),
1344276479Sdim                        "fctiwuz", "$frD, $frB", IIC_FPGeneral,
1345251662Sdim                        [(set f64:$frD, (PPCfctiwuz f64:$frB))]>, isPPC64;
1346193323Sed}
1347193323Sed
1348193323Sed
1349193323Sed//===----------------------------------------------------------------------===//
1350193323Sed// Instruction Patterns
1351193323Sed//
1352193323Sed
1353193323Sed// Extensions and truncates to/from 32-bit regs.
1354249423Sdimdef : Pat<(i64 (zext i32:$in)),
1355249423Sdim          (RLDICL (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $in, sub_32),
1356239462Sdim                  0, 32)>;
1357249423Sdimdef : Pat<(i64 (anyext i32:$in)),
1358249423Sdim          (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $in, sub_32)>;
1359249423Sdimdef : Pat<(i32 (trunc i64:$in)),
1360249423Sdim          (EXTRACT_SUBREG $in, sub_32)>;
1361193323Sed
1362276479Sdim// Implement the 'not' operation with the NOR instruction.
1363276479Sdim// (we could use the default xori pattern, but nor has lower latency on some
1364276479Sdim// cores (such as the A2)).
1365276479Sdimdef i64not : OutPatFrag<(ops node:$in),
1366276479Sdim                        (NOR8 $in, $in)>;
1367276479Sdimdef        : Pat<(not i64:$in),
1368276479Sdim                 (i64not $in)>;
1369276479Sdim
1370193323Sed// Extending loads with i64 targets.
1371193323Seddef : Pat<(zextloadi1 iaddr:$src),
1372193323Sed          (LBZ8 iaddr:$src)>;
1373193323Seddef : Pat<(zextloadi1 xaddr:$src),
1374193323Sed          (LBZX8 xaddr:$src)>;
1375193323Seddef : Pat<(extloadi1 iaddr:$src),
1376193323Sed          (LBZ8 iaddr:$src)>;
1377193323Seddef : Pat<(extloadi1 xaddr:$src),
1378193323Sed          (LBZX8 xaddr:$src)>;
1379193323Seddef : Pat<(extloadi8 iaddr:$src),
1380193323Sed          (LBZ8 iaddr:$src)>;
1381193323Seddef : Pat<(extloadi8 xaddr:$src),
1382193323Sed          (LBZX8 xaddr:$src)>;
1383193323Seddef : Pat<(extloadi16 iaddr:$src),
1384193323Sed          (LHZ8 iaddr:$src)>;
1385193323Seddef : Pat<(extloadi16 xaddr:$src),
1386193323Sed          (LHZX8 xaddr:$src)>;
1387193323Seddef : Pat<(extloadi32 iaddr:$src),
1388193323Sed          (LWZ8 iaddr:$src)>;
1389193323Seddef : Pat<(extloadi32 xaddr:$src),
1390193323Sed          (LWZX8 xaddr:$src)>;
1391193323Sed
1392193323Sed// Standard shifts.  These are represented separately from the real shifts above
1393193323Sed// so that we can distinguish between shifts that allow 6-bit and 7-bit shift
1394193323Sed// amounts.
1395249423Sdimdef : Pat<(sra i64:$rS, i32:$rB),
1396249423Sdim          (SRAD $rS, $rB)>;
1397249423Sdimdef : Pat<(srl i64:$rS, i32:$rB),
1398249423Sdim          (SRD $rS, $rB)>;
1399249423Sdimdef : Pat<(shl i64:$rS, i32:$rB),
1400249423Sdim          (SLD $rS, $rB)>;
1401193323Sed
1402321369Sdim// SUBFIC
1403321369Sdimdef : Pat<(sub imm64SExt16:$imm, i64:$in),
1404321369Sdim          (SUBFIC8 $in, imm:$imm)>;
1405321369Sdim
1406193323Sed// SHL/SRL
1407249423Sdimdef : Pat<(shl i64:$in, (i32 imm:$imm)),
1408249423Sdim          (RLDICR $in, imm:$imm, (SHL64 imm:$imm))>;
1409249423Sdimdef : Pat<(srl i64:$in, (i32 imm:$imm)),
1410249423Sdim          (RLDICL $in, (SRL64 imm:$imm), imm:$imm)>;
1411193323Sed
1412193323Sed// ROTL
1413249423Sdimdef : Pat<(rotl i64:$in, i32:$sh),
1414249423Sdim          (RLDCL $in, $sh, 0)>;
1415249423Sdimdef : Pat<(rotl i64:$in, (i32 imm:$imm)),
1416249423Sdim          (RLDICL $in, imm:$imm, 0)>;
1417193323Sed
1418193323Sed// Hi and Lo for Darwin Global Addresses.
1419193323Seddef : Pat<(PPChi tglobaladdr:$in, 0), (LIS8 tglobaladdr:$in)>;
1420193323Seddef : Pat<(PPClo tglobaladdr:$in, 0), (LI8  tglobaladdr:$in)>;
1421193323Seddef : Pat<(PPChi tconstpool:$in , 0), (LIS8 tconstpool:$in)>;
1422193323Seddef : Pat<(PPClo tconstpool:$in , 0), (LI8  tconstpool:$in)>;
1423193323Seddef : Pat<(PPChi tjumptable:$in , 0), (LIS8 tjumptable:$in)>;
1424193323Seddef : Pat<(PPClo tjumptable:$in , 0), (LI8  tjumptable:$in)>;
1425198953Srdivackydef : Pat<(PPChi tblockaddress:$in, 0), (LIS8 tblockaddress:$in)>;
1426198953Srdivackydef : Pat<(PPClo tblockaddress:$in, 0), (LI8  tblockaddress:$in)>;
1427249423Sdimdef : Pat<(PPChi tglobaltlsaddr:$g, i64:$in),
1428249423Sdim          (ADDIS8 $in, tglobaltlsaddr:$g)>;
1429249423Sdimdef : Pat<(PPClo tglobaltlsaddr:$g, i64:$in),
1430249423Sdim          (ADDI8 $in, tglobaltlsaddr:$g)>;
1431249423Sdimdef : Pat<(add i64:$in, (PPChi tglobaladdr:$g, 0)),
1432249423Sdim          (ADDIS8 $in, tglobaladdr:$g)>;
1433249423Sdimdef : Pat<(add i64:$in, (PPChi tconstpool:$g, 0)),
1434249423Sdim          (ADDIS8 $in, tconstpool:$g)>;
1435249423Sdimdef : Pat<(add i64:$in, (PPChi tjumptable:$g, 0)),
1436249423Sdim          (ADDIS8 $in, tjumptable:$g)>;
1437249423Sdimdef : Pat<(add i64:$in, (PPChi tblockaddress:$g, 0)),
1438249423Sdim          (ADDIS8 $in, tblockaddress:$g)>;
1439249423Sdim
1440249423Sdim// Patterns to match r+r indexed loads and stores for
1441249423Sdim// addresses without at least 4-byte alignment.
1442249423Sdimdef : Pat<(i64 (unaligned4sextloadi32 xoaddr:$src)),
1443249423Sdim          (LWAX xoaddr:$src)>;
1444249423Sdimdef : Pat<(i64 (unaligned4load xoaddr:$src)),
1445249423Sdim          (LDX xoaddr:$src)>;
1446249423Sdimdef : Pat<(unaligned4store i64:$rS, xoaddr:$dst),
1447249423Sdim          (STDX $rS, xoaddr:$dst)>;
1448249423Sdim
1449280031Sdim// 64-bits atomic loads and stores
1450353358Sdimdef : Pat<(atomic_load_64 iaddrX4:$src), (LD  memrix:$src)>;
1451353358Sdimdef : Pat<(atomic_load_64 xaddrX4:$src),  (LDX memrr:$src)>;
1452280031Sdim
1453353358Sdimdef : Pat<(atomic_store_64 iaddrX4:$ptr, i64:$val), (STD  g8rc:$val, memrix:$ptr)>;
1454353358Sdimdef : Pat<(atomic_store_64 xaddrX4:$ptr,  i64:$val), (STDX g8rc:$val, memrr:$ptr)>;
1455309124Sdim
1456309124Sdimlet Predicates = [IsISA3_0] in {
1457309124Sdim
1458309124Sdimclass X_L1_RA5_RB5<bits<6> opcode, bits<10> xo, string opc, RegisterOperand ty,
1459309124Sdim                   InstrItinClass itin, list<dag> pattern>
1460309124Sdim  : X_L1_RS5_RS5<opcode, xo, (outs), (ins ty:$rA, ty:$rB, u1imm:$L),
1461309124Sdim                 !strconcat(opc, " $rA, $rB, $L"), itin, pattern>;
1462309124Sdim
1463309124Sdimlet Interpretation64Bit = 1, isCodeGenOnly = 1 in {
1464309124Sdimdef CP_COPY8   : X_L1_RA5_RB5<31, 774, "copy"  , g8rc, IIC_LdStCOPY, []>;
1465309124Sdimdef CP_PASTE8  : X_L1_RA5_RB5<31, 902, "paste" , g8rc, IIC_LdStPASTE, []>;
1466360784Sdimdef CP_PASTE8_rec : X_L1_RA5_RB5<31, 902, "paste.", g8rc, IIC_LdStPASTE, []>,isRecordForm;
1467309124Sdim}
1468309124Sdim
1469309124Sdim// SLB Invalidate Entry Global
1470309124Sdimdef SLBIEG : XForm_26<31, 466, (outs), (ins gprc:$RS, gprc:$RB),
1471309124Sdim                      "slbieg $RS, $RB", IIC_SprSLBIEG, []>;
1472309124Sdim// SLB Synchronize
1473309124Sdimdef SLBSYNC : XForm_0<31, 338, (outs), (ins), "slbsync", IIC_SprSLBSYNC, []>;
1474309124Sdim
1475309124Sdim} // IsISA3_0
1476