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