blob: f73875062ab7175ecfa3d59a474e37dcdcd3c80e [file] [log] [blame]
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001//===- AlphaInstrInfo.td - The Alpha Instruction Set -------*- tablegen -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
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.
7//
8//===----------------------------------------------------------------------===//
9//
10//
11//===----------------------------------------------------------------------===//
12
13include "AlphaInstrFormats.td"
14
15//********************
16//Custom DAG Nodes
17//********************
18
19def SDTFPUnaryOpUnC : SDTypeProfile<1, 1, [
20 SDTCisFP<1>, SDTCisFP<0>
21]>;
22def Alpha_cvtqt : SDNode<"AlphaISD::CVTQT_", SDTFPUnaryOpUnC, []>;
23def Alpha_cvtqs : SDNode<"AlphaISD::CVTQS_", SDTFPUnaryOpUnC, []>;
24def Alpha_cvttq : SDNode<"AlphaISD::CVTTQ_" , SDTFPUnaryOp, []>;
25def Alpha_gprello : SDNode<"AlphaISD::GPRelLo", SDTIntBinOp, []>;
26def Alpha_gprelhi : SDNode<"AlphaISD::GPRelHi", SDTIntBinOp, []>;
27def Alpha_rellit : SDNode<"AlphaISD::RelLit", SDTIntBinOp, []>;
28
29def retflag : SDNode<"AlphaISD::RET_FLAG", SDTRet,
30 [SDNPHasChain, SDNPOptInFlag]>;
31
32// These are target-independent nodes, but have target-specific formats.
33def SDT_AlphaCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i64> ]>;
34def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_AlphaCallSeq,
35 [SDNPHasChain, SDNPOutFlag]>;
36def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_AlphaCallSeq,
37 [SDNPHasChain, SDNPOutFlag]>;
38
39//********************
40//Paterns for matching
41//********************
42def invX : SDNodeXForm<imm, [{ //invert
43 return getI64Imm(~N->getValue());
44}]>;
45def negX : SDNodeXForm<imm, [{ //negate
46 return getI64Imm(~N->getValue() + 1);
47}]>;
48def SExt32 : SDNodeXForm<imm, [{ //signed extend int to long
49 return getI64Imm(((int64_t)N->getValue() << 32) >> 32);
50}]>;
51def SExt16 : SDNodeXForm<imm, [{ //signed extend int to long
52 return getI64Imm(((int64_t)N->getValue() << 48) >> 48);
53}]>;
54def LL16 : SDNodeXForm<imm, [{ //lda part of constant
55 return getI64Imm(get_lda16(N->getValue()));
56}]>;
57def LH16 : SDNodeXForm<imm, [{ //ldah part of constant (or more if too big)
58 return getI64Imm(get_ldah16(N->getValue()));
59}]>;
60def iZAPX : SDNodeXForm<and, [{ // get imm to ZAPi
61 ConstantSDNode *RHS = cast<ConstantSDNode>(N->getOperand(1));
62 return getI64Imm(get_zapImm(SDOperand(), RHS->getValue()));
63}]>;
64def nearP2X : SDNodeXForm<imm, [{
65 return getI64Imm(Log2_64(getNearPower2((uint64_t)N->getValue())));
66}]>;
67def nearP2RemX : SDNodeXForm<imm, [{
68 uint64_t x = abs(N->getValue() - getNearPower2((uint64_t)N->getValue()));
69 return getI64Imm(Log2_64(x));
70}]>;
71
72def immUExt8 : PatLeaf<(imm), [{ //imm fits in 8 bit zero extended field
73 return (uint64_t)N->getValue() == (uint8_t)N->getValue();
74}]>;
75def immUExt8inv : PatLeaf<(imm), [{ //inverted imm fits in 8 bit zero extended field
76 return (uint64_t)~N->getValue() == (uint8_t)~N->getValue();
77}], invX>;
78def 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);
80}], negX>;
81def immSExt16 : PatLeaf<(imm), [{ //imm fits in 16 bit sign extended field
82 return ((int64_t)N->getValue() << 48) >> 48 == (int64_t)N->getValue();
83}]>;
84def 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;
86}], SExt16>;
87
88def 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());
91 return build != 0;
92 }
93 return false;
94}]>;
95
96def immFPZ : PatLeaf<(fpimm), [{ //the only fpconstant nodes are +/- 0.0
97 (void)N; // silence warning.
98 return true;
99}]>;
100
101def immRem1 : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),1, 0);}]>;
102def immRem2 : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),2, 0);}]>;
103def immRem3 : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),3, 0);}]>;
104def immRem4 : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),4, 0);}]>;
105def immRem5 : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),5, 0);}]>;
106def immRem1n : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),1, 1);}]>;
107def immRem2n : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),2, 1);}]>;
108def immRem3n : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),3, 1);}]>;
109def immRem4n : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),4, 1);}]>;
110def immRem5n : PatLeaf<(imm), [{return chkRemNearPower2(N->getValue(),5, 1);}]>;
111
112def immRemP2n : PatLeaf<(imm), [{
113 return isPowerOf2_64(getNearPower2((uint64_t)N->getValue()) - N->getValue());
114}]>;
115def immRemP2 : PatLeaf<(imm), [{
116 return isPowerOf2_64(N->getValue() - getNearPower2((uint64_t)N->getValue()));
117}]>;
118def 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;
121 switch (d) {
122 case 1: case 3: case 5: return false;
123 default: return (uint64_t)N->getValue() == (uint8_t)N->getValue();
124 };
125}]>;
126
127def intop : PatFrag<(ops node:$op), (sext_inreg node:$op, i32)>;
128def add4 : PatFrag<(ops node:$op1, node:$op2),
129 (add (shl node:$op1, 2), node:$op2)>;
130def sub4 : PatFrag<(ops node:$op1, node:$op2),
131 (sub (shl node:$op1, 2), node:$op2)>;
132def add8 : PatFrag<(ops node:$op1, node:$op2),
133 (add (shl node:$op1, 3), node:$op2)>;
134def sub8 : PatFrag<(ops node:$op1, node:$op2),
135 (sub (shl node:$op1, 3), node:$op2)>;
136class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
137class CmpOpFrag<dag res> : PatFrag<(ops node:$R), res>;
138
139//Pseudo ops for selection
140
Evan Chengb783fa32007-07-19 01:14:50 +0000141def IDEF_I : PseudoInstAlpha<(outs GPRC:$RA), (ins), ";#idef $RA",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000142 [(set GPRC:$RA, (undef))], s_pseudo>;
Evan Chengb783fa32007-07-19 01:14:50 +0000143def IDEF_F32 : PseudoInstAlpha<(outs F4RC:$RA), (ins), ";#idef $RA",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000144 [(set F4RC:$RA, (undef))], s_pseudo>;
Evan Chengb783fa32007-07-19 01:14:50 +0000145def IDEF_F64 : PseudoInstAlpha<(outs F8RC:$RA), (ins), ";#idef $RA",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000146 [(set F8RC:$RA, (undef))], s_pseudo>;
147
Evan Chengb783fa32007-07-19 01:14:50 +0000148def WTF : PseudoInstAlpha<(outs), (ins variable_ops), "#wtf", [], s_pseudo>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000149
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000150let isLoad = 1, hasCtrlDep = 1, Defs = [R30], Uses = [R30] in {
Evan Chengb783fa32007-07-19 01:14:50 +0000151def ADJUSTSTACKUP : PseudoInstAlpha<(outs), (ins s64imm:$amt), "; ADJUP $amt",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000152 [(callseq_start imm:$amt)], s_pseudo>;
Evan Chengb783fa32007-07-19 01:14:50 +0000153def ADJUSTSTACKDOWN : PseudoInstAlpha<(outs), (ins s64imm:$amt), "; ADJDOWN $amt",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000154 [(callseq_end imm:$amt)], s_pseudo>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000155}
Evan Chengb783fa32007-07-19 01:14:50 +0000156def ALTENT : PseudoInstAlpha<(outs), (ins s64imm:$TARGET), "$$$TARGET..ng:\n", [], s_pseudo>;
157def PCLABEL : PseudoInstAlpha<(outs), (ins s64imm:$num), "PCMARKER_$num:\n",[], s_pseudo>;
158def MEMLABEL : PseudoInstAlpha<(outs), (ins s64imm:$i, s64imm:$j, s64imm:$k, s64imm:$m),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000159 "LSMARKER$$$i$$$j$$$k$$$m:", [], s_pseudo>;
160
161
162//***********************
163//Real instructions
164//***********************
165
166//Operation Form:
167
168//conditional moves, int
169
170multiclass cmov_inst<bits<7> fun, string asmstr, PatFrag OpNode> {
171def r : OForm4<0x11, fun, !strconcat(asmstr, " $RCOND,$RTRUE,$RDEST"),
172 [(set GPRC:$RDEST, (select (OpNode GPRC:$RCOND), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>;
173def i : OForm4L<0x11, fun, !strconcat(asmstr, " $RCOND,$RTRUE,$RDEST"),
174 [(set GPRC:$RDEST, (select (OpNode GPRC:$RCOND), immUExt8:$RTRUE, GPRC:$RFALSE))], s_cmov>;
175}
176
177defm CMOVEQ : cmov_inst<0x24, "cmoveq", CmpOpFrag<(seteq node:$R, 0)>>;
178defm CMOVNE : cmov_inst<0x26, "cmovne", CmpOpFrag<(setne node:$R, 0)>>;
179defm CMOVLT : cmov_inst<0x44, "cmovlt", CmpOpFrag<(setlt node:$R, 0)>>;
180defm CMOVLE : cmov_inst<0x64, "cmovle", CmpOpFrag<(setle node:$R, 0)>>;
181defm CMOVGT : cmov_inst<0x66, "cmovgt", CmpOpFrag<(setgt node:$R, 0)>>;
182defm CMOVGE : cmov_inst<0x46, "cmovge", CmpOpFrag<(setge node:$R, 0)>>;
183defm CMOVLBC : cmov_inst<0x16, "cmovlbc", CmpOpFrag<(xor node:$R, 1)>>;
184defm CMOVLBS : cmov_inst<0x14, "cmovlbs", CmpOpFrag<(and node:$R, 1)>>;
185
186//General pattern for cmov
187def : Pat<(select GPRC:$which, GPRC:$src1, GPRC:$src2),
188 (CMOVNEr GPRC:$src2, GPRC:$src1, GPRC:$which)>;
189def : Pat<(select GPRC:$which, GPRC:$src1, immUExt8:$src2),
190 (CMOVEQi GPRC:$src1, immUExt8:$src2, GPRC:$which)>;
191
192//Invert sense when we can for constants:
193def : Pat<(select (setne GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
194 (CMOVEQi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
195def : Pat<(select (setgt GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
196 (CMOVLEi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
197def : Pat<(select (setge GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
198 (CMOVLTi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
199def : Pat<(select (setlt GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
200 (CMOVGEi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
201def : Pat<(select (setle GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
202 (CMOVGTi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
203
204multiclass 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>;
214}
215
216defm MUL : all_inst<0x13, 0x00, 0x20, "mul", BinOpFrag<(mul node:$LHS, node:$RHS)>, s_imul>;
217defm ADD : all_inst<0x10, 0x00, 0x20, "add", BinOpFrag<(add node:$LHS, node:$RHS)>, s_iadd>;
218defm S4ADD : all_inst<0x10, 0x02, 0x22, "s4add", add4, s_iadd>;
219defm S8ADD : all_inst<0x10, 0x12, 0x32, "s8add", add8, s_iadd>;
220defm S4SUB : all_inst<0x10, 0x0B, 0x2B, "s4sub", sub4, s_iadd>;
221defm S8SUB : all_inst<0x10, 0x1B, 0x3B, "s8sub", sub8, s_iadd>;
222defm 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
224def : Pat<(intop (add GPRC:$RA, immUExt8neg:$L)), (SUBLi GPRC:$RA, immUExt8neg:$L)>;
225def : Pat<(add GPRC:$RA, immUExt8neg:$L), (SUBQi GPRC:$RA, immUExt8neg:$L)>;
226def : Pat<(intop (add4 GPRC:$RA, immUExt8neg:$L)), (S4SUBLi GPRC:$RA, immUExt8neg:$L)>;
227def : Pat<(add4 GPRC:$RA, immUExt8neg:$L), (S4SUBQi GPRC:$RA, immUExt8neg:$L)>;
228def : Pat<(intop (add8 GPRC:$RA, immUExt8neg:$L)), (S8SUBLi GPRC:$RA, immUExt8neg:$L)>;
229def : Pat<(add8 GPRC:$RA, immUExt8neg:$L), (S8SUBQi GPRC:$RA, immUExt8neg:$L)>;
230
231multiclass log_inst<bits<6> opc, bits<7> fun, string asmstr, SDNode OpNode, InstrItinClass itin> {
232def r : OForm<opc, fun, !strconcat(asmstr, " $RA,$RB,$RC"),
233 [(set GPRC:$RC, (OpNode GPRC:$RA, GPRC:$RB))], itin>;
234def i : OFormL<opc, fun, !strconcat(asmstr, " $RA,$L,$RC"),
235 [(set GPRC:$RC, (OpNode GPRC:$RA, immUExt8:$L))], itin>;
236}
237multiclass inv_inst<bits<6> opc, bits<7> fun, string asmstr, SDNode OpNode, InstrItinClass itin> {
238def r : OForm<opc, fun, !strconcat(asmstr, " $RA,$RB,$RC"),
239 [(set GPRC:$RC, (OpNode GPRC:$RA, (not GPRC:$RB)))], itin>;
240def i : OFormL<opc, fun, !strconcat(asmstr, " $RA,$L,$RC"),
241 [(set GPRC:$RC, (OpNode GPRC:$RA, immUExt8inv:$L))], itin>;
242}
243
244defm AND : log_inst<0x11, 0x00, "and", and, s_ilog>;
245defm BIC : inv_inst<0x11, 0x08, "bic", and, s_ilog>;
246defm BIS : log_inst<0x11, 0x20, "bis", or, s_ilog>;
247defm ORNOT : inv_inst<0x11, 0x28, "ornot", or, s_ilog>;
248defm XOR : log_inst<0x11, 0x40, "xor", xor, s_ilog>;
249defm EQV : inv_inst<0x11, 0x48, "eqv", xor, s_ilog>;
250
251defm SL : log_inst<0x12, 0x39, "sll", shl, s_ishf>;
252defm SRA : log_inst<0x12, 0x3c, "sra", sra, s_ishf>;
253defm SRL : log_inst<0x12, 0x34, "srl", srl, s_ishf>;
254defm UMULH : log_inst<0x13, 0x30, "umulh", mulhu, s_imul>;
255
256def CTLZ : OForm2<0x1C, 0x32, "CTLZ $RB,$RC",
257 [(set GPRC:$RC, (ctlz GPRC:$RB))], s_imisc>;
258def CTPOP : OForm2<0x1C, 0x30, "CTPOP $RB,$RC",
259 [(set GPRC:$RC, (ctpop GPRC:$RB))], s_imisc>;
260def CTTZ : OForm2<0x1C, 0x33, "CTTZ $RB,$RC",
261 [(set GPRC:$RC, (cttz GPRC:$RB))], s_imisc>;
262def EXTBL : OForm< 0x12, 0x06, "EXTBL $RA,$RB,$RC",
263 [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 255))], s_ishf>;
264def EXTWL : OForm< 0x12, 0x16, "EXTWL $RA,$RB,$RC",
265 [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 65535))], s_ishf>;
266def EXTLL : OForm< 0x12, 0x26, "EXTLL $RA,$RB,$RC",
267 [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 4294967295))], s_ishf>;
268def SEXTB : OForm2<0x1C, 0x00, "sextb $RB,$RC",
269 [(set GPRC:$RC, (sext_inreg GPRC:$RB, i8))], s_ishf>;
270def SEXTW : OForm2<0x1C, 0x01, "sextw $RB,$RC",
271 [(set GPRC:$RC, (sext_inreg GPRC:$RB, i16))], s_ishf>;
272
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
284
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
299
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
314
315def ZAPNOTi : OFormL<0x12, 0x31, "zapnot $RA,$L,$RC", [], s_ishf>;
316
317// Define the pattern that produces ZAPNOTi.
318def : Pat<(i64 (zappat GPRC:$RA):$imm),
319 (ZAPNOTi GPRC:$RA, (iZAPX GPRC:$imm))>;
320
321
322//Comparison, int
323//So this is a waste of what this instruction can do, but it still saves something
324def CMPBGE : OForm< 0x10, 0x0F, "cmpbge $RA,$RB,$RC",
325 [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), (and GPRC:$RB, 255)))], s_ilog>;
326def CMPBGEi : OFormL<0x10, 0x0F, "cmpbge $RA,$L,$RC",
327 [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), immUExt8:$L))], s_ilog>;
328def CMPEQ : OForm< 0x10, 0x2D, "cmpeq $RA,$RB,$RC",
329 [(set GPRC:$RC, (seteq GPRC:$RA, GPRC:$RB))], s_iadd>;
330def CMPEQi : OFormL<0x10, 0x2D, "cmpeq $RA,$L,$RC",
331 [(set GPRC:$RC, (seteq GPRC:$RA, immUExt8:$L))], s_iadd>;
332def CMPLE : OForm< 0x10, 0x6D, "cmple $RA,$RB,$RC",
333 [(set GPRC:$RC, (setle GPRC:$RA, GPRC:$RB))], s_iadd>;
334def CMPLEi : OFormL<0x10, 0x6D, "cmple $RA,$L,$RC",
335 [(set GPRC:$RC, (setle GPRC:$RA, immUExt8:$L))], s_iadd>;
336def CMPLT : OForm< 0x10, 0x4D, "cmplt $RA,$RB,$RC",
337 [(set GPRC:$RC, (setlt GPRC:$RA, GPRC:$RB))], s_iadd>;
338def CMPLTi : OFormL<0x10, 0x4D, "cmplt $RA,$L,$RC",
339 [(set GPRC:$RC, (setlt GPRC:$RA, immUExt8:$L))], s_iadd>;
340def CMPULE : OForm< 0x10, 0x3D, "cmpule $RA,$RB,$RC",
341 [(set GPRC:$RC, (setule GPRC:$RA, GPRC:$RB))], s_iadd>;
342def CMPULEi : OFormL<0x10, 0x3D, "cmpule $RA,$L,$RC",
343 [(set GPRC:$RC, (setule GPRC:$RA, immUExt8:$L))], s_iadd>;
344def CMPULT : OForm< 0x10, 0x1D, "cmpult $RA,$RB,$RC",
345 [(set GPRC:$RC, (setult GPRC:$RA, GPRC:$RB))], s_iadd>;
346def CMPULTi : OFormL<0x10, 0x1D, "cmpult $RA,$L,$RC",
347 [(set GPRC:$RC, (setult GPRC:$RA, immUExt8:$L))], s_iadd>;
348
349//Patterns for unsupported int comparisons
350def : Pat<(setueq GPRC:$X, GPRC:$Y), (CMPEQ GPRC:$X, GPRC:$Y)>;
351def : Pat<(setueq GPRC:$X, immUExt8:$Y), (CMPEQi GPRC:$X, immUExt8:$Y)>;
352
353def : Pat<(setugt GPRC:$X, GPRC:$Y), (CMPULT GPRC:$Y, GPRC:$X)>;
354def : Pat<(setugt immUExt8:$X, GPRC:$Y), (CMPULTi GPRC:$Y, immUExt8:$X)>;
355
356def : Pat<(setuge GPRC:$X, GPRC:$Y), (CMPULE GPRC:$Y, GPRC:$X)>;
357def : Pat<(setuge immUExt8:$X, GPRC:$Y), (CMPULEi GPRC:$Y, immUExt8:$X)>;
358
359def : Pat<(setgt GPRC:$X, GPRC:$Y), (CMPLT GPRC:$Y, GPRC:$X)>;
360def : Pat<(setgt immUExt8:$X, GPRC:$Y), (CMPLTi GPRC:$Y, immUExt8:$X)>;
361
362def : Pat<(setge GPRC:$X, GPRC:$Y), (CMPLE GPRC:$Y, GPRC:$X)>;
363def : Pat<(setge immUExt8:$X, GPRC:$Y), (CMPLEi GPRC:$Y, immUExt8:$X)>;
364
365def : Pat<(setne GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>;
366def : Pat<(setne GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQi GPRC:$X, immUExt8:$Y), 0)>;
367
368def : Pat<(setune GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>;
369def : Pat<(setune GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQ GPRC:$X, immUExt8:$Y), 0)>;
370
371
Evan Cheng37e7c752007-07-21 00:34:19 +0000372let isReturn = 1, isTerminator = 1, Ra = 31, Rb = 26, disp = 1, Uses = [R26] in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000373 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
375}
376
Owen Andersonf8053082007-11-12 07:39:39 +0000377let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1, Ra = 31, disp = 0 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000378def JMP : MbrpForm< 0x1A, 0x00, (ops GPRC:$RS), "jmp $$31,($RS),0",
379 [(brind GPRC:$RS)], s_jsr>; //Jump
380
Evan Cheng37e7c752007-07-21 00:34:19 +0000381let isCall = 1, Ra = 26,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000382 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,
384 F0, F1,
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
388}
Evan Cheng37e7c752007-07-21 00:34:19 +0000389let isCall = 1, Ra = 26, Rb = 27, disp = 0,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000390 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,
392 F0, F1,
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
396}
397
Evan Cheng37e7c752007-07-21 00:34:19 +0000398let isCall = 1, Ra = 23, Rb = 27, disp = 0,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000399 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
401
402
403def JSR_COROUTINE : MbrForm< 0x1A, 0x03, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr_coroutine $RD,($RS),$DISP", s_jsr>; //Jump to subroutine return
404
405
Evan Chengb783fa32007-07-19 01:14:50 +0000406let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000407def LDQ : MForm<0x29, 0, 1, "ldq $RA,$DISP($RB)",
408 [(set GPRC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
409def 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>;
411def LDL : MForm<0x28, 0, 1, "ldl $RA,$DISP($RB)",
412 [(set GPRC:$RA, (sextloadi32 (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
413def 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>;
415def LDBU : MForm<0x0A, 0, 1, "ldbu $RA,$DISP($RB)",
416 [(set GPRC:$RA, (zextloadi8 (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
417def 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>;
419def LDWU : MForm<0x0C, 0, 1, "ldwu $RA,$DISP($RB)",
420 [(set GPRC:$RA, (zextloadi16 (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
421def 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>;
Evan Chengb783fa32007-07-19 01:14:50 +0000423}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000424
425
Evan Chengb783fa32007-07-19 01:14:50 +0000426let OutOperandList = (ops), InOperandList = (ops GPRC:$RA, s64imm:$DISP, GPRC:$RB) in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000427def STB : MForm<0x0E, 1, 0, "stb $RA,$DISP($RB)",
428 [(truncstorei8 GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
429def STBr : MForm<0x0E, 1, 0, "stb $RA,$DISP($RB)\t\t!gprellow",
430 [(truncstorei8 GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
431def STW : MForm<0x0D, 1, 0, "stw $RA,$DISP($RB)",
432 [(truncstorei16 GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
433def STWr : MForm<0x0D, 1, 0, "stw $RA,$DISP($RB)\t\t!gprellow",
434 [(truncstorei16 GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
435def STL : MForm<0x2C, 1, 0, "stl $RA,$DISP($RB)",
436 [(truncstorei32 GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
437def STLr : MForm<0x2C, 1, 0, "stl $RA,$DISP($RB)\t\t!gprellow",
438 [(truncstorei32 GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
439def STQ : MForm<0x2D, 1, 0, "stq $RA,$DISP($RB)",
440 [(store GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
441def STQr : MForm<0x2D, 1, 0, "stq $RA,$DISP($RB)\t\t!gprellow",
442 [(store GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
Evan Chengb783fa32007-07-19 01:14:50 +0000443}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000444
445//Load address
Evan Chengb783fa32007-07-19 01:14:50 +0000446let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000447def LDA : MForm<0x08, 0, 0, "lda $RA,$DISP($RB)",
448 [(set GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_lda>;
449def 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
451def LDAH : MForm<0x09, 0, 0, "ldah $RA,$DISP($RB)",
452 [], s_lda>; //Load address high
453def 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
455}
456
Evan Chengb783fa32007-07-19 01:14:50 +0000457let OutOperandList = (ops), InOperandList = (ops F4RC:$RA, s64imm:$DISP, GPRC:$RB) in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000458def STS : MForm<0x26, 1, 0, "sts $RA,$DISP($RB)",
459 [(store F4RC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_fst>;
460def STSr : MForm<0x26, 1, 0, "sts $RA,$DISP($RB)\t\t!gprellow",
461 [(store F4RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_fst>;
Evan Chengb783fa32007-07-19 01:14:50 +0000462}
463let OutOperandList = (ops F4RC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000464def LDS : MForm<0x22, 0, 1, "lds $RA,$DISP($RB)",
465 [(set F4RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_fld>;
466def 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>;
468}
Evan Chengb783fa32007-07-19 01:14:50 +0000469let OutOperandList = (ops), InOperandList = (ops F8RC:$RA, s64imm:$DISP, GPRC:$RB) in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000470def STT : MForm<0x27, 1, 0, "stt $RA,$DISP($RB)",
471 [(store F8RC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_fst>;
472def STTr : MForm<0x27, 1, 0, "stt $RA,$DISP($RB)\t\t!gprellow",
473 [(store F8RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_fst>;
Evan Chengb783fa32007-07-19 01:14:50 +0000474}
475let OutOperandList = (ops F8RC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000476def LDT : MForm<0x23, 0, 1, "ldt $RA,$DISP($RB)",
477 [(set F8RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_fld>;
478def 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>;
480}
481
482
483//constpool rels
484def : Pat<(i64 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
485 (LDQr tconstpool:$DISP, GPRC:$RB)>;
486def : Pat<(i64 (sextloadi32 (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
487 (LDLr tconstpool:$DISP, GPRC:$RB)>;
488def : Pat<(i64 (zextloadi8 (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
489 (LDBUr tconstpool:$DISP, GPRC:$RB)>;
490def : Pat<(i64 (zextloadi16 (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
491 (LDWUr tconstpool:$DISP, GPRC:$RB)>;
492def : Pat<(i64 (Alpha_gprello tconstpool:$DISP, GPRC:$RB)),
493 (LDAr tconstpool:$DISP, GPRC:$RB)>;
494def : Pat<(i64 (Alpha_gprelhi tconstpool:$DISP, GPRC:$RB)),
495 (LDAHr tconstpool:$DISP, GPRC:$RB)>;
496def : Pat<(f32 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
497 (LDSr tconstpool:$DISP, GPRC:$RB)>;
498def : Pat<(f64 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
499 (LDTr tconstpool:$DISP, GPRC:$RB)>;
500
501//jumptable rels
502def : Pat<(i64 (Alpha_gprelhi tjumptable:$DISP, GPRC:$RB)),
503 (LDAHr tjumptable:$DISP, GPRC:$RB)>;
504def : Pat<(i64 (Alpha_gprello tjumptable:$DISP, GPRC:$RB)),
505 (LDAr tjumptable:$DISP, GPRC:$RB)>;
506
507
508//misc ext patterns
509def : Pat<(i64 (extloadi8 (add GPRC:$RB, immSExt16:$DISP))),
510 (LDBU immSExt16:$DISP, GPRC:$RB)>;
511def : Pat<(i64 (extloadi16 (add GPRC:$RB, immSExt16:$DISP))),
512 (LDWU immSExt16:$DISP, GPRC:$RB)>;
513def : Pat<(i64 (extloadi32 (add GPRC:$RB, immSExt16:$DISP))),
514 (LDL immSExt16:$DISP, GPRC:$RB)>;
515
516//0 disp patterns
517def : Pat<(i64 (load GPRC:$addr)),
518 (LDQ 0, GPRC:$addr)>;
519def : Pat<(f64 (load GPRC:$addr)),
520 (LDT 0, GPRC:$addr)>;
521def : Pat<(f32 (load GPRC:$addr)),
522 (LDS 0, GPRC:$addr)>;
523def : Pat<(i64 (sextloadi32 GPRC:$addr)),
524 (LDL 0, GPRC:$addr)>;
525def : Pat<(i64 (zextloadi16 GPRC:$addr)),
526 (LDWU 0, GPRC:$addr)>;
527def : Pat<(i64 (zextloadi8 GPRC:$addr)),
528 (LDBU 0, GPRC:$addr)>;
529def : Pat<(i64 (extloadi8 GPRC:$addr)),
530 (LDBU 0, GPRC:$addr)>;
531def : Pat<(i64 (extloadi16 GPRC:$addr)),
532 (LDWU 0, GPRC:$addr)>;
533def : Pat<(i64 (extloadi32 GPRC:$addr)),
534 (LDL 0, GPRC:$addr)>;
535
536def : Pat<(store GPRC:$DATA, GPRC:$addr),
537 (STQ GPRC:$DATA, 0, GPRC:$addr)>;
538def : Pat<(store F8RC:$DATA, GPRC:$addr),
539 (STT F8RC:$DATA, 0, GPRC:$addr)>;
540def : Pat<(store F4RC:$DATA, GPRC:$addr),
541 (STS F4RC:$DATA, 0, GPRC:$addr)>;
542def : Pat<(truncstorei32 GPRC:$DATA, GPRC:$addr),
543 (STL GPRC:$DATA, 0, GPRC:$addr)>;
544def : Pat<(truncstorei16 GPRC:$DATA, GPRC:$addr),
545 (STW GPRC:$DATA, 0, GPRC:$addr)>;
546def : Pat<(truncstorei8 GPRC:$DATA, GPRC:$addr),
547 (STB GPRC:$DATA, 0, GPRC:$addr)>;
548
549
550//load address, rellocated gpdist form
Evan Chengb783fa32007-07-19 01:14:50 +0000551let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s16imm:$DISP, GPRC:$RB, s16imm:$NUM) in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000552def LDAg : MForm<0x08, 0, 1, "lda $RA,0($RB)\t\t!gpdisp!$NUM", [], s_lda>; //Load address
553def LDAHg : MForm<0x09, 0, 1, "ldah $RA,0($RB)\t\t!gpdisp!$NUM", [], s_lda>; //Load address
554}
555
556//Load quad, rellocated literal form
Evan Chengb783fa32007-07-19 01:14:50 +0000557let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000558def LDQl : MForm<0x29, 0, 1, "ldq $RA,$DISP($RB)\t\t!literal",
559 [(set GPRC:$RA, (Alpha_rellit tglobaladdr:$DISP, GPRC:$RB))], s_ild>;
560def : Pat<(Alpha_rellit texternalsym:$ext, GPRC:$RB),
561 (LDQl texternalsym:$ext, GPRC:$RB)>;
562
563
564def RPCC : MfcForm<0x18, 0xC000, "rpcc $RA", s_rpcc>; //Read process cycle counter
565
566//Basic Floating point ops
567
568//Floats
569
Evan Chengb783fa32007-07-19 01:14:50 +0000570let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F4RC:$RB), Fa = 31 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000571def SQRTS : FPForm<0x14, 0x58B, "sqrts/su $RB,$RC",
572 [(set F4RC:$RC, (fsqrt F4RC:$RB))], s_fsqrts>;
573
Evan Chengb783fa32007-07-19 01:14:50 +0000574let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F4RC:$RA, F4RC:$RB) in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000575def ADDS : FPForm<0x16, 0x580, "adds/su $RA,$RB,$RC",
576 [(set F4RC:$RC, (fadd F4RC:$RA, F4RC:$RB))], s_fadd>;
577def SUBS : FPForm<0x16, 0x581, "subs/su $RA,$RB,$RC",
578 [(set F4RC:$RC, (fsub F4RC:$RA, F4RC:$RB))], s_fadd>;
579def DIVS : FPForm<0x16, 0x583, "divs/su $RA,$RB,$RC",
580 [(set F4RC:$RC, (fdiv F4RC:$RA, F4RC:$RB))], s_fdivs>;
581def MULS : FPForm<0x16, 0x582, "muls/su $RA,$RB,$RC",
582 [(set F4RC:$RC, (fmul F4RC:$RA, F4RC:$RB))], s_fmul>;
583
584def CPYSS : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
585 [(set F4RC:$RC, (fcopysign F4RC:$RB, F4RC:$RA))], s_fadd>;
586def CPYSES : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent
587def CPYSNS : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
588 [(set F4RC:$RC, (fneg (fcopysign F4RC:$RB, F4RC:$RA)))], s_fadd>;
589}
590
591//Doubles
592
Evan Chengb783fa32007-07-19 01:14:50 +0000593let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000594def SQRTT : FPForm<0x14, 0x5AB, "sqrtt/su $RB,$RC",
595 [(set F8RC:$RC, (fsqrt F8RC:$RB))], s_fsqrtt>;
596
Evan Chengb783fa32007-07-19 01:14:50 +0000597let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F8RC:$RA, F8RC:$RB) in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000598def ADDT : FPForm<0x16, 0x5A0, "addt/su $RA,$RB,$RC",
599 [(set F8RC:$RC, (fadd F8RC:$RA, F8RC:$RB))], s_fadd>;
600def SUBT : FPForm<0x16, 0x5A1, "subt/su $RA,$RB,$RC",
601 [(set F8RC:$RC, (fsub F8RC:$RA, F8RC:$RB))], s_fadd>;
602def DIVT : FPForm<0x16, 0x5A3, "divt/su $RA,$RB,$RC",
603 [(set F8RC:$RC, (fdiv F8RC:$RA, F8RC:$RB))], s_fdivt>;
604def MULT : FPForm<0x16, 0x5A2, "mult/su $RA,$RB,$RC",
605 [(set F8RC:$RC, (fmul F8RC:$RA, F8RC:$RB))], s_fmul>;
606
607def CPYST : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
608 [(set F8RC:$RC, (fcopysign F8RC:$RB, F8RC:$RA))], s_fadd>;
609def CPYSET : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent
610def CPYSNT : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
611 [(set F8RC:$RC, (fneg (fcopysign F8RC:$RB, F8RC:$RA)))], s_fadd>;
612
613def CMPTEQ : FPForm<0x16, 0x5A5, "cmpteq/su $RA,$RB,$RC", [], s_fadd>;
614// [(set F8RC:$RC, (seteq F8RC:$RA, F8RC:$RB))]>;
615def CMPTLE : FPForm<0x16, 0x5A7, "cmptle/su $RA,$RB,$RC", [], s_fadd>;
616// [(set F8RC:$RC, (setle F8RC:$RA, F8RC:$RB))]>;
617def CMPTLT : FPForm<0x16, 0x5A6, "cmptlt/su $RA,$RB,$RC", [], s_fadd>;
618// [(set F8RC:$RC, (setlt F8RC:$RA, F8RC:$RB))]>;
619def CMPTUN : FPForm<0x16, 0x5A4, "cmptun/su $RA,$RB,$RC", [], s_fadd>;
620// [(set F8RC:$RC, (setuo F8RC:$RA, F8RC:$RB))]>;
621}
622
623//More CPYS forms:
Evan Chengb783fa32007-07-19 01:14:50 +0000624let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F4RC:$RA, F8RC:$RB) in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000625def CPYSTs : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
626 [(set F8RC:$RC, (fcopysign F8RC:$RB, F4RC:$RA))], s_fadd>;
627def CPYSNTs : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
628 [(set F8RC:$RC, (fneg (fcopysign F8RC:$RB, F4RC:$RA)))], s_fadd>;
629}
Evan Chengb783fa32007-07-19 01:14:50 +0000630let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F8RC:$RA, F4RC:$RB) in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000631def CPYSSt : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
632 [(set F4RC:$RC, (fcopysign F4RC:$RB, F8RC:$RA))], s_fadd>;
633def CPYSESt : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent
634def CPYSNSt : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
635 [(set F4RC:$RC, (fneg (fcopysign F4RC:$RB, F8RC:$RA)))], s_fadd>;
636}
637
638//conditional moves, floats
Evan Chengb783fa32007-07-19 01:14:50 +0000639let OutOperandList = (ops F4RC:$RDEST), InOperandList = (ops F4RC:$RFALSE, F4RC:$RTRUE, F8RC:$RCOND),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000640 isTwoAddress = 1 in {
641def FCMOVEQS : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if = zero
642def FCMOVGES : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if >= zero
643def FCMOVGTS : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if > zero
644def FCMOVLES : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if <= zero
645def FCMOVLTS : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST",[], s_fcmov>; // FCMOVE if < zero
646def FCMOVNES : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if != zero
647}
648//conditional moves, doubles
Evan Chengb783fa32007-07-19 01:14:50 +0000649let OutOperandList = (ops F8RC:$RDEST), InOperandList = (ops F8RC:$RFALSE, F8RC:$RTRUE, F8RC:$RCOND),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000650 isTwoAddress = 1 in {
651def FCMOVEQT : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
652def FCMOVGET : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
653def FCMOVGTT : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
654def FCMOVLET : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
655def FCMOVLTT : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
656def FCMOVNET : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
657}
658
659//misc FP selects
660//Select double
661
662def : Pat<(select (seteq F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
663 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
664def : Pat<(select (setoeq F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
665 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
666def : Pat<(select (setueq F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
667 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
668
669def : Pat<(select (setne F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
670 (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
671def : Pat<(select (setone F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
672 (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
673def : Pat<(select (setune F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
674 (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
675
676def : Pat<(select (setgt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
677 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
678def : Pat<(select (setogt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
679 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
680def : Pat<(select (setugt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
681 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
682
683def : Pat<(select (setge F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
684 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
685def : Pat<(select (setoge F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
686 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
687def : Pat<(select (setuge F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
688 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
689
690def : Pat<(select (setlt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
691 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
692def : Pat<(select (setolt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
693 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
694def : Pat<(select (setult F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
695 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
696
697def : Pat<(select (setle F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
698 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
699def : Pat<(select (setole F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
700 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
701def : Pat<(select (setule F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
702 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
703
704//Select single
705def : Pat<(select (seteq F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
706 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
707def : Pat<(select (setoeq F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
708 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
709def : Pat<(select (setueq F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
710 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
711
712def : Pat<(select (setne F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
713 (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
714def : Pat<(select (setone F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
715 (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
716def : Pat<(select (setune F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
717 (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
718
719def : Pat<(select (setgt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
720 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
721def : Pat<(select (setogt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
722 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
723def : Pat<(select (setugt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
724 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
725
726def : Pat<(select (setge F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
727 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
728def : Pat<(select (setoge F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
729 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
730def : Pat<(select (setuge F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
731 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
732
733def : Pat<(select (setlt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
734 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
735def : Pat<(select (setolt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
736 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
737def : Pat<(select (setult F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
738 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
739
740def : Pat<(select (setle F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
741 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
742def : Pat<(select (setole F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
743 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
744def : Pat<(select (setule F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
745 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
746
747
748
Evan Chengb783fa32007-07-19 01:14:50 +0000749let OutOperandList = (ops GPRC:$RC), InOperandList = (ops F4RC:$RA), Fb = 31 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000750def FTOIS : FPForm<0x1C, 0x078, "ftois $RA,$RC",[], s_ftoi>; //Floating to integer move, S_floating
Evan Chengb783fa32007-07-19 01:14:50 +0000751let OutOperandList = (ops GPRC:$RC), InOperandList = (ops F8RC:$RA), Fb = 31 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000752def FTOIT : FPForm<0x1C, 0x070, "ftoit $RA,$RC",
753 [(set GPRC:$RC, (bitconvert F8RC:$RA))], s_ftoi>; //Floating to integer move
Evan Chengb783fa32007-07-19 01:14:50 +0000754let OutOperandList = (ops F4RC:$RC), InOperandList = (ops GPRC:$RA), Fb = 31 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000755def ITOFS : FPForm<0x14, 0x004, "itofs $RA,$RC",[], s_itof>; //Integer to floating move, S_floating
Evan Chengb783fa32007-07-19 01:14:50 +0000756let OutOperandList = (ops F8RC:$RC), InOperandList = (ops GPRC:$RA), Fb = 31 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000757def ITOFT : FPForm<0x14, 0x024, "itoft $RA,$RC",
758 [(set F8RC:$RC, (bitconvert GPRC:$RA))], s_itof>; //Integer to floating move
759
760
Evan Chengb783fa32007-07-19 01:14:50 +0000761let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000762def CVTQS : FPForm<0x16, 0x7BC, "cvtqs/sui $RB,$RC",
763 [(set F4RC:$RC, (Alpha_cvtqs F8RC:$RB))], s_fadd>;
Evan Chengb783fa32007-07-19 01:14:50 +0000764let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000765def CVTQT : FPForm<0x16, 0x7BE, "cvtqt/sui $RB,$RC",
766 [(set F8RC:$RC, (Alpha_cvtqt F8RC:$RB))], s_fadd>;
Evan Chengb783fa32007-07-19 01:14:50 +0000767let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000768def CVTTQ : FPForm<0x16, 0x52F, "cvttq/svc $RB,$RC",
769 [(set F8RC:$RC, (Alpha_cvttq F8RC:$RB))], s_fadd>;
Evan Chengb783fa32007-07-19 01:14:50 +0000770let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F4RC:$RB), Fa = 31 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000771def CVTST : FPForm<0x16, 0x6AC, "cvtst/s $RB,$RC",
772 [(set F8RC:$RC, (fextend F4RC:$RB))], s_fadd>;
Evan Chengb783fa32007-07-19 01:14:50 +0000773let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000774def CVTTS : FPForm<0x16, 0x7AC, "cvtts/sui $RB,$RC",
775 [(set F4RC:$RC, (fround F8RC:$RB))], s_fadd>;
776
777
778/////////////////////////////////////////////////////////
779//Branching
780/////////////////////////////////////////////////////////
781class br_icc<bits<6> opc, string asmstr>
782 : BFormN<opc, (ops u64imm:$opc, GPRC:$R, target:$dst),
783 !strconcat(asmstr, " $R,$dst"), s_icbr>;
784class br_fcc<bits<6> opc, string asmstr>
785 : BFormN<opc, (ops u64imm:$opc, F8RC:$R, target:$dst),
786 !strconcat(asmstr, " $R,$dst"), s_fbr>;
787
Evan Cheng37e7c752007-07-21 00:34:19 +0000788let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000789let Ra = 31 in
790def BR : BFormD<0x30, "br $$31,$DISP", [(br bb:$DISP)], s_ubr>;
791
792def COND_BRANCH_I : BFormN<0, (ops u64imm:$opc, GPRC:$R, target:$dst),
793 "{:comment} COND_BRANCH imm:$opc, GPRC:$R, bb:$dst",
794 s_icbr>;
795def COND_BRANCH_F : BFormN<0, (ops u64imm:$opc, F8RC:$R, target:$dst),
796 "{:comment} COND_BRANCH imm:$opc, F8RC:$R, bb:$dst",
797 s_fbr>;
798//Branches, int
799def BEQ : br_icc<0x39, "beq">;
800def BGE : br_icc<0x3E, "bge">;
801def BGT : br_icc<0x3F, "bgt">;
802def BLBC : br_icc<0x38, "blbc">;
803def BLBS : br_icc<0x3C, "blbs">;
804def BLE : br_icc<0x3B, "ble">;
805def BLT : br_icc<0x3A, "blt">;
806def BNE : br_icc<0x3D, "bne">;
807
808//Branches, float
809def FBEQ : br_fcc<0x31, "fbeq">;
810def FBGE : br_fcc<0x36, "fbge">;
811def FBGT : br_fcc<0x37, "fbgt">;
812def FBLE : br_fcc<0x33, "fble">;
813def FBLT : br_fcc<0x32, "fblt">;
814def FBNE : br_fcc<0x36, "fbne">;
815}
816
817//An ugly trick to get the opcode as an imm I can use
818def 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");
835 }
836}]>;
837
838//Int cond patterns
839def : Pat<(brcond (seteq GPRC:$RA, 0), bb:$DISP),
840 (COND_BRANCH_I (immBRCond 0), GPRC:$RA, bb:$DISP)>;
841def : Pat<(brcond (setge GPRC:$RA, 0), bb:$DISP),
842 (COND_BRANCH_I (immBRCond 2), GPRC:$RA, bb:$DISP)>;
843def : Pat<(brcond (setgt GPRC:$RA, 0), bb:$DISP),
844 (COND_BRANCH_I (immBRCond 3), GPRC:$RA, bb:$DISP)>;
845def : Pat<(brcond (and GPRC:$RA, 1), bb:$DISP),
846 (COND_BRANCH_I (immBRCond 6), GPRC:$RA, bb:$DISP)>;
847def : Pat<(brcond (setle GPRC:$RA, 0), bb:$DISP),
848 (COND_BRANCH_I (immBRCond 4), GPRC:$RA, bb:$DISP)>;
849def : Pat<(brcond (setlt GPRC:$RA, 0), bb:$DISP),
850 (COND_BRANCH_I (immBRCond 5), GPRC:$RA, bb:$DISP)>;
851def : Pat<(brcond (setne GPRC:$RA, 0), bb:$DISP),
852 (COND_BRANCH_I (immBRCond 1), GPRC:$RA, bb:$DISP)>;
853
854def : Pat<(brcond GPRC:$RA, bb:$DISP),
855 (COND_BRANCH_I (immBRCond 1), GPRC:$RA, bb:$DISP)>;
856def : Pat<(brcond (setne GPRC:$RA, GPRC:$RB), bb:$DISP),
857 (COND_BRANCH_I (immBRCond 0), (CMPEQ GPRC:$RA, GPRC:$RB), bb:$DISP)>;
858def : Pat<(brcond (setne GPRC:$RA, immUExt8:$L), bb:$DISP),
859 (COND_BRANCH_I (immBRCond 0), (CMPEQi GPRC:$RA, immUExt8:$L), bb:$DISP)>;
860
861//FP cond patterns
862def : Pat<(brcond (seteq F8RC:$RA, immFPZ), bb:$DISP),
863 (COND_BRANCH_F (immBRCond 20), F8RC:$RA, bb:$DISP)>;
864def : Pat<(brcond (setne F8RC:$RA, immFPZ), bb:$DISP),
865 (COND_BRANCH_F (immBRCond 21), F8RC:$RA, bb:$DISP)>;
866def : Pat<(brcond (setge F8RC:$RA, immFPZ), bb:$DISP),
867 (COND_BRANCH_F (immBRCond 22), F8RC:$RA, bb:$DISP)>;
868def : Pat<(brcond (setgt F8RC:$RA, immFPZ), bb:$DISP),
869 (COND_BRANCH_F (immBRCond 23), F8RC:$RA, bb:$DISP)>;
870def : Pat<(brcond (setle F8RC:$RA, immFPZ), bb:$DISP),
871 (COND_BRANCH_F (immBRCond 24), F8RC:$RA, bb:$DISP)>;
872def : Pat<(brcond (setlt F8RC:$RA, immFPZ), bb:$DISP),
873 (COND_BRANCH_F (immBRCond 25), F8RC:$RA, bb:$DISP)>;
874
875
876def : Pat<(brcond (seteq F8RC:$RA, F8RC:$RB), bb:$DISP),
877 (COND_BRANCH_F (immBRCond 21), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
878def : Pat<(brcond (setoeq F8RC:$RA, F8RC:$RB), bb:$DISP),
879 (COND_BRANCH_F (immBRCond 21), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
880def : Pat<(brcond (setueq F8RC:$RA, F8RC:$RB), bb:$DISP),
881 (COND_BRANCH_F (immBRCond 21), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
882
883def : Pat<(brcond (setlt F8RC:$RA, F8RC:$RB), bb:$DISP),
884 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
885def : Pat<(brcond (setolt F8RC:$RA, F8RC:$RB), bb:$DISP),
886 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
887def : Pat<(brcond (setult F8RC:$RA, F8RC:$RB), bb:$DISP),
888 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
889
890def : Pat<(brcond (setle F8RC:$RA, F8RC:$RB), bb:$DISP),
891 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
892def : Pat<(brcond (setole F8RC:$RA, F8RC:$RB), bb:$DISP),
893 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
894def : Pat<(brcond (setule F8RC:$RA, F8RC:$RB), bb:$DISP),
895 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
896
897def : Pat<(brcond (setgt F8RC:$RA, F8RC:$RB), bb:$DISP),
898 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
899def : Pat<(brcond (setogt F8RC:$RA, F8RC:$RB), bb:$DISP),
900 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
901def : Pat<(brcond (setugt F8RC:$RA, F8RC:$RB), bb:$DISP),
902 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
903
904def : Pat<(brcond (setge F8RC:$RA, F8RC:$RB), bb:$DISP),
905 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
906def : Pat<(brcond (setoge F8RC:$RA, F8RC:$RB), bb:$DISP),
907 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
908def : Pat<(brcond (setuge F8RC:$RA, F8RC:$RB), bb:$DISP),
909 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
910
911def : Pat<(brcond (setne F8RC:$RA, F8RC:$RB), bb:$DISP),
912 (COND_BRANCH_F (immBRCond 20), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
913def : Pat<(brcond (setone F8RC:$RA, F8RC:$RB), bb:$DISP),
914 (COND_BRANCH_F (immBRCond 20), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
915def : Pat<(brcond (setune F8RC:$RA, F8RC:$RB), bb:$DISP),
916 (COND_BRANCH_F (immBRCond 20), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
917
918
919def : Pat<(brcond (setoeq F8RC:$RA, immFPZ), bb:$DISP),
920 (COND_BRANCH_F (immBRCond 20), F8RC:$RA,bb:$DISP)>;
921def : Pat<(brcond (setueq F8RC:$RA, immFPZ), bb:$DISP),
922 (COND_BRANCH_F (immBRCond 20), F8RC:$RA,bb:$DISP)>;
923
924def : Pat<(brcond (setoge F8RC:$RA, immFPZ), bb:$DISP),
925 (COND_BRANCH_F (immBRCond 22), F8RC:$RA,bb:$DISP)>;
926def : Pat<(brcond (setuge F8RC:$RA, immFPZ), bb:$DISP),
927 (COND_BRANCH_F (immBRCond 22), F8RC:$RA,bb:$DISP)>;
928
929def : Pat<(brcond (setogt F8RC:$RA, immFPZ), bb:$DISP),
930 (COND_BRANCH_F (immBRCond 23), F8RC:$RA,bb:$DISP)>;
931def : Pat<(brcond (setugt F8RC:$RA, immFPZ), bb:$DISP),
932 (COND_BRANCH_F (immBRCond 23), F8RC:$RA,bb:$DISP)>;
933
934def : Pat<(brcond (setole F8RC:$RA, immFPZ), bb:$DISP),
935 (COND_BRANCH_F (immBRCond 24), F8RC:$RA,bb:$DISP)>;
936def : Pat<(brcond (setule F8RC:$RA, immFPZ), bb:$DISP),
937 (COND_BRANCH_F (immBRCond 24), F8RC:$RA,bb:$DISP)>;
938
939def : Pat<(brcond (setolt F8RC:$RA, immFPZ), bb:$DISP),
940 (COND_BRANCH_F (immBRCond 25), F8RC:$RA,bb:$DISP)>;
941def : Pat<(brcond (setult F8RC:$RA, immFPZ), bb:$DISP),
942 (COND_BRANCH_F (immBRCond 25), F8RC:$RA,bb:$DISP)>;
943
944def : Pat<(brcond (setone F8RC:$RA, immFPZ), bb:$DISP),
945 (COND_BRANCH_F (immBRCond 21), F8RC:$RA,bb:$DISP)>;
946def : Pat<(brcond (setune F8RC:$RA, immFPZ), bb:$DISP),
947 (COND_BRANCH_F (immBRCond 21), F8RC:$RA,bb:$DISP)>;
948
949//End Branches
950
951//S_floating : IEEE Single
952//T_floating : IEEE Double
953
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  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
989
990
991//Constant handling
992
993def 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);
997}]>;
998def 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
1005}], SExt32>;
1006
1007def : Pat<(i64 immConst2Part:$imm),
1008 (LDA (LL16 immConst2Part:$imm), (LDAH (LH16 immConst2Part:$imm), R31))>;
1009
1010def : Pat<(i64 immSExt16:$imm),
1011 (LDA immSExt16:$imm, R31)>;
1012
1013def : Pat<(i64 immSExt16int:$imm),
1014 (ZAPNOTi (LDA (SExt16 immSExt16int:$imm), R31), 15)>;
1015def : Pat<(i64 immConst2PartInt:$imm),
1016 (ZAPNOTi (LDA (LL16 (SExt32 immConst2PartInt:$imm)),
1017 (LDAH (LH16 (SExt32 immConst2PartInt:$imm)), R31)), 15)>;
1018
1019
1020//TODO: I want to just define these like this!
1021//def : Pat<(i64 0),
1022// (R31)>;
1023//def : Pat<(f64 0.0),
1024// (F31)>;
1025//def : Pat<(f64 -0.0),
1026// (CPYSNT F31, F31)>;
1027//def : Pat<(f32 0.0),
1028// (F31)>;
1029//def : Pat<(f32 -0.0),
1030// (CPYSNS F31, F31)>;
1031
1032//Misc Patterns:
1033
1034def : Pat<(sext_inreg GPRC:$RB, i32),
1035 (ADDLi GPRC:$RB, 0)>;
1036
1037def : Pat<(fabs F8RC:$RB),
1038 (CPYST F31, F8RC:$RB)>;
1039def : Pat<(fabs F4RC:$RB),
1040 (CPYSS F31, F4RC:$RB)>;
1041def : Pat<(fneg F8RC:$RB),
1042 (CPYSNT F8RC:$RB, F8RC:$RB)>;
1043def : Pat<(fneg F4RC:$RB),
1044 (CPYSNS F4RC:$RB, F4RC:$RB)>;
1045
1046def : Pat<(fcopysign F4RC:$A, (fneg F4RC:$B)),
1047 (CPYSNS F4RC:$B, F4RC:$A)>;
1048def : Pat<(fcopysign F8RC:$A, (fneg F8RC:$B)),
1049 (CPYSNT F8RC:$B, F8RC:$A)>;
1050def : Pat<(fcopysign F4RC:$A, (fneg F8RC:$B)),
1051 (CPYSNSt F8RC:$B, F4RC:$A)>;
1052def : Pat<(fcopysign F8RC:$A, (fneg F4RC:$B)),
1053 (CPYSNTs F4RC:$B, F8RC:$A)>;
1054
1055//Yes, signed multiply high is ugly
1056def : 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)))>;
1059
1060//Stupid crazy arithmetic stuff:
1061let AddedComplexity = 1 in {
1062def : Pat<(mul GPRC:$RA, 5), (S4ADDQr GPRC:$RA, GPRC:$RA)>;
1063def : Pat<(mul GPRC:$RA, 9), (S8ADDQr GPRC:$RA, GPRC:$RA)>;
1064def : Pat<(mul GPRC:$RA, 3), (S4SUBQr GPRC:$RA, GPRC:$RA)>;
1065def : Pat<(mul GPRC:$RA, 7), (S8SUBQr GPRC:$RA, GPRC:$RA)>;
1066
1067//slight tree expansion if we are multiplying near to a power of 2
1068//n is above a power of 2
1069def : Pat<(mul GPRC:$RA, immRem1:$imm),
1070 (ADDQr (SLr GPRC:$RA, (nearP2X immRem1:$imm)), GPRC:$RA)>;
1071def : Pat<(mul GPRC:$RA, immRem2:$imm),
1072 (ADDQr (SLr GPRC:$RA, (nearP2X immRem2:$imm)), (ADDQr GPRC:$RA, GPRC:$RA))>;
1073def : Pat<(mul GPRC:$RA, immRem3:$imm),
1074 (ADDQr (SLr GPRC:$RA, (nearP2X immRem3:$imm)), (S4SUBQr GPRC:$RA, GPRC:$RA))>;
1075def : Pat<(mul GPRC:$RA, immRem4:$imm),
1076 (S4ADDQr GPRC:$RA, (SLr GPRC:$RA, (nearP2X immRem4:$imm)))>;
1077def : Pat<(mul GPRC:$RA, immRem5:$imm),
1078 (ADDQr (SLr GPRC:$RA, (nearP2X immRem5:$imm)), (S4ADDQr GPRC:$RA, GPRC:$RA))>;
1079def : Pat<(mul GPRC:$RA, immRemP2:$imm),
1080 (ADDQr (SLr GPRC:$RA, (nearP2X immRemP2:$imm)), (SLi GPRC:$RA, (nearP2RemX immRemP2:$imm)))>;
1081
1082//n is below a power of 2
1083def : Pat<(mul GPRC:$RA, immRem1n:$imm),
1084 (SUBQr (SLr GPRC:$RA, (nearP2X immRem1n:$imm)), GPRC:$RA)>;
1085def : Pat<(mul GPRC:$RA, immRem2n:$imm),
1086 (SUBQr (SLr GPRC:$RA, (nearP2X immRem2n:$imm)), (ADDQr GPRC:$RA, GPRC:$RA))>;
1087def : Pat<(mul GPRC:$RA, immRem3n:$imm),
1088 (SUBQr (SLr GPRC:$RA, (nearP2X immRem3n:$imm)), (S4SUBQr GPRC:$RA, GPRC:$RA))>;
1089def : Pat<(mul GPRC:$RA, immRem4n:$imm),
1090 (SUBQr (SLr GPRC:$RA, (nearP2X immRem4n:$imm)), (SLi GPRC:$RA, 2))>;
1091def : Pat<(mul GPRC:$RA, immRem5n:$imm),
1092 (SUBQr (SLr GPRC:$RA, (nearP2X immRem5n:$imm)), (S4ADDQr GPRC:$RA, GPRC:$RA))>;
1093def : Pat<(mul GPRC:$RA, immRemP2n:$imm),
1094 (SUBQr (SLr GPRC:$RA, (nearP2X immRemP2n:$imm)), (SLi GPRC:$RA, (nearP2RemX immRemP2n:$imm)))>;
1095} //Added complexity