1 //===- AlphaInstrInfo.td - The Alpha Instruction Set -------*- tablegen -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source 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, []>;
29 def retflag : SDNode<"AlphaISD::RET_FLAG", SDTRet,
30 [SDNPHasChain, SDNPOptInFlag]>;
32 // These are target-independent nodes, but have target-specific formats.
33 def SDT_AlphaCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i64> ]>;
34 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_AlphaCallSeq,
35 [SDNPHasChain, SDNPOutFlag]>;
36 def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_AlphaCallSeq,
37 [SDNPHasChain, SDNPOutFlag]>;
39 //********************
40 //Paterns for matching
41 //********************
42 def invX : SDNodeXForm<imm, [{ //invert
43 return getI64Imm(~N->getValue());
45 def negX : SDNodeXForm<imm, [{ //negate
46 return getI64Imm(~N->getValue() + 1);
48 def SExt32 : SDNodeXForm<imm, [{ //signed extend int to long
49 return getI64Imm(((int64_t)N->getValue() << 32) >> 32);
51 def SExt16 : SDNodeXForm<imm, [{ //signed extend int to long
52 return getI64Imm(((int64_t)N->getValue() << 48) >> 48);
54 def LL16 : SDNodeXForm<imm, [{ //lda part of constant
55 return getI64Imm(get_lda16(N->getValue()));
57 def LH16 : SDNodeXForm<imm, [{ //ldah part of constant (or more if too big)
58 return getI64Imm(get_ldah16(N->getValue()));
60 def iZAPX : SDNodeXForm<and, [{ // get imm to ZAPi
61 ConstantSDNode *RHS = cast<ConstantSDNode>(N->getOperand(1));
62 return getI64Imm(get_zapImm(SDOperand(), RHS->getValue()));
64 def nearP2X : SDNodeXForm<imm, [{
65 return getI64Imm(Log2_64(getNearPower2((uint64_t)N->getValue())));
67 def nearP2RemX : SDNodeXForm<imm, [{
68 uint64_t x = abs(N->getValue() - getNearPower2((uint64_t)N->getValue()));
69 return getI64Imm(Log2_64(x));
72 def immUExt8 : PatLeaf<(imm), [{ //imm fits in 8 bit zero extended field
73 return (uint64_t)N->getValue() == (uint8_t)N->getValue();
75 def immUExt8inv : PatLeaf<(imm), [{ //inverted imm fits in 8 bit zero extended field
76 return (uint64_t)~N->getValue() == (uint8_t)~N->getValue();
78 def immUExt8neg : PatLeaf<(imm), [{ //negated imm fits in 8 bit zero extended field
79 return ((uint64_t)~N->getValue() + 1) == (uint8_t)((uint64_t)~N->getValue() + 1);
81 def immSExt16 : PatLeaf<(imm), [{ //imm fits in 16 bit sign extended field
82 return ((int64_t)N->getValue() << 48) >> 48 == (int64_t)N->getValue();
84 def immSExt16int : PatLeaf<(imm), [{ //(int)imm fits in a 16 bit sign extended field
85 return ((int64_t)N->getValue() << 48) >> 48 == ((int64_t)N->getValue() << 32) >> 32;
88 def zappat : PatFrag<(ops node:$LHS), (and node:$LHS, imm:$L), [{
89 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N->getOperand(1))) {
90 uint64_t build = get_zapImm(N->getOperand(0), (uint64_t)RHS->getValue());
96 def immFPZ : PatLeaf<(fpimm), [{ //the only fpconstant nodes are +/- 0.0
97 (void)N; // silence warning.
101 def immRem1 : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),1, 0);}]>;
102 def immRem2 : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),2, 0);}]>;
103 def immRem3 : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),3, 0);}]>;
104 def immRem4 : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),4, 0);}]>;
105 def immRem5 : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),5, 0);}]>;
106 def immRem1n : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),1, 1);}]>;
107 def immRem2n : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),2, 1);}]>;
108 def immRem3n : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),3, 1);}]>;
109 def immRem4n : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),4, 1);}]>;
110 def immRem5n : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),5, 1);}]>;
112 def immRemP2n : PatLeaf<(imm), [{
113 return isPowerOf2_64(getNearPower2((uint64_t)N->getValue()) - N->getValue());
115 def immRemP2 : PatLeaf<(imm), [{
116 return isPowerOf2_64(N->getValue() - getNearPower2((uint64_t)N->getValue()));
118 def immUExt8ME : PatLeaf<(imm), [{ //use this imm for mulqi
119 int64_t d = abs((int64_t)N->getValue() - (int64_t)getNearPower2((uint64_t)N->getValue()));
120 if (isPowerOf2_64(d)) return false;
122 case 1: case 3: case 5: return false;
123 default: return (uint64_t)N->getValue() == (uint8_t)N->getValue();
127 def intop : PatFrag<(ops node:$op), (sext_inreg node:$op, i32)>;
128 def add4 : PatFrag<(ops node:$op1, node:$op2),
129 (add (shl node:$op1, 2), node:$op2)>;
130 def sub4 : PatFrag<(ops node:$op1, node:$op2),
131 (sub (shl node:$op1, 2), node:$op2)>;
132 def add8 : PatFrag<(ops node:$op1, node:$op2),
133 (add (shl node:$op1, 3), node:$op2)>;
134 def sub8 : PatFrag<(ops node:$op1, node:$op2),
135 (sub (shl node:$op1, 3), node:$op2)>;
136 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
137 class CmpOpFrag<dag res> : PatFrag<(ops node:$R), res>;
139 //Pseudo ops for selection
141 def IDEF_I : PseudoInstAlpha<(outs GPRC:$RA), (ins), ";#idef $RA",
142 [(set GPRC:$RA, (undef))], s_pseudo>;
143 def IDEF_F32 : PseudoInstAlpha<(outs F4RC:$RA), (ins), ";#idef $RA",
144 [(set F4RC:$RA, (undef))], s_pseudo>;
145 def IDEF_F64 : PseudoInstAlpha<(outs F8RC:$RA), (ins), ";#idef $RA",
146 [(set F8RC:$RA, (undef))], s_pseudo>;
148 def WTF : PseudoInstAlpha<(outs), (ins variable_ops), "#wtf", [], s_pseudo>;
150 let isLoad = 1, hasCtrlDep = 1, Defs = [R30], Uses = [R30] in {
151 def ADJUSTSTACKUP : PseudoInstAlpha<(outs), (ins s64imm:$amt), "; ADJUP $amt",
152 [(callseq_start imm:$amt)], s_pseudo>;
153 def ADJUSTSTACKDOWN : PseudoInstAlpha<(outs), (ins s64imm:$amt), "; ADJDOWN $amt",
154 [(callseq_end imm:$amt)], s_pseudo>;
156 def ALTENT : PseudoInstAlpha<(outs), (ins s64imm:$TARGET), "$$$TARGET..ng:\n", [], s_pseudo>;
157 def PCLABEL : PseudoInstAlpha<(outs), (ins s64imm:$num), "PCMARKER_$num:\n",[], s_pseudo>;
158 def MEMLABEL : PseudoInstAlpha<(outs), (ins s64imm:$i, s64imm:$j, s64imm:$k, s64imm:$m),
159 "LSMARKER$$$i$$$j$$$k$$$m:", [], s_pseudo>;
162 //***********************
164 //***********************
168 //conditional moves, int
170 multiclass cmov_inst<bits<7> fun, string asmstr, PatFrag OpNode> {
171 def r : OForm4<0x11, fun, !strconcat(asmstr, " $RCOND,$RTRUE,$RDEST"),
172 [(set GPRC:$RDEST, (select (OpNode GPRC:$RCOND), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>;
173 def i : OForm4L<0x11, fun, !strconcat(asmstr, " $RCOND,$RTRUE,$RDEST"),
174 [(set GPRC:$RDEST, (select (OpNode GPRC:$RCOND), immUExt8:$RTRUE, GPRC:$RFALSE))], s_cmov>;
177 defm CMOVEQ : cmov_inst<0x24, "cmoveq", CmpOpFrag<(seteq node:$R, 0)>>;
178 defm CMOVNE : cmov_inst<0x26, "cmovne", CmpOpFrag<(setne node:$R, 0)>>;
179 defm CMOVLT : cmov_inst<0x44, "cmovlt", CmpOpFrag<(setlt node:$R, 0)>>;
180 defm CMOVLE : cmov_inst<0x64, "cmovle", CmpOpFrag<(setle node:$R, 0)>>;
181 defm CMOVGT : cmov_inst<0x66, "cmovgt", CmpOpFrag<(setgt node:$R, 0)>>;
182 defm CMOVGE : cmov_inst<0x46, "cmovge", CmpOpFrag<(setge node:$R, 0)>>;
183 defm CMOVLBC : cmov_inst<0x16, "cmovlbc", CmpOpFrag<(xor node:$R, 1)>>;
184 defm CMOVLBS : cmov_inst<0x14, "cmovlbs", CmpOpFrag<(and node:$R, 1)>>;
186 //General pattern for cmov
187 def : Pat<(select GPRC:$which, GPRC:$src1, GPRC:$src2),
188 (CMOVNEr GPRC:$src2, GPRC:$src1, GPRC:$which)>;
189 def : Pat<(select GPRC:$which, GPRC:$src1, immUExt8:$src2),
190 (CMOVEQi GPRC:$src1, immUExt8:$src2, GPRC:$which)>;
192 //Invert sense when we can for constants:
193 def : Pat<(select (setne GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
194 (CMOVEQi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
195 def : Pat<(select (setgt GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
196 (CMOVLEi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
197 def : Pat<(select (setge GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
198 (CMOVLTi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
199 def : Pat<(select (setlt GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
200 (CMOVGEi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
201 def : Pat<(select (setle GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
202 (CMOVGTi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
204 multiclass all_inst<bits<6> opc, bits<7> funl, bits<7> funq,
205 string asmstr, PatFrag OpNode, InstrItinClass itin> {
206 def Lr : OForm< opc, funl, !strconcat(asmstr, "l $RA,$RB,$RC"),
207 [(set GPRC:$RC, (intop (OpNode GPRC:$RA, GPRC:$RB)))], itin>;
208 def Li : OFormL<opc, funl, !strconcat(asmstr, "l $RA,$L,$RC"),
209 [(set GPRC:$RC, (intop (OpNode GPRC:$RA, immUExt8:$L)))], itin>;
210 def Qr : OForm< opc, funq, !strconcat(asmstr, "q $RA,$RB,$RC"),
211 [(set GPRC:$RC, (OpNode GPRC:$RA, GPRC:$RB))], itin>;
212 def Qi : OFormL<opc, funq, !strconcat(asmstr, "q $RA,$L,$RC"),
213 [(set GPRC:$RC, (OpNode GPRC:$RA, immUExt8:$L))], itin>;
216 defm MUL : all_inst<0x13, 0x00, 0x20, "mul", BinOpFrag<(mul node:$LHS, node:$RHS)>, s_imul>;
217 defm ADD : all_inst<0x10, 0x00, 0x20, "add", BinOpFrag<(add node:$LHS, node:$RHS)>, s_iadd>;
218 defm S4ADD : all_inst<0x10, 0x02, 0x22, "s4add", add4, s_iadd>;
219 defm S8ADD : all_inst<0x10, 0x12, 0x32, "s8add", add8, s_iadd>;
220 defm S4SUB : all_inst<0x10, 0x0B, 0x2B, "s4sub", sub4, s_iadd>;
221 defm S8SUB : all_inst<0x10, 0x1B, 0x3B, "s8sub", sub8, s_iadd>;
222 defm SUB : all_inst<0x10, 0x09, 0x29, "sub", BinOpFrag<(sub node:$LHS, node:$RHS)>, s_iadd>;
223 //Const cases since legalize does sub x, int -> add x, inv(int) + 1
224 def : Pat<(intop (add GPRC:$RA, immUExt8neg:$L)), (SUBLi GPRC:$RA, immUExt8neg:$L)>;
225 def : Pat<(add GPRC:$RA, immUExt8neg:$L), (SUBQi GPRC:$RA, immUExt8neg:$L)>;
226 def : Pat<(intop (add4 GPRC:$RA, immUExt8neg:$L)), (S4SUBLi GPRC:$RA, immUExt8neg:$L)>;
227 def : Pat<(add4 GPRC:$RA, immUExt8neg:$L), (S4SUBQi GPRC:$RA, immUExt8neg:$L)>;
228 def : Pat<(intop (add8 GPRC:$RA, immUExt8neg:$L)), (S8SUBLi GPRC:$RA, immUExt8neg:$L)>;
229 def : Pat<(add8 GPRC:$RA, immUExt8neg:$L), (S8SUBQi GPRC:$RA, immUExt8neg:$L)>;
231 multiclass log_inst<bits<6> opc, bits<7> fun, string asmstr, SDNode OpNode, InstrItinClass itin> {
232 def r : OForm<opc, fun, !strconcat(asmstr, " $RA,$RB,$RC"),
233 [(set GPRC:$RC, (OpNode GPRC:$RA, GPRC:$RB))], itin>;
234 def i : OFormL<opc, fun, !strconcat(asmstr, " $RA,$L,$RC"),
235 [(set GPRC:$RC, (OpNode GPRC:$RA, immUExt8:$L))], itin>;
237 multiclass inv_inst<bits<6> opc, bits<7> fun, string asmstr, SDNode OpNode, InstrItinClass itin> {
238 def r : OForm<opc, fun, !strconcat(asmstr, " $RA,$RB,$RC"),
239 [(set GPRC:$RC, (OpNode GPRC:$RA, (not GPRC:$RB)))], itin>;
240 def i : OFormL<opc, fun, !strconcat(asmstr, " $RA,$L,$RC"),
241 [(set GPRC:$RC, (OpNode GPRC:$RA, immUExt8inv:$L))], itin>;
244 defm AND : log_inst<0x11, 0x00, "and", and, s_ilog>;
245 defm BIC : inv_inst<0x11, 0x08, "bic", and, s_ilog>;
246 defm BIS : log_inst<0x11, 0x20, "bis", or, s_ilog>;
247 defm ORNOT : inv_inst<0x11, 0x28, "ornot", or, s_ilog>;
248 defm XOR : log_inst<0x11, 0x40, "xor", xor, s_ilog>;
249 defm EQV : inv_inst<0x11, 0x48, "eqv", xor, s_ilog>;
251 defm SL : log_inst<0x12, 0x39, "sll", shl, s_ishf>;
252 defm SRA : log_inst<0x12, 0x3c, "sra", sra, s_ishf>;
253 defm SRL : log_inst<0x12, 0x34, "srl", srl, s_ishf>;
254 defm UMULH : log_inst<0x13, 0x30, "umulh", mulhu, s_imul>;
256 def CTLZ : OForm2<0x1C, 0x32, "CTLZ $RB,$RC",
257 [(set GPRC:$RC, (ctlz GPRC:$RB))], s_imisc>;
258 def CTPOP : OForm2<0x1C, 0x30, "CTPOP $RB,$RC",
259 [(set GPRC:$RC, (ctpop GPRC:$RB))], s_imisc>;
260 def CTTZ : OForm2<0x1C, 0x33, "CTTZ $RB,$RC",
261 [(set GPRC:$RC, (cttz GPRC:$RB))], s_imisc>;
262 def EXTBL : OForm< 0x12, 0x06, "EXTBL $RA,$RB,$RC",
263 [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 255))], s_ishf>;
264 def EXTWL : OForm< 0x12, 0x16, "EXTWL $RA,$RB,$RC",
265 [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 65535))], s_ishf>;
266 def EXTLL : OForm< 0x12, 0x26, "EXTLL $RA,$RB,$RC",
267 [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 4294967295))], s_ishf>;
268 def SEXTB : OForm2<0x1C, 0x00, "sextb $RB,$RC",
269 [(set GPRC:$RC, (sext_inreg GPRC:$RB, i8))], s_ishf>;
270 def SEXTW : OForm2<0x1C, 0x01, "sextw $RB,$RC",
271 [(set GPRC:$RC, (sext_inreg GPRC:$RB, i16))], s_ishf>;
273 //def EXTBLi : OFormL<0x12, 0x06, "EXTBL $RA,$L,$RC", []>; //Extract byte low
274 //def EXTLH : OForm< 0x12, 0x6A, "EXTLH $RA,$RB,$RC", []>; //Extract longword high
275 //def EXTLHi : OFormL<0x12, 0x6A, "EXTLH $RA,$L,$RC", []>; //Extract longword high
276 //def EXTLLi : OFormL<0x12, 0x26, "EXTLL $RA,$L,$RC", []>; //Extract longword low
277 //def EXTQH : OForm< 0x12, 0x7A, "EXTQH $RA,$RB,$RC", []>; //Extract quadword high
278 //def EXTQHi : OFormL<0x12, 0x7A, "EXTQH $RA,$L,$RC", []>; //Extract quadword high
279 //def EXTQ : OForm< 0x12, 0x36, "EXTQ $RA,$RB,$RC", []>; //Extract quadword low
280 //def EXTQi : OFormL<0x12, 0x36, "EXTQ $RA,$L,$RC", []>; //Extract quadword low
281 //def EXTWH : OForm< 0x12, 0x5A, "EXTWH $RA,$RB,$RC", []>; //Extract word high
282 //def EXTWHi : OFormL<0x12, 0x5A, "EXTWH $RA,$L,$RC", []>; //Extract word high
283 //def EXTWLi : OFormL<0x12, 0x16, "EXTWL $RA,$L,$RC", []>; //Extract word low
285 //def INSBL : OForm< 0x12, 0x0B, "INSBL $RA,$RB,$RC", []>; //Insert byte low
286 //def INSBLi : OFormL<0x12, 0x0B, "INSBL $RA,$L,$RC", []>; //Insert byte low
287 //def INSLH : OForm< 0x12, 0x67, "INSLH $RA,$RB,$RC", []>; //Insert longword high
288 //def INSLHi : OFormL<0x12, 0x67, "INSLH $RA,$L,$RC", []>; //Insert longword high
289 //def INSLL : OForm< 0x12, 0x2B, "INSLL $RA,$RB,$RC", []>; //Insert longword low
290 //def INSLLi : OFormL<0x12, 0x2B, "INSLL $RA,$L,$RC", []>; //Insert longword low
291 //def INSQH : OForm< 0x12, 0x77, "INSQH $RA,$RB,$RC", []>; //Insert quadword high
292 //def INSQHi : OFormL<0x12, 0x77, "INSQH $RA,$L,$RC", []>; //Insert quadword high
293 //def INSQL : OForm< 0x12, 0x3B, "INSQL $RA,$RB,$RC", []>; //Insert quadword low
294 //def INSQLi : OFormL<0x12, 0x3B, "INSQL $RA,$L,$RC", []>; //Insert quadword low
295 //def INSWH : OForm< 0x12, 0x57, "INSWH $RA,$RB,$RC", []>; //Insert word high
296 //def INSWHi : OFormL<0x12, 0x57, "INSWH $RA,$L,$RC", []>; //Insert word high
297 //def INSWL : OForm< 0x12, 0x1B, "INSWL $RA,$RB,$RC", []>; //Insert word low
298 //def INSWLi : OFormL<0x12, 0x1B, "INSWL $RA,$L,$RC", []>; //Insert word low
300 //def MSKBL : OForm< 0x12, 0x02, "MSKBL $RA,$RB,$RC", []>; //Mask byte low
301 //def MSKBLi : OFormL<0x12, 0x02, "MSKBL $RA,$L,$RC", []>; //Mask byte low
302 //def MSKLH : OForm< 0x12, 0x62, "MSKLH $RA,$RB,$RC", []>; //Mask longword high
303 //def MSKLHi : OFormL<0x12, 0x62, "MSKLH $RA,$L,$RC", []>; //Mask longword high
304 //def MSKLL : OForm< 0x12, 0x22, "MSKLL $RA,$RB,$RC", []>; //Mask longword low
305 //def MSKLLi : OFormL<0x12, 0x22, "MSKLL $RA,$L,$RC", []>; //Mask longword low
306 //def MSKQH : OForm< 0x12, 0x72, "MSKQH $RA,$RB,$RC", []>; //Mask quadword high
307 //def MSKQHi : OFormL<0x12, 0x72, "MSKQH $RA,$L,$RC", []>; //Mask quadword high
308 //def MSKQL : OForm< 0x12, 0x32, "MSKQL $RA,$RB,$RC", []>; //Mask quadword low
309 //def MSKQLi : OFormL<0x12, 0x32, "MSKQL $RA,$L,$RC", []>; //Mask quadword low
310 //def MSKWH : OForm< 0x12, 0x52, "MSKWH $RA,$RB,$RC", []>; //Mask word high
311 //def MSKWHi : OFormL<0x12, 0x52, "MSKWH $RA,$L,$RC", []>; //Mask word high
312 //def MSKWL : OForm< 0x12, 0x12, "MSKWL $RA,$RB,$RC", []>; //Mask word low
313 //def MSKWLi : OFormL<0x12, 0x12, "MSKWL $RA,$L,$RC", []>; //Mask word low
315 def ZAPNOTi : OFormL<0x12, 0x31, "zapnot $RA,$L,$RC", [], s_ishf>;
317 // Define the pattern that produces ZAPNOTi.
318 def : Pat<(i64 (zappat GPRC:$RA):$imm),
319 (ZAPNOTi GPRC:$RA, (iZAPX GPRC:$imm))>;
323 //So this is a waste of what this instruction can do, but it still saves something
324 def CMPBGE : OForm< 0x10, 0x0F, "cmpbge $RA,$RB,$RC",
325 [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), (and GPRC:$RB, 255)))], s_ilog>;
326 def CMPBGEi : OFormL<0x10, 0x0F, "cmpbge $RA,$L,$RC",
327 [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), immUExt8:$L))], s_ilog>;
328 def CMPEQ : OForm< 0x10, 0x2D, "cmpeq $RA,$RB,$RC",
329 [(set GPRC:$RC, (seteq GPRC:$RA, GPRC:$RB))], s_iadd>;
330 def CMPEQi : OFormL<0x10, 0x2D, "cmpeq $RA,$L,$RC",
331 [(set GPRC:$RC, (seteq GPRC:$RA, immUExt8:$L))], s_iadd>;
332 def CMPLE : OForm< 0x10, 0x6D, "cmple $RA,$RB,$RC",
333 [(set GPRC:$RC, (setle GPRC:$RA, GPRC:$RB))], s_iadd>;
334 def CMPLEi : OFormL<0x10, 0x6D, "cmple $RA,$L,$RC",
335 [(set GPRC:$RC, (setle GPRC:$RA, immUExt8:$L))], s_iadd>;
336 def CMPLT : OForm< 0x10, 0x4D, "cmplt $RA,$RB,$RC",
337 [(set GPRC:$RC, (setlt GPRC:$RA, GPRC:$RB))], s_iadd>;
338 def CMPLTi : OFormL<0x10, 0x4D, "cmplt $RA,$L,$RC",
339 [(set GPRC:$RC, (setlt GPRC:$RA, immUExt8:$L))], s_iadd>;
340 def CMPULE : OForm< 0x10, 0x3D, "cmpule $RA,$RB,$RC",
341 [(set GPRC:$RC, (setule GPRC:$RA, GPRC:$RB))], s_iadd>;
342 def CMPULEi : OFormL<0x10, 0x3D, "cmpule $RA,$L,$RC",
343 [(set GPRC:$RC, (setule GPRC:$RA, immUExt8:$L))], s_iadd>;
344 def CMPULT : OForm< 0x10, 0x1D, "cmpult $RA,$RB,$RC",
345 [(set GPRC:$RC, (setult GPRC:$RA, GPRC:$RB))], s_iadd>;
346 def CMPULTi : OFormL<0x10, 0x1D, "cmpult $RA,$L,$RC",
347 [(set GPRC:$RC, (setult GPRC:$RA, immUExt8:$L))], s_iadd>;
349 //Patterns for unsupported int comparisons
350 def : Pat<(setueq GPRC:$X, GPRC:$Y), (CMPEQ GPRC:$X, GPRC:$Y)>;
351 def : Pat<(setueq GPRC:$X, immUExt8:$Y), (CMPEQi GPRC:$X, immUExt8:$Y)>;
353 def : Pat<(setugt GPRC:$X, GPRC:$Y), (CMPULT GPRC:$Y, GPRC:$X)>;
354 def : Pat<(setugt immUExt8:$X, GPRC:$Y), (CMPULTi GPRC:$Y, immUExt8:$X)>;
356 def : Pat<(setuge GPRC:$X, GPRC:$Y), (CMPULE GPRC:$Y, GPRC:$X)>;
357 def : Pat<(setuge immUExt8:$X, GPRC:$Y), (CMPULEi GPRC:$Y, immUExt8:$X)>;
359 def : Pat<(setgt GPRC:$X, GPRC:$Y), (CMPLT GPRC:$Y, GPRC:$X)>;
360 def : Pat<(setgt immUExt8:$X, GPRC:$Y), (CMPLTi GPRC:$Y, immUExt8:$X)>;
362 def : Pat<(setge GPRC:$X, GPRC:$Y), (CMPLE GPRC:$Y, GPRC:$X)>;
363 def : Pat<(setge immUExt8:$X, GPRC:$Y), (CMPLEi GPRC:$Y, immUExt8:$X)>;
365 def : Pat<(setne GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>;
366 def : Pat<(setne GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQi GPRC:$X, immUExt8:$Y), 0)>;
368 def : Pat<(setune GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>;
369 def : Pat<(setune GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQ GPRC:$X, immUExt8:$Y), 0)>;
372 let isReturn = 1, isTerminator = 1, Ra = 31, Rb = 26, disp = 1, Uses = [R26] in {
373 def RETDAG : MbrForm< 0x1A, 0x02, (ops), "ret $$31,($$26),1", s_jsr>; //Return from subroutine
374 def RETDAGp : MbrpForm< 0x1A, 0x02, (ops), "ret $$31,($$26),1", [(retflag)], s_jsr>; //Return from subroutine
377 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1, Ra = 31, disp = 0 in
378 def JMP : MbrpForm< 0x1A, 0x00, (ops GPRC:$RS), "jmp $$31,($RS),0",
379 [(brind GPRC:$RS)], s_jsr>; //Jump
381 let isCall = 1, Ra = 26,
382 Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19,
383 R20, R21, R22, R23, R24, R25, R26, R27, R28, R29,
385 F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
386 F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R29] in {
387 def BSR : BFormD<0x34, "bsr $$26,$$$DISP..ng", [], s_jsr>; //Branch to subroutine
389 let isCall = 1, Ra = 26, Rb = 27, disp = 0,
390 Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19,
391 R20, R21, R22, R23, R24, R25, R26, R27, R28, R29,
393 F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
394 F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R27, R29] in {
395 def JSR : MbrForm< 0x1A, 0x01, (ops ), "jsr $$26,($$27),0", s_jsr>; //Jump to subroutine
398 let isCall = 1, Ra = 23, Rb = 27, disp = 0,
399 Defs = [R23, R24, R25, R27, R28], Uses = [R24, R25, R27] in
400 def JSRs : MbrForm< 0x1A, 0x01, (ops ), "jsr $$23,($$27),0", s_jsr>; //Jump to div or rem
403 def JSR_COROUTINE : MbrForm< 0x1A, 0x03, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr_coroutine $RD,($RS),$DISP", s_jsr>; //Jump to subroutine return
406 let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
407 def LDQ : MForm<0x29, 0, 1, "ldq $RA,$DISP($RB)",
408 [(set GPRC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
409 def LDQr : MForm<0x29, 0, 1, "ldq $RA,$DISP($RB)\t\t!gprellow",
410 [(set GPRC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>;
411 def LDL : MForm<0x28, 0, 1, "ldl $RA,$DISP($RB)",
412 [(set GPRC:$RA, (sextloadi32 (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
413 def LDLr : MForm<0x28, 0, 1, "ldl $RA,$DISP($RB)\t\t!gprellow",
414 [(set GPRC:$RA, (sextloadi32 (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>;
415 def LDBU : MForm<0x0A, 0, 1, "ldbu $RA,$DISP($RB)",
416 [(set GPRC:$RA, (zextloadi8 (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
417 def LDBUr : MForm<0x0A, 0, 1, "ldbu $RA,$DISP($RB)\t\t!gprellow",
418 [(set GPRC:$RA, (zextloadi8 (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>;
419 def LDWU : MForm<0x0C, 0, 1, "ldwu $RA,$DISP($RB)",
420 [(set GPRC:$RA, (zextloadi16 (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
421 def LDWUr : MForm<0x0C, 0, 1, "ldwu $RA,$DISP($RB)\t\t!gprellow",
422 [(set GPRC:$RA, (zextloadi16 (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>;
426 let OutOperandList = (ops), InOperandList = (ops GPRC:$RA, s64imm:$DISP, GPRC:$RB) in {
427 def STB : MForm<0x0E, 1, 0, "stb $RA,$DISP($RB)",
428 [(truncstorei8 GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
429 def STBr : MForm<0x0E, 1, 0, "stb $RA,$DISP($RB)\t\t!gprellow",
430 [(truncstorei8 GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
431 def STW : MForm<0x0D, 1, 0, "stw $RA,$DISP($RB)",
432 [(truncstorei16 GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
433 def STWr : MForm<0x0D, 1, 0, "stw $RA,$DISP($RB)\t\t!gprellow",
434 [(truncstorei16 GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
435 def STL : MForm<0x2C, 1, 0, "stl $RA,$DISP($RB)",
436 [(truncstorei32 GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
437 def STLr : MForm<0x2C, 1, 0, "stl $RA,$DISP($RB)\t\t!gprellow",
438 [(truncstorei32 GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
439 def STQ : MForm<0x2D, 1, 0, "stq $RA,$DISP($RB)",
440 [(store GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
441 def STQr : MForm<0x2D, 1, 0, "stq $RA,$DISP($RB)\t\t!gprellow",
442 [(store GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
446 let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
447 def LDA : MForm<0x08, 0, 0, "lda $RA,$DISP($RB)",
448 [(set GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_lda>;
449 def LDAr : MForm<0x08, 0, 0, "lda $RA,$DISP($RB)\t\t!gprellow",
450 [(set GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_lda>; //Load address
451 def LDAH : MForm<0x09, 0, 0, "ldah $RA,$DISP($RB)",
452 [], s_lda>; //Load address high
453 def LDAHr : MForm<0x09, 0, 0, "ldah $RA,$DISP($RB)\t\t!gprelhigh",
454 [(set GPRC:$RA, (Alpha_gprelhi tglobaladdr:$DISP, GPRC:$RB))], s_lda>; //Load address high
457 let OutOperandList = (ops), InOperandList = (ops F4RC:$RA, s64imm:$DISP, GPRC:$RB) in {
458 def STS : MForm<0x26, 1, 0, "sts $RA,$DISP($RB)",
459 [(store F4RC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_fst>;
460 def STSr : MForm<0x26, 1, 0, "sts $RA,$DISP($RB)\t\t!gprellow",
461 [(store F4RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_fst>;
463 let OutOperandList = (ops F4RC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
464 def LDS : MForm<0x22, 0, 1, "lds $RA,$DISP($RB)",
465 [(set F4RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_fld>;
466 def LDSr : MForm<0x22, 0, 1, "lds $RA,$DISP($RB)\t\t!gprellow",
467 [(set F4RC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_fld>;
469 let OutOperandList = (ops), InOperandList = (ops F8RC:$RA, s64imm:$DISP, GPRC:$RB) in {
470 def STT : MForm<0x27, 1, 0, "stt $RA,$DISP($RB)",
471 [(store F8RC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_fst>;
472 def STTr : MForm<0x27, 1, 0, "stt $RA,$DISP($RB)\t\t!gprellow",
473 [(store F8RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_fst>;
475 let OutOperandList = (ops F8RC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
476 def LDT : MForm<0x23, 0, 1, "ldt $RA,$DISP($RB)",
477 [(set F8RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_fld>;
478 def LDTr : MForm<0x23, 0, 1, "ldt $RA,$DISP($RB)\t\t!gprellow",
479 [(set F8RC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_fld>;
484 def : Pat<(i64 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
485 (LDQr tconstpool:$DISP, GPRC:$RB)>;
486 def : Pat<(i64 (sextloadi32 (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
487 (LDLr tconstpool:$DISP, GPRC:$RB)>;
488 def : Pat<(i64 (zextloadi8 (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
489 (LDBUr tconstpool:$DISP, GPRC:$RB)>;
490 def : Pat<(i64 (zextloadi16 (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
491 (LDWUr tconstpool:$DISP, GPRC:$RB)>;
492 def : Pat<(i64 (Alpha_gprello tconstpool:$DISP, GPRC:$RB)),
493 (LDAr tconstpool:$DISP, GPRC:$RB)>;
494 def : Pat<(i64 (Alpha_gprelhi tconstpool:$DISP, GPRC:$RB)),
495 (LDAHr tconstpool:$DISP, GPRC:$RB)>;
496 def : Pat<(f32 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
497 (LDSr tconstpool:$DISP, GPRC:$RB)>;
498 def : Pat<(f64 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
499 (LDTr tconstpool:$DISP, GPRC:$RB)>;
502 def : Pat<(i64 (Alpha_gprelhi tjumptable:$DISP, GPRC:$RB)),
503 (LDAHr tjumptable:$DISP, GPRC:$RB)>;
504 def : Pat<(i64 (Alpha_gprello tjumptable:$DISP, GPRC:$RB)),
505 (LDAr tjumptable:$DISP, GPRC:$RB)>;
509 def : Pat<(i64 (extloadi8 (add GPRC:$RB, immSExt16:$DISP))),
510 (LDBU immSExt16:$DISP, GPRC:$RB)>;
511 def : Pat<(i64 (extloadi16 (add GPRC:$RB, immSExt16:$DISP))),
512 (LDWU immSExt16:$DISP, GPRC:$RB)>;
513 def : Pat<(i64 (extloadi32 (add GPRC:$RB, immSExt16:$DISP))),
514 (LDL immSExt16:$DISP, GPRC:$RB)>;
517 def : Pat<(i64 (load GPRC:$addr)),
518 (LDQ 0, GPRC:$addr)>;
519 def : Pat<(f64 (load GPRC:$addr)),
520 (LDT 0, GPRC:$addr)>;
521 def : Pat<(f32 (load GPRC:$addr)),
522 (LDS 0, GPRC:$addr)>;
523 def : Pat<(i64 (sextloadi32 GPRC:$addr)),
524 (LDL 0, GPRC:$addr)>;
525 def : Pat<(i64 (zextloadi16 GPRC:$addr)),
526 (LDWU 0, GPRC:$addr)>;
527 def : Pat<(i64 (zextloadi8 GPRC:$addr)),
528 (LDBU 0, GPRC:$addr)>;
529 def : Pat<(i64 (extloadi8 GPRC:$addr)),
530 (LDBU 0, GPRC:$addr)>;
531 def : Pat<(i64 (extloadi16 GPRC:$addr)),
532 (LDWU 0, GPRC:$addr)>;
533 def : Pat<(i64 (extloadi32 GPRC:$addr)),
534 (LDL 0, GPRC:$addr)>;
536 def : Pat<(store GPRC:$DATA, GPRC:$addr),
537 (STQ GPRC:$DATA, 0, GPRC:$addr)>;
538 def : Pat<(store F8RC:$DATA, GPRC:$addr),
539 (STT F8RC:$DATA, 0, GPRC:$addr)>;
540 def : Pat<(store F4RC:$DATA, GPRC:$addr),
541 (STS F4RC:$DATA, 0, GPRC:$addr)>;
542 def : Pat<(truncstorei32 GPRC:$DATA, GPRC:$addr),
543 (STL GPRC:$DATA, 0, GPRC:$addr)>;
544 def : Pat<(truncstorei16 GPRC:$DATA, GPRC:$addr),
545 (STW GPRC:$DATA, 0, GPRC:$addr)>;
546 def : Pat<(truncstorei8 GPRC:$DATA, GPRC:$addr),
547 (STB GPRC:$DATA, 0, GPRC:$addr)>;
550 //load address, rellocated gpdist form
551 let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s16imm:$DISP, GPRC:$RB, s16imm:$NUM) in {
552 def LDAg : MForm<0x08, 0, 1, "lda $RA,0($RB)\t\t!gpdisp!$NUM", [], s_lda>; //Load address
553 def LDAHg : MForm<0x09, 0, 1, "ldah $RA,0($RB)\t\t!gpdisp!$NUM", [], s_lda>; //Load address
556 //Load quad, rellocated literal form
557 let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in
558 def LDQl : MForm<0x29, 0, 1, "ldq $RA,$DISP($RB)\t\t!literal",
559 [(set GPRC:$RA, (Alpha_rellit tglobaladdr:$DISP, GPRC:$RB))], s_ild>;
560 def : Pat<(Alpha_rellit texternalsym:$ext, GPRC:$RB),
561 (LDQl texternalsym:$ext, GPRC:$RB)>;
564 def RPCC : MfcForm<0x18, 0xC000, "rpcc $RA", s_rpcc>; //Read process cycle counter
566 //Basic Floating point ops
570 let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F4RC:$RB), Fa = 31 in
571 def SQRTS : FPForm<0x14, 0x58B, "sqrts/su $RB,$RC",
572 [(set F4RC:$RC, (fsqrt F4RC:$RB))], s_fsqrts>;
574 let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F4RC:$RA, F4RC:$RB) in {
575 def ADDS : FPForm<0x16, 0x580, "adds/su $RA,$RB,$RC",
576 [(set F4RC:$RC, (fadd F4RC:$RA, F4RC:$RB))], s_fadd>;
577 def SUBS : FPForm<0x16, 0x581, "subs/su $RA,$RB,$RC",
578 [(set F4RC:$RC, (fsub F4RC:$RA, F4RC:$RB))], s_fadd>;
579 def DIVS : FPForm<0x16, 0x583, "divs/su $RA,$RB,$RC",
580 [(set F4RC:$RC, (fdiv F4RC:$RA, F4RC:$RB))], s_fdivs>;
581 def MULS : FPForm<0x16, 0x582, "muls/su $RA,$RB,$RC",
582 [(set F4RC:$RC, (fmul F4RC:$RA, F4RC:$RB))], s_fmul>;
584 def CPYSS : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
585 [(set F4RC:$RC, (fcopysign F4RC:$RB, F4RC:$RA))], s_fadd>;
586 def CPYSES : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent
587 def CPYSNS : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
588 [(set F4RC:$RC, (fneg (fcopysign F4RC:$RB, F4RC:$RA)))], s_fadd>;
593 let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in
594 def SQRTT : FPForm<0x14, 0x5AB, "sqrtt/su $RB,$RC",
595 [(set F8RC:$RC, (fsqrt F8RC:$RB))], s_fsqrtt>;
597 let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F8RC:$RA, F8RC:$RB) in {
598 def ADDT : FPForm<0x16, 0x5A0, "addt/su $RA,$RB,$RC",
599 [(set F8RC:$RC, (fadd F8RC:$RA, F8RC:$RB))], s_fadd>;
600 def SUBT : FPForm<0x16, 0x5A1, "subt/su $RA,$RB,$RC",
601 [(set F8RC:$RC, (fsub F8RC:$RA, F8RC:$RB))], s_fadd>;
602 def DIVT : FPForm<0x16, 0x5A3, "divt/su $RA,$RB,$RC",
603 [(set F8RC:$RC, (fdiv F8RC:$RA, F8RC:$RB))], s_fdivt>;
604 def MULT : FPForm<0x16, 0x5A2, "mult/su $RA,$RB,$RC",
605 [(set F8RC:$RC, (fmul F8RC:$RA, F8RC:$RB))], s_fmul>;
607 def CPYST : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
608 [(set F8RC:$RC, (fcopysign F8RC:$RB, F8RC:$RA))], s_fadd>;
609 def CPYSET : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent
610 def CPYSNT : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
611 [(set F8RC:$RC, (fneg (fcopysign F8RC:$RB, F8RC:$RA)))], s_fadd>;
613 def CMPTEQ : FPForm<0x16, 0x5A5, "cmpteq/su $RA,$RB,$RC", [], s_fadd>;
614 // [(set F8RC:$RC, (seteq F8RC:$RA, F8RC:$RB))]>;
615 def CMPTLE : FPForm<0x16, 0x5A7, "cmptle/su $RA,$RB,$RC", [], s_fadd>;
616 // [(set F8RC:$RC, (setle F8RC:$RA, F8RC:$RB))]>;
617 def CMPTLT : FPForm<0x16, 0x5A6, "cmptlt/su $RA,$RB,$RC", [], s_fadd>;
618 // [(set F8RC:$RC, (setlt F8RC:$RA, F8RC:$RB))]>;
619 def CMPTUN : FPForm<0x16, 0x5A4, "cmptun/su $RA,$RB,$RC", [], s_fadd>;
620 // [(set F8RC:$RC, (setuo F8RC:$RA, F8RC:$RB))]>;
624 let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F4RC:$RA, F8RC:$RB) in {
625 def CPYSTs : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
626 [(set F8RC:$RC, (fcopysign F8RC:$RB, F4RC:$RA))], s_fadd>;
627 def CPYSNTs : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
628 [(set F8RC:$RC, (fneg (fcopysign F8RC:$RB, F4RC:$RA)))], s_fadd>;
630 let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F8RC:$RA, F4RC:$RB) in {
631 def CPYSSt : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
632 [(set F4RC:$RC, (fcopysign F4RC:$RB, F8RC:$RA))], s_fadd>;
633 def CPYSESt : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent
634 def CPYSNSt : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
635 [(set F4RC:$RC, (fneg (fcopysign F4RC:$RB, F8RC:$RA)))], s_fadd>;
638 //conditional moves, floats
639 let OutOperandList = (ops F4RC:$RDEST), InOperandList = (ops F4RC:$RFALSE, F4RC:$RTRUE, F8RC:$RCOND),
640 isTwoAddress = 1 in {
641 def FCMOVEQS : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if = zero
642 def FCMOVGES : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if >= zero
643 def FCMOVGTS : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if > zero
644 def FCMOVLES : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if <= zero
645 def FCMOVLTS : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST",[], s_fcmov>; // FCMOVE if < zero
646 def FCMOVNES : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if != zero
648 //conditional moves, doubles
649 let OutOperandList = (ops F8RC:$RDEST), InOperandList = (ops F8RC:$RFALSE, F8RC:$RTRUE, F8RC:$RCOND),
650 isTwoAddress = 1 in {
651 def FCMOVEQT : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
652 def FCMOVGET : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
653 def FCMOVGTT : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
654 def FCMOVLET : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
655 def FCMOVLTT : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
656 def FCMOVNET : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
662 def : Pat<(select (seteq F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
663 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
664 def : Pat<(select (setoeq F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
665 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
666 def : Pat<(select (setueq F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
667 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
669 def : Pat<(select (setne F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
670 (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
671 def : Pat<(select (setone F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
672 (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
673 def : Pat<(select (setune F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
674 (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
676 def : Pat<(select (setgt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
677 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
678 def : Pat<(select (setogt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
679 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
680 def : Pat<(select (setugt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
681 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
683 def : Pat<(select (setge F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
684 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
685 def : Pat<(select (setoge F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
686 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
687 def : Pat<(select (setuge F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
688 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
690 def : Pat<(select (setlt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
691 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
692 def : Pat<(select (setolt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
693 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
694 def : Pat<(select (setult F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
695 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
697 def : Pat<(select (setle F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
698 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
699 def : Pat<(select (setole F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
700 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
701 def : Pat<(select (setule F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
702 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
705 def : Pat<(select (seteq F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
706 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
707 def : Pat<(select (setoeq F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
708 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
709 def : Pat<(select (setueq F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
710 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
712 def : Pat<(select (setne F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
713 (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
714 def : Pat<(select (setone F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
715 (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
716 def : Pat<(select (setune F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
717 (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
719 def : Pat<(select (setgt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
720 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
721 def : Pat<(select (setogt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
722 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
723 def : Pat<(select (setugt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
724 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
726 def : Pat<(select (setge F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
727 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
728 def : Pat<(select (setoge F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
729 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
730 def : Pat<(select (setuge F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
731 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
733 def : Pat<(select (setlt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
734 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
735 def : Pat<(select (setolt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
736 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
737 def : Pat<(select (setult F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
738 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
740 def : Pat<(select (setle F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
741 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
742 def : Pat<(select (setole F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
743 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
744 def : Pat<(select (setule F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
745 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
749 let OutOperandList = (ops GPRC:$RC), InOperandList = (ops F4RC:$RA), Fb = 31 in
750 def FTOIS : FPForm<0x1C, 0x078, "ftois $RA,$RC",[], s_ftoi>; //Floating to integer move, S_floating
751 let OutOperandList = (ops GPRC:$RC), InOperandList = (ops F8RC:$RA), Fb = 31 in
752 def FTOIT : FPForm<0x1C, 0x070, "ftoit $RA,$RC",
753 [(set GPRC:$RC, (bitconvert F8RC:$RA))], s_ftoi>; //Floating to integer move
754 let OutOperandList = (ops F4RC:$RC), InOperandList = (ops GPRC:$RA), Fb = 31 in
755 def ITOFS : FPForm<0x14, 0x004, "itofs $RA,$RC",[], s_itof>; //Integer to floating move, S_floating
756 let OutOperandList = (ops F8RC:$RC), InOperandList = (ops GPRC:$RA), Fb = 31 in
757 def ITOFT : FPForm<0x14, 0x024, "itoft $RA,$RC",
758 [(set F8RC:$RC, (bitconvert GPRC:$RA))], s_itof>; //Integer to floating move
761 let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in
762 def CVTQS : FPForm<0x16, 0x7BC, "cvtqs/sui $RB,$RC",
763 [(set F4RC:$RC, (Alpha_cvtqs F8RC:$RB))], s_fadd>;
764 let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in
765 def CVTQT : FPForm<0x16, 0x7BE, "cvtqt/sui $RB,$RC",
766 [(set F8RC:$RC, (Alpha_cvtqt F8RC:$RB))], s_fadd>;
767 let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in
768 def CVTTQ : FPForm<0x16, 0x52F, "cvttq/svc $RB,$RC",
769 [(set F8RC:$RC, (Alpha_cvttq F8RC:$RB))], s_fadd>;
770 let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F4RC:$RB), Fa = 31 in
771 def CVTST : FPForm<0x16, 0x6AC, "cvtst/s $RB,$RC",
772 [(set F8RC:$RC, (fextend F4RC:$RB))], s_fadd>;
773 let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in
774 def CVTTS : FPForm<0x16, 0x7AC, "cvtts/sui $RB,$RC",
775 [(set F4RC:$RC, (fround F8RC:$RB))], s_fadd>;
778 /////////////////////////////////////////////////////////
780 /////////////////////////////////////////////////////////
781 class br_icc<bits<6> opc, string asmstr>
782 : BFormN<opc, (ops u64imm:$opc, GPRC:$R, target:$dst),
783 !strconcat(asmstr, " $R,$dst"), s_icbr>;
784 class br_fcc<bits<6> opc, string asmstr>
785 : BFormN<opc, (ops u64imm:$opc, F8RC:$R, target:$dst),
786 !strconcat(asmstr, " $R,$dst"), s_fbr>;
788 let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in {
790 def BR : BFormD<0x30, "br $$31,$DISP", [(br bb:$DISP)], s_ubr>;
792 def COND_BRANCH_I : BFormN<0, (ops u64imm:$opc, GPRC:$R, target:$dst),
793 "{:comment} COND_BRANCH imm:$opc, GPRC:$R, bb:$dst",
795 def COND_BRANCH_F : BFormN<0, (ops u64imm:$opc, F8RC:$R, target:$dst),
796 "{:comment} COND_BRANCH imm:$opc, F8RC:$R, bb:$dst",
799 def BEQ : br_icc<0x39, "beq">;
800 def BGE : br_icc<0x3E, "bge">;
801 def BGT : br_icc<0x3F, "bgt">;
802 def BLBC : br_icc<0x38, "blbc">;
803 def BLBS : br_icc<0x3C, "blbs">;
804 def BLE : br_icc<0x3B, "ble">;
805 def BLT : br_icc<0x3A, "blt">;
806 def BNE : br_icc<0x3D, "bne">;
809 def FBEQ : br_fcc<0x31, "fbeq">;
810 def FBGE : br_fcc<0x36, "fbge">;
811 def FBGT : br_fcc<0x37, "fbgt">;
812 def FBLE : br_fcc<0x33, "fble">;
813 def FBLT : br_fcc<0x32, "fblt">;
814 def FBNE : br_fcc<0x36, "fbne">;
817 //An ugly trick to get the opcode as an imm I can use
818 def immBRCond : SDNodeXForm<imm, [{
819 switch((uint64_t)N->getValue()) {
820 case 0: return getI64Imm(Alpha::BEQ);
821 case 1: return getI64Imm(Alpha::BNE);
822 case 2: return getI64Imm(Alpha::BGE);
823 case 3: return getI64Imm(Alpha::BGT);
824 case 4: return getI64Imm(Alpha::BLE);
825 case 5: return getI64Imm(Alpha::BLT);
826 case 6: return getI64Imm(Alpha::BLBS);
827 case 7: return getI64Imm(Alpha::BLBC);
828 case 20: return getI64Imm(Alpha::FBEQ);
829 case 21: return getI64Imm(Alpha::FBNE);
830 case 22: return getI64Imm(Alpha::FBGE);
831 case 23: return getI64Imm(Alpha::FBGT);
832 case 24: return getI64Imm(Alpha::FBLE);
833 case 25: return getI64Imm(Alpha::FBLT);
834 default: assert(0 && "Unknown branch type");
839 def : Pat<(brcond (seteq GPRC:$RA, 0), bb:$DISP),
840 (COND_BRANCH_I (immBRCond 0), GPRC:$RA, bb:$DISP)>;
841 def : Pat<(brcond (setge GPRC:$RA, 0), bb:$DISP),
842 (COND_BRANCH_I (immBRCond 2), GPRC:$RA, bb:$DISP)>;
843 def : Pat<(brcond (setgt GPRC:$RA, 0), bb:$DISP),
844 (COND_BRANCH_I (immBRCond 3), GPRC:$RA, bb:$DISP)>;
845 def : Pat<(brcond (and GPRC:$RA, 1), bb:$DISP),
846 (COND_BRANCH_I (immBRCond 6), GPRC:$RA, bb:$DISP)>;
847 def : Pat<(brcond (setle GPRC:$RA, 0), bb:$DISP),
848 (COND_BRANCH_I (immBRCond 4), GPRC:$RA, bb:$DISP)>;
849 def : Pat<(brcond (setlt GPRC:$RA, 0), bb:$DISP),
850 (COND_BRANCH_I (immBRCond 5), GPRC:$RA, bb:$DISP)>;
851 def : Pat<(brcond (setne GPRC:$RA, 0), bb:$DISP),
852 (COND_BRANCH_I (immBRCond 1), GPRC:$RA, bb:$DISP)>;
854 def : Pat<(brcond GPRC:$RA, bb:$DISP),
855 (COND_BRANCH_I (immBRCond 1), GPRC:$RA, bb:$DISP)>;
856 def : Pat<(brcond (setne GPRC:$RA, GPRC:$RB), bb:$DISP),
857 (COND_BRANCH_I (immBRCond 0), (CMPEQ GPRC:$RA, GPRC:$RB), bb:$DISP)>;
858 def : Pat<(brcond (setne GPRC:$RA, immUExt8:$L), bb:$DISP),
859 (COND_BRANCH_I (immBRCond 0), (CMPEQi GPRC:$RA, immUExt8:$L), bb:$DISP)>;
862 def : Pat<(brcond (seteq F8RC:$RA, immFPZ), bb:$DISP),
863 (COND_BRANCH_F (immBRCond 20), F8RC:$RA, bb:$DISP)>;
864 def : Pat<(brcond (setne F8RC:$RA, immFPZ), bb:$DISP),
865 (COND_BRANCH_F (immBRCond 21), F8RC:$RA, bb:$DISP)>;
866 def : Pat<(brcond (setge F8RC:$RA, immFPZ), bb:$DISP),
867 (COND_BRANCH_F (immBRCond 22), F8RC:$RA, bb:$DISP)>;
868 def : Pat<(brcond (setgt F8RC:$RA, immFPZ), bb:$DISP),
869 (COND_BRANCH_F (immBRCond 23), F8RC:$RA, bb:$DISP)>;
870 def : Pat<(brcond (setle F8RC:$RA, immFPZ), bb:$DISP),
871 (COND_BRANCH_F (immBRCond 24), F8RC:$RA, bb:$DISP)>;
872 def : Pat<(brcond (setlt F8RC:$RA, immFPZ), bb:$DISP),
873 (COND_BRANCH_F (immBRCond 25), F8RC:$RA, bb:$DISP)>;
876 def : Pat<(brcond (seteq F8RC:$RA, F8RC:$RB), bb:$DISP),
877 (COND_BRANCH_F (immBRCond 21), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
878 def : Pat<(brcond (setoeq F8RC:$RA, F8RC:$RB), bb:$DISP),
879 (COND_BRANCH_F (immBRCond 21), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
880 def : Pat<(brcond (setueq F8RC:$RA, F8RC:$RB), bb:$DISP),
881 (COND_BRANCH_F (immBRCond 21), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
883 def : Pat<(brcond (setlt F8RC:$RA, F8RC:$RB), bb:$DISP),
884 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
885 def : Pat<(brcond (setolt F8RC:$RA, F8RC:$RB), bb:$DISP),
886 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
887 def : Pat<(brcond (setult F8RC:$RA, F8RC:$RB), bb:$DISP),
888 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
890 def : Pat<(brcond (setle F8RC:$RA, F8RC:$RB), bb:$DISP),
891 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
892 def : Pat<(brcond (setole F8RC:$RA, F8RC:$RB), bb:$DISP),
893 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
894 def : Pat<(brcond (setule F8RC:$RA, F8RC:$RB), bb:$DISP),
895 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
897 def : Pat<(brcond (setgt F8RC:$RA, F8RC:$RB), bb:$DISP),
898 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
899 def : Pat<(brcond (setogt F8RC:$RA, F8RC:$RB), bb:$DISP),
900 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
901 def : Pat<(brcond (setugt F8RC:$RA, F8RC:$RB), bb:$DISP),
902 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
904 def : Pat<(brcond (setge F8RC:$RA, F8RC:$RB), bb:$DISP),
905 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
906 def : Pat<(brcond (setoge F8RC:$RA, F8RC:$RB), bb:$DISP),
907 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
908 def : Pat<(brcond (setuge F8RC:$RA, F8RC:$RB), bb:$DISP),
909 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
911 def : Pat<(brcond (setne F8RC:$RA, F8RC:$RB), bb:$DISP),
912 (COND_BRANCH_F (immBRCond 20), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
913 def : Pat<(brcond (setone F8RC:$RA, F8RC:$RB), bb:$DISP),
914 (COND_BRANCH_F (immBRCond 20), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
915 def : Pat<(brcond (setune F8RC:$RA, F8RC:$RB), bb:$DISP),
916 (COND_BRANCH_F (immBRCond 20), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
919 def : Pat<(brcond (setoeq F8RC:$RA, immFPZ), bb:$DISP),
920 (COND_BRANCH_F (immBRCond 20), F8RC:$RA,bb:$DISP)>;
921 def : Pat<(brcond (setueq F8RC:$RA, immFPZ), bb:$DISP),
922 (COND_BRANCH_F (immBRCond 20), F8RC:$RA,bb:$DISP)>;
924 def : Pat<(brcond (setoge F8RC:$RA, immFPZ), bb:$DISP),
925 (COND_BRANCH_F (immBRCond 22), F8RC:$RA,bb:$DISP)>;
926 def : Pat<(brcond (setuge F8RC:$RA, immFPZ), bb:$DISP),
927 (COND_BRANCH_F (immBRCond 22), F8RC:$RA,bb:$DISP)>;
929 def : Pat<(brcond (setogt F8RC:$RA, immFPZ), bb:$DISP),
930 (COND_BRANCH_F (immBRCond 23), F8RC:$RA,bb:$DISP)>;
931 def : Pat<(brcond (setugt F8RC:$RA, immFPZ), bb:$DISP),
932 (COND_BRANCH_F (immBRCond 23), F8RC:$RA,bb:$DISP)>;
934 def : Pat<(brcond (setole F8RC:$RA, immFPZ), bb:$DISP),
935 (COND_BRANCH_F (immBRCond 24), F8RC:$RA,bb:$DISP)>;
936 def : Pat<(brcond (setule F8RC:$RA, immFPZ), bb:$DISP),
937 (COND_BRANCH_F (immBRCond 24), F8RC:$RA,bb:$DISP)>;
939 def : Pat<(brcond (setolt F8RC:$RA, immFPZ), bb:$DISP),
940 (COND_BRANCH_F (immBRCond 25), F8RC:$RA,bb:$DISP)>;
941 def : Pat<(brcond (setult F8RC:$RA, immFPZ), bb:$DISP),
942 (COND_BRANCH_F (immBRCond 25), F8RC:$RA,bb:$DISP)>;
944 def : Pat<(brcond (setone F8RC:$RA, immFPZ), bb:$DISP),
945 (COND_BRANCH_F (immBRCond 21), F8RC:$RA,bb:$DISP)>;
946 def : Pat<(brcond (setune F8RC:$RA, immFPZ), bb:$DISP),
947 (COND_BRANCH_F (immBRCond 21), F8RC:$RA,bb:$DISP)>;
951 //S_floating : IEEE Single
952 //T_floating : IEEE Double
954 //Unused instructions
955 //Mnemonic Format Opcode Description
956 //CALL_PAL Pcd 00 Trap to PALcode
957 //ECB Mfc 18.E800 Evict cache block
958 //EXCB Mfc 18.0400 Exception barrier
959 //FETCH Mfc 18.8000 Prefetch data
960 //FETCH_M Mfc 18.A000 Prefetch data, modify intent
961 //LDL_L Mem 2A Load sign-extended longword locked
962 //LDQ_L Mem 2B Load quadword locked
963 //LDQ_U Mem 0B Load unaligned quadword
964 //MB Mfc 18.4000 Memory barrier
965 //STL_C Mem 2E Store longword conditional
966 //STQ_C Mem 2F Store quadword conditional
967 //STQ_U Mem 0F Store unaligned quadword
968 //TRAPB Mfc 18.0000 Trap barrier
969 //WH64 Mfc 18.F800 Write hint
\14 64 bytes
970 //WMB Mfc 18.4400 Write memory barrier
971 //MF_FPCR F-P 17.025 Move from FPCR
972 //MT_FPCR F-P 17.024 Move to FPCR
973 //There are in the Multimedia extentions, so let's not use them yet
974 //def MAXSB8 : OForm<0x1C, 0x3E, "MAXSB8 $RA,$RB,$RC">; //Vector signed byte maximum
975 //def MAXSW4 : OForm< 0x1C, 0x3F, "MAXSW4 $RA,$RB,$RC">; //Vector signed word maximum
976 //def MAXUB8 : OForm<0x1C, 0x3C, "MAXUB8 $RA,$RB,$RC">; //Vector unsigned byte maximum
977 //def MAXUW4 : OForm< 0x1C, 0x3D, "MAXUW4 $RA,$RB,$RC">; //Vector unsigned word maximum
978 //def MINSB8 : OForm< 0x1C, 0x38, "MINSB8 $RA,$RB,$RC">; //Vector signed byte minimum
979 //def MINSW4 : OForm< 0x1C, 0x39, "MINSW4 $RA,$RB,$RC">; //Vector signed word minimum
980 //def MINUB8 : OForm< 0x1C, 0x3A, "MINUB8 $RA,$RB,$RC">; //Vector unsigned byte minimum
981 //def MINUW4 : OForm< 0x1C, 0x3B, "MINUW4 $RA,$RB,$RC">; //Vector unsigned word minimum
982 //def PERR : OForm< 0x1C, 0x31, "PERR $RA,$RB,$RC">; //Pixel error
983 //def PKLB : OForm< 0x1C, 0x37, "PKLB $RA,$RB,$RC">; //Pack longwords to bytes
984 //def PKWB : OForm<0x1C, 0x36, "PKWB $RA,$RB,$RC">; //Pack words to bytes
985 //def UNPKBL : OForm< 0x1C, 0x35, "UNPKBL $RA,$RB,$RC">; //Unpack bytes to longwords
986 //def UNPKBW : OForm< 0x1C, 0x34, "UNPKBW $RA,$RB,$RC">; //Unpack bytes to words
987 //CVTLQ F-P 17.010 Convert longword to quadword
988 //CVTQL F-P 17.030 Convert quadword to longword
993 def immConst2Part : PatLeaf<(imm), [{
994 //true if imm fits in a LDAH LDA pair
995 int64_t val = (int64_t)N->getValue();
996 return (val <= IMM_FULLHIGH && val >= IMM_FULLLOW);
998 def immConst2PartInt : PatLeaf<(imm), [{
999 //true if imm fits in a LDAH LDA pair with zeroext
1000 uint64_t uval = N->getValue();
1001 int32_t val32 = (int32_t)uval;
1002 return ((uval >> 32) == 0 && //empty upper bits
1003 val32 <= IMM_FULLHIGH);
1004 // val32 >= IMM_FULLLOW + IMM_LOW * IMM_MULT); //Always True
1007 def : Pat<(i64 immConst2Part:$imm),
1008 (LDA (LL16 immConst2Part:$imm), (LDAH (LH16 immConst2Part:$imm), R31))>;
1010 def : Pat<(i64 immSExt16:$imm),
1011 (LDA immSExt16:$imm, R31)>;
1013 def : Pat<(i64 immSExt16int:$imm),
1014 (ZAPNOTi (LDA (SExt16 immSExt16int:$imm), R31), 15)>;
1015 def : Pat<(i64 immConst2PartInt:$imm),
1016 (ZAPNOTi (LDA (LL16 (SExt32 immConst2PartInt:$imm)),
1017 (LDAH (LH16 (SExt32 immConst2PartInt:$imm)), R31)), 15)>;
1020 //TODO: I want to just define these like this!
1021 //def : Pat<(i64 0),
1023 //def : Pat<(f64 0.0),
1025 //def : Pat<(f64 -0.0),
1026 // (CPYSNT F31, F31)>;
1027 //def : Pat<(f32 0.0),
1029 //def : Pat<(f32 -0.0),
1030 // (CPYSNS F31, F31)>;
1034 def : Pat<(sext_inreg GPRC:$RB, i32),
1035 (ADDLi GPRC:$RB, 0)>;
1037 def : Pat<(fabs F8RC:$RB),
1038 (CPYST F31, F8RC:$RB)>;
1039 def : Pat<(fabs F4RC:$RB),
1040 (CPYSS F31, F4RC:$RB)>;
1041 def : Pat<(fneg F8RC:$RB),
1042 (CPYSNT F8RC:$RB, F8RC:$RB)>;
1043 def : Pat<(fneg F4RC:$RB),
1044 (CPYSNS F4RC:$RB, F4RC:$RB)>;
1046 def : Pat<(fcopysign F4RC:$A, (fneg F4RC:$B)),
1047 (CPYSNS F4RC:$B, F4RC:$A)>;
1048 def : Pat<(fcopysign F8RC:$A, (fneg F8RC:$B)),
1049 (CPYSNT F8RC:$B, F8RC:$A)>;
1050 def : Pat<(fcopysign F4RC:$A, (fneg F8RC:$B)),
1051 (CPYSNSt F8RC:$B, F4RC:$A)>;
1052 def : Pat<(fcopysign F8RC:$A, (fneg F4RC:$B)),
1053 (CPYSNTs F4RC:$B, F8RC:$A)>;
1055 //Yes, signed multiply high is ugly
1056 def : Pat<(mulhs GPRC:$RA, GPRC:$RB),
1057 (SUBQr (UMULHr GPRC:$RA, GPRC:$RB), (ADDQr (CMOVGEr GPRC:$RB, R31, GPRC:$RA),
1058 (CMOVGEr GPRC:$RA, R31, GPRC:$RB)))>;
1060 //Stupid crazy arithmetic stuff:
1061 let AddedComplexity = 1 in {
1062 def : Pat<(mul GPRC:$RA, 5), (S4ADDQr GPRC:$RA, GPRC:$RA)>;
1063 def : Pat<(mul GPRC:$RA, 9), (S8ADDQr GPRC:$RA, GPRC:$RA)>;
1064 def : Pat<(mul GPRC:$RA, 3), (S4SUBQr GPRC:$RA, GPRC:$RA)>;
1065 def : Pat<(mul GPRC:$RA, 7), (S8SUBQr GPRC:$RA, GPRC:$RA)>;
1067 //slight tree expansion if we are multiplying near to a power of 2
1068 //n is above a power of 2
1069 def : Pat<(mul GPRC:$RA, immRem1:$imm),
1070 (ADDQr (SLr GPRC:$RA, (nearP2X immRem1:$imm)), GPRC:$RA)>;
1071 def : Pat<(mul GPRC:$RA, immRem2:$imm),
1072 (ADDQr (SLr GPRC:$RA, (nearP2X immRem2:$imm)), (ADDQr GPRC:$RA, GPRC:$RA))>;
1073 def : Pat<(mul GPRC:$RA, immRem3:$imm),
1074 (ADDQr (SLr GPRC:$RA, (nearP2X immRem3:$imm)), (S4SUBQr GPRC:$RA, GPRC:$RA))>;
1075 def : Pat<(mul GPRC:$RA, immRem4:$imm),
1076 (S4ADDQr GPRC:$RA, (SLr GPRC:$RA, (nearP2X immRem4:$imm)))>;
1077 def : Pat<(mul GPRC:$RA, immRem5:$imm),
1078 (ADDQr (SLr GPRC:$RA, (nearP2X immRem5:$imm)), (S4ADDQr GPRC:$RA, GPRC:$RA))>;
1079 def : Pat<(mul GPRC:$RA, immRemP2:$imm),
1080 (ADDQr (SLr GPRC:$RA, (nearP2X immRemP2:$imm)), (SLi GPRC:$RA, (nearP2RemX immRemP2:$imm)))>;
1082 //n is below a power of 2
1083 def : Pat<(mul GPRC:$RA, immRem1n:$imm),
1084 (SUBQr (SLr GPRC:$RA, (nearP2X immRem1n:$imm)), GPRC:$RA)>;
1085 def : Pat<(mul GPRC:$RA, immRem2n:$imm),
1086 (SUBQr (SLr GPRC:$RA, (nearP2X immRem2n:$imm)), (ADDQr GPRC:$RA, GPRC:$RA))>;
1087 def : Pat<(mul GPRC:$RA, immRem3n:$imm),
1088 (SUBQr (SLr GPRC:$RA, (nearP2X immRem3n:$imm)), (S4SUBQr GPRC:$RA, GPRC:$RA))>;
1089 def : Pat<(mul GPRC:$RA, immRem4n:$imm),
1090 (SUBQr (SLr GPRC:$RA, (nearP2X immRem4n:$imm)), (SLi GPRC:$RA, 2))>;
1091 def : Pat<(mul GPRC:$RA, immRem5n:$imm),
1092 (SUBQr (SLr GPRC:$RA, (nearP2X immRem5n:$imm)), (S4ADDQr GPRC:$RA, GPRC:$RA))>;
1093 def : Pat<(mul GPRC:$RA, immRemP2n:$imm),
1094 (SUBQr (SLr GPRC:$RA, (nearP2X immRemP2n:$imm)), (SLi GPRC:$RA, (nearP2RemX immRemP2n:$imm)))>;
1095 } //Added complexity