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()));
60 def nearP2X : SDNodeXForm<imm, [{
61 return getI64Imm(Log2_64(getNearPower2((uint64_t)N->getValue())));
63 def nearP2RemX : SDNodeXForm<imm, [{
64 uint64_t x = abs(N->getValue() - getNearPower2((uint64_t)N->getValue()));
65 return getI64Imm(Log2_64(x));
68 def immUExt8 : PatLeaf<(imm), [{ //imm fits in 8 bit zero extended field
69 return (uint64_t)N->getValue() == (uint8_t)N->getValue();
71 def immUExt8inv : PatLeaf<(imm), [{ //inverted imm fits in 8 bit zero extended field
72 return (uint64_t)~N->getValue() == (uint8_t)~N->getValue();
74 def immUExt8neg : PatLeaf<(imm), [{ //negated imm fits in 8 bit zero extended field
75 return ((uint64_t)~N->getValue() + 1) == (uint8_t)((uint64_t)~N->getValue() + 1);
77 def immSExt16 : PatLeaf<(imm), [{ //imm fits in 16 bit sign extended field
78 return ((int64_t)N->getValue() << 48) >> 48 == (int64_t)N->getValue();
80 def immSExt16int : PatLeaf<(imm), [{ //(int)imm fits in a 16 bit sign extended field
81 return ((int64_t)N->getValue() << 48) >> 48 == ((int64_t)N->getValue() << 32) >> 32;
83 def immZAP : PatLeaf<(imm), [{ //imm is good for zapi
84 uint64_t build = get_zapImm((uint64_t)N->getValue());
87 def immFPZ : PatLeaf<(fpimm), [{ //the only fpconstant nodes are +/- 0.0
90 def immRem1 : PatLeaf<(imm), [{
91 return N->getValue() - getNearPower2((uint64_t)N->getValue()) == 1;
93 def immRem3 : PatLeaf<(imm), [{
94 return N->getValue() - getNearPower2((uint64_t)N->getValue()) == 3;
96 def immRem4 : PatLeaf<(imm), [{
97 return N->getValue() - getNearPower2((uint64_t)N->getValue()) == 4;
99 def immRem5 : PatLeaf<(imm), [{
100 return N->getValue() - getNearPower2((uint64_t)N->getValue()) == 5;
102 def immRem1n : PatLeaf<(imm), [{
103 return getNearPower2((uint64_t)N->getValue()) - N->getValue() == 1;
105 def immRem3n : PatLeaf<(imm), [{
106 return getNearPower2((uint64_t)N->getValue()) - N->getValue() == 3;
108 def immRem4n : PatLeaf<(imm), [{
109 return getNearPower2((uint64_t)N->getValue()) - N->getValue() == 4;
111 def immRem5n : PatLeaf<(imm), [{
112 return getNearPower2((uint64_t)N->getValue()) - N->getValue() == 5;
114 def immRemP2n : PatLeaf<(imm), [{
115 return isPowerOf2_64(getNearPower2((uint64_t)N->getValue()) - N->getValue());
117 def immRemP2 : PatLeaf<(imm), [{
118 return isPowerOf2_64(N->getValue() - getNearPower2((uint64_t)N->getValue()));
120 def immUExt8ME : PatLeaf<(imm), [{ //use this imm for mulqi
121 int64_t d = abs((int64_t)N->getValue() - (int64_t)getNearPower2((uint64_t)N->getValue()));
122 if (isPowerOf2_64(d)) return false;
124 case 1: case 3: case 5: return false;
125 default: return (uint64_t)N->getValue() == (uint8_t)N->getValue();
129 def intop : PatFrag<(ops node:$op), (sext_inreg node:$op, i32)>;
130 def add4 : PatFrag<(ops node:$op1, node:$op2),
131 (add (shl node:$op1, 2), node:$op2)>;
132 def sub4 : PatFrag<(ops node:$op1, node:$op2),
133 (sub (shl node:$op1, 2), node:$op2)>;
134 def add8 : PatFrag<(ops node:$op1, node:$op2),
135 (add (shl node:$op1, 3), node:$op2)>;
136 def sub8 : PatFrag<(ops node:$op1, node:$op2),
137 (sub (shl node:$op1, 3), node:$op2)>;
140 //Pseudo ops for selection
142 def IDEF_I : PseudoInstAlpha<(ops GPRC:$RA), "#idef $RA",
143 [(set GPRC:$RA, (undef))], s_pseudo>;
144 def IDEF_F32 : PseudoInstAlpha<(ops F4RC:$RA), "#idef $RA",
145 [(set F4RC:$RA, (undef))], s_pseudo>;
146 def IDEF_F64 : PseudoInstAlpha<(ops F8RC:$RA), "#idef $RA",
147 [(set F8RC:$RA, (undef))], s_pseudo>;
149 def WTF : PseudoInstAlpha<(ops variable_ops), "#wtf", [], s_pseudo>;
151 let isLoad = 1, hasCtrlDep = 1 in {
152 def ADJUSTSTACKUP : PseudoInstAlpha<(ops s64imm:$amt), "; ADJUP $amt",
153 [(callseq_start imm:$amt)], s_pseudo>;
154 def ADJUSTSTACKDOWN : PseudoInstAlpha<(ops s64imm:$amt), "; ADJDOWN $amt",
155 [(callseq_end imm:$amt)], s_pseudo>;
157 def ALTENT : PseudoInstAlpha<(ops s64imm:$TARGET), "$$$TARGET..ng:\n", [], s_pseudo>;
158 def PCLABEL : PseudoInstAlpha<(ops s64imm:$num), "PCMARKER_$num:\n",[], s_pseudo>;
159 def MEMLABEL : PseudoInstAlpha<(ops s64imm:$i, s64imm:$j, s64imm:$k, s64imm:$m),
160 "LSMARKER$$$i$$$j$$$k$$$m:", [], s_pseudo>;
163 //***********************
165 //***********************
169 //conditional moves, int
171 def CMOVLBC : OForm4< 0x11, 0x16, "cmovlbc $RCOND,$RTRUE,$RDEST",
172 [(set GPRC:$RDEST, (select (xor GPRC:$RCOND, 1), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>;
173 def CMOVLBS : OForm4< 0x11, 0x14, "cmovlbs $RCOND,$RTRUE,$RDEST",
174 [(set GPRC:$RDEST, (select (and GPRC:$RCOND, 1), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>;
175 def CMOVEQ : OForm4< 0x11, 0x24, "cmoveq $RCOND,$RTRUE,$RDEST",
176 [(set GPRC:$RDEST, (select (seteq GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>;
177 def CMOVGE : OForm4< 0x11, 0x46, "cmovge $RCOND,$RTRUE,$RDEST",
178 [(set GPRC:$RDEST, (select (setge GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>;
179 def CMOVGT : OForm4< 0x11, 0x66, "cmovgt $RCOND,$RTRUE,$RDEST",
180 [(set GPRC:$RDEST, (select (setgt GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>;
181 def CMOVLE : OForm4< 0x11, 0x64, "cmovle $RCOND,$RTRUE,$RDEST",
182 [(set GPRC:$RDEST, (select (setle GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>;
183 def CMOVLT : OForm4< 0x11, 0x44, "cmovlt $RCOND,$RTRUE,$RDEST",
184 [(set GPRC:$RDEST, (select (setlt GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>;
185 def CMOVNE : OForm4< 0x11, 0x26, "cmovne $RCOND,$RTRUE,$RDEST",
186 [(set GPRC:$RDEST, (select (setne GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>;
188 def CMOVEQi : OForm4L< 0x11, 0x24, "cmoveq $RCOND,$RTRUE,$RDEST",
189 [(set GPRC:$RDEST, (select (setne GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))], s_cmov>;
190 def CMOVGEi : OForm4L< 0x11, 0x46, "cmovge $RCOND,$RTRUE,$RDEST",
191 [(set GPRC:$RDEST, (select (setlt GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))], s_cmov>;
192 def CMOVGTi : OForm4L< 0x11, 0x66, "cmovgt $RCOND,$RTRUE,$RDEST",
193 [(set GPRC:$RDEST, (select (setle GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))], s_cmov>;
194 def CMOVLEi : OForm4L< 0x11, 0x64, "cmovle $RCOND,$RTRUE,$RDEST",
195 [(set GPRC:$RDEST, (select (setgt GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))], s_cmov>;
196 def CMOVLTi : OForm4L< 0x11, 0x44, "cmovlt $RCOND,$RTRUE,$RDEST",
197 [(set GPRC:$RDEST, (select (setge GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))], s_cmov>;
198 def CMOVNEi : OForm4L< 0x11, 0x26, "cmovne $RCOND,$RTRUE,$RDEST",
199 [(set GPRC:$RDEST, (select (seteq GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))], s_cmov>;
200 def CMOVLBCi : OForm4L< 0x11, 0x16, "cmovlbc $RCOND,$RTRUE,$RDEST",
201 [(set GPRC:$RDEST, (select (and GPRC:$RCOND, 1), GPRC:$RFALSE, immUExt8:$RTRUE))], s_cmov>;
202 def CMOVLBSi : OForm4L< 0x11, 0x14, "cmovlbs $RCOND,$RTRUE,$RDEST",
203 [(set GPRC:$RDEST, (select (xor GPRC:$RCOND, 1), GPRC:$RFALSE, immUExt8:$RTRUE))], s_cmov>;
206 //General pattern for cmov
207 def : Pat<(select GPRC:$which, GPRC:$src1, GPRC:$src2),
208 (CMOVNE GPRC:$src2, GPRC:$src1, GPRC:$which)>;
209 def : Pat<(select GPRC:$which, GPRC:$src1, immUExt8:$src2),
210 (CMOVEQi GPRC:$src1, immUExt8:$src2, GPRC:$which)>;
213 def ADDL : OForm< 0x10, 0x00, "addl $RA,$RB,$RC",
214 [(set GPRC:$RC, (intop (add GPRC:$RA, GPRC:$RB)))], s_iadd>;
215 def ADDLi : OFormL<0x10, 0x00, "addl $RA,$L,$RC",
216 [(set GPRC:$RC, (intop (add GPRC:$RA, immUExt8:$L)))], s_iadd>;
217 def ADDQ : OForm< 0x10, 0x20, "addq $RA,$RB,$RC",
218 [(set GPRC:$RC, (add GPRC:$RA, GPRC:$RB))], s_iadd>;
219 def ADDQi : OFormL<0x10, 0x20, "addq $RA,$L,$RC",
220 [(set GPRC:$RC, (add GPRC:$RA, immUExt8:$L))], s_iadd>;
221 def AND : OForm< 0x11, 0x00, "and $RA,$RB,$RC",
222 [(set GPRC:$RC, (and GPRC:$RA, GPRC:$RB))], s_ilog>;
223 def ANDi : OFormL<0x11, 0x00, "and $RA,$L,$RC",
224 [(set GPRC:$RC, (and GPRC:$RA, immUExt8:$L))], s_ilog>;
225 def BIC : OForm< 0x11, 0x08, "bic $RA,$RB,$RC",
226 [(set GPRC:$RC, (and GPRC:$RA, (not GPRC:$RB)))], s_ilog>;
227 def BICi : OFormL<0x11, 0x08, "bic $RA,$L,$RC",
228 [(set GPRC:$RC, (and GPRC:$RA, immUExt8inv:$L))], s_ilog>;
229 def BIS : OForm< 0x11, 0x20, "bis $RA,$RB,$RC",
230 [(set GPRC:$RC, (or GPRC:$RA, GPRC:$RB))], s_ilog>;
231 def BISi : OFormL<0x11, 0x20, "bis $RA,$L,$RC",
232 [(set GPRC:$RC, (or GPRC:$RA, immUExt8:$L))], s_ilog>;
233 def CTLZ : OForm2<0x1C, 0x32, "CTLZ $RB,$RC",
234 [(set GPRC:$RC, (ctlz GPRC:$RB))], s_imisc>;
235 def CTPOP : OForm2<0x1C, 0x30, "CTPOP $RB,$RC",
236 [(set GPRC:$RC, (ctpop GPRC:$RB))], s_imisc>;
237 def CTTZ : OForm2<0x1C, 0x33, "CTTZ $RB,$RC",
238 [(set GPRC:$RC, (cttz GPRC:$RB))], s_imisc>;
239 def EQV : OForm< 0x11, 0x48, "eqv $RA,$RB,$RC",
240 [(set GPRC:$RC, (xor GPRC:$RA, (not GPRC:$RB)))], s_ilog>;
241 def EQVi : OFormL<0x11, 0x48, "eqv $RA,$L,$RC",
242 [(set GPRC:$RC, (xor GPRC:$RA, immUExt8inv:$L))], s_ilog>;
243 def EXTBL : OForm< 0x12, 0x06, "EXTBL $RA,$RB,$RC",
244 [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 255))], s_ishf>;
245 def EXTWL : OForm< 0x12, 0x16, "EXTWL $RA,$RB,$RC",
246 [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 65535))], s_ishf>;
247 def EXTLL : OForm< 0x12, 0x26, "EXTLL $RA,$RB,$RC",
248 [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 4294967295))], s_ishf>;
250 //def EXTBLi : OFormL<0x12, 0x06, "EXTBL $RA,$L,$RC", []>; //Extract byte low
251 //def EXTLH : OForm< 0x12, 0x6A, "EXTLH $RA,$RB,$RC", []>; //Extract longword high
252 //def EXTLHi : OFormL<0x12, 0x6A, "EXTLH $RA,$L,$RC", []>; //Extract longword high
253 //def EXTLLi : OFormL<0x12, 0x26, "EXTLL $RA,$L,$RC", []>; //Extract longword low
254 //def EXTQH : OForm< 0x12, 0x7A, "EXTQH $RA,$RB,$RC", []>; //Extract quadword high
255 //def EXTQHi : OFormL<0x12, 0x7A, "EXTQH $RA,$L,$RC", []>; //Extract quadword high
256 //def EXTQ : OForm< 0x12, 0x36, "EXTQ $RA,$RB,$RC", []>; //Extract quadword low
257 //def EXTQi : OFormL<0x12, 0x36, "EXTQ $RA,$L,$RC", []>; //Extract quadword low
258 //def EXTWH : OForm< 0x12, 0x5A, "EXTWH $RA,$RB,$RC", []>; //Extract word high
259 //def EXTWHi : OFormL<0x12, 0x5A, "EXTWH $RA,$L,$RC", []>; //Extract word high
260 //def EXTWLi : OFormL<0x12, 0x16, "EXTWL $RA,$L,$RC", []>; //Extract word low
262 //def IMPLVER : OForm< 0x11, 0x6C, "IMPLVER $RA,$RB,$RC", []>; //Implementation version
263 //def IMPLVERi : OFormL<0x11, 0x6C, "IMPLVER $RA,$L,$RC", []>; //Implementation version
264 //def INSBL : OForm< 0x12, 0x0B, "INSBL $RA,$RB,$RC", []>; //Insert byte low
265 //def INSBLi : OFormL<0x12, 0x0B, "INSBL $RA,$L,$RC", []>; //Insert byte low
266 //def INSLH : OForm< 0x12, 0x67, "INSLH $RA,$RB,$RC", []>; //Insert longword high
267 //def INSLHi : OFormL<0x12, 0x67, "INSLH $RA,$L,$RC", []>; //Insert longword high
268 //def INSLL : OForm< 0x12, 0x2B, "INSLL $RA,$RB,$RC", []>; //Insert longword low
269 //def INSLLi : OFormL<0x12, 0x2B, "INSLL $RA,$L,$RC", []>; //Insert longword low
270 //def INSQH : OForm< 0x12, 0x77, "INSQH $RA,$RB,$RC", []>; //Insert quadword high
271 //def INSQHi : OFormL<0x12, 0x77, "INSQH $RA,$L,$RC", []>; //Insert quadword high
272 //def INSQL : OForm< 0x12, 0x3B, "INSQL $RA,$RB,$RC", []>; //Insert quadword low
273 //def INSQLi : OFormL<0x12, 0x3B, "INSQL $RA,$L,$RC", []>; //Insert quadword low
274 //def INSWH : OForm< 0x12, 0x57, "INSWH $RA,$RB,$RC", []>; //Insert word high
275 //def INSWHi : OFormL<0x12, 0x57, "INSWH $RA,$L,$RC", []>; //Insert word high
276 //def INSWL : OForm< 0x12, 0x1B, "INSWL $RA,$RB,$RC", []>; //Insert word low
277 //def INSWLi : OFormL<0x12, 0x1B, "INSWL $RA,$L,$RC", []>; //Insert word low
278 //def MSKBL : OForm< 0x12, 0x02, "MSKBL $RA,$RB,$RC", []>; //Mask byte low
279 //def MSKBLi : OFormL<0x12, 0x02, "MSKBL $RA,$L,$RC", []>; //Mask byte low
280 //def MSKLH : OForm< 0x12, 0x62, "MSKLH $RA,$RB,$RC", []>; //Mask longword high
281 //def MSKLHi : OFormL<0x12, 0x62, "MSKLH $RA,$L,$RC", []>; //Mask longword high
282 //def MSKLL : OForm< 0x12, 0x22, "MSKLL $RA,$RB,$RC", []>; //Mask longword low
283 //def MSKLLi : OFormL<0x12, 0x22, "MSKLL $RA,$L,$RC", []>; //Mask longword low
284 //def MSKQH : OForm< 0x12, 0x72, "MSKQH $RA,$RB,$RC", []>; //Mask quadword high
285 //def MSKQHi : OFormL<0x12, 0x72, "MSKQH $RA,$L,$RC", []>; //Mask quadword high
286 //def MSKQL : OForm< 0x12, 0x32, "MSKQL $RA,$RB,$RC", []>; //Mask quadword low
287 //def MSKQLi : OFormL<0x12, 0x32, "MSKQL $RA,$L,$RC", []>; //Mask quadword low
288 //def MSKWH : OForm< 0x12, 0x52, "MSKWH $RA,$RB,$RC", []>; //Mask word high
289 //def MSKWHi : OFormL<0x12, 0x52, "MSKWH $RA,$L,$RC", []>; //Mask word high
290 //def MSKWL : OForm< 0x12, 0x12, "MSKWL $RA,$RB,$RC", []>; //Mask word low
291 //def MSKWLi : OFormL<0x12, 0x12, "MSKWL $RA,$L,$RC", []>; //Mask word low
293 def MULL : OForm< 0x13, 0x00, "mull $RA,$RB,$RC",
294 [(set GPRC:$RC, (intop (mul GPRC:$RA, GPRC:$RB)))], s_imul>;
295 def MULLi : OFormL<0x13, 0x00, "mull $RA,$L,$RC",
296 [(set GPRC:$RC, (intop (mul GPRC:$RA, immUExt8:$L)))], s_imul>;
297 def MULQ : OForm< 0x13, 0x20, "mulq $RA,$RB,$RC",
298 [(set GPRC:$RC, (mul GPRC:$RA, GPRC:$RB))], s_imul>;
299 def MULQi : OFormL<0x13, 0x20, "mulq $RA,$L,$RC",
300 [(set GPRC:$RC, (mul GPRC:$RA, immUExt8ME:$L))], s_imul>;
301 def ORNOT : OForm< 0x11, 0x28, "ornot $RA,$RB,$RC",
302 [(set GPRC:$RC, (or GPRC:$RA, (not GPRC:$RB)))], s_ilog>;
303 def ORNOTi : OFormL<0x11, 0x28, "ornot $RA,$L,$RC",
304 [(set GPRC:$RC, (or GPRC:$RA, immUExt8inv:$L))], s_ilog>;
305 def S4ADDL : OForm< 0x10, 0x02, "s4addl $RA,$RB,$RC",
306 [(set GPRC:$RC, (intop (add4 GPRC:$RA, GPRC:$RB)))], s_iadd>;
307 def S4ADDLi : OFormL<0x10, 0x02, "s4addl $RA,$L,$RC",
308 [(set GPRC:$RC, (intop (add4 GPRC:$RA, immUExt8:$L)))], s_iadd>;
309 def S4ADDQ : OForm< 0x10, 0x22, "s4addq $RA,$RB,$RC",
310 [(set GPRC:$RC, (add4 GPRC:$RA, GPRC:$RB))], s_iadd>;
311 def S4ADDQi : OFormL<0x10, 0x22, "s4addq $RA,$L,$RC",
312 [(set GPRC:$RC, (add4 GPRC:$RA, immUExt8:$L))], s_iadd>;
313 def S4SUBL : OForm< 0x10, 0x0B, "s4subl $RA,$RB,$RC",
314 [(set GPRC:$RC, (intop (sub4 GPRC:$RA, GPRC:$RB)))], s_iadd>;
315 def S4SUBLi : OFormL<0x10, 0x0B, "s4subl $RA,$L,$RC",
316 [(set GPRC:$RC, (intop (sub4 GPRC:$RA, immUExt8:$L)))], s_iadd>;
317 def S4SUBQ : OForm< 0x10, 0x2B, "s4subq $RA,$RB,$RC",
318 [(set GPRC:$RC, (sub4 GPRC:$RA, GPRC:$RB))], s_iadd>;
319 def S4SUBQi : OFormL<0x10, 0x2B, "s4subq $RA,$L,$RC",
320 [(set GPRC:$RC, (sub4 GPRC:$RA, immUExt8:$L))], s_iadd>;
321 def S8ADDL : OForm< 0x10, 0x12, "s8addl $RA,$RB,$RC",
322 [(set GPRC:$RC, (intop (add8 GPRC:$RA, GPRC:$RB)))], s_iadd>;
323 def S8ADDLi : OFormL<0x10, 0x12, "s8addl $RA,$L,$RC",
324 [(set GPRC:$RC, (intop (add8 GPRC:$RA, immUExt8:$L)))], s_iadd>;
325 def S8ADDQ : OForm< 0x10, 0x32, "s8addq $RA,$RB,$RC",
326 [(set GPRC:$RC, (add8 GPRC:$RA, GPRC:$RB))], s_iadd>;
327 def S8ADDQi : OFormL<0x10, 0x32, "s8addq $RA,$L,$RC",
328 [(set GPRC:$RC, (add8 GPRC:$RA, immUExt8:$L))], s_iadd>;
329 def S8SUBL : OForm< 0x10, 0x1B, "s8subl $RA,$RB,$RC",
330 [(set GPRC:$RC, (intop (sub8 GPRC:$RA, GPRC:$RB)))], s_iadd>;
331 def S8SUBLi : OFormL<0x10, 0x1B, "s8subl $RA,$L,$RC",
332 [(set GPRC:$RC, (intop (add8 GPRC:$RA, immUExt8neg:$L)))], s_iadd>;
333 def S8SUBQ : OForm< 0x10, 0x3B, "s8subq $RA,$RB,$RC",
334 [(set GPRC:$RC, (sub8 GPRC:$RA, GPRC:$RB))], s_iadd>;
335 def S8SUBQi : OFormL<0x10, 0x3B, "s8subq $RA,$L,$RC",
336 [(set GPRC:$RC, (add8 GPRC:$RA, immUExt8neg:$L))], s_iadd>;
337 def SEXTB : OForm2<0x1C, 0x00, "sextb $RB,$RC",
338 [(set GPRC:$RC, (sext_inreg GPRC:$RB, i8))], s_ishf>;
339 def SEXTW : OForm2<0x1C, 0x01, "sextw $RB,$RC",
340 [(set GPRC:$RC, (sext_inreg GPRC:$RB, i16))], s_ishf>;
341 def SL : OForm< 0x12, 0x39, "sll $RA,$RB,$RC",
342 [(set GPRC:$RC, (shl GPRC:$RA, GPRC:$RB))], s_ishf>;
343 def SLi : OFormL<0x12, 0x39, "sll $RA,$L,$RC",
344 [(set GPRC:$RC, (shl GPRC:$RA, immUExt8:$L))], s_ishf>;
345 def SRA : OForm< 0x12, 0x3C, "sra $RA,$RB,$RC",
346 [(set GPRC:$RC, (sra GPRC:$RA, GPRC:$RB))], s_ishf>;
347 def SRAi : OFormL<0x12, 0x3C, "sra $RA,$L,$RC",
348 [(set GPRC:$RC, (sra GPRC:$RA, immUExt8:$L))], s_ishf>;
349 def SRL : OForm< 0x12, 0x34, "srl $RA,$RB,$RC",
350 [(set GPRC:$RC, (srl GPRC:$RA, GPRC:$RB))], s_ishf>;
351 def SRLi : OFormL<0x12, 0x34, "srl $RA,$L,$RC",
352 [(set GPRC:$RC, (srl GPRC:$RA, immUExt8:$L))], s_ishf>;
353 def SUBL : OForm< 0x10, 0x09, "subl $RA,$RB,$RC",
354 [(set GPRC:$RC, (intop (sub GPRC:$RA, GPRC:$RB)))], s_iadd>;
355 def SUBLi : OFormL<0x10, 0x09, "subl $RA,$L,$RC",
356 [(set GPRC:$RC, (intop (add GPRC:$RA, immUExt8neg:$L)))], s_iadd>;
357 def SUBQ : OForm< 0x10, 0x29, "subq $RA,$RB,$RC",
358 [(set GPRC:$RC, (sub GPRC:$RA, GPRC:$RB))], s_iadd>;
359 def SUBQi : OFormL<0x10, 0x29, "subq $RA,$L,$RC",
360 [(set GPRC:$RC, (add GPRC:$RA, immUExt8neg:$L))], s_iadd>;
361 def UMULH : OForm< 0x13, 0x30, "umulh $RA,$RB,$RC",
362 [(set GPRC:$RC, (mulhu GPRC:$RA, GPRC:$RB))], s_imul>;
363 def UMULHi : OFormL<0x13, 0x30, "umulh $RA,$L,$RC",
364 [(set GPRC:$RC, (mulhu GPRC:$RA, immUExt8:$L))], s_imul>;
365 def XOR : OForm< 0x11, 0x40, "xor $RA,$RB,$RC",
366 [(set GPRC:$RC, (xor GPRC:$RA, GPRC:$RB))], s_ilog>;
367 def XORi : OFormL<0x11, 0x40, "xor $RA,$L,$RC",
368 [(set GPRC:$RC, (xor GPRC:$RA, immUExt8:$L))], s_ilog>;
369 //FIXME: what to do about zap? the cases it catches are very complex
370 def ZAP : OForm< 0x12, 0x30, "zap $RA,$RB,$RC", [], s_ishf>; //Zero bytes
371 //ZAPi is useless give ZAPNOTi
372 def ZAPi : OFormL<0x12, 0x30, "zap $RA,$L,$RC", [], s_ishf>; //Zero bytes
373 //FIXME: what to do about zapnot? see ZAP :)
374 def ZAPNOT : OForm< 0x12, 0x31, "zapnot $RA,$RB,$RC", [], s_ishf>; //Zero bytes not
375 def ZAPNOTi : OFormL<0x12, 0x31, "zapnot $RA,$L,$RC",
376 [(set GPRC:$RC, (and GPRC:$RA, immZAP:$L))], s_ishf>;
379 //So this is a waste of what this instruction can do, but it still saves something
380 def CMPBGE : OForm< 0x10, 0x0F, "cmpbge $RA,$RB,$RC",
381 [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), (and GPRC:$RB, 255)))], s_ilog>;
382 def CMPBGEi : OFormL<0x10, 0x0F, "cmpbge $RA,$L,$RC",
383 [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), immUExt8:$L))], s_ilog>;
384 def CMPEQ : OForm< 0x10, 0x2D, "cmpeq $RA,$RB,$RC",
385 [(set GPRC:$RC, (seteq GPRC:$RA, GPRC:$RB))], s_iadd>;
386 def CMPEQi : OFormL<0x10, 0x2D, "cmpeq $RA,$L,$RC",
387 [(set GPRC:$RC, (seteq GPRC:$RA, immUExt8:$L))], s_iadd>;
388 def CMPLE : OForm< 0x10, 0x6D, "cmple $RA,$RB,$RC",
389 [(set GPRC:$RC, (setle GPRC:$RA, GPRC:$RB))], s_iadd>;
390 def CMPLEi : OFormL<0x10, 0x6D, "cmple $RA,$L,$RC",
391 [(set GPRC:$RC, (setle GPRC:$RA, immUExt8:$L))], s_iadd>;
392 def CMPLT : OForm< 0x10, 0x4D, "cmplt $RA,$RB,$RC",
393 [(set GPRC:$RC, (setlt GPRC:$RA, GPRC:$RB))], s_iadd>;
394 def CMPLTi : OFormL<0x10, 0x4D, "cmplt $RA,$L,$RC",
395 [(set GPRC:$RC, (setlt GPRC:$RA, immUExt8:$L))], s_iadd>;
396 def CMPULE : OForm< 0x10, 0x3D, "cmpule $RA,$RB,$RC",
397 [(set GPRC:$RC, (setule GPRC:$RA, GPRC:$RB))], s_iadd>;
398 def CMPULEi : OFormL<0x10, 0x3D, "cmpule $RA,$L,$RC",
399 [(set GPRC:$RC, (setule GPRC:$RA, immUExt8:$L))], s_iadd>;
400 def CMPULT : OForm< 0x10, 0x1D, "cmpult $RA,$RB,$RC",
401 [(set GPRC:$RC, (setult GPRC:$RA, GPRC:$RB))], s_iadd>;
402 def CMPULTi : OFormL<0x10, 0x1D, "cmpult $RA,$L,$RC",
403 [(set GPRC:$RC, (setult GPRC:$RA, immUExt8:$L))], s_iadd>;
405 //Patterns for unsupported int comparisons
406 def : Pat<(setueq GPRC:$X, GPRC:$Y), (CMPEQ GPRC:$X, GPRC:$Y)>;
407 def : Pat<(setueq GPRC:$X, immUExt8:$Y), (CMPEQi GPRC:$X, immUExt8:$Y)>;
409 def : Pat<(setugt GPRC:$X, GPRC:$Y), (CMPULT GPRC:$Y, GPRC:$X)>;
410 def : Pat<(setugt immUExt8:$X, GPRC:$Y), (CMPULTi GPRC:$Y, immUExt8:$X)>;
412 def : Pat<(setuge GPRC:$X, GPRC:$Y), (CMPULE GPRC:$Y, GPRC:$X)>;
413 def : Pat<(setuge immUExt8:$X, GPRC:$Y), (CMPULEi GPRC:$Y, immUExt8:$X)>;
415 def : Pat<(setgt GPRC:$X, GPRC:$Y), (CMPLT GPRC:$Y, GPRC:$X)>;
416 def : Pat<(setgt immUExt8:$X, GPRC:$Y), (CMPLTi GPRC:$Y, immUExt8:$X)>;
418 def : Pat<(setge GPRC:$X, GPRC:$Y), (CMPLE GPRC:$Y, GPRC:$X)>;
419 def : Pat<(setge immUExt8:$X, GPRC:$Y), (CMPLEi GPRC:$Y, immUExt8:$X)>;
421 def : Pat<(setne GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>;
422 def : Pat<(setne GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQi GPRC:$X, immUExt8:$Y), 0)>;
424 def : Pat<(setune GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>;
425 def : Pat<(setune GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQ GPRC:$X, immUExt8:$Y), 0)>;
428 let isReturn = 1, isTerminator = 1, noResults = 1, Ra = 31, Rb = 26, disp = 1, Uses = [R26] in
429 def RETDAG : MbrForm< 0x1A, 0x02, (ops), "ret $$31,($$26),1", s_jsr>; //Return from subroutine
431 def JMP : MbrForm< 0x1A, 0x00, (ops GPRC:$RD, GPRC:$RS, GPRC:$DISP), "jmp $RD,($RS),$DISP", s_jsr>; //Jump
432 let isCall = 1, noResults = 1, Ra = 26,
433 Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19,
434 R20, R21, R22, R23, R24, R25, R26, R27, R28, R29,
436 F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
437 F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R29] in {
438 def BSR : BFormD<0x34, "bsr $$26,$$$DISP..ng", [], s_jsr>; //Branch to subroutine
440 let isCall = 1, noResults = 1, Ra = 26, Rb = 27, disp = 0,
441 Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19,
442 R20, R21, R22, R23, R24, R25, R26, R27, R28, R29,
444 F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
445 F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R27, R29] in {
446 def JSR : MbrForm< 0x1A, 0x01, (ops ), "jsr $$26,($$27),0", s_jsr>; //Jump to subroutine
449 let isCall = 1, noResults = 1, Ra = 23, Rb = 27, disp = 0,
450 Defs = [R23, R24, R25, R27, R28], Uses = [R24, R25, R27] in
451 def JSRs : MbrForm< 0x1A, 0x01, (ops ), "jsr $$23,($$27),0", s_jsr>; //Jump to div or rem
454 def JSR_COROUTINE : MbrForm< 0x1A, 0x03, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr_coroutine $RD,($RS),$DISP", s_jsr>; //Jump to subroutine return
456 let OperandList = (ops GPRC:$RA, s64imm:$DISP, GPRC:$RB) in {
457 def LDQ : MForm<0x29, 0, 1, "ldq $RA,$DISP($RB)",
458 [(set GPRC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
459 def LDQr : MForm<0x29, 0, 1, "ldq $RA,$DISP($RB)\t\t!gprellow",
460 [(set GPRC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>;
461 def LDL : MForm<0x28, 0, 1, "ldl $RA,$DISP($RB)",
462 [(set GPRC:$RA, (sextload (add GPRC:$RB, immSExt16:$DISP), i32))], s_ild>;
463 def LDLr : MForm<0x28, 0, 1, "ldl $RA,$DISP($RB)\t\t!gprellow",
464 [(set GPRC:$RA, (sextload (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i32))], s_ild>;
465 def LDBU : MForm<0x0A, 0, 1, "ldbu $RA,$DISP($RB)",
466 [(set GPRC:$RA, (zextload (add GPRC:$RB, immSExt16:$DISP), i8))], s_ild>;
467 def LDBUr : MForm<0x0A, 0, 1, "ldbu $RA,$DISP($RB)\t\t!gprellow",
468 [(set GPRC:$RA, (zextload (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i8))], s_ild>;
469 def LDWU : MForm<0x0C, 0, 1, "ldwu $RA,$DISP($RB)",
470 [(set GPRC:$RA, (zextload (add GPRC:$RB, immSExt16:$DISP), i16))], s_ild>;
471 def LDWUr : MForm<0x0C, 0, 1, "ldwu $RA,$DISP($RB)\t\t!gprellow",
472 [(set GPRC:$RA, (zextload (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i16))], s_ild>;
473 def STB : MForm<0x0E, 1, 0, "stb $RA,$DISP($RB)",
474 [(truncstore GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP), i8)], s_ist>;
475 def STBr : MForm<0x0E, 1, 0, "stb $RA,$DISP($RB)\t\t!gprellow",
476 [(truncstore GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i8)], s_ist>;
477 def STW : MForm<0x0D, 1, 0, "stw $RA,$DISP($RB)",
478 [(truncstore GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP), i16)], s_ist>;
479 def STWr : MForm<0x0D, 1, 0, "stw $RA,$DISP($RB)\t\t!gprellow",
480 [(truncstore GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i16)], s_ist>;
481 def STL : MForm<0x2C, 1, 0, "stl $RA,$DISP($RB)",
482 [(truncstore GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP), i32)], s_ist>;
483 def STLr : MForm<0x2C, 1, 0, "stl $RA,$DISP($RB)\t\t!gprellow",
484 [(truncstore GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB), i32)], s_ist>;
485 def STQ : MForm<0x2D, 1, 0, "stq $RA,$DISP($RB)",
486 [(store GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
487 def STQr : MForm<0x2D, 1, 0, "stq $RA,$DISP($RB)\t\t!gprellow",
488 [(store GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
491 def LDA : MForm<0x08, 0, 0, "lda $RA,$DISP($RB)",
492 [(set GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_lda>;
493 def LDAr : MForm<0x08, 0, 0, "lda $RA,$DISP($RB)\t\t!gprellow",
494 [(set GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_lda>; //Load address
495 def LDAH : MForm<0x09, 0, 0, "ldah $RA,$DISP($RB)",
496 [], s_lda>; //Load address high
497 def LDAHr : MForm<0x09, 0, 0, "ldah $RA,$DISP($RB)\t\t!gprelhigh",
498 [(set GPRC:$RA, (Alpha_gprelhi tglobaladdr:$DISP, GPRC:$RB))], s_lda>; //Load address high
501 let OperandList = (ops F4RC:$RA, s64imm:$DISP, GPRC:$RB) in {
502 def STS : MForm<0x26, 1, 0, "sts $RA,$DISP($RB)",
503 [(store F4RC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_fst>;
504 def STSr : MForm<0x26, 1, 0, "sts $RA,$DISP($RB)\t\t!gprellow",
505 [(store F4RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_fst>;
506 def LDS : MForm<0x22, 0, 1, "lds $RA,$DISP($RB)",
507 [(set F4RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_fld>;
508 def LDSr : MForm<0x22, 0, 1, "lds $RA,$DISP($RB)\t\t!gprellow",
509 [(set F4RC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_fld>;
511 let OperandList = (ops F8RC:$RA, s64imm:$DISP, GPRC:$RB) in {
512 def STT : MForm<0x27, 1, 0, "stt $RA,$DISP($RB)",
513 [(store F8RC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_fst>;
514 def STTr : MForm<0x27, 1, 0, "stt $RA,$DISP($RB)\t\t!gprellow",
515 [(store F8RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_fst>;
516 def LDT : MForm<0x23, 0, 1, "ldt $RA,$DISP($RB)",
517 [(set F8RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_fld>;
518 def LDTr : MForm<0x23, 0, 1, "ldt $RA,$DISP($RB)\t\t!gprellow",
519 [(set F8RC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_fld>;
524 def : Pat<(i64 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
525 (LDQr tconstpool:$DISP, GPRC:$RB)>;
526 def : Pat<(i64 (sextload (Alpha_gprello tconstpool:$DISP, GPRC:$RB), i32)),
527 (LDLr tconstpool:$DISP, GPRC:$RB)>;
528 def : Pat<(i64 (zextload (Alpha_gprello tconstpool:$DISP, GPRC:$RB), i8)),
529 (LDBUr tconstpool:$DISP, GPRC:$RB)>;
530 def : Pat<(i64 (zextload (Alpha_gprello tconstpool:$DISP, GPRC:$RB), i16)),
531 (LDWUr tconstpool:$DISP, GPRC:$RB)>;
532 def : Pat<(i64 (Alpha_gprello tconstpool:$DISP, GPRC:$RB)),
533 (LDAr tconstpool:$DISP, GPRC:$RB)>;
534 def : Pat<(i64 (Alpha_gprelhi tconstpool:$DISP, GPRC:$RB)),
535 (LDAHr tconstpool:$DISP, GPRC:$RB)>;
536 def : Pat<(f32 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
537 (LDSr tconstpool:$DISP, GPRC:$RB)>;
538 def : Pat<(f64 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
539 (LDTr tconstpool:$DISP, GPRC:$RB)>;
543 def : Pat<(i64 (extload (add GPRC:$RB, immSExt16:$DISP), i8)),
544 (LDBU immSExt16:$DISP, GPRC:$RB)>;
545 def : Pat<(i64 (extload (add GPRC:$RB, immSExt16:$DISP), i16)),
546 (LDWU immSExt16:$DISP, GPRC:$RB)>;
547 def : Pat<(i64 (extload (add GPRC:$RB, immSExt16:$DISP), i32)),
548 (LDL immSExt16:$DISP, GPRC:$RB)>;
551 def : Pat<(i64 (load GPRC:$addr)),
552 (LDQ 0, GPRC:$addr)>;
553 def : Pat<(f64 (load GPRC:$addr)),
554 (LDT 0, GPRC:$addr)>;
555 def : Pat<(f32 (load GPRC:$addr)),
556 (LDS 0, GPRC:$addr)>;
557 def : Pat<(i64 (sextload GPRC:$addr, i32)),
558 (LDL 0, GPRC:$addr)>;
559 def : Pat<(i64 (zextload GPRC:$addr, i16)),
560 (LDWU 0, GPRC:$addr)>;
561 def : Pat<(i64 (zextload GPRC:$addr, i8)),
562 (LDBU 0, GPRC:$addr)>;
563 def : Pat<(i64 (extload GPRC:$addr, i8)),
564 (LDBU 0, GPRC:$addr)>;
565 def : Pat<(i64 (extload GPRC:$addr, i16)),
566 (LDWU 0, GPRC:$addr)>;
567 def : Pat<(i64 (extload GPRC:$addr, i32)),
568 (LDL 0, GPRC:$addr)>;
570 def : Pat<(store GPRC:$DATA, GPRC:$addr),
571 (STQ GPRC:$DATA, 0, GPRC:$addr)>;
572 def : Pat<(store F8RC:$DATA, GPRC:$addr),
573 (STT F8RC:$DATA, 0, GPRC:$addr)>;
574 def : Pat<(store F4RC:$DATA, GPRC:$addr),
575 (STS F4RC:$DATA, 0, GPRC:$addr)>;
576 def : Pat<(truncstore GPRC:$DATA, GPRC:$addr, i32),
577 (STL GPRC:$DATA, 0, GPRC:$addr)>;
578 def : Pat<(truncstore GPRC:$DATA, GPRC:$addr, i16),
579 (STW GPRC:$DATA, 0, GPRC:$addr)>;
580 def : Pat<(truncstore GPRC:$DATA, GPRC:$addr, i8),
581 (STB GPRC:$DATA, 0, GPRC:$addr)>;
584 //load address, rellocated gpdist form
585 let OperandList = (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB, s16imm:$NUM) in {
586 def LDAg : MForm<0x08, 0, 1, "lda $RA,0($RB)\t\t!gpdisp!$NUM", [], s_lda>; //Load address
587 def LDAHg : MForm<0x09, 0, 1, "ldah $RA,0($RB)\t\t!gpdisp!$NUM", [], s_lda>; //Load address
590 //Load quad, rellocated literal form
591 let OperandList = (ops GPRC:$RA, s64imm:$DISP, GPRC:$RB) in
592 def LDQl : MForm<0x29, 0, 1, "ldq $RA,$DISP($RB)\t\t!literal",
593 [(set GPRC:$RA, (Alpha_rellit tglobaladdr:$DISP, GPRC:$RB))], s_ild>;
594 def : Pat<(Alpha_rellit texternalsym:$ext, GPRC:$RB),
595 (LDQl texternalsym:$ext, GPRC:$RB)>;
598 def RPCC : MfcForm<0x18, 0xC000, "rpcc $RA", s_rpcc>; //Read process cycle counter
600 //Basic Floating point ops
604 let OperandList = (ops F4RC:$RC, F4RC:$RB), Fa = 31 in
605 def SQRTS : FPForm<0x14, 0x58B, "sqrts/su $RB,$RC",
606 [(set F4RC:$RC, (fsqrt F4RC:$RB))], s_fsqrts>;
608 let OperandList = (ops F4RC:$RC, F4RC:$RA, F4RC:$RB) in {
609 def ADDS : FPForm<0x16, 0x580, "adds/su $RA,$RB,$RC",
610 [(set F4RC:$RC, (fadd F4RC:$RA, F4RC:$RB))], s_fadd>;
611 def SUBS : FPForm<0x16, 0x581, "subs/su $RA,$RB,$RC",
612 [(set F4RC:$RC, (fsub F4RC:$RA, F4RC:$RB))], s_fadd>;
613 def DIVS : FPForm<0x16, 0x583, "divs/su $RA,$RB,$RC",
614 [(set F4RC:$RC, (fdiv F4RC:$RA, F4RC:$RB))], s_fdivs>;
615 def MULS : FPForm<0x16, 0x582, "muls/su $RA,$RB,$RC",
616 [(set F4RC:$RC, (fmul F4RC:$RA, F4RC:$RB))], s_fmul>;
618 def CPYSS : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
619 [(set F4RC:$RC, (fcopysign F4RC:$RB, F4RC:$RA))], s_fadd>;
620 def CPYSES : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent
621 def CPYSNS : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
622 [(set F4RC:$RC, (fneg (fcopysign F4RC:$RB, F4RC:$RA)))], s_fadd>;
627 let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in
628 def SQRTT : FPForm<0x14, 0x5AB, "sqrtt/su $RB,$RC",
629 [(set F8RC:$RC, (fsqrt F8RC:$RB))], s_fsqrtt>;
631 let OperandList = (ops F8RC:$RC, F8RC:$RA, F8RC:$RB) in {
632 def ADDT : FPForm<0x16, 0x5A0, "addt/su $RA,$RB,$RC",
633 [(set F8RC:$RC, (fadd F8RC:$RA, F8RC:$RB))], s_fadd>;
634 def SUBT : FPForm<0x16, 0x5A1, "subt/su $RA,$RB,$RC",
635 [(set F8RC:$RC, (fsub F8RC:$RA, F8RC:$RB))], s_fadd>;
636 def DIVT : FPForm<0x16, 0x5A3, "divt/su $RA,$RB,$RC",
637 [(set F8RC:$RC, (fdiv F8RC:$RA, F8RC:$RB))], s_fdivt>;
638 def MULT : FPForm<0x16, 0x5A2, "mult/su $RA,$RB,$RC",
639 [(set F8RC:$RC, (fmul F8RC:$RA, F8RC:$RB))], s_fmul>;
641 def CPYST : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
642 [(set F8RC:$RC, (fcopysign F8RC:$RB, F8RC:$RA))], s_fadd>;
643 def CPYSET : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent
644 def CPYSNT : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
645 [(set F8RC:$RC, (fneg (fcopysign F8RC:$RB, F8RC:$RA)))], s_fadd>;
647 def CMPTEQ : FPForm<0x16, 0x5A5, "cmpteq/su $RA,$RB,$RC", [], s_fadd>;
648 // [(set F8RC:$RC, (seteq F8RC:$RA, F8RC:$RB))]>;
649 def CMPTLE : FPForm<0x16, 0x5A7, "cmptle/su $RA,$RB,$RC", [], s_fadd>;
650 // [(set F8RC:$RC, (setle F8RC:$RA, F8RC:$RB))]>;
651 def CMPTLT : FPForm<0x16, 0x5A6, "cmptlt/su $RA,$RB,$RC", [], s_fadd>;
652 // [(set F8RC:$RC, (setlt F8RC:$RA, F8RC:$RB))]>;
653 def CMPTUN : FPForm<0x16, 0x5A4, "cmptun/su $RA,$RB,$RC", [], s_fadd>;
654 // [(set F8RC:$RC, (setuo F8RC:$RA, F8RC:$RB))]>;
658 let OperandList = (ops F8RC:$RC, F4RC:$RA, F8RC:$RB) in {
659 def CPYSTs : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
660 [(set F8RC:$RC, (fcopysign F8RC:$RB, F4RC:$RA))], s_fadd>;
661 def CPYSNTs : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
662 [(set F8RC:$RC, (fneg (fcopysign F8RC:$RB, F4RC:$RA)))], s_fadd>;
664 let OperandList = (ops F4RC:$RC, F8RC:$RA, F4RC:$RB) in {
665 def CPYSSt : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
666 [(set F4RC:$RC, (fcopysign F4RC:$RB, F8RC:$RA))], s_fadd>;
667 def CPYSESt : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent
668 def CPYSNSt : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
669 [(set F4RC:$RC, (fneg (fcopysign F4RC:$RB, F8RC:$RA)))], s_fadd>;
672 //conditional moves, floats
673 let OperandList = (ops F4RC:$RDEST, F4RC:$RFALSE, F4RC:$RTRUE, F8RC:$RCOND),
674 isTwoAddress = 1 in {
675 def FCMOVEQS : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if = zero
676 def FCMOVGES : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if >= zero
677 def FCMOVGTS : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if > zero
678 def FCMOVLES : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if <= zero
679 def FCMOVLTS : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST",[], s_fcmov>; // FCMOVE if < zero
680 def FCMOVNES : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if != zero
682 //conditional moves, doubles
683 let OperandList = (ops F8RC:$RDEST, F8RC:$RFALSE, F8RC:$RTRUE, F8RC:$RCOND),
684 isTwoAddress = 1 in {
685 def FCMOVEQT : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
686 def FCMOVGET : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
687 def FCMOVGTT : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
688 def FCMOVLET : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
689 def FCMOVLTT : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
690 def FCMOVNET : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
695 def : Pat<(select (seteq F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
696 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
697 def : Pat<(select (setne F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
698 (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
699 def : Pat<(select (setgt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
700 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
701 def : Pat<(select (setge F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
702 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
703 def : Pat<(select (setlt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
704 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
705 def : Pat<(select (setle F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
706 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
708 def : Pat<(select (seteq F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
709 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
710 def : Pat<(select (setne F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
711 (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
712 def : Pat<(select (setgt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
713 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
714 def : Pat<(select (setge F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
715 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
716 def : Pat<(select (setlt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
717 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
718 def : Pat<(select (setle F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
719 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
723 let OperandList = (ops GPRC:$RC, F4RC:$RA), Fb = 31 in
724 def FTOIS : FPForm<0x1C, 0x078, "ftois $RA,$RC",[], s_ftoi>; //Floating to integer move, S_floating
725 let OperandList = (ops GPRC:$RC, F8RC:$RA), Fb = 31 in
726 def FTOIT : FPForm<0x1C, 0x070, "ftoit $RA,$RC",
727 [(set GPRC:$RC, (Alpha_ftoit F8RC:$RA))], s_ftoi>; //Floating to integer move
728 let OperandList = (ops F4RC:$RC, GPRC:$RA), Fb = 31 in
729 def ITOFS : FPForm<0x14, 0x004, "itofs $RA,$RC",[], s_itof>; //Integer to floating move, S_floating
730 let OperandList = (ops F8RC:$RC, GPRC:$RA), Fb = 31 in
731 def ITOFT : FPForm<0x14, 0x024, "itoft $RA,$RC",
732 [(set F8RC:$RC, (Alpha_itoft GPRC:$RA))], s_itof>; //Integer to floating move
735 let OperandList = (ops F4RC:$RC, F8RC:$RB), Fa = 31 in
736 def CVTQS : FPForm<0x16, 0x7BC, "cvtqs/sui $RB,$RC",
737 [(set F4RC:$RC, (Alpha_cvtqs F8RC:$RB))], s_fadd>;
738 let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in
739 def CVTQT : FPForm<0x16, 0x7BE, "cvtqt/sui $RB,$RC",
740 [(set F8RC:$RC, (Alpha_cvtqt F8RC:$RB))], s_fadd>;
741 let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in
742 def CVTTQ : FPForm<0x16, 0x52F, "cvttq/svc $RB,$RC",
743 [(set F8RC:$RC, (Alpha_cvttq F8RC:$RB))], s_fadd>;
744 let OperandList = (ops F8RC:$RC, F4RC:$RB), Fa = 31 in
745 def CVTST : FPForm<0x16, 0x6AC, "cvtst/s $RB,$RC",
746 [(set F8RC:$RC, (fextend F4RC:$RB))], s_fadd>;
747 let OperandList = (ops F4RC:$RC, F8RC:$RB), Fa = 31 in
748 def CVTTS : FPForm<0x16, 0x7AC, "cvtts/sui $RB,$RC",
749 [(set F4RC:$RC, (fround F8RC:$RB))], s_fadd>;
752 /////////////////////////////////////////////////////////
754 /////////////////////////////////////////////////////////
755 let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, noResults = 1 in {
757 def BR : BFormD<0x30, "br $$31,$DISP", [(br bb:$DISP)], s_ubr>;
760 def BEQ : BForm<0x39, "beq $RA,$DISP",
761 [(brcond (seteq GPRC:$RA, 0), bb:$DISP)], s_icbr>;
762 def BGE : BForm<0x3E, "bge $RA,$DISP",
763 [(brcond (setge GPRC:$RA, 0), bb:$DISP)], s_icbr>;
764 def BGT : BForm<0x3F, "bgt $RA,$DISP",
765 [(brcond (setgt GPRC:$RA, 0), bb:$DISP)], s_icbr>;
766 def BLBC : BForm<0x38, "blbc $RA,$DISP", [], s_icbr>; //TODO: Low bit clear
767 def BLBS : BForm<0x3C, "blbs $RA,$DISP",
768 [(brcond (and GPRC:$RA, 1), bb:$DISP)], s_icbr>;
769 def BLE : BForm<0x3B, "ble $RA,$DISP",
770 [(brcond (setle GPRC:$RA, 0), bb:$DISP)], s_icbr>;
771 def BLT : BForm<0x3A, "blt $RA,$DISP",
772 [(brcond (setlt GPRC:$RA, 0), bb:$DISP)], s_icbr>;
773 def BNE : BForm<0x3D, "bne $RA,$DISP",
774 [(brcond (setne GPRC:$RA, 0), bb:$DISP)], s_icbr>;
777 def FBEQ : FBForm<0x31, "fbeq $RA,$DISP",
778 [(brcond (seteq F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>;
779 def FBGE : FBForm<0x36, "fbge $RA,$DISP",
780 [(brcond (setge F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>;
781 def FBGT : FBForm<0x37, "fbgt $RA,$DISP",
782 [(brcond (setgt F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>;
783 def FBLE : FBForm<0x33, "fble $RA,$DISP",
784 [(brcond (setle F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>;
785 def FBLT : FBForm<0x32, "fblt $RA,$DISP",
786 [(brcond (setlt F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>;
787 def FBNE : FBForm<0x35, "fbne $RA,$DISP",
788 [(brcond (setne F8RC:$RA, immFPZ), bb:$DISP)], s_fbr>;
791 def : Pat<(brcond GPRC:$RA, bb:$DISP), (BNE GPRC:$RA, bb:$DISP)>;
792 def : Pat<(brcond (setne GPRC:$RA, GPRC:$RB), bb:$DISP),
793 (BEQ (CMPEQ GPRC:$RA, GPRC:$RB), bb:$DISP)>;
794 def : Pat<(brcond (setne GPRC:$RA, immUExt8:$L), bb:$DISP),
795 (BEQ (CMPEQi GPRC:$RA, immUExt8:$L), bb:$DISP)>;
796 def : Pat<(brcond (seteq F8RC:$RA, F8RC:$RB), bb:$DISP),
797 (FBNE (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
798 def : Pat<(brcond (setlt F8RC:$RA, F8RC:$RB), bb:$DISP),
799 (FBNE (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
800 def : Pat<(brcond (setle F8RC:$RA, F8RC:$RB), bb:$DISP),
801 (FBNE (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
802 def : Pat<(brcond (setgt F8RC:$RA, F8RC:$RB), bb:$DISP),
803 (FBNE (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
804 def : Pat<(brcond (setge F8RC:$RA, F8RC:$RB), bb:$DISP),
805 (FBNE (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
806 def : Pat<(brcond (setne F8RC:$RA, F8RC:$RB), bb:$DISP),
807 (FBEQ (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
811 //S_floating : IEEE Single
812 //T_floating : IEEE Double
814 //Unused instructions
815 //Mnemonic Format Opcode Description
816 //CALL_PAL Pcd 00 Trap to PALcode
817 //ECB Mfc 18.E800 Evict cache block
818 //EXCB Mfc 18.0400 Exception barrier
819 //FETCH Mfc 18.8000 Prefetch data
820 //FETCH_M Mfc 18.A000 Prefetch data, modify intent
821 //LDL_L Mem 2A Load sign-extended longword locked
822 //LDQ_L Mem 2B Load quadword locked
823 //LDQ_U Mem 0B Load unaligned quadword
824 //MB Mfc 18.4000 Memory barrier
825 //STL_C Mem 2E Store longword conditional
826 //STQ_C Mem 2F Store quadword conditional
827 //STQ_U Mem 0F Store unaligned quadword
828 //TRAPB Mfc 18.0000 Trap barrier
829 //WH64 Mfc 18.F800 Write hint
\14 64 bytes
830 //WMB Mfc 18.4400 Write memory barrier
831 //MF_FPCR F-P 17.025 Move from FPCR
832 //MT_FPCR F-P 17.024 Move to FPCR
833 //There are in the Multimedia extentions, so let's not use them yet
834 //def MAXSB8 : OForm<0x1C, 0x3E, "MAXSB8 $RA,$RB,$RC">; //Vector signed byte maximum
835 //def MAXSW4 : OForm< 0x1C, 0x3F, "MAXSW4 $RA,$RB,$RC">; //Vector signed word maximum
836 //def MAXUB8 : OForm<0x1C, 0x3C, "MAXUB8 $RA,$RB,$RC">; //Vector unsigned byte maximum
837 //def MAXUW4 : OForm< 0x1C, 0x3D, "MAXUW4 $RA,$RB,$RC">; //Vector unsigned word maximum
838 //def MINSB8 : OForm< 0x1C, 0x38, "MINSB8 $RA,$RB,$RC">; //Vector signed byte minimum
839 //def MINSW4 : OForm< 0x1C, 0x39, "MINSW4 $RA,$RB,$RC">; //Vector signed word minimum
840 //def MINUB8 : OForm< 0x1C, 0x3A, "MINUB8 $RA,$RB,$RC">; //Vector unsigned byte minimum
841 //def MINUW4 : OForm< 0x1C, 0x3B, "MINUW4 $RA,$RB,$RC">; //Vector unsigned word minimum
842 //def PERR : OForm< 0x1C, 0x31, "PERR $RA,$RB,$RC">; //Pixel error
843 //def PKLB : OForm< 0x1C, 0x37, "PKLB $RA,$RB,$RC">; //Pack longwords to bytes
844 //def PKWB : OForm<0x1C, 0x36, "PKWB $RA,$RB,$RC">; //Pack words to bytes
845 //def UNPKBL : OForm< 0x1C, 0x35, "UNPKBL $RA,$RB,$RC">; //Unpack bytes to longwords
846 //def UNPKBW : OForm< 0x1C, 0x34, "UNPKBW $RA,$RB,$RC">; //Unpack bytes to words
847 //CVTLQ F-P 17.010 Convert longword to quadword
848 //CVTQL F-P 17.030 Convert quadword to longword
849 //def AMASK : OForm< 0x11, 0x61, "AMASK $RA,$RB,$RC", []>; //Architecture mask
850 //def AMASKi : OFormL<0x11, 0x61, "AMASK $RA,$L,$RC", []>; //Architecture mask
855 def immConst2Part : PatLeaf<(imm), [{
856 //true if imm fits in a LDAH LDA pair
857 int64_t val = (int64_t)N->getValue();
858 return (val <= IMM_FULLHIGH && val >= IMM_FULLLOW);
860 def immConst2PartInt : PatLeaf<(imm), [{
861 //true if imm fits in a LDAH LDA pair with zeroext
862 uint64_t uval = N->getValue();
863 int32_t val32 = (int32_t)uval;
864 return ((uval >> 32) == 0 && //empty upper bits
865 val32 <= IMM_FULLHIGH);
866 // val32 >= IMM_FULLLOW + IMM_LOW * IMM_MULT); //Always True
869 def : Pat<(i64 immConst2Part:$imm),
870 (LDA (LL16 immConst2Part:$imm), (LDAH (LH16 immConst2Part:$imm), R31))>;
872 def : Pat<(i64 immSExt16:$imm),
873 (LDA immSExt16:$imm, R31)>;
875 def : Pat<(i64 immSExt16int:$imm),
876 (ZAPNOTi (LDA (SExt16 immSExt16int:$imm), R31), 15)>;
877 def : Pat<(i64 immConst2PartInt:$imm),
878 (ZAPNOTi (LDA (LL16 (SExt32 immConst2PartInt:$imm)),
879 (LDAH (LH16 (SExt32 immConst2PartInt:$imm)), R31)), 15)>;
882 //TODO: I want to just define these like this!
885 //def : Pat<(f64 0.0),
887 //def : Pat<(f64 -0.0),
888 // (CPYSNT F31, F31)>;
889 //def : Pat<(f32 0.0),
891 //def : Pat<(f32 -0.0),
892 // (CPYSNS F31, F31)>;
896 def : Pat<(sext_inreg GPRC:$RB, i32),
897 (ADDLi GPRC:$RB, 0)>;
899 def : Pat<(select GPRC:$which, GPRC:$src1, GPRC:$src2),
900 (CMOVEQ GPRC:$src1, GPRC:$src2, GPRC:$which)>; //may be CMOVNE
902 def : Pat<(fabs F8RC:$RB),
903 (CPYST F31, F8RC:$RB)>;
904 def : Pat<(fabs F4RC:$RB),
905 (CPYSS F31, F4RC:$RB)>;
906 def : Pat<(fneg F8RC:$RB),
907 (CPYSNT F8RC:$RB, F8RC:$RB)>;
908 def : Pat<(fneg F4RC:$RB),
909 (CPYSNS F4RC:$RB, F4RC:$RB)>;
911 def : Pat<(fcopysign F4RC:$A, (fneg F4RC:$B)),
912 (CPYSNS F4RC:$B, F4RC:$A)>;
913 def : Pat<(fcopysign F8RC:$A, (fneg F8RC:$B)),
914 (CPYSNT F8RC:$B, F8RC:$A)>;
915 def : Pat<(fcopysign F4RC:$A, (fneg F8RC:$B)),
916 (CPYSNSt F8RC:$B, F4RC:$A)>;
917 def : Pat<(fcopysign F8RC:$A, (fneg F4RC:$B)),
918 (CPYSNTs F4RC:$B, F8RC:$A)>;
920 //Yes, signed multiply high is ugly
921 def : Pat<(mulhs GPRC:$RA, GPRC:$RB),
922 (SUBQ (UMULH GPRC:$RA, GPRC:$RB), (ADDQ (CMOVGE GPRC:$RB, R31, GPRC:$RA),
923 (CMOVGE GPRC:$RA, R31, GPRC:$RB)))>;
925 //Stupid crazy arithmetic stuff:
926 def : Pat<(mul GPRC:$RA, 5), (S4ADDQ GPRC:$RA, GPRC:$RA)>;
927 def : Pat<(mul GPRC:$RA, 3), (S4SUBQ GPRC:$RA, GPRC:$RA)>;
929 def : Pat<(mul GPRC:$RA, immRem1:$imm),
930 (ADDQ (SL GPRC:$RA, (nearP2X immRem1:$imm)), GPRC:$RA)>;
931 def : Pat<(mul GPRC:$RA, immRem3:$imm),
932 (ADDQ (SL GPRC:$RA, (nearP2X immRem3:$imm)), (S4SUBQ GPRC:$RA, GPRC:$RA))>;
933 def : Pat<(mul GPRC:$RA, immRem5:$imm),
934 (ADDQ (SL GPRC:$RA, (nearP2X immRem5:$imm)), (S4ADDQ GPRC:$RA, GPRC:$RA))>;
935 def : Pat<(mul GPRC:$RA, immRem4:$imm),
936 (S4ADDQ GPRC:$RA, (SL GPRC:$RA, (nearP2X immRem4:$imm)))>;
937 def : Pat<(mul GPRC:$RA, immRemP2:$imm),
938 (ADDQ (SL GPRC:$RA, (nearP2X immRemP2:$imm)), (SLi GPRC:$RA, (nearP2RemX immRemP2:$imm)))>;
940 def : Pat<(mul GPRC:$RA, immRem1n:$imm),
941 (SUBQ (SL GPRC:$RA, (nearP2X immRem1n:$imm)), GPRC:$RA)>;
942 def : Pat<(mul GPRC:$RA, immRem3n:$imm),
943 (SUBQ (SL GPRC:$RA, (nearP2X immRem3n:$imm)), (S4SUBQ GPRC:$RA, GPRC:$RA))>;
944 def : Pat<(mul GPRC:$RA, immRem5n:$imm),
945 (SUBQ (SL GPRC:$RA, (nearP2X immRem5n:$imm)), (S4ADDQ GPRC:$RA, GPRC:$RA))>;
946 def : Pat<(mul GPRC:$RA, immRemP2n:$imm),
947 (SUBQ (SL GPRC:$RA, (nearP2X immRemP2n:$imm)), (SLi GPRC:$RA, (nearP2RemX immRemP2n:$imm)))>;