1 //===- AlphaInstrInfo.td - The Alpha Instruction Set -------*- tablegen -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 //===----------------------------------------------------------------------===//
13 include "AlphaInstrFormats.td"
15 //********************
17 //********************
19 def SDTFPUnaryOpUnC : SDTypeProfile<1, 1, [
20 SDTCisFP<1>, SDTCisFP<0>
22 def Alpha_itoft : SDNode<"AlphaISD::ITOFT_", SDTIntToFPOp, []>;
23 def Alpha_ftoit : SDNode<"AlphaISD::FTOIT_", SDTFPToIntOp, []>;
24 def Alpha_cvtqt : SDNode<"AlphaISD::CVTQT_", SDTFPUnaryOpUnC, []>;
25 def Alpha_cvtqs : SDNode<"AlphaISD::CVTQS_", SDTFPUnaryOpUnC, []>;
26 def Alpha_cvttq : SDNode<"AlphaISD::CVTTQ_" , SDTFPUnaryOp, []>;
27 def Alpha_gprello : SDNode<"AlphaISD::GPRelLo", SDTIntBinOp, []>;
28 def Alpha_gprelhi : SDNode<"AlphaISD::GPRelHi", SDTIntBinOp, []>;
29 def Alpha_rellit : SDNode<"AlphaISD::RelLit", SDTIntBinOp, []>;
31 // These are target-independent nodes, but have target-specific formats.
32 def SDT_AlphaCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i64> ]>;
33 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_AlphaCallSeq,[SDNPHasChain]>;
34 def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_AlphaCallSeq,[SDNPHasChain]>;
36 //********************
37 //Paterns for matching
38 //********************
39 def invX : SDNodeXForm<imm, [{ //invert
40 return getI64Imm(~N->getValue());
42 def negX : SDNodeXForm<imm, [{ //negate
43 return getI64Imm(~N->getValue() + 1);
45 def SExt32 : SDNodeXForm<imm, [{ //signed extend int to long
46 return getI64Imm(((int64_t)N->getValue() << 32) >> 32);
48 def SExt16 : SDNodeXForm<imm, [{ //signed extend int to long
49 return getI64Imm(((int64_t)N->getValue() << 48) >> 48);
51 def LL16 : SDNodeXForm<imm, [{ //lda part of constant
52 return getI64Imm(get_lda16(N->getValue()));
54 def LH16 : SDNodeXForm<imm, [{ //ldah part of constant (or more if too big)
55 return getI64Imm(get_ldah16(N->getValue()));
57 def iZAPX : SDNodeXForm<imm, [{ // get imm to ZAPi
58 return getI64Imm(get_zapImm((uint64_t)N->getValue()));
61 def immUExt8 : PatLeaf<(imm), [{ //imm fits in 8 bit zero extended field
62 return (uint64_t)N->getValue() == (uint8_t)N->getValue();
64 def immUExt8inv : PatLeaf<(imm), [{ //inverted imm fits in 8 bit zero extended field
65 return (uint64_t)~N->getValue() == (uint8_t)~N->getValue();
67 def immUExt8neg : PatLeaf<(imm), [{ //negated imm fits in 8 bit zero extended field
68 return ((uint64_t)~N->getValue() + 1) == (uint8_t)((uint64_t)~N->getValue() + 1);
70 def immSExt16 : PatLeaf<(imm), [{ //imm fits in 16 bit sign extended field
71 return ((int64_t)N->getValue() << 48) >> 48 == (int64_t)N->getValue();
73 def immSExt16int : PatLeaf<(imm), [{ //(int)imm fits in a 16 bit sign extended field
74 return ((int64_t)N->getValue() << 48) >> 48 == ((int64_t)N->getValue() << 32) >> 32;
76 def immZAP : PatLeaf<(imm), [{ //imm is good for zapi
77 uint64_t build = get_zapImm((uint64_t)N->getValue());
80 def immFPZ : PatLeaf<(fpimm), [{ //the only fpconstant nodes are +/- 0.0
84 def intop : PatFrag<(ops node:$op), (sext_inreg node:$op, i32)>;
85 def add4 : PatFrag<(ops node:$op1, node:$op2),
86 (add (shl node:$op1, 2), node:$op2)>;
87 def sub4 : PatFrag<(ops node:$op1, node:$op2),
88 (sub (shl node:$op1, 2), node:$op2)>;
89 def add8 : PatFrag<(ops node:$op1, node:$op2),
90 (add (shl node:$op1, 3), node:$op2)>;
91 def sub8 : PatFrag<(ops node:$op1, node:$op2),
92 (sub (shl node:$op1, 3), node:$op2)>;
95 //Pseudo ops for selection
97 def IDEF_I : PseudoInstAlpha<(ops GPRC:$RA), "#idef $RA",
98 [(set GPRC:$RA, (undef))], s_pseudo>;
99 def IDEF_F32 : PseudoInstAlpha<(ops F4RC:$RA), "#idef $RA",
100 [(set F4RC:$RA, (undef))], s_pseudo>;
101 def IDEF_F64 : PseudoInstAlpha<(ops F8RC:$RA), "#idef $RA",
102 [(set F8RC:$RA, (undef))], s_pseudo>;
104 def WTF : PseudoInstAlpha<(ops variable_ops), "#wtf", [], s_pseudo>;
106 let isLoad = 1, hasCtrlDep = 1 in {
107 def ADJUSTSTACKUP : PseudoInstAlpha<(ops s64imm:$amt), "; ADJUP $amt",
108 [(callseq_start imm:$amt)], s_pseudo>;
109 def ADJUSTSTACKDOWN : PseudoInstAlpha<(ops s64imm:$amt), "; ADJDOWN $amt",
110 [(callseq_end imm:$amt)], s_pseudo>;
112 def ALTENT : PseudoInstAlpha<(ops s64imm:$TARGET), "$$$TARGET..ng:\n", [], s_pseudo>;
113 def PCLABEL : PseudoInstAlpha<(ops s64imm:$num), "PCMARKER_$num:\n",[], s_pseudo>;
114 def MEMLABEL : PseudoInstAlpha<(ops s64imm:$i, s64imm:$j, s64imm:$k, s64imm:$m),
115 "LSMARKER$$$i$$$j$$$k$$$m:", [], s_pseudo>;
118 //***********************
120 //***********************
124 //conditional moves, int
126 def CMOVLBC : OForm4< 0x11, 0x16, "cmovlbc $RCOND,$RTRUE,$RDEST",
127 [(set GPRC:$RDEST, (select (xor GPRC:$RCOND, 1), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>;
128 def CMOVLBS : OForm4< 0x11, 0x14, "cmovlbs $RCOND,$RTRUE,$RDEST",
129 [(set GPRC:$RDEST, (select (and GPRC:$RCOND, 1), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>;
130 def CMOVEQ : OForm4< 0x11, 0x24, "cmoveq $RCOND,$RTRUE,$RDEST",
131 [(set GPRC:$RDEST, (select (seteq GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>;
132 def CMOVGE : OForm4< 0x11, 0x46, "cmovge $RCOND,$RTRUE,$RDEST",
133 [(set GPRC:$RDEST, (select (setge GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>;
134 def CMOVGT : OForm4< 0x11, 0x66, "cmovgt $RCOND,$RTRUE,$RDEST",
135 [(set GPRC:$RDEST, (select (setgt GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>;
136 def CMOVLE : OForm4< 0x11, 0x64, "cmovle $RCOND,$RTRUE,$RDEST",
137 [(set GPRC:$RDEST, (select (setle GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>;
138 def CMOVLT : OForm4< 0x11, 0x44, "cmovlt $RCOND,$RTRUE,$RDEST",
139 [(set GPRC:$RDEST, (select (setlt GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>;
140 def CMOVNE : OForm4< 0x11, 0x26, "cmovne $RCOND,$RTRUE,$RDEST",
141 [(set GPRC:$RDEST, (select (setne GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>;
143 def CMOVEQi : OForm4L< 0x11, 0x24, "cmoveq $RCOND,$RTRUE,$RDEST",
144 [(set GPRC:$RDEST, (select (setne GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))], s_cmov>;
145 def CMOVGEi : OForm4L< 0x11, 0x46, "cmovge $RCOND,$RTRUE,$RDEST",
146 [(set GPRC:$RDEST, (select (setlt GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))], s_cmov>;
147 def CMOVGTi : OForm4L< 0x11, 0x66, "cmovgt $RCOND,$RTRUE,$RDEST",
148 [(set GPRC:$RDEST, (select (setle GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))], s_cmov>;
149 def CMOVLEi : OForm4L< 0x11, 0x64, "cmovle $RCOND,$RTRUE,$RDEST",
150 [(set GPRC:$RDEST, (select (setgt GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))], s_cmov>;
151 def CMOVLTi : OForm4L< 0x11, 0x44, "cmovlt $RCOND,$RTRUE,$RDEST",
152 [(set GPRC:$RDEST, (select (setge GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))], s_cmov>;
153 def CMOVNEi : OForm4L< 0x11, 0x26, "cmovne $RCOND,$RTRUE,$RDEST",
154 [(set GPRC:$RDEST, (select (seteq GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))], s_cmov>;
155 def CMOVLBCi : OForm4L< 0x11, 0x16, "cmovlbc $RCOND,$RTRUE,$RDEST",
156 [(set GPRC:$RDEST, (select (and GPRC:$RCOND, 1), GPRC:$RFALSE, immUExt8:$RTRUE))], s_cmov>;
157 def CMOVLBSi : OForm4L< 0x11, 0x14, "cmovlbs $RCOND,$RTRUE,$RDEST",
158 [(set GPRC:$RDEST, (select (xor GPRC:$RCOND, 1), GPRC:$RFALSE, immUExt8:$RTRUE))], s_cmov>;
161 //General pattern for cmov
162 def : Pat<(select GPRC:$which, GPRC:$src1, GPRC:$src2),
163 (CMOVNE GPRC:$src2, GPRC:$src1, GPRC:$which)>;
164 def : Pat<(select GPRC:$which, GPRC:$src1, immUExt8:$src2),
165 (CMOVEQi GPRC:$src1, immUExt8:$src2, GPRC:$which)>;
168 def ADDL : OForm< 0x10, 0x00, "addl $RA,$RB,$RC",
169 [(set GPRC:$RC, (intop (add GPRC:$RA, GPRC:$RB)))], s_iadd>;
170 def ADDLi : OFormL<0x10, 0x00, "addl $RA,$L,$RC",
171 [(set GPRC:$RC, (intop (add GPRC:$RA, immUExt8:$L)))], s_iadd>;
172 def ADDQ : OForm< 0x10, 0x20, "addq $RA,$RB,$RC",
173 [(set GPRC:$RC, (add GPRC:$RA, GPRC:$RB))], s_iadd>;
174 def ADDQi : OFormL<0x10, 0x20, "addq $RA,$L,$RC",
175 [(set GPRC:$RC, (add GPRC:$RA, immUExt8:$L))], s_iadd>;
176 def AND : OForm< 0x11, 0x00, "and $RA,$RB,$RC",
177 [(set GPRC:$RC, (and GPRC:$RA, GPRC:$RB))], s_ilog>;
178 def ANDi : OFormL<0x11, 0x00, "and $RA,$L,$RC",
179 [(set GPRC:$RC, (and GPRC:$RA, immUExt8:$L))], s_ilog>;
180 def BIC : OForm< 0x11, 0x08, "bic $RA,$RB,$RC",
181 [(set GPRC:$RC, (and GPRC:$RA, (not GPRC:$RB)))], s_ilog>;
182 def BICi : OFormL<0x11, 0x08, "bic $RA,$L,$RC",
183 [(set GPRC:$RC, (and GPRC:$RA, immUExt8inv:$L))], s_ilog>;
184 def BIS : OForm< 0x11, 0x20, "bis $RA,$RB,$RC",
185 [(set GPRC:$RC, (or GPRC:$RA, GPRC:$RB))], s_ilog>;
186 def BISi : OFormL<0x11, 0x20, "bis $RA,$L,$RC",
187 [(set GPRC:$RC, (or GPRC:$RA, immUExt8:$L))], s_ilog>;
188 def CTLZ : OForm2<0x1C, 0x32, "CTLZ $RB,$RC",
189 [(set GPRC:$RC, (ctlz GPRC:$RB))], s_imisc>;
190 def CTPOP : OForm2<0x1C, 0x30, "CTPOP $RB,$RC",
191 [(set GPRC:$RC, (ctpop GPRC:$RB))], s_imisc>;
192 def CTTZ : OForm2<0x1C, 0x33, "CTTZ $RB,$RC",
193 [(set GPRC:$RC, (cttz GPRC:$RB))], s_imisc>;
194 def EQV : OForm< 0x11, 0x48, "eqv $RA,$RB,$RC",
195 [(set GPRC:$RC, (xor GPRC:$RA, (not GPRC:$RB)))], s_ilog>;
196 def EQVi : OFormL<0x11, 0x48, "eqv $RA,$L,$RC",
197 [(set GPRC:$RC, (xor GPRC:$RA, immUExt8inv:$L))], s_ilog>;
198 def EXTBL : OForm< 0x12, 0x06, "EXTBL $RA,$RB,$RC",
199 [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 255))], s_ishf>;
200 def EXTWL : OForm< 0x12, 0x16, "EXTWL $RA,$RB,$RC",
201 [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 65535))], s_ishf>;
202 def EXTLL : OForm< 0x12, 0x26, "EXTLL $RA,$RB,$RC",
203 [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 4294967295))], s_ishf>;
205 //def EXTBLi : OFormL<0x12, 0x06, "EXTBL $RA,$L,$RC", []>; //Extract byte low
206 //def EXTLH : OForm< 0x12, 0x6A, "EXTLH $RA,$RB,$RC", []>; //Extract longword high
207 //def EXTLHi : OFormL<0x12, 0x6A, "EXTLH $RA,$L,$RC", []>; //Extract longword high
208 //def EXTLLi : OFormL<0x12, 0x26, "EXTLL $RA,$L,$RC", []>; //Extract longword low
209 //def EXTQH : OForm< 0x12, 0x7A, "EXTQH $RA,$RB,$RC", []>; //Extract quadword high
210 //def EXTQHi : OFormL<0x12, 0x7A, "EXTQH $RA,$L,$RC", []>; //Extract quadword high
211 //def EXTQ : OForm< 0x12, 0x36, "EXTQ $RA,$RB,$RC", []>; //Extract quadword low
212 //def EXTQi : OFormL<0x12, 0x36, "EXTQ $RA,$L,$RC", []>; //Extract quadword low
213 //def EXTWH : OForm< 0x12, 0x5A, "EXTWH $RA,$RB,$RC", []>; //Extract word high
214 //def EXTWHi : OFormL<0x12, 0x5A, "EXTWH $RA,$L,$RC", []>; //Extract word high
215 //def EXTWLi : OFormL<0x12, 0x16, "EXTWL $RA,$L,$RC", []>; //Extract word low
217 //def IMPLVER : OForm< 0x11, 0x6C, "IMPLVER $RA,$RB,$RC", []>; //Implementation version
218 //def IMPLVERi : OFormL<0x11, 0x6C, "IMPLVER $RA,$L,$RC", []>; //Implementation version
219 //def INSBL : OForm< 0x12, 0x0B, "INSBL $RA,$RB,$RC", []>; //Insert byte low
220 //def INSBLi : OFormL<0x12, 0x0B, "INSBL $RA,$L,$RC", []>; //Insert byte low
221 //def INSLH : OForm< 0x12, 0x67, "INSLH $RA,$RB,$RC", []>; //Insert longword high
222 //def INSLHi : OFormL<0x12, 0x67, "INSLH $RA,$L,$RC", []>; //Insert longword high
223 //def INSLL : OForm< 0x12, 0x2B, "INSLL $RA,$RB,$RC", []>; //Insert longword low
224 //def INSLLi : OFormL<0x12, 0x2B, "INSLL $RA,$L,$RC", []>; //Insert longword low
225 //def INSQH : OForm< 0x12, 0x77, "INSQH $RA,$RB,$RC", []>; //Insert quadword high
226 //def INSQHi : OFormL<0x12, 0x77, "INSQH $RA,$L,$RC", []>; //Insert quadword high
227 //def INSQL : OForm< 0x12, 0x3B, "INSQL $RA,$RB,$RC", []>; //Insert quadword low
228 //def INSQLi : OFormL<0x12, 0x3B, "INSQL $RA,$L,$RC", []>; //Insert quadword low
229 //def INSWH : OForm< 0x12, 0x57, "INSWH $RA,$RB,$RC", []>; //Insert word high
230 //def INSWHi : OFormL<0x12, 0x57, "INSWH $RA,$L,$RC", []>; //Insert word high
231 //def INSWL : OForm< 0x12, 0x1B, "INSWL $RA,$RB,$RC", []>; //Insert word low
232 //def INSWLi : OFormL<0x12, 0x1B, "INSWL $RA,$L,$RC", []>; //Insert word low
233 //def MSKBL : OForm< 0x12, 0x02, "MSKBL $RA,$RB,$RC", []>; //Mask byte low
234 //def MSKBLi : OFormL<0x12, 0x02, "MSKBL $RA,$L,$RC", []>; //Mask byte low
235 //def MSKLH : OForm< 0x12, 0x62, "MSKLH $RA,$RB,$RC", []>; //Mask longword high
236 //def MSKLHi : OFormL<0x12, 0x62, "MSKLH $RA,$L,$RC", []>; //Mask longword high
237 //def MSKLL : OForm< 0x12, 0x22, "MSKLL $RA,$RB,$RC", []>; //Mask longword low
238 //def MSKLLi : OFormL<0x12, 0x22, "MSKLL $RA,$L,$RC", []>; //Mask longword low
239 //def MSKQH : OForm< 0x12, 0x72, "MSKQH $RA,$RB,$RC", []>; //Mask quadword high
240 //def MSKQHi : OFormL<0x12, 0x72, "MSKQH $RA,$L,$RC", []>; //Mask quadword high
241 //def MSKQL : OForm< 0x12, 0x32, "MSKQL $RA,$RB,$RC", []>; //Mask quadword low
242 //def MSKQLi : OFormL<0x12, 0x32, "MSKQL $RA,$L,$RC", []>; //Mask quadword low
243 //def MSKWH : OForm< 0x12, 0x52, "MSKWH $RA,$RB,$RC", []>; //Mask word high
244 //def MSKWHi : OFormL<0x12, 0x52, "MSKWH $RA,$L,$RC", []>; //Mask word high
245 //def MSKWL : OForm< 0x12, 0x12, "MSKWL $RA,$RB,$RC", []>; //Mask word low
246 //def MSKWLi : OFormL<0x12, 0x12, "MSKWL $RA,$L,$RC", []>; //Mask word low
248 def MULL : OForm< 0x13, 0x00, "mull $RA,$RB,$RC",
249 [(set GPRC:$RC, (intop (mul GPRC:$RA, GPRC:$RB)))], s_imul>;
250 def MULLi : OFormL<0x13, 0x00, "mull $RA,$L,$RC",
251 [(set GPRC:$RC, (intop (mul GPRC:$RA, immUExt8:$L)))], s_imul>;
252 def MULQ : OForm< 0x13, 0x20, "mulq $RA,$RB,$RC",
253 [(set GPRC:$RC, (mul GPRC:$RA, GPRC:$RB))], s_imul>;
254 def MULQi : OFormL<0x13, 0x20, "mulq $RA,$L,$RC",
255 [(set GPRC:$RC, (mul GPRC:$RA, immUExt8:$L))], s_imul>;
256 def ORNOT : OForm< 0x11, 0x28, "ornot $RA,$RB,$RC",
257 [(set GPRC:$RC, (or GPRC:$RA, (not GPRC:$RB)))], s_ilog>;
258 def ORNOTi : OFormL<0x11, 0x28, "ornot $RA,$L,$RC",
259 [(set GPRC:$RC, (or GPRC:$RA, immUExt8inv:$L))], s_ilog>;
260 def S4ADDL : OForm< 0x10, 0x02, "s4addl $RA,$RB,$RC",
261 [(set GPRC:$RC, (intop (add4 GPRC:$RA, GPRC:$RB)))], s_iadd>;
262 def S4ADDLi : OFormL<0x10, 0x02, "s4addl $RA,$L,$RC",
263 [(set GPRC:$RC, (intop (add4 GPRC:$RA, immUExt8:$L)))], s_iadd>;
264 def S4ADDQ : OForm< 0x10, 0x22, "s4addq $RA,$RB,$RC",
265 [(set GPRC:$RC, (add4 GPRC:$RA, GPRC:$RB))], s_iadd>;
266 def S4ADDQi : OFormL<0x10, 0x22, "s4addq $RA,$L,$RC",
267 [(set GPRC:$RC, (add4 GPRC:$RA, immUExt8:$L))], s_iadd>;
268 def S4SUBL : OForm< 0x10, 0x0B, "s4subl $RA,$RB,$RC",
269 [(set GPRC:$RC, (intop (sub4 GPRC:$RA, GPRC:$RB)))], s_iadd>;
270 def S4SUBLi : OFormL<0x10, 0x0B, "s4subl $RA,$L,$RC",
271 [(set GPRC:$RC, (intop (sub4 GPRC:$RA, immUExt8:$L)))], s_iadd>;
272 def S4SUBQ : OForm< 0x10, 0x2B, "s4subq $RA,$RB,$RC",
273 [(set GPRC:$RC, (sub4 GPRC:$RA, GPRC:$RB))], s_iadd>;
274 def S4SUBQi : OFormL<0x10, 0x2B, "s4subq $RA,$L,$RC",
275 [(set GPRC:$RC, (sub4 GPRC:$RA, immUExt8:$L))], s_iadd>;
276 def S8ADDL : OForm< 0x10, 0x12, "s8addl $RA,$RB,$RC",
277 [(set GPRC:$RC, (intop (add8 GPRC:$RA, GPRC:$RB)))], s_iadd>;
278 def S8ADDLi : OFormL<0x10, 0x12, "s8addl $RA,$L,$RC",
279 [(set GPRC:$RC, (intop (add8 GPRC:$RA, immUExt8:$L)))], s_iadd>;
280 def S8ADDQ : OForm< 0x10, 0x32, "s8addq $RA,$RB,$RC",
281 [(set GPRC:$RC, (add8 GPRC:$RA, GPRC:$RB))], s_iadd>;
282 def S8ADDQi : OFormL<0x10, 0x32, "s8addq $RA,$L,$RC",
283 [(set GPRC:$RC, (add8 GPRC:$RA, immUExt8:$L))], s_iadd>;
284 def S8SUBL : OForm< 0x10, 0x1B, "s8subl $RA,$RB,$RC",
285 [(set GPRC:$RC, (intop (sub8 GPRC:$RA, GPRC:$RB)))], s_iadd>;
286 def S8SUBLi : OFormL<0x10, 0x1B, "s8subl $RA,$L,$RC",
287 [(set GPRC:$RC, (intop (add8 GPRC:$RA, immUExt8neg:$L)))], s_iadd>;
288 def S8SUBQ : OForm< 0x10, 0x3B, "s8subq $RA,$RB,$RC",
289 [(set GPRC:$RC, (sub8 GPRC:$RA, GPRC:$RB))], s_iadd>;
290 def S8SUBQi : OFormL<0x10, 0x3B, "s8subq $RA,$L,$RC",
291 [(set GPRC:$RC, (add8 GPRC:$RA, immUExt8neg:$L))], s_iadd>;
292 def SEXTB : OForm2<0x1C, 0x00, "sextb $RB,$RC",
293 [(set GPRC:$RC, (sext_inreg GPRC:$RB, i8))], s_ishf>;
294 def SEXTW : OForm2<0x1C, 0x01, "sextw $RB,$RC",
295 [(set GPRC:$RC, (sext_inreg GPRC:$RB, i16))], s_ishf>;
296 def SL : OForm< 0x12, 0x39, "sll $RA,$RB,$RC",
297 [(set GPRC:$RC, (shl GPRC:$RA, GPRC:$RB))], s_ishf>;
298 def SLi : OFormL<0x12, 0x39, "sll $RA,$L,$RC",
299 [(set GPRC:$RC, (shl GPRC:$RA, immUExt8:$L))], s_ishf>;
300 def SRA : OForm< 0x12, 0x3C, "sra $RA,$RB,$RC",
301 [(set GPRC:$RC, (sra GPRC:$RA, GPRC:$RB))], s_ishf>;
302 def SRAi : OFormL<0x12, 0x3C, "sra $RA,$L,$RC",
303 [(set GPRC:$RC, (sra GPRC:$RA, immUExt8:$L))], s_ishf>;
304 def SRL : OForm< 0x12, 0x34, "srl $RA,$RB,$RC",
305 [(set GPRC:$RC, (srl GPRC:$RA, GPRC:$RB))], s_ishf>;
306 def SRLi : OFormL<0x12, 0x34, "srl $RA,$L,$RC",
307 [(set GPRC:$RC, (srl GPRC:$RA, immUExt8:$L))], s_ishf>;
308 def SUBL : OForm< 0x10, 0x09, "subl $RA,$RB,$RC",
309 [(set GPRC:$RC, (intop (sub GPRC:$RA, GPRC:$RB)))], s_iadd>;
310 def SUBLi : OFormL<0x10, 0x09, "subl $RA,$L,$RC",
311 [(set GPRC:$RC, (intop (add GPRC:$RA, immUExt8neg:$L)))], s_iadd>;
312 def SUBQ : OForm< 0x10, 0x29, "subq $RA,$RB,$RC",
313 [(set GPRC:$RC, (sub GPRC:$RA, GPRC:$RB))], s_iadd>;
314 def SUBQi : OFormL<0x10, 0x29, "subq $RA,$L,$RC",
315 [(set GPRC:$RC, (add GPRC:$RA, immUExt8neg:$L))], s_iadd>;
316 def UMULH : OForm< 0x13, 0x30, "umulh $RA,$RB,$RC",
317 [(set GPRC:$RC, (mulhu GPRC:$RA, GPRC:$RB))], s_imul>;
318 def UMULHi : OFormL<0x13, 0x30, "umulh $RA,$L,$RC",
319 [(set GPRC:$RC, (mulhu GPRC:$RA, immUExt8:$L))], s_imul>;
320 def XOR : OForm< 0x11, 0x40, "xor $RA,$RB,$RC",
321 [(set GPRC:$RC, (xor GPRC:$RA, GPRC:$RB))], s_ilog>;
322 def XORi : OFormL<0x11, 0x40, "xor $RA,$L,$RC",
323 [(set GPRC:$RC, (xor GPRC:$RA, immUExt8:$L))], s_ilog>;
324 //FIXME: what to do about zap? the cases it catches are very complex
325 def ZAP : OForm< 0x12, 0x30, "zap $RA,$RB,$RC", [], s_ishf>; //Zero bytes
326 //ZAPi is useless give ZAPNOTi
327 def ZAPi : OFormL<0x12, 0x30, "zap $RA,$L,$RC", [], s_ishf>; //Zero bytes
328 //FIXME: what to do about zapnot? see ZAP :)
329 def ZAPNOT : OForm< 0x12, 0x31, "zapnot $RA,$RB,$RC", [], s_ishf>; //Zero bytes not
330 def ZAPNOTi : OFormL<0x12, 0x31, "zapnot $RA,$L,$RC",
331 [(set GPRC:$RC, (and GPRC:$RA, immZAP:$L))], s_ishf>;
334 //So this is a waste of what this instruction can do, but it still saves something
335 def CMPBGE : OForm< 0x10, 0x0F, "cmpbge $RA,$RB,$RC",
336 [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), (and GPRC:$RB, 255)))], s_ilog>;
337 def CMPBGEi : OFormL<0x10, 0x0F, "cmpbge $RA,$L,$RC",
338 [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), immUExt8:$L))], s_ilog>;
339 def CMPEQ : OForm< 0x10, 0x2D, "cmpeq $RA,$RB,$RC",
340 [(set GPRC:$RC, (seteq GPRC:$RA, GPRC:$RB))], s_iadd>;
341 def CMPEQi : OFormL<0x10, 0x2D, "cmpeq $RA,$L,$RC",
342 [(set GPRC:$RC, (seteq GPRC:$RA, immUExt8:$L))], s_iadd>;
343 def CMPLE : OForm< 0x10, 0x6D, "cmple $RA,$RB,$RC",
344 [(set GPRC:$RC, (setle GPRC:$RA, GPRC:$RB))], s_iadd>;
345 def CMPLEi : OFormL<0x10, 0x6D, "cmple $RA,$L,$RC",
346 [(set GPRC:$RC, (setle GPRC:$RA, immUExt8:$L))], s_iadd>;
347 def CMPLT : OForm< 0x10, 0x4D, "cmplt $RA,$RB,$RC",
348 [(set GPRC:$RC, (setlt GPRC:$RA, GPRC:$RB))], s_iadd>;
349 def CMPLTi : OFormL<0x10, 0x4D, "cmplt $RA,$L,$RC",
350 [(set GPRC:$RC, (setlt GPRC:$RA, immUExt8:$L))], s_iadd>;
351 def CMPULE : OForm< 0x10, 0x3D, "cmpule $RA,$RB,$RC",
352 [(set GPRC:$RC, (setule GPRC:$RA, GPRC:$RB))], s_iadd>;
353 def CMPULEi : OFormL<0x10, 0x3D, "cmpule $RA,$L,$RC",
354 [(set GPRC:$RC, (setule GPRC:$RA, immUExt8:$L))], s_iadd>;
355 def CMPULT : OForm< 0x10, 0x1D, "cmpult $RA,$RB,$RC",
356 [(set GPRC:$RC, (setult GPRC:$RA, GPRC:$RB))], s_iadd>;
357 def CMPULTi : OFormL<0x10, 0x1D, "cmpult $RA,$L,$RC",
358 [(set GPRC:$RC, (setult GPRC:$RA, immUExt8:$L))], s_iadd>;
360 //Patterns for unsupported int comparisons
361 def : Pat<(setueq GPRC:$X, GPRC:$Y), (CMPEQ GPRC:$X, GPRC:$Y)>;
362 def : Pat<(setueq GPRC:$X, immUExt8:$Y), (CMPEQi GPRC:$X, immUExt8:$Y)>;
364 def : Pat<(setugt GPRC:$X, GPRC:$Y), (CMPULT GPRC:$Y, GPRC:$X)>;
365 def : Pat<(setugt immUExt8:$X, GPRC:$Y), (CMPULTi GPRC:$Y, immUExt8:$X)>;
367 def : Pat<(setuge GPRC:$X, GPRC:$Y), (CMPULE GPRC:$Y, GPRC:$X)>;
368 def : Pat<(setuge immUExt8:$X, GPRC:$Y), (CMPULEi GPRC:$Y, immUExt8:$X)>;
370 def : Pat<(setgt GPRC:$X, GPRC:$Y), (CMPLT GPRC:$Y, GPRC:$X)>;
371 def : Pat<(setgt immUExt8:$X, GPRC:$Y), (CMPLTi GPRC:$Y, immUExt8:$X)>;
373 def : Pat<(setge GPRC:$X, GPRC:$Y), (CMPLE GPRC:$Y, GPRC:$X)>;
374 def : Pat<(setge immUExt8:$X, GPRC:$Y), (CMPLEi GPRC:$Y, immUExt8:$X)>;
376 def : Pat<(setne GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>;
377 def : Pat<(setne GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQi GPRC:$X, immUExt8:$Y), 0)>;
379 def : Pat<(setune GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>;
380 def : Pat<(setune GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQ GPRC:$X, immUExt8:$Y), 0)>;
383 let isReturn = 1, isTerminator = 1, noResults = 1, Ra = 31, Rb = 26, disp = 1, Uses = [R26] in
384 def RETDAG : MbrForm< 0x1A, 0x02, (ops), "ret $$31,($$26),1", s_jsr>; //Return from subroutine
386 def JMP : MbrForm< 0x1A, 0x00, (ops GPRC:$RD, GPRC:$RS, GPRC:$DISP), "jmp $RD,($RS),$DISP", s_jsr>; //Jump
387 let isCall = 1, noResults = 1, Ra = 26,
388 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,
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
395 let isCall = 1, noResults = 1, Ra = 26, Rb = 27, disp = 0,
396 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,
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
404 let isCall = 1, noResults = 1, Ra = 23, Rb = 27, disp = 0,
405 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
409 def JSR_COROUTINE : MbrForm< 0x1A, 0x03, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr_coroutine $RD,($RS),$DISP", s_jsr>; //Jump to subroutine return
411 let OperandList = (ops GPRC:$RA, s64imm:$DISP, GPRC:$RB) in {
412 def LDQ : MForm<0x29, 0, 1, "ldq $RA,$DISP($RB)",
413 [(set GPRC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
414 def LDQr : MForm<0x29, 0, 1, "ldq $RA,$DISP($RB)\t\t!gprellow",
415 [(set GPRC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>;
416 def LDL : MForm<0x28, 0, 1, "ldl $RA,$DISP($RB)",
417 [(set GPRC:$RA, (sextload (add GPRC:$RB, immSExt16:$DISP), i32))], s_ild>;
418 def LDLr : MForm<0x28, 0, 1, "ldl $RA,$DISP($RB)\t\t!gprellow",
419 [(set GPRC:$RA, (sextload (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i32))], s_ild>;
420 def LDBU : MForm<0x0A, 0, 1, "ldbu $RA,$DISP($RB)",
421 [(set GPRC:$RA, (zextload (add GPRC:$RB, immSExt16:$DISP), i8))], s_ild>;
422 def LDBUr : MForm<0x0A, 0, 1, "ldbu $RA,$DISP($RB)\t\t!gprellow",
423 [(set GPRC:$RA, (zextload (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i8))], s_ild>;
424 def LDWU : MForm<0x0C, 0, 1, "ldwu $RA,$DISP($RB)",
425 [(set GPRC:$RA, (zextload (add GPRC:$RB, immSExt16:$DISP), i16))], s_ild>;
426 def LDWUr : MForm<0x0C, 0, 1, "ldwu $RA,$DISP($RB)\t\t!gprellow",
427 [(set GPRC:$RA, (zextload (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i16))], s_ild>;
428 def STB : MForm<0x0E, 1, 0, "stb $RA,$DISP($RB)",
429 [(truncstore GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP), i8)], s_ist>;
430 def STBr : MForm<0x0E, 1, 0, "stb $RA,$DISP($RB)\t\t!gprellow",
431 [(truncstore GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i8)], s_ist>;
432 def STW : MForm<0x0D, 1, 0, "stw $RA,$DISP($RB)",
433 [(truncstore GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP), i16)], s_ist>;
434 def STWr : MForm<0x0D, 1, 0, "stw $RA,$DISP($RB)\t\t!gprellow",
435 [(truncstore GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i16)], s_ist>;
436 def STL : MForm<0x2C, 1, 0, "stl $RA,$DISP($RB)",
437 [(truncstore GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP), i32)], s_ist>;
438 def STLr : MForm<0x2C, 1, 0, "stl $RA,$DISP($RB)\t\t!gprellow",
439 [(truncstore GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i32)], s_ist>;
440 def STQ : MForm<0x2D, 1, 0, "stq $RA,$DISP($RB)",
441 [(store GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
442 def STQr : MForm<0x2D, 1, 0, "stq $RA,$DISP($RB)\t\t!gprellow",
443 [(store GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
446 def LDA : MForm<0x08, 0, 0, "lda $RA,$DISP($RB)",
447 [(set GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_lda>;
448 def LDAr : MForm<0x08, 0, 0, "lda $RA,$DISP($RB)\t\t!gprellow",
449 [(set GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_lda>; //Load address
450 def LDAH : MForm<0x09, 0, 0, "ldah $RA,$DISP($RB)",
451 [], s_lda>; //Load address high
452 def LDAHr : MForm<0x09, 0, 0, "ldah $RA,$DISP($RB)\t\t!gprelhigh",
453 [(set GPRC:$RA, (Alpha_gprelhi tglobaladdr:$DISP, GPRC:$RB))], s_lda>; //Load address high
456 let OperandList = (ops F4RC:$RA, s64imm:$DISP, GPRC:$RB) in {
457 def STS : MForm<0x26, 1, 0, "sts $RA,$DISP($RB)",
458 [(store F4RC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_fst>;
459 def STSr : MForm<0x26, 1, 0, "sts $RA,$DISP($RB)\t\t!gprellow",
460 [(store F4RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_fst>;
461 def LDS : MForm<0x22, 0, 1, "lds $RA,$DISP($RB)",
462 [(set F4RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_fld>;
463 def LDSr : MForm<0x22, 0, 1, "lds $RA,$DISP($RB)\t\t!gprellow",
464 [(set F4RC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_fld>;
466 let OperandList = (ops F8RC:$RA, s64imm:$DISP, GPRC:$RB) in {
467 def STT : MForm<0x27, 1, 0, "stt $RA,$DISP($RB)",
468 [(store F8RC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_fst>;
469 def STTr : MForm<0x27, 1, 0, "stt $RA,$DISP($RB)\t\t!gprellow",
470 [(store F8RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_fst>;
471 def LDT : MForm<0x23, 0, 1, "ldt $RA,$DISP($RB)",
472 [(set F8RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_fld>;
473 def LDTr : MForm<0x23, 0, 1, "ldt $RA,$DISP($RB)\t\t!gprellow",
474 [(set F8RC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_fld>;
479 def : Pat<(i64 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
480 (LDQr tconstpool:$DISP, GPRC:$RB)>;
481 def : Pat<(i64 (sextload (Alpha_gprello tconstpool:$DISP, GPRC:$RB), i32)),
482 (LDLr tconstpool:$DISP, GPRC:$RB)>;
483 def : Pat<(i64 (zextload (Alpha_gprello tconstpool:$DISP, GPRC:$RB), i8)),
484 (LDBUr tconstpool:$DISP, GPRC:$RB)>;
485 def : Pat<(i64 (zextload (Alpha_gprello tconstpool:$DISP, GPRC:$RB), i16)),
486 (LDWUr tconstpool:$DISP, GPRC:$RB)>;
487 def : Pat<(i64 (Alpha_gprello tconstpool:$DISP, GPRC:$RB)),
488 (LDAr tconstpool:$DISP, GPRC:$RB)>;
489 def : Pat<(i64 (Alpha_gprelhi tconstpool:$DISP, GPRC:$RB)),
490 (LDAHr tconstpool:$DISP, GPRC:$RB)>;
491 def : Pat<(f32 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
492 (LDSr tconstpool:$DISP, GPRC:$RB)>;
493 def : Pat<(f64 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
494 (LDTr tconstpool:$DISP, GPRC:$RB)>;
498 def : Pat<(i64 (extload (add GPRC:$RB, immSExt16:$DISP), i8)),
499 (LDBU immSExt16:$DISP, GPRC:$RB)>;
500 def : Pat<(i64 (extload (add GPRC:$RB, immSExt16:$DISP), i16)),
501 (LDWU immSExt16:$DISP, GPRC:$RB)>;
502 def : Pat<(i64 (extload (add GPRC:$RB, immSExt16:$DISP), i32)),
503 (LDL immSExt16:$DISP, GPRC:$RB)>;
506 def : Pat<(i64 (load GPRC:$addr)),
507 (LDQ 0, GPRC:$addr)>;
508 def : Pat<(f64 (load GPRC:$addr)),
509 (LDT 0, GPRC:$addr)>;
510 def : Pat<(f32 (load GPRC:$addr)),
511 (LDS 0, GPRC:$addr)>;
512 def : Pat<(i64 (sextload GPRC:$addr, i32)),
513 (LDL 0, GPRC:$addr)>;
514 def : Pat<(i64 (zextload GPRC:$addr, i16)),
515 (LDWU 0, GPRC:$addr)>;
516 def : Pat<(i64 (zextload GPRC:$addr, i8)),
517 (LDBU 0, GPRC:$addr)>;
518 def : Pat<(i64 (extload GPRC:$addr, i8)),
519 (LDBU 0, GPRC:$addr)>;
520 def : Pat<(i64 (extload GPRC:$addr, i16)),
521 (LDWU 0, GPRC:$addr)>;
522 def : Pat<(i64 (extload GPRC:$addr, i32)),
523 (LDL 0, GPRC:$addr)>;
525 def : Pat<(store GPRC:$DATA, GPRC:$addr),
526 (STQ GPRC:$DATA, 0, GPRC:$addr)>;
527 def : Pat<(store F8RC:$DATA, GPRC:$addr),
528 (STT F8RC:$DATA, 0, GPRC:$addr)>;
529 def : Pat<(store F4RC:$DATA, GPRC:$addr),
530 (STS F4RC:$DATA, 0, GPRC:$addr)>;
531 def : Pat<(truncstore GPRC:$DATA, GPRC:$addr, i32),
532 (STL GPRC:$DATA, 0, GPRC:$addr)>;
533 def : Pat<(truncstore GPRC:$DATA, GPRC:$addr, i16),
534 (STW GPRC:$DATA, 0, GPRC:$addr)>;
535 def : Pat<(truncstore GPRC:$DATA, GPRC:$addr, i8),
536 (STB GPRC:$DATA, 0, GPRC:$addr)>;
539 //load address, rellocated gpdist form
540 let OperandList = (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB, s16imm:$NUM) in {
541 def LDAg : MForm<0x08, 0, 1, "lda $RA,0($RB)\t\t!gpdisp!$NUM", [], s_lda>; //Load address
542 def LDAHg : MForm<0x09, 0, 1, "ldah $RA,0($RB)\t\t!gpdisp!$NUM", [], s_lda>; //Load address
545 //Load quad, rellocated literal form
546 let OperandList = (ops GPRC:$RA, s64imm:$DISP, GPRC:$RB) in
547 def LDQl : MForm<0x29, 0, 1, "ldq $RA,$DISP($RB)\t\t!literal",
548 [(set GPRC:$RA, (Alpha_rellit tglobaladdr:$DISP, GPRC:$RB))], s_ild>;
549 def : Pat<(Alpha_rellit texternalsym:$ext, GPRC:$RB),
550 (LDQl texternalsym:$ext, GPRC:$RB)>;
553 def RPCC : MfcForm<0x18, 0xC000, "rpcc $RA", s_rpcc>; //Read process cycle counter
555 //Basic Floating point ops
559 let OperandList = (ops F4RC:$RC, F4RC:$RB), Fa = 31 in
560 def SQRTS : FPForm<0x14, 0x58B, "sqrts/su $RB,$RC",
561 [(set F4RC:$RC, (fsqrt F4RC:$RB))], s_fsqrts>;
563 let OperandList = (ops F4RC:$RC, F4RC:$RA, F4RC:$RB) in {
564 def ADDS : FPForm<0x16, 0x580, "adds/su $RA,$RB,$RC",
565 [(set F4RC:$RC, (fadd F4RC:$RA, F4RC:$RB))], s_fadd>;
566 def SUBS : FPForm<0x16, 0x581, "subs/su $RA,$RB,$RC",
567 [(set F4RC:$RC, (fsub F4RC:$RA, F4RC:$RB))], s_fadd>;
568 def DIVS : FPForm<0x16, 0x583, "divs/su $RA,$RB,$RC",
569 [(set F4RC:$RC, (fdiv F4RC:$RA, F4RC:$RB))], s_fdivs>;
570 def MULS : FPForm<0x16, 0x582, "muls/su $RA,$RB,$RC",
571 [(set F4RC:$RC, (fmul F4RC:$RA, F4RC:$RB))], s_fmul>;
573 def CPYSS : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
574 [(set F4RC:$RC, (fcopysign F4RC:$RB, F4RC:$RA))], s_fadd>;
575 def CPYSES : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent
576 def CPYSNS : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
577 [(set F4RC:$RC, (fneg (fcopysign F4RC:$RB, F4RC:$RA)))], s_fadd>;
582 let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in
583 def SQRTT : FPForm<0x14, 0x5AB, "sqrtt/su $RB,$RC",
584 [(set F8RC:$RC, (fsqrt F8RC:$RB))], s_fsqrtt>;
586 let OperandList = (ops F8RC:$RC, F8RC:$RA, F8RC:$RB) in {
587 def ADDT : FPForm<0x16, 0x5A0, "addt/su $RA,$RB,$RC",
588 [(set F8RC:$RC, (fadd F8RC:$RA, F8RC:$RB))], s_fadd>;
589 def SUBT : FPForm<0x16, 0x5A1, "subt/su $RA,$RB,$RC",
590 [(set F8RC:$RC, (fsub F8RC:$RA, F8RC:$RB))], s_fadd>;
591 def DIVT : FPForm<0x16, 0x5A3, "divt/su $RA,$RB,$RC",
592 [(set F8RC:$RC, (fdiv F8RC:$RA, F8RC:$RB))], s_fdivt>;
593 def MULT : FPForm<0x16, 0x5A2, "mult/su $RA,$RB,$RC",
594 [(set F8RC:$RC, (fmul F8RC:$RA, F8RC:$RB))], s_fmul>;
596 def CPYST : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
597 [(set F8RC:$RC, (fcopysign F8RC:$RB, F8RC:$RA))], s_fadd>;
598 def CPYSET : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent
599 def CPYSNT : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
600 [(set F8RC:$RC, (fneg (fcopysign F8RC:$RB, F8RC:$RA)))], s_fadd>;
602 def CMPTEQ : FPForm<0x16, 0x5A5, "cmpteq/su $RA,$RB,$RC", [], s_fadd>;
603 // [(set F8RC:$RC, (seteq F8RC:$RA, F8RC:$RB))]>;
604 def CMPTLE : FPForm<0x16, 0x5A7, "cmptle/su $RA,$RB,$RC", [], s_fadd>;
605 // [(set F8RC:$RC, (setle F8RC:$RA, F8RC:$RB))]>;
606 def CMPTLT : FPForm<0x16, 0x5A6, "cmptlt/su $RA,$RB,$RC", [], s_fadd>;
607 // [(set F8RC:$RC, (setlt F8RC:$RA, F8RC:$RB))]>;
608 def CMPTUN : FPForm<0x16, 0x5A4, "cmptun/su $RA,$RB,$RC", [], s_fadd>;
609 // [(set F8RC:$RC, (setuo F8RC:$RA, F8RC:$RB))]>;
611 //TODO: Add lots more FP patterns
613 //conditional moves, floats
614 let OperandList = (ops F4RC:$RDEST, F4RC:$RFALSE, F4RC:$RTRUE, F8RC:$RCOND),
615 isTwoAddress = 1 in {
616 def FCMOVEQS : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if = zero
617 def FCMOVGES : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if >= zero
618 def FCMOVGTS : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if > zero
619 def FCMOVLES : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if <= zero
620 def FCMOVLTS : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST",[], s_fcmov>; // FCMOVE if < zero
621 def FCMOVNES : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if != zero
623 //conditional moves, doubles
624 let OperandList = (ops F8RC:$RDEST, F8RC:$RFALSE, F8RC:$RTRUE, F8RC:$RCOND),
625 isTwoAddress = 1 in {
626 def FCMOVEQT : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
627 def FCMOVGET : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
628 def FCMOVGTT : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
629 def FCMOVLET : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
630 def FCMOVLTT : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
631 def FCMOVNET : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
636 def : Pat<(select (seteq F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
637 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
638 def : Pat<(select (setne F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
639 (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
640 def : Pat<(select (setgt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
641 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
642 def : Pat<(select (setge F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
643 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
644 def : Pat<(select (setlt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
645 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
646 def : Pat<(select (setle F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
647 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
649 def : Pat<(select (seteq F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
650 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
651 def : Pat<(select (setne F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
652 (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
653 def : Pat<(select (setgt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
654 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
655 def : Pat<(select (setge F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
656 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
657 def : Pat<(select (setlt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
658 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
659 def : Pat<(select (setle F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
660 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
664 let OperandList = (ops GPRC:$RC, F4RC:$RA), Fb = 31 in
665 def FTOIS : FPForm<0x1C, 0x078, "ftois $RA,$RC",[], s_ftoi>; //Floating to integer move, S_floating
666 let OperandList = (ops GPRC:$RC, F8RC:$RA), Fb = 31 in
667 def FTOIT : FPForm<0x1C, 0x070, "ftoit $RA,$RC",
668 [(set GPRC:$RC, (Alpha_ftoit F8RC:$RA))], s_ftoi>; //Floating to integer move
669 let OperandList = (ops F4RC:$RC, GPRC:$RA), Fb = 31 in
670 def ITOFS : FPForm<0x14, 0x004, "itofs $RA,$RC",[], s_itof>; //Integer to floating move, S_floating
671 let OperandList = (ops F8RC:$RC, GPRC:$RA), Fb = 31 in
672 def ITOFT : FPForm<0x14, 0x024, "itoft $RA,$RC",
673 [(set F8RC:$RC, (Alpha_itoft GPRC:$RA))], s_itof>; //Integer to floating move
676 let OperandList = (ops F4RC:$RC, F8RC:$RB), Fa = 31 in
677 def CVTQS : FPForm<0x16, 0x7BC, "cvtqs/sui $RB,$RC",
678 [(set F4RC:$RC, (Alpha_cvtqs F8RC:$RB))], s_fadd>;
679 let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in
680 def CVTQT : FPForm<0x16, 0x7BE, "cvtqt/sui $RB,$RC",
681 [(set F8RC:$RC, (Alpha_cvtqt F8RC:$RB))], s_fadd>;
682 let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in
683 def CVTTQ : FPForm<0x16, 0x52F, "cvttq/svc $RB,$RC",
684 [(set F8RC:$RC, (Alpha_cvttq F8RC:$RB))], s_fadd>;
685 let OperandList = (ops F8RC:$RC, F4RC:$RB), Fa = 31 in
686 def CVTST : FPForm<0x16, 0x6AC, "cvtst/s $RB,$RC",
687 [(set F8RC:$RC, (fextend F4RC:$RB))], s_fadd>;
688 let OperandList = (ops F4RC:$RC, F8RC:$RB), Fa = 31 in
689 def CVTTS : FPForm<0x16, 0x7AC, "cvtts/sui $RB,$RC",
690 [(set F4RC:$RC, (fround F8RC:$RB))], s_fadd>;
693 /////////////////////////////////////////////////////////
695 /////////////////////////////////////////////////////////
696 let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, noResults = 1 in {
698 def BR : BFormD<0x30, "br $$31,$DISP", [(br bb:$DISP)], s_ubr>;
701 def BEQ : BForm<0x39, "beq $RA,$DISP",
702 [(brcond (seteq GPRC:$RA, 0), bb:$DISP)], s_icbr>;
703 def BGE : BForm<0x3E, "bge $RA,$DISP",
704 [(brcond (setge GPRC:$RA, 0), bb:$DISP)], s_icbr>;
705 def BGT : BForm<0x3F, "bgt $RA,$DISP",
706 [(brcond (setgt GPRC:$RA, 0), bb:$DISP)], s_icbr>;
707 def BLBC : BForm<0x38, "blbc $RA,$DISP", [], s_icbr>; //TODO: Low bit clear
708 def BLBS : BForm<0x3C, "blbs $RA,$DISP",
709 [(brcond (and GPRC:$RA, 1), bb:$DISP)], s_icbr>;
710 def BLE : BForm<0x3B, "ble $RA,$DISP",
711 [(brcond (setle GPRC:$RA, 0), bb:$DISP)], s_icbr>;
712 def BLT : BForm<0x3A, "blt $RA,$DISP",
713 [(brcond (setlt GPRC:$RA, 0), bb:$DISP)], s_icbr>;
714 def BNE : BForm<0x3D, "bne $RA,$DISP",
715 [(brcond (setne GPRC:$RA, 0), bb:$DISP)], s_icbr>;
718 def FBEQ : FBForm<0x31, "fbeq $RA,$DISP",
719 [(brcond (seteq F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>;
720 def FBGE : FBForm<0x36, "fbge $RA,$DISP",
721 [(brcond (setge F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>;
722 def FBGT : FBForm<0x37, "fbgt $RA,$DISP",
723 [(brcond (setgt F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>;
724 def FBLE : FBForm<0x33, "fble $RA,$DISP",
725 [(brcond (setle F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>;
726 def FBLT : FBForm<0x32, "fblt $RA,$DISP",
727 [(brcond (setlt F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>;
728 def FBNE : FBForm<0x35, "fbne $RA,$DISP",
729 [(brcond (setne F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>;
732 def : Pat<(brcond GPRC:$RA, bb:$DISP), (BNE GPRC:$RA, bb:$DISP)>;
733 def : Pat<(brcond (setne GPRC:$RA, GPRC:$RB), bb:$DISP),
734 (BEQ (CMPEQ GPRC:$RA, GPRC:$RB), bb:$DISP)>;
735 def : Pat<(brcond (setne GPRC:$RA, immUExt8:$L), bb:$DISP),
736 (BEQ (CMPEQi GPRC:$RA, immUExt8:$L), bb:$DISP)>;
737 def : Pat<(brcond (seteq F8RC:$RA, F8RC:$RB), bb:$DISP),
738 (FBNE (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
739 def : Pat<(brcond (setlt F8RC:$RA, F8RC:$RB), bb:$DISP),
740 (FBNE (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
741 def : Pat<(brcond (setle F8RC:$RA, F8RC:$RB), bb:$DISP),
742 (FBNE (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
743 def : Pat<(brcond (setgt F8RC:$RA, F8RC:$RB), bb:$DISP),
744 (FBNE (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
745 def : Pat<(brcond (setge F8RC:$RA, F8RC:$RB), bb:$DISP),
746 (FBNE (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
747 def : Pat<(brcond (setne F8RC:$RA, F8RC:$RB), bb:$DISP),
748 (FBEQ (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
752 //S_floating : IEEE Single
753 //T_floating : IEEE Double
755 //Unused instructions
756 //Mnemonic Format Opcode Description
757 //CALL_PAL Pcd 00 Trap to PALcode
758 //ECB Mfc 18.E800 Evict cache block
759 //EXCB Mfc 18.0400 Exception barrier
760 //FETCH Mfc 18.8000 Prefetch data
761 //FETCH_M Mfc 18.A000 Prefetch data, modify intent
762 //LDL_L Mem 2A Load sign-extended longword locked
763 //LDQ_L Mem 2B Load quadword locked
764 //LDQ_U Mem 0B Load unaligned quadword
765 //MB Mfc 18.4000 Memory barrier
766 //STL_C Mem 2E Store longword conditional
767 //STQ_C Mem 2F Store quadword conditional
768 //STQ_U Mem 0F Store unaligned quadword
769 //TRAPB Mfc 18.0000 Trap barrier
770 //WH64 Mfc 18.F800 Write hint
\14 64 bytes
771 //WMB Mfc 18.4400 Write memory barrier
772 //MF_FPCR F-P 17.025 Move from FPCR
773 //MT_FPCR F-P 17.024 Move to FPCR
774 //There are in the Multimedia extentions, so let's not use them yet
775 //def MAXSB8 : OForm<0x1C, 0x3E, "MAXSB8 $RA,$RB,$RC">; //Vector signed byte maximum
776 //def MAXSW4 : OForm< 0x1C, 0x3F, "MAXSW4 $RA,$RB,$RC">; //Vector signed word maximum
777 //def MAXUB8 : OForm<0x1C, 0x3C, "MAXUB8 $RA,$RB,$RC">; //Vector unsigned byte maximum
778 //def MAXUW4 : OForm< 0x1C, 0x3D, "MAXUW4 $RA,$RB,$RC">; //Vector unsigned word maximum
779 //def MINSB8 : OForm< 0x1C, 0x38, "MINSB8 $RA,$RB,$RC">; //Vector signed byte minimum
780 //def MINSW4 : OForm< 0x1C, 0x39, "MINSW4 $RA,$RB,$RC">; //Vector signed word minimum
781 //def MINUB8 : OForm< 0x1C, 0x3A, "MINUB8 $RA,$RB,$RC">; //Vector unsigned byte minimum
782 //def MINUW4 : OForm< 0x1C, 0x3B, "MINUW4 $RA,$RB,$RC">; //Vector unsigned word minimum
783 //def PERR : OForm< 0x1C, 0x31, "PERR $RA,$RB,$RC">; //Pixel error
784 //def PKLB : OForm< 0x1C, 0x37, "PKLB $RA,$RB,$RC">; //Pack longwords to bytes
785 //def PKWB : OForm<0x1C, 0x36, "PKWB $RA,$RB,$RC">; //Pack words to bytes
786 //def UNPKBL : OForm< 0x1C, 0x35, "UNPKBL $RA,$RB,$RC">; //Unpack bytes to longwords
787 //def UNPKBW : OForm< 0x1C, 0x34, "UNPKBW $RA,$RB,$RC">; //Unpack bytes to words
788 //CVTLQ F-P 17.010 Convert longword to quadword
789 //CVTQL F-P 17.030 Convert quadword to longword
790 //def AMASK : OForm< 0x11, 0x61, "AMASK $RA,$RB,$RC", []>; //Architecture mask
791 //def AMASKi : OFormL<0x11, 0x61, "AMASK $RA,$L,$RC", []>; //Architecture mask
796 def immConst2Part : PatLeaf<(imm), [{
797 //true if imm fits in a LDAH LDA pair
798 int64_t val = (int64_t)N->getValue();
799 return (val <= IMM_FULLHIGH && val >= IMM_FULLLOW);
801 def immConst2PartInt : PatLeaf<(imm), [{
802 //true if imm fits in a LDAH LDA pair with zeroext
803 uint64_t uval = N->getValue();
804 int32_t val32 = (int32_t)uval;
805 return ((uval >> 32) == 0 && //empty upper bits
806 val32 <= IMM_FULLHIGH);
807 // val32 >= IMM_FULLLOW + IMM_LOW * IMM_MULT); //Always True
810 def : Pat<(i64 immConst2Part:$imm),
811 (LDA (LL16 immConst2Part:$imm), (LDAH (LH16 immConst2Part:$imm), R31))>;
813 def : Pat<(i64 immSExt16:$imm),
814 (LDA immSExt16:$imm, R31)>;
816 def : Pat<(i64 immSExt16int:$imm),
817 (ZAPNOTi (LDA (SExt16 immSExt16int:$imm), R31), 15)>;
818 def : Pat<(i64 immConst2PartInt:$imm),
819 (ZAPNOTi (LDA (LL16 (SExt32 immConst2PartInt:$imm)),
820 (LDAH (LH16 (SExt32 immConst2PartInt:$imm)), R31)), 15)>;
823 //TODO: I want to just define these like this!
826 //def : Pat<(f64 0.0),
828 //def : Pat<(f64 -0.0),
829 // (CPYSNT F31, F31)>;
830 //def : Pat<(f32 0.0),
832 //def : Pat<(f32 -0.0),
833 // (CPYSNS F31, F31)>;
837 def : Pat<(sext_inreg GPRC:$RB, i32),
838 (ADDLi GPRC:$RB, 0)>;
840 def : Pat<(select GPRC:$which, GPRC:$src1, GPRC:$src2),
841 (CMOVEQ GPRC:$src1, GPRC:$src2, GPRC:$which)>; //may be CMOVNE
843 def : Pat<(fabs F8RC:$RB),
844 (CPYST F31, F8RC:$RB)>;
845 def : Pat<(fabs F4RC:$RB),
846 (CPYSS F31, F4RC:$RB)>;
847 def : Pat<(fneg F8RC:$RB),
848 (CPYSNT F8RC:$RB, F8RC:$RB)>;
849 def : Pat<(fneg F4RC:$RB),
850 (CPYSNS F4RC:$RB, F4RC:$RB)>;
851 def : Pat<(fcopysign F4RC:$A, (fneg F4RC:$B)),
852 (CPYSNS F4RC:$B, F4RC:$A)>;
853 def : Pat<(fcopysign F8RC:$A, (fneg F8RC:$B)),
854 (CPYSNT F8RC:$B, F8RC:$A)>;
856 //Yes, signed multiply high is ugly
857 def : Pat<(mulhs GPRC:$RA, GPRC:$RB),
858 (SUBQ (UMULH GPRC:$RA, GPRC:$RB), (ADDQ (CMOVGE GPRC:$RB, R31, GPRC:$RA),
859 (CMOVGE GPRC:$RA, R31, GPRC:$RB)))>;