1 //===- AlphaInstrInfo.td - The Alpha Instruction Set -------*- tablegen -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 //===----------------------------------------------------------------------===//
13 include "AlphaInstrFormats.td"
15 //********************
17 //********************
19 def SDTFPUnaryOpUnC : SDTypeProfile<1, 1, [
20 SDTCisFP<1>, SDTCisFP<0>
22 def Alpha_cvtqt : SDNode<"AlphaISD::CVTQT_", SDTFPUnaryOpUnC, []>;
23 def Alpha_cvtqs : SDNode<"AlphaISD::CVTQS_", SDTFPUnaryOpUnC, []>;
24 def Alpha_cvttq : SDNode<"AlphaISD::CVTTQ_" , SDTFPUnaryOp, []>;
25 def Alpha_gprello : SDNode<"AlphaISD::GPRelLo", SDTIntBinOp, []>;
26 def Alpha_gprelhi : SDNode<"AlphaISD::GPRelHi", SDTIntBinOp, []>;
27 def Alpha_rellit : SDNode<"AlphaISD::RelLit", SDTIntBinOp, [SDNPMayLoad]>;
29 def retflag : SDNode<"AlphaISD::RET_FLAG", SDTNone,
30 [SDNPHasChain, SDNPOptInFlag]>;
32 // These are target-independent nodes, but have target-specific formats.
33 def SDT_AlphaCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i64> ]>;
34 def SDT_AlphaCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i64>,
37 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_AlphaCallSeqStart,
38 [SDNPHasChain, SDNPOutFlag]>;
39 def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_AlphaCallSeqEnd,
40 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
42 //********************
43 //Paterns for matching
44 //********************
45 def invX : SDNodeXForm<imm, [{ //invert
46 return getI64Imm(~N->getValue());
48 def negX : SDNodeXForm<imm, [{ //negate
49 return getI64Imm(~N->getValue() + 1);
51 def SExt32 : SDNodeXForm<imm, [{ //signed extend int to long
52 return getI64Imm(((int64_t)N->getValue() << 32) >> 32);
54 def SExt16 : SDNodeXForm<imm, [{ //signed extend int to long
55 return getI64Imm(((int64_t)N->getValue() << 48) >> 48);
57 def LL16 : SDNodeXForm<imm, [{ //lda part of constant
58 return getI64Imm(get_lda16(N->getValue()));
60 def LH16 : SDNodeXForm<imm, [{ //ldah part of constant (or more if too big)
61 return getI64Imm(get_ldah16(N->getValue()));
63 def iZAPX : SDNodeXForm<and, [{ // get imm to ZAPi
64 ConstantSDNode *RHS = cast<ConstantSDNode>(N->getOperand(1));
65 return getI64Imm(get_zapImm(SDOperand(), RHS->getValue()));
67 def nearP2X : SDNodeXForm<imm, [{
68 return getI64Imm(Log2_64(getNearPower2((uint64_t)N->getValue())));
70 def nearP2RemX : SDNodeXForm<imm, [{
71 uint64_t x = abs(N->getValue() - getNearPower2((uint64_t)N->getValue()));
72 return getI64Imm(Log2_64(x));
75 def immUExt8 : PatLeaf<(imm), [{ //imm fits in 8 bit zero extended field
76 return (uint64_t)N->getValue() == (uint8_t)N->getValue();
78 def immUExt8inv : PatLeaf<(imm), [{ //inverted imm fits in 8 bit zero extended field
79 return (uint64_t)~N->getValue() == (uint8_t)~N->getValue();
81 def immUExt8neg : PatLeaf<(imm), [{ //negated imm fits in 8 bit zero extended field
82 return ((uint64_t)~N->getValue() + 1) == (uint8_t)((uint64_t)~N->getValue() + 1);
84 def immSExt16 : PatLeaf<(imm), [{ //imm fits in 16 bit sign extended field
85 return ((int64_t)N->getValue() << 48) >> 48 == (int64_t)N->getValue();
87 def immSExt16int : PatLeaf<(imm), [{ //(int)imm fits in a 16 bit sign extended field
88 return ((int64_t)N->getValue() << 48) >> 48 == ((int64_t)N->getValue() << 32) >> 32;
91 def zappat : PatFrag<(ops node:$LHS), (and node:$LHS, imm:$L), [{
92 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N->getOperand(1))) {
93 uint64_t build = get_zapImm(N->getOperand(0), (uint64_t)RHS->getValue());
99 def immFPZ : PatLeaf<(fpimm), [{ //the only fpconstant nodes are +/- 0.0
100 (void)N; // silence warning.
104 def immRem1 : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),1, 0);}]>;
105 def immRem2 : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),2, 0);}]>;
106 def immRem3 : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),3, 0);}]>;
107 def immRem4 : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),4, 0);}]>;
108 def immRem5 : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),5, 0);}]>;
109 def immRem1n : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),1, 1);}]>;
110 def immRem2n : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),2, 1);}]>;
111 def immRem3n : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),3, 1);}]>;
112 def immRem4n : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),4, 1);}]>;
113 def immRem5n : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),5, 1);}]>;
115 def immRemP2n : PatLeaf<(imm), [{
116 return isPowerOf2_64(getNearPower2((uint64_t)N->getValue()) - N->getValue());
118 def immRemP2 : PatLeaf<(imm), [{
119 return isPowerOf2_64(N->getValue() - getNearPower2((uint64_t)N->getValue()));
121 def immUExt8ME : PatLeaf<(imm), [{ //use this imm for mulqi
122 int64_t d = abs((int64_t)N->getValue() - (int64_t)getNearPower2((uint64_t)N->getValue()));
123 if (isPowerOf2_64(d)) return false;
125 case 1: case 3: case 5: return false;
126 default: return (uint64_t)N->getValue() == (uint8_t)N->getValue();
130 def intop : PatFrag<(ops node:$op), (sext_inreg node:$op, i32)>;
131 def add4 : PatFrag<(ops node:$op1, node:$op2),
132 (add (shl node:$op1, 2), node:$op2)>;
133 def sub4 : PatFrag<(ops node:$op1, node:$op2),
134 (sub (shl node:$op1, 2), node:$op2)>;
135 def add8 : PatFrag<(ops node:$op1, node:$op2),
136 (add (shl node:$op1, 3), node:$op2)>;
137 def sub8 : PatFrag<(ops node:$op1, node:$op2),
138 (sub (shl node:$op1, 3), node:$op2)>;
139 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
140 class CmpOpFrag<dag res> : PatFrag<(ops node:$R), res>;
142 //Pseudo ops for selection
144 def WTF : PseudoInstAlpha<(outs), (ins variable_ops), "#wtf", [], s_pseudo>;
146 let hasCtrlDep = 1, Defs = [R30], Uses = [R30] in {
147 def ADJUSTSTACKUP : PseudoInstAlpha<(outs), (ins s64imm:$amt),
149 [(callseq_start imm:$amt)], s_pseudo>;
150 def ADJUSTSTACKDOWN : PseudoInstAlpha<(outs), (ins s64imm:$amt1, s64imm:$amt2),
152 [(callseq_end imm:$amt1, imm:$amt2)], s_pseudo>;
155 def ALTENT : PseudoInstAlpha<(outs), (ins s64imm:$TARGET), "$$$TARGET..ng:\n", [], s_pseudo>;
156 def PCLABEL : PseudoInstAlpha<(outs), (ins s64imm:$num), "PCMARKER_$num:\n",[], s_pseudo>;
157 def MEMLABEL : PseudoInstAlpha<(outs), (ins s64imm:$i, s64imm:$j, s64imm:$k, s64imm:$m),
158 "LSMARKER$$$i$$$j$$$k$$$m:", [], s_pseudo>;
161 let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler.
162 def CAS32 : PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$cmp, GPRC:$swp), "",
163 [(set GPRC:$dst, (atomic_cmp_swap_32 GPRC:$ptr, GPRC:$cmp, GPRC:$swp))], s_pseudo>;
164 def CAS64 : PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$cmp, GPRC:$swp), "",
165 [(set GPRC:$dst, (atomic_cmp_swap_64 GPRC:$ptr, GPRC:$cmp, GPRC:$swp))], s_pseudo>;
167 def LAS32 : PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$swp), "",
168 [(set GPRC:$dst, (atomic_load_add_32 GPRC:$ptr, GPRC:$swp))], s_pseudo>;
169 def LAS64 :PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$swp), "",
170 [(set GPRC:$dst, (atomic_load_add_64 GPRC:$ptr, GPRC:$swp))], s_pseudo>;
172 def SWAP32 : PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$swp), "",
173 [(set GPRC:$dst, (atomic_swap_32 GPRC:$ptr, GPRC:$swp))], s_pseudo>;
174 def SWAP64 :PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$swp), "",
175 [(set GPRC:$dst, (atomic_swap_64 GPRC:$ptr, GPRC:$swp))], s_pseudo>;
178 //***********************
180 //***********************
184 //conditional moves, int
186 multiclass cmov_inst<bits<7> fun, string asmstr, PatFrag OpNode> {
187 def r : OForm4<0x11, fun, !strconcat(asmstr, " $RCOND,$RTRUE,$RDEST"),
188 [(set GPRC:$RDEST, (select (OpNode GPRC:$RCOND), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>;
189 def i : OForm4L<0x11, fun, !strconcat(asmstr, " $RCOND,$RTRUE,$RDEST"),
190 [(set GPRC:$RDEST, (select (OpNode GPRC:$RCOND), immUExt8:$RTRUE, GPRC:$RFALSE))], s_cmov>;
193 defm CMOVEQ : cmov_inst<0x24, "cmoveq", CmpOpFrag<(seteq node:$R, 0)>>;
194 defm CMOVNE : cmov_inst<0x26, "cmovne", CmpOpFrag<(setne node:$R, 0)>>;
195 defm CMOVLT : cmov_inst<0x44, "cmovlt", CmpOpFrag<(setlt node:$R, 0)>>;
196 defm CMOVLE : cmov_inst<0x64, "cmovle", CmpOpFrag<(setle node:$R, 0)>>;
197 defm CMOVGT : cmov_inst<0x66, "cmovgt", CmpOpFrag<(setgt node:$R, 0)>>;
198 defm CMOVGE : cmov_inst<0x46, "cmovge", CmpOpFrag<(setge node:$R, 0)>>;
199 defm CMOVLBC : cmov_inst<0x16, "cmovlbc", CmpOpFrag<(xor node:$R, 1)>>;
200 defm CMOVLBS : cmov_inst<0x14, "cmovlbs", CmpOpFrag<(and node:$R, 1)>>;
202 //General pattern for cmov
203 def : Pat<(select GPRC:$which, GPRC:$src1, GPRC:$src2),
204 (CMOVNEr GPRC:$src2, GPRC:$src1, GPRC:$which)>;
205 def : Pat<(select GPRC:$which, GPRC:$src1, immUExt8:$src2),
206 (CMOVEQi GPRC:$src1, immUExt8:$src2, GPRC:$which)>;
208 //Invert sense when we can for constants:
209 def : Pat<(select (setne GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
210 (CMOVEQi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
211 def : Pat<(select (setgt GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
212 (CMOVLEi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
213 def : Pat<(select (setge GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
214 (CMOVLTi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
215 def : Pat<(select (setlt GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
216 (CMOVGEi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
217 def : Pat<(select (setle GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
218 (CMOVGTi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
220 multiclass all_inst<bits<6> opc, bits<7> funl, bits<7> funq,
221 string asmstr, PatFrag OpNode, InstrItinClass itin> {
222 def Lr : OForm< opc, funl, !strconcat(asmstr, "l $RA,$RB,$RC"),
223 [(set GPRC:$RC, (intop (OpNode GPRC:$RA, GPRC:$RB)))], itin>;
224 def Li : OFormL<opc, funl, !strconcat(asmstr, "l $RA,$L,$RC"),
225 [(set GPRC:$RC, (intop (OpNode GPRC:$RA, immUExt8:$L)))], itin>;
226 def Qr : OForm< opc, funq, !strconcat(asmstr, "q $RA,$RB,$RC"),
227 [(set GPRC:$RC, (OpNode GPRC:$RA, GPRC:$RB))], itin>;
228 def Qi : OFormL<opc, funq, !strconcat(asmstr, "q $RA,$L,$RC"),
229 [(set GPRC:$RC, (OpNode GPRC:$RA, immUExt8:$L))], itin>;
232 defm MUL : all_inst<0x13, 0x00, 0x20, "mul", BinOpFrag<(mul node:$LHS, node:$RHS)>, s_imul>;
233 defm ADD : all_inst<0x10, 0x00, 0x20, "add", BinOpFrag<(add node:$LHS, node:$RHS)>, s_iadd>;
234 defm S4ADD : all_inst<0x10, 0x02, 0x22, "s4add", add4, s_iadd>;
235 defm S8ADD : all_inst<0x10, 0x12, 0x32, "s8add", add8, s_iadd>;
236 defm S4SUB : all_inst<0x10, 0x0B, 0x2B, "s4sub", sub4, s_iadd>;
237 defm S8SUB : all_inst<0x10, 0x1B, 0x3B, "s8sub", sub8, s_iadd>;
238 defm SUB : all_inst<0x10, 0x09, 0x29, "sub", BinOpFrag<(sub node:$LHS, node:$RHS)>, s_iadd>;
239 //Const cases since legalize does sub x, int -> add x, inv(int) + 1
240 def : Pat<(intop (add GPRC:$RA, immUExt8neg:$L)), (SUBLi GPRC:$RA, immUExt8neg:$L)>;
241 def : Pat<(add GPRC:$RA, immUExt8neg:$L), (SUBQi GPRC:$RA, immUExt8neg:$L)>;
242 def : Pat<(intop (add4 GPRC:$RA, immUExt8neg:$L)), (S4SUBLi GPRC:$RA, immUExt8neg:$L)>;
243 def : Pat<(add4 GPRC:$RA, immUExt8neg:$L), (S4SUBQi GPRC:$RA, immUExt8neg:$L)>;
244 def : Pat<(intop (add8 GPRC:$RA, immUExt8neg:$L)), (S8SUBLi GPRC:$RA, immUExt8neg:$L)>;
245 def : Pat<(add8 GPRC:$RA, immUExt8neg:$L), (S8SUBQi GPRC:$RA, immUExt8neg:$L)>;
247 multiclass log_inst<bits<6> opc, bits<7> fun, string asmstr, SDNode OpNode, InstrItinClass itin> {
248 def r : OForm<opc, fun, !strconcat(asmstr, " $RA,$RB,$RC"),
249 [(set GPRC:$RC, (OpNode GPRC:$RA, GPRC:$RB))], itin>;
250 def i : OFormL<opc, fun, !strconcat(asmstr, " $RA,$L,$RC"),
251 [(set GPRC:$RC, (OpNode GPRC:$RA, immUExt8:$L))], itin>;
253 multiclass inv_inst<bits<6> opc, bits<7> fun, string asmstr, SDNode OpNode, InstrItinClass itin> {
254 def r : OForm<opc, fun, !strconcat(asmstr, " $RA,$RB,$RC"),
255 [(set GPRC:$RC, (OpNode GPRC:$RA, (not GPRC:$RB)))], itin>;
256 def i : OFormL<opc, fun, !strconcat(asmstr, " $RA,$L,$RC"),
257 [(set GPRC:$RC, (OpNode GPRC:$RA, immUExt8inv:$L))], itin>;
260 defm AND : log_inst<0x11, 0x00, "and", and, s_ilog>;
261 defm BIC : inv_inst<0x11, 0x08, "bic", and, s_ilog>;
262 defm BIS : log_inst<0x11, 0x20, "bis", or, s_ilog>;
263 defm ORNOT : inv_inst<0x11, 0x28, "ornot", or, s_ilog>;
264 defm XOR : log_inst<0x11, 0x40, "xor", xor, s_ilog>;
265 defm EQV : inv_inst<0x11, 0x48, "eqv", xor, s_ilog>;
267 defm SL : log_inst<0x12, 0x39, "sll", shl, s_ishf>;
268 defm SRA : log_inst<0x12, 0x3c, "sra", sra, s_ishf>;
269 defm SRL : log_inst<0x12, 0x34, "srl", srl, s_ishf>;
270 defm UMULH : log_inst<0x13, 0x30, "umulh", mulhu, s_imul>;
272 def CTLZ : OForm2<0x1C, 0x32, "CTLZ $RB,$RC",
273 [(set GPRC:$RC, (ctlz GPRC:$RB))], s_imisc>;
274 def CTPOP : OForm2<0x1C, 0x30, "CTPOP $RB,$RC",
275 [(set GPRC:$RC, (ctpop GPRC:$RB))], s_imisc>;
276 def CTTZ : OForm2<0x1C, 0x33, "CTTZ $RB,$RC",
277 [(set GPRC:$RC, (cttz GPRC:$RB))], s_imisc>;
278 def EXTBL : OForm< 0x12, 0x06, "EXTBL $RA,$RB,$RC",
279 [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 255))], s_ishf>;
280 def EXTWL : OForm< 0x12, 0x16, "EXTWL $RA,$RB,$RC",
281 [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 65535))], s_ishf>;
282 def EXTLL : OForm< 0x12, 0x26, "EXTLL $RA,$RB,$RC",
283 [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 4294967295))], s_ishf>;
284 def SEXTB : OForm2<0x1C, 0x00, "sextb $RB,$RC",
285 [(set GPRC:$RC, (sext_inreg GPRC:$RB, i8))], s_ishf>;
286 def SEXTW : OForm2<0x1C, 0x01, "sextw $RB,$RC",
287 [(set GPRC:$RC, (sext_inreg GPRC:$RB, i16))], s_ishf>;
289 //def EXTBLi : OFormL<0x12, 0x06, "EXTBL $RA,$L,$RC", []>; //Extract byte low
290 //def EXTLH : OForm< 0x12, 0x6A, "EXTLH $RA,$RB,$RC", []>; //Extract longword high
291 //def EXTLHi : OFormL<0x12, 0x6A, "EXTLH $RA,$L,$RC", []>; //Extract longword high
292 //def EXTLLi : OFormL<0x12, 0x26, "EXTLL $RA,$L,$RC", []>; //Extract longword low
293 //def EXTQH : OForm< 0x12, 0x7A, "EXTQH $RA,$RB,$RC", []>; //Extract quadword high
294 //def EXTQHi : OFormL<0x12, 0x7A, "EXTQH $RA,$L,$RC", []>; //Extract quadword high
295 //def EXTQ : OForm< 0x12, 0x36, "EXTQ $RA,$RB,$RC", []>; //Extract quadword low
296 //def EXTQi : OFormL<0x12, 0x36, "EXTQ $RA,$L,$RC", []>; //Extract quadword low
297 //def EXTWH : OForm< 0x12, 0x5A, "EXTWH $RA,$RB,$RC", []>; //Extract word high
298 //def EXTWHi : OFormL<0x12, 0x5A, "EXTWH $RA,$L,$RC", []>; //Extract word high
299 //def EXTWLi : OFormL<0x12, 0x16, "EXTWL $RA,$L,$RC", []>; //Extract word low
301 //def INSBL : OForm< 0x12, 0x0B, "INSBL $RA,$RB,$RC", []>; //Insert byte low
302 //def INSBLi : OFormL<0x12, 0x0B, "INSBL $RA,$L,$RC", []>; //Insert byte low
303 //def INSLH : OForm< 0x12, 0x67, "INSLH $RA,$RB,$RC", []>; //Insert longword high
304 //def INSLHi : OFormL<0x12, 0x67, "INSLH $RA,$L,$RC", []>; //Insert longword high
305 //def INSLL : OForm< 0x12, 0x2B, "INSLL $RA,$RB,$RC", []>; //Insert longword low
306 //def INSLLi : OFormL<0x12, 0x2B, "INSLL $RA,$L,$RC", []>; //Insert longword low
307 //def INSQH : OForm< 0x12, 0x77, "INSQH $RA,$RB,$RC", []>; //Insert quadword high
308 //def INSQHi : OFormL<0x12, 0x77, "INSQH $RA,$L,$RC", []>; //Insert quadword high
309 //def INSQL : OForm< 0x12, 0x3B, "INSQL $RA,$RB,$RC", []>; //Insert quadword low
310 //def INSQLi : OFormL<0x12, 0x3B, "INSQL $RA,$L,$RC", []>; //Insert quadword low
311 //def INSWH : OForm< 0x12, 0x57, "INSWH $RA,$RB,$RC", []>; //Insert word high
312 //def INSWHi : OFormL<0x12, 0x57, "INSWH $RA,$L,$RC", []>; //Insert word high
313 //def INSWL : OForm< 0x12, 0x1B, "INSWL $RA,$RB,$RC", []>; //Insert word low
314 //def INSWLi : OFormL<0x12, 0x1B, "INSWL $RA,$L,$RC", []>; //Insert word low
316 //def MSKBL : OForm< 0x12, 0x02, "MSKBL $RA,$RB,$RC", []>; //Mask byte low
317 //def MSKBLi : OFormL<0x12, 0x02, "MSKBL $RA,$L,$RC", []>; //Mask byte low
318 //def MSKLH : OForm< 0x12, 0x62, "MSKLH $RA,$RB,$RC", []>; //Mask longword high
319 //def MSKLHi : OFormL<0x12, 0x62, "MSKLH $RA,$L,$RC", []>; //Mask longword high
320 //def MSKLL : OForm< 0x12, 0x22, "MSKLL $RA,$RB,$RC", []>; //Mask longword low
321 //def MSKLLi : OFormL<0x12, 0x22, "MSKLL $RA,$L,$RC", []>; //Mask longword low
322 //def MSKQH : OForm< 0x12, 0x72, "MSKQH $RA,$RB,$RC", []>; //Mask quadword high
323 //def MSKQHi : OFormL<0x12, 0x72, "MSKQH $RA,$L,$RC", []>; //Mask quadword high
324 //def MSKQL : OForm< 0x12, 0x32, "MSKQL $RA,$RB,$RC", []>; //Mask quadword low
325 //def MSKQLi : OFormL<0x12, 0x32, "MSKQL $RA,$L,$RC", []>; //Mask quadword low
326 //def MSKWH : OForm< 0x12, 0x52, "MSKWH $RA,$RB,$RC", []>; //Mask word high
327 //def MSKWHi : OFormL<0x12, 0x52, "MSKWH $RA,$L,$RC", []>; //Mask word high
328 //def MSKWL : OForm< 0x12, 0x12, "MSKWL $RA,$RB,$RC", []>; //Mask word low
329 //def MSKWLi : OFormL<0x12, 0x12, "MSKWL $RA,$L,$RC", []>; //Mask word low
331 def ZAPNOTi : OFormL<0x12, 0x31, "zapnot $RA,$L,$RC", [], s_ishf>;
333 // Define the pattern that produces ZAPNOTi.
334 def : Pat<(i64 (zappat GPRC:$RA):$imm),
335 (ZAPNOTi GPRC:$RA, (iZAPX GPRC:$imm))>;
339 //So this is a waste of what this instruction can do, but it still saves something
340 def CMPBGE : OForm< 0x10, 0x0F, "cmpbge $RA,$RB,$RC",
341 [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), (and GPRC:$RB, 255)))], s_ilog>;
342 def CMPBGEi : OFormL<0x10, 0x0F, "cmpbge $RA,$L,$RC",
343 [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), immUExt8:$L))], s_ilog>;
344 def CMPEQ : OForm< 0x10, 0x2D, "cmpeq $RA,$RB,$RC",
345 [(set GPRC:$RC, (seteq GPRC:$RA, GPRC:$RB))], s_iadd>;
346 def CMPEQi : OFormL<0x10, 0x2D, "cmpeq $RA,$L,$RC",
347 [(set GPRC:$RC, (seteq GPRC:$RA, immUExt8:$L))], s_iadd>;
348 def CMPLE : OForm< 0x10, 0x6D, "cmple $RA,$RB,$RC",
349 [(set GPRC:$RC, (setle GPRC:$RA, GPRC:$RB))], s_iadd>;
350 def CMPLEi : OFormL<0x10, 0x6D, "cmple $RA,$L,$RC",
351 [(set GPRC:$RC, (setle GPRC:$RA, immUExt8:$L))], s_iadd>;
352 def CMPLT : OForm< 0x10, 0x4D, "cmplt $RA,$RB,$RC",
353 [(set GPRC:$RC, (setlt GPRC:$RA, GPRC:$RB))], s_iadd>;
354 def CMPLTi : OFormL<0x10, 0x4D, "cmplt $RA,$L,$RC",
355 [(set GPRC:$RC, (setlt GPRC:$RA, immUExt8:$L))], s_iadd>;
356 def CMPULE : OForm< 0x10, 0x3D, "cmpule $RA,$RB,$RC",
357 [(set GPRC:$RC, (setule GPRC:$RA, GPRC:$RB))], s_iadd>;
358 def CMPULEi : OFormL<0x10, 0x3D, "cmpule $RA,$L,$RC",
359 [(set GPRC:$RC, (setule GPRC:$RA, immUExt8:$L))], s_iadd>;
360 def CMPULT : OForm< 0x10, 0x1D, "cmpult $RA,$RB,$RC",
361 [(set GPRC:$RC, (setult GPRC:$RA, GPRC:$RB))], s_iadd>;
362 def CMPULTi : OFormL<0x10, 0x1D, "cmpult $RA,$L,$RC",
363 [(set GPRC:$RC, (setult GPRC:$RA, immUExt8:$L))], s_iadd>;
365 //Patterns for unsupported int comparisons
366 def : Pat<(setueq GPRC:$X, GPRC:$Y), (CMPEQ GPRC:$X, GPRC:$Y)>;
367 def : Pat<(setueq GPRC:$X, immUExt8:$Y), (CMPEQi GPRC:$X, immUExt8:$Y)>;
369 def : Pat<(setugt GPRC:$X, GPRC:$Y), (CMPULT GPRC:$Y, GPRC:$X)>;
370 def : Pat<(setugt immUExt8:$X, GPRC:$Y), (CMPULTi GPRC:$Y, immUExt8:$X)>;
372 def : Pat<(setuge GPRC:$X, GPRC:$Y), (CMPULE GPRC:$Y, GPRC:$X)>;
373 def : Pat<(setuge immUExt8:$X, GPRC:$Y), (CMPULEi GPRC:$Y, immUExt8:$X)>;
375 def : Pat<(setgt GPRC:$X, GPRC:$Y), (CMPLT GPRC:$Y, GPRC:$X)>;
376 def : Pat<(setgt immUExt8:$X, GPRC:$Y), (CMPLTi GPRC:$Y, immUExt8:$X)>;
378 def : Pat<(setge GPRC:$X, GPRC:$Y), (CMPLE GPRC:$Y, GPRC:$X)>;
379 def : Pat<(setge immUExt8:$X, GPRC:$Y), (CMPLEi GPRC:$Y, immUExt8:$X)>;
381 def : Pat<(setne GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>;
382 def : Pat<(setne GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQi GPRC:$X, immUExt8:$Y), 0)>;
384 def : Pat<(setune GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>;
385 def : Pat<(setune GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQ GPRC:$X, immUExt8:$Y), 0)>;
388 let isReturn = 1, isTerminator = 1, Ra = 31, Rb = 26, disp = 1, Uses = [R26] in {
389 def RETDAG : MbrForm< 0x1A, 0x02, (ops), "ret $$31,($$26),1", s_jsr>; //Return from subroutine
390 def RETDAGp : MbrpForm< 0x1A, 0x02, (ops), "ret $$31,($$26),1", [(retflag)], s_jsr>; //Return from subroutine
393 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1, Ra = 31, disp = 0 in
394 def JMP : MbrpForm< 0x1A, 0x00, (ops GPRC:$RS), "jmp $$31,($RS),0",
395 [(brind GPRC:$RS)], s_jsr>; //Jump
397 let isCall = 1, Ra = 26,
398 Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19,
399 R20, R21, R22, R23, R24, R25, R26, R27, R28, R29,
401 F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
402 F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R29] in {
403 def BSR : BFormD<0x34, "bsr $$26,$$$DISP..ng", [], s_jsr>; //Branch to subroutine
405 let isCall = 1, Ra = 26, Rb = 27, disp = 0,
406 Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19,
407 R20, R21, R22, R23, R24, R25, R26, R27, R28, R29,
409 F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
410 F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R27, R29] in {
411 def JSR : MbrForm< 0x1A, 0x01, (ops ), "jsr $$26,($$27),0", s_jsr>; //Jump to subroutine
414 let isCall = 1, Ra = 23, Rb = 27, disp = 0,
415 Defs = [R23, R24, R25, R27, R28], Uses = [R24, R25, R27] in
416 def JSRs : MbrForm< 0x1A, 0x01, (ops ), "jsr $$23,($$27),0", s_jsr>; //Jump to div or rem
419 def JSR_COROUTINE : MbrForm< 0x1A, 0x03, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr_coroutine $RD,($RS),$DISP", s_jsr>; //Jump to subroutine return
422 let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
423 def LDQ : MForm<0x29, 1, "ldq $RA,$DISP($RB)",
424 [(set GPRC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
425 def LDQr : MForm<0x29, 1, "ldq $RA,$DISP($RB)\t\t!gprellow",
426 [(set GPRC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>;
427 def LDL : MForm<0x28, 1, "ldl $RA,$DISP($RB)",
428 [(set GPRC:$RA, (sextloadi32 (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
429 def LDLr : MForm<0x28, 1, "ldl $RA,$DISP($RB)\t\t!gprellow",
430 [(set GPRC:$RA, (sextloadi32 (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>;
431 def LDBU : MForm<0x0A, 1, "ldbu $RA,$DISP($RB)",
432 [(set GPRC:$RA, (zextloadi8 (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
433 def LDBUr : MForm<0x0A, 1, "ldbu $RA,$DISP($RB)\t\t!gprellow",
434 [(set GPRC:$RA, (zextloadi8 (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>;
435 def LDWU : MForm<0x0C, 1, "ldwu $RA,$DISP($RB)",
436 [(set GPRC:$RA, (zextloadi16 (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
437 def LDWUr : MForm<0x0C, 1, "ldwu $RA,$DISP($RB)\t\t!gprellow",
438 [(set GPRC:$RA, (zextloadi16 (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>;
442 let OutOperandList = (ops), InOperandList = (ops GPRC:$RA, s64imm:$DISP, GPRC:$RB) in {
443 def STB : MForm<0x0E, 0, "stb $RA,$DISP($RB)",
444 [(truncstorei8 GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
445 def STBr : MForm<0x0E, 0, "stb $RA,$DISP($RB)\t\t!gprellow",
446 [(truncstorei8 GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
447 def STW : MForm<0x0D, 0, "stw $RA,$DISP($RB)",
448 [(truncstorei16 GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
449 def STWr : MForm<0x0D, 0, "stw $RA,$DISP($RB)\t\t!gprellow",
450 [(truncstorei16 GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
451 def STL : MForm<0x2C, 0, "stl $RA,$DISP($RB)",
452 [(truncstorei32 GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
453 def STLr : MForm<0x2C, 0, "stl $RA,$DISP($RB)\t\t!gprellow",
454 [(truncstorei32 GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
455 def STQ : MForm<0x2D, 0, "stq $RA,$DISP($RB)",
456 [(store GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
457 def STQr : MForm<0x2D, 0, "stq $RA,$DISP($RB)\t\t!gprellow",
458 [(store GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
462 let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
463 def LDA : MForm<0x08, 0, "lda $RA,$DISP($RB)",
464 [(set GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_lda>;
465 def LDAr : MForm<0x08, 0, "lda $RA,$DISP($RB)\t\t!gprellow",
466 [(set GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_lda>; //Load address
467 def LDAH : MForm<0x09, 0, "ldah $RA,$DISP($RB)",
468 [], s_lda>; //Load address high
469 def LDAHr : MForm<0x09, 0, "ldah $RA,$DISP($RB)\t\t!gprelhigh",
470 [(set GPRC:$RA, (Alpha_gprelhi tglobaladdr:$DISP, GPRC:$RB))], s_lda>; //Load address high
473 let OutOperandList = (ops), InOperandList = (ops F4RC:$RA, s64imm:$DISP, GPRC:$RB) in {
474 def STS : MForm<0x26, 0, "sts $RA,$DISP($RB)",
475 [(store F4RC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_fst>;
476 def STSr : MForm<0x26, 0, "sts $RA,$DISP($RB)\t\t!gprellow",
477 [(store F4RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_fst>;
479 let OutOperandList = (ops F4RC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
480 def LDS : MForm<0x22, 1, "lds $RA,$DISP($RB)",
481 [(set F4RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_fld>;
482 def LDSr : MForm<0x22, 1, "lds $RA,$DISP($RB)\t\t!gprellow",
483 [(set F4RC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_fld>;
485 let OutOperandList = (ops), InOperandList = (ops F8RC:$RA, s64imm:$DISP, GPRC:$RB) in {
486 def STT : MForm<0x27, 0, "stt $RA,$DISP($RB)",
487 [(store F8RC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_fst>;
488 def STTr : MForm<0x27, 0, "stt $RA,$DISP($RB)\t\t!gprellow",
489 [(store F8RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_fst>;
491 let OutOperandList = (ops F8RC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
492 def LDT : MForm<0x23, 1, "ldt $RA,$DISP($RB)",
493 [(set F8RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_fld>;
494 def LDTr : MForm<0x23, 1, "ldt $RA,$DISP($RB)\t\t!gprellow",
495 [(set F8RC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_fld>;
500 def : Pat<(i64 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
501 (LDQr tconstpool:$DISP, GPRC:$RB)>;
502 def : Pat<(i64 (sextloadi32 (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
503 (LDLr tconstpool:$DISP, GPRC:$RB)>;
504 def : Pat<(i64 (zextloadi8 (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
505 (LDBUr tconstpool:$DISP, GPRC:$RB)>;
506 def : Pat<(i64 (zextloadi16 (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
507 (LDWUr tconstpool:$DISP, GPRC:$RB)>;
508 def : Pat<(i64 (Alpha_gprello tconstpool:$DISP, GPRC:$RB)),
509 (LDAr tconstpool:$DISP, GPRC:$RB)>;
510 def : Pat<(i64 (Alpha_gprelhi tconstpool:$DISP, GPRC:$RB)),
511 (LDAHr tconstpool:$DISP, GPRC:$RB)>;
512 def : Pat<(f32 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
513 (LDSr tconstpool:$DISP, GPRC:$RB)>;
514 def : Pat<(f64 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
515 (LDTr tconstpool:$DISP, GPRC:$RB)>;
518 def : Pat<(i64 (Alpha_gprelhi tjumptable:$DISP, GPRC:$RB)),
519 (LDAHr tjumptable:$DISP, GPRC:$RB)>;
520 def : Pat<(i64 (Alpha_gprello tjumptable:$DISP, GPRC:$RB)),
521 (LDAr tjumptable:$DISP, GPRC:$RB)>;
525 def : Pat<(i64 (extloadi8 (add GPRC:$RB, immSExt16:$DISP))),
526 (LDBU immSExt16:$DISP, GPRC:$RB)>;
527 def : Pat<(i64 (extloadi16 (add GPRC:$RB, immSExt16:$DISP))),
528 (LDWU immSExt16:$DISP, GPRC:$RB)>;
529 def : Pat<(i64 (extloadi32 (add GPRC:$RB, immSExt16:$DISP))),
530 (LDL immSExt16:$DISP, GPRC:$RB)>;
533 def : Pat<(i64 (load GPRC:$addr)),
534 (LDQ 0, GPRC:$addr)>;
535 def : Pat<(f64 (load GPRC:$addr)),
536 (LDT 0, GPRC:$addr)>;
537 def : Pat<(f32 (load GPRC:$addr)),
538 (LDS 0, GPRC:$addr)>;
539 def : Pat<(i64 (sextloadi32 GPRC:$addr)),
540 (LDL 0, GPRC:$addr)>;
541 def : Pat<(i64 (zextloadi16 GPRC:$addr)),
542 (LDWU 0, GPRC:$addr)>;
543 def : Pat<(i64 (zextloadi8 GPRC:$addr)),
544 (LDBU 0, GPRC:$addr)>;
545 def : Pat<(i64 (extloadi8 GPRC:$addr)),
546 (LDBU 0, GPRC:$addr)>;
547 def : Pat<(i64 (extloadi16 GPRC:$addr)),
548 (LDWU 0, GPRC:$addr)>;
549 def : Pat<(i64 (extloadi32 GPRC:$addr)),
550 (LDL 0, GPRC:$addr)>;
552 def : Pat<(store GPRC:$DATA, GPRC:$addr),
553 (STQ GPRC:$DATA, 0, GPRC:$addr)>;
554 def : Pat<(store F8RC:$DATA, GPRC:$addr),
555 (STT F8RC:$DATA, 0, GPRC:$addr)>;
556 def : Pat<(store F4RC:$DATA, GPRC:$addr),
557 (STS F4RC:$DATA, 0, GPRC:$addr)>;
558 def : Pat<(truncstorei32 GPRC:$DATA, GPRC:$addr),
559 (STL GPRC:$DATA, 0, GPRC:$addr)>;
560 def : Pat<(truncstorei16 GPRC:$DATA, GPRC:$addr),
561 (STW GPRC:$DATA, 0, GPRC:$addr)>;
562 def : Pat<(truncstorei8 GPRC:$DATA, GPRC:$addr),
563 (STB GPRC:$DATA, 0, GPRC:$addr)>;
566 //load address, rellocated gpdist form
567 let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s16imm:$DISP, GPRC:$RB, s16imm:$NUM) in {
568 def LDAg : MForm<0x08, 1, "lda $RA,0($RB)\t\t!gpdisp!$NUM", [], s_lda>; //Load address
569 def LDAHg : MForm<0x09, 1, "ldah $RA,0($RB)\t\t!gpdisp!$NUM", [], s_lda>; //Load address
572 //Load quad, rellocated literal form
573 let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in
574 def LDQl : MForm<0x29, 1, "ldq $RA,$DISP($RB)\t\t!literal",
575 [(set GPRC:$RA, (Alpha_rellit tglobaladdr:$DISP, GPRC:$RB))], s_ild>;
576 def : Pat<(Alpha_rellit texternalsym:$ext, GPRC:$RB),
577 (LDQl texternalsym:$ext, GPRC:$RB)>;
579 let OutOperandList = (outs GPRC:$RR),
580 InOperandList = (ins GPRC:$RA, s64imm:$DISP, GPRC:$RB),
581 Constraints = "$RA = $RR",
582 DisableEncoding = "$RR" in {
583 def STQ_C : MForm<0x2F, 0, "stq_l $RA,$DISP($RB)", [], s_ist>;
584 def STL_C : MForm<0x2E, 0, "stl_l $RA,$DISP($RB)", [], s_ist>;
586 let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
587 def LDQ_L : MForm<0x2B, 1, "ldq_l $RA,$DISP($RB)", [], s_ild>;
588 def LDL_L : MForm<0x2A, 1, "ldl_l $RA,$DISP($RB)", [], s_ild>;
591 def RPCC : MfcForm<0x18, 0xC000, "rpcc $RA", s_rpcc>; //Read process cycle counter
592 def MB : MfcPForm<0x18, 0x4000, "mb", s_imisc>; //memory barrier
593 def WMB : MfcPForm<0x18, 0x4400, "wmb", s_imisc>; //write memory barrier
595 def : Pat<(membarrier (i64 imm:$ll), (i64 imm:$ls), (i64 imm:$sl), (i64 1), (i64 imm:$dev)),
597 def : Pat<(membarrier (i64 imm:$ll), (i64 imm:$ls), (i64 imm:$sl), (i64 imm:$ss), (i64 imm:$dev)),
600 //Basic Floating point ops
604 let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F4RC:$RB), Fa = 31 in
605 def SQRTS : FPForm<0x14, 0x58B, "sqrts/su $RB,$RC",
606 [(set F4RC:$RC, (fsqrt F4RC:$RB))], s_fsqrts>;
608 let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F4RC:$RA, F4RC:$RB) in {
609 def ADDS : FPForm<0x16, 0x580, "adds/su $RA,$RB,$RC",
610 [(set F4RC:$RC, (fadd F4RC:$RA, F4RC:$RB))], s_fadd>;
611 def SUBS : FPForm<0x16, 0x581, "subs/su $RA,$RB,$RC",
612 [(set F4RC:$RC, (fsub F4RC:$RA, F4RC:$RB))], s_fadd>;
613 def DIVS : FPForm<0x16, 0x583, "divs/su $RA,$RB,$RC",
614 [(set F4RC:$RC, (fdiv F4RC:$RA, F4RC:$RB))], s_fdivs>;
615 def MULS : FPForm<0x16, 0x582, "muls/su $RA,$RB,$RC",
616 [(set F4RC:$RC, (fmul F4RC:$RA, F4RC:$RB))], s_fmul>;
618 def CPYSS : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
619 [(set F4RC:$RC, (fcopysign F4RC:$RB, F4RC:$RA))], s_fadd>;
620 def CPYSES : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent
621 def CPYSNS : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
622 [(set F4RC:$RC, (fneg (fcopysign F4RC:$RB, F4RC:$RA)))], s_fadd>;
627 let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in
628 def SQRTT : FPForm<0x14, 0x5AB, "sqrtt/su $RB,$RC",
629 [(set F8RC:$RC, (fsqrt F8RC:$RB))], s_fsqrtt>;
631 let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F8RC:$RA, F8RC:$RB) in {
632 def ADDT : FPForm<0x16, 0x5A0, "addt/su $RA,$RB,$RC",
633 [(set F8RC:$RC, (fadd F8RC:$RA, F8RC:$RB))], s_fadd>;
634 def SUBT : FPForm<0x16, 0x5A1, "subt/su $RA,$RB,$RC",
635 [(set F8RC:$RC, (fsub F8RC:$RA, F8RC:$RB))], s_fadd>;
636 def DIVT : FPForm<0x16, 0x5A3, "divt/su $RA,$RB,$RC",
637 [(set F8RC:$RC, (fdiv F8RC:$RA, F8RC:$RB))], s_fdivt>;
638 def MULT : FPForm<0x16, 0x5A2, "mult/su $RA,$RB,$RC",
639 [(set F8RC:$RC, (fmul F8RC:$RA, F8RC:$RB))], s_fmul>;
641 def CPYST : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
642 [(set F8RC:$RC, (fcopysign F8RC:$RB, F8RC:$RA))], s_fadd>;
643 def CPYSET : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent
644 def CPYSNT : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
645 [(set F8RC:$RC, (fneg (fcopysign F8RC:$RB, F8RC:$RA)))], s_fadd>;
647 def CMPTEQ : FPForm<0x16, 0x5A5, "cmpteq/su $RA,$RB,$RC", [], s_fadd>;
648 // [(set F8RC:$RC, (seteq F8RC:$RA, F8RC:$RB))]>;
649 def CMPTLE : FPForm<0x16, 0x5A7, "cmptle/su $RA,$RB,$RC", [], s_fadd>;
650 // [(set F8RC:$RC, (setle F8RC:$RA, F8RC:$RB))]>;
651 def CMPTLT : FPForm<0x16, 0x5A6, "cmptlt/su $RA,$RB,$RC", [], s_fadd>;
652 // [(set F8RC:$RC, (setlt F8RC:$RA, F8RC:$RB))]>;
653 def CMPTUN : FPForm<0x16, 0x5A4, "cmptun/su $RA,$RB,$RC", [], s_fadd>;
654 // [(set F8RC:$RC, (setuo F8RC:$RA, F8RC:$RB))]>;
658 let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F4RC:$RA, F8RC:$RB) in {
659 def CPYSTs : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
660 [(set F8RC:$RC, (fcopysign F8RC:$RB, F4RC:$RA))], s_fadd>;
661 def CPYSNTs : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
662 [(set F8RC:$RC, (fneg (fcopysign F8RC:$RB, F4RC:$RA)))], s_fadd>;
664 let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F8RC:$RA, F4RC:$RB) in {
665 def CPYSSt : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
666 [(set F4RC:$RC, (fcopysign F4RC:$RB, F8RC:$RA))], s_fadd>;
667 def CPYSESt : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent
668 def CPYSNSt : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
669 [(set F4RC:$RC, (fneg (fcopysign F4RC:$RB, F8RC:$RA)))], s_fadd>;
672 //conditional moves, floats
673 let OutOperandList = (ops F4RC:$RDEST), InOperandList = (ops F4RC:$RFALSE, F4RC:$RTRUE, F8RC:$RCOND),
674 isTwoAddress = 1 in {
675 def FCMOVEQS : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if = zero
676 def FCMOVGES : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if >= zero
677 def FCMOVGTS : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if > zero
678 def FCMOVLES : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if <= zero
679 def FCMOVLTS : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST",[], s_fcmov>; // FCMOVE if < zero
680 def FCMOVNES : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if != zero
682 //conditional moves, doubles
683 let OutOperandList = (ops F8RC:$RDEST), InOperandList = (ops F8RC:$RFALSE, F8RC:$RTRUE, F8RC:$RCOND),
684 isTwoAddress = 1 in {
685 def FCMOVEQT : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
686 def FCMOVGET : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
687 def FCMOVGTT : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
688 def FCMOVLET : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
689 def FCMOVLTT : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
690 def FCMOVNET : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
696 def : Pat<(select (seteq F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
697 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
698 def : Pat<(select (setoeq F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
699 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
700 def : Pat<(select (setueq F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
701 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
703 def : Pat<(select (setne F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
704 (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
705 def : Pat<(select (setone F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
706 (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
707 def : Pat<(select (setune F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
708 (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
710 def : Pat<(select (setgt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
711 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
712 def : Pat<(select (setogt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
713 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
714 def : Pat<(select (setugt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
715 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
717 def : Pat<(select (setge F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
718 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
719 def : Pat<(select (setoge F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
720 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
721 def : Pat<(select (setuge F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
722 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
724 def : Pat<(select (setlt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
725 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
726 def : Pat<(select (setolt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
727 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
728 def : Pat<(select (setult F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
729 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
731 def : Pat<(select (setle F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
732 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
733 def : Pat<(select (setole F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
734 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
735 def : Pat<(select (setule F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
736 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
739 def : Pat<(select (seteq F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
740 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
741 def : Pat<(select (setoeq F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
742 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
743 def : Pat<(select (setueq F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
744 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
746 def : Pat<(select (setne F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
747 (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
748 def : Pat<(select (setone F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
749 (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
750 def : Pat<(select (setune F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
751 (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
753 def : Pat<(select (setgt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
754 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
755 def : Pat<(select (setogt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
756 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
757 def : Pat<(select (setugt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
758 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
760 def : Pat<(select (setge F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
761 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
762 def : Pat<(select (setoge F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
763 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
764 def : Pat<(select (setuge F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
765 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
767 def : Pat<(select (setlt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
768 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
769 def : Pat<(select (setolt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
770 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
771 def : Pat<(select (setult F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
772 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
774 def : Pat<(select (setle F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
775 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
776 def : Pat<(select (setole F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
777 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
778 def : Pat<(select (setule F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
779 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
783 let OutOperandList = (ops GPRC:$RC), InOperandList = (ops F4RC:$RA), Fb = 31 in
784 def FTOIS : FPForm<0x1C, 0x078, "ftois $RA,$RC",[], s_ftoi>; //Floating to integer move, S_floating
785 let OutOperandList = (ops GPRC:$RC), InOperandList = (ops F8RC:$RA), Fb = 31 in
786 def FTOIT : FPForm<0x1C, 0x070, "ftoit $RA,$RC",
787 [(set GPRC:$RC, (bitconvert F8RC:$RA))], s_ftoi>; //Floating to integer move
788 let OutOperandList = (ops F4RC:$RC), InOperandList = (ops GPRC:$RA), Fb = 31 in
789 def ITOFS : FPForm<0x14, 0x004, "itofs $RA,$RC",[], s_itof>; //Integer to floating move, S_floating
790 let OutOperandList = (ops F8RC:$RC), InOperandList = (ops GPRC:$RA), Fb = 31 in
791 def ITOFT : FPForm<0x14, 0x024, "itoft $RA,$RC",
792 [(set F8RC:$RC, (bitconvert GPRC:$RA))], s_itof>; //Integer to floating move
795 let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in
796 def CVTQS : FPForm<0x16, 0x7BC, "cvtqs/sui $RB,$RC",
797 [(set F4RC:$RC, (Alpha_cvtqs F8RC:$RB))], s_fadd>;
798 let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in
799 def CVTQT : FPForm<0x16, 0x7BE, "cvtqt/sui $RB,$RC",
800 [(set F8RC:$RC, (Alpha_cvtqt F8RC:$RB))], s_fadd>;
801 let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in
802 def CVTTQ : FPForm<0x16, 0x52F, "cvttq/svc $RB,$RC",
803 [(set F8RC:$RC, (Alpha_cvttq F8RC:$RB))], s_fadd>;
804 let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F4RC:$RB), Fa = 31 in
805 def CVTST : FPForm<0x16, 0x6AC, "cvtst/s $RB,$RC",
806 [(set F8RC:$RC, (fextend F4RC:$RB))], s_fadd>;
807 let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in
808 def CVTTS : FPForm<0x16, 0x7AC, "cvtts/sui $RB,$RC",
809 [(set F4RC:$RC, (fround F8RC:$RB))], s_fadd>;
812 /////////////////////////////////////////////////////////
814 /////////////////////////////////////////////////////////
815 class br_icc<bits<6> opc, string asmstr>
816 : BFormN<opc, (ops u64imm:$opc, GPRC:$R, target:$dst),
817 !strconcat(asmstr, " $R,$dst"), s_icbr>;
818 class br_fcc<bits<6> opc, string asmstr>
819 : BFormN<opc, (ops u64imm:$opc, F8RC:$R, target:$dst),
820 !strconcat(asmstr, " $R,$dst"), s_fbr>;
822 let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in {
824 def BR : BFormD<0x30, "br $$31,$DISP", [(br bb:$DISP)], s_ubr>;
826 def COND_BRANCH_I : BFormN<0, (ops u64imm:$opc, GPRC:$R, target:$dst),
827 "{:comment} COND_BRANCH imm:$opc, GPRC:$R, bb:$dst",
829 def COND_BRANCH_F : BFormN<0, (ops u64imm:$opc, F8RC:$R, target:$dst),
830 "{:comment} COND_BRANCH imm:$opc, F8RC:$R, bb:$dst",
833 def BEQ : br_icc<0x39, "beq">;
834 def BGE : br_icc<0x3E, "bge">;
835 def BGT : br_icc<0x3F, "bgt">;
836 def BLBC : br_icc<0x38, "blbc">;
837 def BLBS : br_icc<0x3C, "blbs">;
838 def BLE : br_icc<0x3B, "ble">;
839 def BLT : br_icc<0x3A, "blt">;
840 def BNE : br_icc<0x3D, "bne">;
843 def FBEQ : br_fcc<0x31, "fbeq">;
844 def FBGE : br_fcc<0x36, "fbge">;
845 def FBGT : br_fcc<0x37, "fbgt">;
846 def FBLE : br_fcc<0x33, "fble">;
847 def FBLT : br_fcc<0x32, "fblt">;
848 def FBNE : br_fcc<0x36, "fbne">;
851 //An ugly trick to get the opcode as an imm I can use
852 def immBRCond : SDNodeXForm<imm, [{
853 switch((uint64_t)N->getValue()) {
854 case 0: return getI64Imm(Alpha::BEQ);
855 case 1: return getI64Imm(Alpha::BNE);
856 case 2: return getI64Imm(Alpha::BGE);
857 case 3: return getI64Imm(Alpha::BGT);
858 case 4: return getI64Imm(Alpha::BLE);
859 case 5: return getI64Imm(Alpha::BLT);
860 case 6: return getI64Imm(Alpha::BLBS);
861 case 7: return getI64Imm(Alpha::BLBC);
862 case 20: return getI64Imm(Alpha::FBEQ);
863 case 21: return getI64Imm(Alpha::FBNE);
864 case 22: return getI64Imm(Alpha::FBGE);
865 case 23: return getI64Imm(Alpha::FBGT);
866 case 24: return getI64Imm(Alpha::FBLE);
867 case 25: return getI64Imm(Alpha::FBLT);
868 default: assert(0 && "Unknown branch type");
873 def : Pat<(brcond (seteq GPRC:$RA, 0), bb:$DISP),
874 (COND_BRANCH_I (immBRCond 0), GPRC:$RA, bb:$DISP)>;
875 def : Pat<(brcond (setge GPRC:$RA, 0), bb:$DISP),
876 (COND_BRANCH_I (immBRCond 2), GPRC:$RA, bb:$DISP)>;
877 def : Pat<(brcond (setgt GPRC:$RA, 0), bb:$DISP),
878 (COND_BRANCH_I (immBRCond 3), GPRC:$RA, bb:$DISP)>;
879 def : Pat<(brcond (and GPRC:$RA, 1), bb:$DISP),
880 (COND_BRANCH_I (immBRCond 6), GPRC:$RA, bb:$DISP)>;
881 def : Pat<(brcond (setle GPRC:$RA, 0), bb:$DISP),
882 (COND_BRANCH_I (immBRCond 4), GPRC:$RA, bb:$DISP)>;
883 def : Pat<(brcond (setlt GPRC:$RA, 0), bb:$DISP),
884 (COND_BRANCH_I (immBRCond 5), GPRC:$RA, bb:$DISP)>;
885 def : Pat<(brcond (setne GPRC:$RA, 0), bb:$DISP),
886 (COND_BRANCH_I (immBRCond 1), GPRC:$RA, bb:$DISP)>;
888 def : Pat<(brcond GPRC:$RA, bb:$DISP),
889 (COND_BRANCH_I (immBRCond 1), GPRC:$RA, bb:$DISP)>;
890 def : Pat<(brcond (setne GPRC:$RA, GPRC:$RB), bb:$DISP),
891 (COND_BRANCH_I (immBRCond 0), (CMPEQ GPRC:$RA, GPRC:$RB), bb:$DISP)>;
892 def : Pat<(brcond (setne GPRC:$RA, immUExt8:$L), bb:$DISP),
893 (COND_BRANCH_I (immBRCond 0), (CMPEQi GPRC:$RA, immUExt8:$L), bb:$DISP)>;
896 def : Pat<(brcond (seteq F8RC:$RA, immFPZ), bb:$DISP),
897 (COND_BRANCH_F (immBRCond 20), F8RC:$RA, bb:$DISP)>;
898 def : Pat<(brcond (setne F8RC:$RA, immFPZ), bb:$DISP),
899 (COND_BRANCH_F (immBRCond 21), F8RC:$RA, bb:$DISP)>;
900 def : Pat<(brcond (setge F8RC:$RA, immFPZ), bb:$DISP),
901 (COND_BRANCH_F (immBRCond 22), F8RC:$RA, bb:$DISP)>;
902 def : Pat<(brcond (setgt F8RC:$RA, immFPZ), bb:$DISP),
903 (COND_BRANCH_F (immBRCond 23), F8RC:$RA, bb:$DISP)>;
904 def : Pat<(brcond (setle F8RC:$RA, immFPZ), bb:$DISP),
905 (COND_BRANCH_F (immBRCond 24), F8RC:$RA, bb:$DISP)>;
906 def : Pat<(brcond (setlt F8RC:$RA, immFPZ), bb:$DISP),
907 (COND_BRANCH_F (immBRCond 25), F8RC:$RA, bb:$DISP)>;
910 def : Pat<(brcond (seteq F8RC:$RA, F8RC:$RB), bb:$DISP),
911 (COND_BRANCH_F (immBRCond 21), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
912 def : Pat<(brcond (setoeq F8RC:$RA, F8RC:$RB), bb:$DISP),
913 (COND_BRANCH_F (immBRCond 21), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
914 def : Pat<(brcond (setueq F8RC:$RA, F8RC:$RB), bb:$DISP),
915 (COND_BRANCH_F (immBRCond 21), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
917 def : Pat<(brcond (setlt F8RC:$RA, F8RC:$RB), bb:$DISP),
918 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
919 def : Pat<(brcond (setolt F8RC:$RA, F8RC:$RB), bb:$DISP),
920 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
921 def : Pat<(brcond (setult F8RC:$RA, F8RC:$RB), bb:$DISP),
922 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
924 def : Pat<(brcond (setle F8RC:$RA, F8RC:$RB), bb:$DISP),
925 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
926 def : Pat<(brcond (setole F8RC:$RA, F8RC:$RB), bb:$DISP),
927 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
928 def : Pat<(brcond (setule F8RC:$RA, F8RC:$RB), bb:$DISP),
929 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
931 def : Pat<(brcond (setgt F8RC:$RA, F8RC:$RB), bb:$DISP),
932 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
933 def : Pat<(brcond (setogt F8RC:$RA, F8RC:$RB), bb:$DISP),
934 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
935 def : Pat<(brcond (setugt F8RC:$RA, F8RC:$RB), bb:$DISP),
936 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
938 def : Pat<(brcond (setge F8RC:$RA, F8RC:$RB), bb:$DISP),
939 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
940 def : Pat<(brcond (setoge F8RC:$RA, F8RC:$RB), bb:$DISP),
941 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
942 def : Pat<(brcond (setuge F8RC:$RA, F8RC:$RB), bb:$DISP),
943 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
945 def : Pat<(brcond (setne F8RC:$RA, F8RC:$RB), bb:$DISP),
946 (COND_BRANCH_F (immBRCond 20), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
947 def : Pat<(brcond (setone F8RC:$RA, F8RC:$RB), bb:$DISP),
948 (COND_BRANCH_F (immBRCond 20), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
949 def : Pat<(brcond (setune F8RC:$RA, F8RC:$RB), bb:$DISP),
950 (COND_BRANCH_F (immBRCond 20), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
953 def : Pat<(brcond (setoeq F8RC:$RA, immFPZ), bb:$DISP),
954 (COND_BRANCH_F (immBRCond 20), F8RC:$RA,bb:$DISP)>;
955 def : Pat<(brcond (setueq F8RC:$RA, immFPZ), bb:$DISP),
956 (COND_BRANCH_F (immBRCond 20), F8RC:$RA,bb:$DISP)>;
958 def : Pat<(brcond (setoge F8RC:$RA, immFPZ), bb:$DISP),
959 (COND_BRANCH_F (immBRCond 22), F8RC:$RA,bb:$DISP)>;
960 def : Pat<(brcond (setuge F8RC:$RA, immFPZ), bb:$DISP),
961 (COND_BRANCH_F (immBRCond 22), F8RC:$RA,bb:$DISP)>;
963 def : Pat<(brcond (setogt F8RC:$RA, immFPZ), bb:$DISP),
964 (COND_BRANCH_F (immBRCond 23), F8RC:$RA,bb:$DISP)>;
965 def : Pat<(brcond (setugt F8RC:$RA, immFPZ), bb:$DISP),
966 (COND_BRANCH_F (immBRCond 23), F8RC:$RA,bb:$DISP)>;
968 def : Pat<(brcond (setole F8RC:$RA, immFPZ), bb:$DISP),
969 (COND_BRANCH_F (immBRCond 24), F8RC:$RA,bb:$DISP)>;
970 def : Pat<(brcond (setule F8RC:$RA, immFPZ), bb:$DISP),
971 (COND_BRANCH_F (immBRCond 24), F8RC:$RA,bb:$DISP)>;
973 def : Pat<(brcond (setolt F8RC:$RA, immFPZ), bb:$DISP),
974 (COND_BRANCH_F (immBRCond 25), F8RC:$RA,bb:$DISP)>;
975 def : Pat<(brcond (setult F8RC:$RA, immFPZ), bb:$DISP),
976 (COND_BRANCH_F (immBRCond 25), F8RC:$RA,bb:$DISP)>;
978 def : Pat<(brcond (setone F8RC:$RA, immFPZ), bb:$DISP),
979 (COND_BRANCH_F (immBRCond 21), F8RC:$RA,bb:$DISP)>;
980 def : Pat<(brcond (setune F8RC:$RA, immFPZ), bb:$DISP),
981 (COND_BRANCH_F (immBRCond 21), F8RC:$RA,bb:$DISP)>;
985 //S_floating : IEEE Single
986 //T_floating : IEEE Double
988 //Unused instructions
989 //Mnemonic Format Opcode Description
990 //CALL_PAL Pcd 00 Trap to PALcode
991 //ECB Mfc 18.E800 Evict cache block
992 //EXCB Mfc 18.0400 Exception barrier
993 //FETCH Mfc 18.8000 Prefetch data
994 //FETCH_M Mfc 18.A000 Prefetch data, modify intent
995 //LDQ_U Mem 0B Load unaligned quadword
996 //MB Mfc 18.4000 Memory barrier
997 //STQ_U Mem 0F Store unaligned quadword
998 //TRAPB Mfc 18.0000 Trap barrier
999 //WH64 Mfc 18.F800 Write hint
\14 64 bytes
1000 //WMB Mfc 18.4400 Write memory barrier
1001 //MF_FPCR F-P 17.025 Move from FPCR
1002 //MT_FPCR F-P 17.024 Move to FPCR
1003 //There are in the Multimedia extentions, so let's not use them yet
1004 //def MAXSB8 : OForm<0x1C, 0x3E, "MAXSB8 $RA,$RB,$RC">; //Vector signed byte maximum
1005 //def MAXSW4 : OForm< 0x1C, 0x3F, "MAXSW4 $RA,$RB,$RC">; //Vector signed word maximum
1006 //def MAXUB8 : OForm<0x1C, 0x3C, "MAXUB8 $RA,$RB,$RC">; //Vector unsigned byte maximum
1007 //def MAXUW4 : OForm< 0x1C, 0x3D, "MAXUW4 $RA,$RB,$RC">; //Vector unsigned word maximum
1008 //def MINSB8 : OForm< 0x1C, 0x38, "MINSB8 $RA,$RB,$RC">; //Vector signed byte minimum
1009 //def MINSW4 : OForm< 0x1C, 0x39, "MINSW4 $RA,$RB,$RC">; //Vector signed word minimum
1010 //def MINUB8 : OForm< 0x1C, 0x3A, "MINUB8 $RA,$RB,$RC">; //Vector unsigned byte minimum
1011 //def MINUW4 : OForm< 0x1C, 0x3B, "MINUW4 $RA,$RB,$RC">; //Vector unsigned word minimum
1012 //def PERR : OForm< 0x1C, 0x31, "PERR $RA,$RB,$RC">; //Pixel error
1013 //def PKLB : OForm< 0x1C, 0x37, "PKLB $RA,$RB,$RC">; //Pack longwords to bytes
1014 //def PKWB : OForm<0x1C, 0x36, "PKWB $RA,$RB,$RC">; //Pack words to bytes
1015 //def UNPKBL : OForm< 0x1C, 0x35, "UNPKBL $RA,$RB,$RC">; //Unpack bytes to longwords
1016 //def UNPKBW : OForm< 0x1C, 0x34, "UNPKBW $RA,$RB,$RC">; //Unpack bytes to words
1017 //CVTLQ F-P 17.010 Convert longword to quadword
1018 //CVTQL F-P 17.030 Convert quadword to longword
1023 def immConst2Part : PatLeaf<(imm), [{
1024 //true if imm fits in a LDAH LDA pair
1025 int64_t val = (int64_t)N->getValue();
1026 return (val <= IMM_FULLHIGH && val >= IMM_FULLLOW);
1028 def immConst2PartInt : PatLeaf<(imm), [{
1029 //true if imm fits in a LDAH LDA pair with zeroext
1030 uint64_t uval = N->getValue();
1031 int32_t val32 = (int32_t)uval;
1032 return ((uval >> 32) == 0 && //empty upper bits
1033 val32 <= IMM_FULLHIGH);
1034 // val32 >= IMM_FULLLOW + IMM_LOW * IMM_MULT); //Always True
1037 def : Pat<(i64 immConst2Part:$imm),
1038 (LDA (LL16 immConst2Part:$imm), (LDAH (LH16 immConst2Part:$imm), R31))>;
1040 def : Pat<(i64 immSExt16:$imm),
1041 (LDA immSExt16:$imm, R31)>;
1043 def : Pat<(i64 immSExt16int:$imm),
1044 (ZAPNOTi (LDA (SExt16 immSExt16int:$imm), R31), 15)>;
1045 def : Pat<(i64 immConst2PartInt:$imm),
1046 (ZAPNOTi (LDA (LL16 (SExt32 immConst2PartInt:$imm)),
1047 (LDAH (LH16 (SExt32 immConst2PartInt:$imm)), R31)), 15)>;
1050 //TODO: I want to just define these like this!
1051 //def : Pat<(i64 0),
1053 //def : Pat<(f64 0.0),
1055 //def : Pat<(f64 -0.0),
1056 // (CPYSNT F31, F31)>;
1057 //def : Pat<(f32 0.0),
1059 //def : Pat<(f32 -0.0),
1060 // (CPYSNS F31, F31)>;
1064 def : Pat<(sext_inreg GPRC:$RB, i32),
1065 (ADDLi GPRC:$RB, 0)>;
1067 def : Pat<(fabs F8RC:$RB),
1068 (CPYST F31, F8RC:$RB)>;
1069 def : Pat<(fabs F4RC:$RB),
1070 (CPYSS F31, F4RC:$RB)>;
1071 def : Pat<(fneg F8RC:$RB),
1072 (CPYSNT F8RC:$RB, F8RC:$RB)>;
1073 def : Pat<(fneg F4RC:$RB),
1074 (CPYSNS F4RC:$RB, F4RC:$RB)>;
1076 def : Pat<(fcopysign F4RC:$A, (fneg F4RC:$B)),
1077 (CPYSNS F4RC:$B, F4RC:$A)>;
1078 def : Pat<(fcopysign F8RC:$A, (fneg F8RC:$B)),
1079 (CPYSNT F8RC:$B, F8RC:$A)>;
1080 def : Pat<(fcopysign F4RC:$A, (fneg F8RC:$B)),
1081 (CPYSNSt F8RC:$B, F4RC:$A)>;
1082 def : Pat<(fcopysign F8RC:$A, (fneg F4RC:$B)),
1083 (CPYSNTs F4RC:$B, F8RC:$A)>;
1085 //Yes, signed multiply high is ugly
1086 def : Pat<(mulhs GPRC:$RA, GPRC:$RB),
1087 (SUBQr (UMULHr GPRC:$RA, GPRC:$RB), (ADDQr (CMOVGEr GPRC:$RB, R31, GPRC:$RA),
1088 (CMOVGEr GPRC:$RA, R31, GPRC:$RB)))>;
1090 //Stupid crazy arithmetic stuff:
1091 let AddedComplexity = 1 in {
1092 def : Pat<(mul GPRC:$RA, 5), (S4ADDQr GPRC:$RA, GPRC:$RA)>;
1093 def : Pat<(mul GPRC:$RA, 9), (S8ADDQr GPRC:$RA, GPRC:$RA)>;
1094 def : Pat<(mul GPRC:$RA, 3), (S4SUBQr GPRC:$RA, GPRC:$RA)>;
1095 def : Pat<(mul GPRC:$RA, 7), (S8SUBQr GPRC:$RA, GPRC:$RA)>;
1097 //slight tree expansion if we are multiplying near to a power of 2
1098 //n is above a power of 2
1099 def : Pat<(mul GPRC:$RA, immRem1:$imm),
1100 (ADDQr (SLr GPRC:$RA, (nearP2X immRem1:$imm)), GPRC:$RA)>;
1101 def : Pat<(mul GPRC:$RA, immRem2:$imm),
1102 (ADDQr (SLr GPRC:$RA, (nearP2X immRem2:$imm)), (ADDQr GPRC:$RA, GPRC:$RA))>;
1103 def : Pat<(mul GPRC:$RA, immRem3:$imm),
1104 (ADDQr (SLr GPRC:$RA, (nearP2X immRem3:$imm)), (S4SUBQr GPRC:$RA, GPRC:$RA))>;
1105 def : Pat<(mul GPRC:$RA, immRem4:$imm),
1106 (S4ADDQr GPRC:$RA, (SLr GPRC:$RA, (nearP2X immRem4:$imm)))>;
1107 def : Pat<(mul GPRC:$RA, immRem5:$imm),
1108 (ADDQr (SLr GPRC:$RA, (nearP2X immRem5:$imm)), (S4ADDQr GPRC:$RA, GPRC:$RA))>;
1109 def : Pat<(mul GPRC:$RA, immRemP2:$imm),
1110 (ADDQr (SLr GPRC:$RA, (nearP2X immRemP2:$imm)), (SLi GPRC:$RA, (nearP2RemX immRemP2:$imm)))>;
1112 //n is below a power of 2
1113 //FIXME: figure out why something is truncating the imm to 32bits
1114 // this will fix 2007-11-27-mulneg3
1115 //def : Pat<(mul GPRC:$RA, immRem1n:$imm),
1116 // (SUBQr (SLr GPRC:$RA, (nearP2X immRem1n:$imm)), GPRC:$RA)>;
1117 //def : Pat<(mul GPRC:$RA, immRem2n:$imm),
1118 // (SUBQr (SLr GPRC:$RA, (nearP2X immRem2n:$imm)), (ADDQr GPRC:$RA, GPRC:$RA))>;
1119 //def : Pat<(mul GPRC:$RA, immRem3n:$imm),
1120 // (SUBQr (SLr GPRC:$RA, (nearP2X immRem3n:$imm)), (S4SUBQr GPRC:$RA, GPRC:$RA))>;
1121 //def : Pat<(mul GPRC:$RA, immRem4n:$imm),
1122 // (SUBQr (SLr GPRC:$RA, (nearP2X immRem4n:$imm)), (SLi GPRC:$RA, 2))>;
1123 //def : Pat<(mul GPRC:$RA, immRem5n:$imm),
1124 // (SUBQr (SLr GPRC:$RA, (nearP2X immRem5n:$imm)), (S4ADDQr GPRC:$RA, GPRC:$RA))>;
1125 //def : Pat<(mul GPRC:$RA, immRemP2n:$imm),
1126 // (SUBQr (SLr GPRC:$RA, (nearP2X immRemP2n:$imm)), (SLi GPRC:$RA, (nearP2RemX immRemP2n:$imm)))>;
1127 } //Added complexity