blob: 1769ec2a21437aa73ef5270cc398dab63bdf8dec [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//
Chris Lattner081ce942007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Dan Gohmanf17a25c2007-07-18 16:29:46 +00007//
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, []>;
Chris Lattnerca4e0fe2008-01-10 05:12:37 +000027def Alpha_rellit : SDNode<"AlphaISD::RelLit", SDTIntBinOp, [SDNPMayLoad]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +000028
Chris Lattner3d254552008-01-15 22:02:54 +000029def retflag : SDNode<"AlphaISD::RET_FLAG", SDTNone,
Bill Wendling6c02cd22008-02-27 06:33:05 +000030 [SDNPHasChain, SDNPOptInFlag]>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +000031
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,
Bill Wendling6c02cd22008-02-27 06:33:05 +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 Chenge399fbb2007-12-12 23:12:09 +0000144let isImplicitDef = 1 in {
Evan Chengb783fa32007-07-19 01:14:50 +0000145def IDEF_I : PseudoInstAlpha<(outs GPRC:$RA), (ins), ";#idef $RA",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000146 [(set GPRC:$RA, (undef))], s_pseudo>;
Evan Chengb783fa32007-07-19 01:14:50 +0000147def IDEF_F32 : PseudoInstAlpha<(outs F4RC:$RA), (ins), ";#idef $RA",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000148 [(set F4RC:$RA, (undef))], s_pseudo>;
Evan Chengb783fa32007-07-19 01:14:50 +0000149def IDEF_F64 : PseudoInstAlpha<(outs F8RC:$RA), (ins), ";#idef $RA",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000150 [(set F8RC:$RA, (undef))], s_pseudo>;
Evan Chenge399fbb2007-12-12 23:12:09 +0000151}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000152
Evan Chengb783fa32007-07-19 01:14:50 +0000153def WTF : PseudoInstAlpha<(outs), (ins variable_ops), "#wtf", [], s_pseudo>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000154
Chris Lattner1a1932c2008-01-06 23:38:27 +0000155let hasCtrlDep = 1, Defs = [R30], Uses = [R30] in {
Bill Wendling22f8deb2007-11-13 00:44:25 +0000156def ADJUSTSTACKUP : PseudoInstAlpha<(outs), (ins s64imm:$amt),
157 "; ADJUP $amt",
Evan Cheng6e4d1d92007-09-11 19:55:27 +0000158 [(callseq_start imm:$amt)], s_pseudo>;
Bill Wendling22f8deb2007-11-13 00:44:25 +0000159def ADJUSTSTACKDOWN : PseudoInstAlpha<(outs), (ins s64imm:$amt1, s64imm:$amt2),
160 "; ADJDOWN $amt1",
161 [(callseq_end imm:$amt1, imm:$amt2)], s_pseudo>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000162}
Bill Wendling22f8deb2007-11-13 00:44:25 +0000163
Evan Chengb783fa32007-07-19 01:14:50 +0000164def ALTENT : PseudoInstAlpha<(outs), (ins s64imm:$TARGET), "$$$TARGET..ng:\n", [], s_pseudo>;
165def PCLABEL : PseudoInstAlpha<(outs), (ins s64imm:$num), "PCMARKER_$num:\n",[], s_pseudo>;
166def MEMLABEL : PseudoInstAlpha<(outs), (ins s64imm:$i, s64imm:$j, s64imm:$k, s64imm:$m),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000167 "LSMARKER$$$i$$$j$$$k$$$m:", [], s_pseudo>;
168
169
Andrew Lenharthe44f3902008-02-21 06:45:13 +0000170let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler.
171def CAS32 : PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$cmp, GPRC:$swp), "",
172 [(set GPRC:$dst, (atomic_lcs_32 GPRC:$ptr, GPRC:$cmp, GPRC:$swp))], s_pseudo>;
173def CAS64 : PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$cmp, GPRC:$swp), "",
174 [(set GPRC:$dst, (atomic_lcs_64 GPRC:$ptr, GPRC:$cmp, GPRC:$swp))], s_pseudo>;
175
176def LAS32 : PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$swp), "",
177 [(set GPRC:$dst, (atomic_las_32 GPRC:$ptr, GPRC:$swp))], s_pseudo>;
178def LAS64 :PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$swp), "",
179 [(set GPRC:$dst, (atomic_las_64 GPRC:$ptr, GPRC:$swp))], s_pseudo>;
180
181def SWAP32 : PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$swp), "",
182 [(set GPRC:$dst, (atomic_swap_32 GPRC:$ptr, GPRC:$swp))], s_pseudo>;
183def SWAP64 :PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$swp), "",
184 [(set GPRC:$dst, (atomic_swap_64 GPRC:$ptr, GPRC:$swp))], s_pseudo>;
185}
186
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000187//***********************
188//Real instructions
189//***********************
190
191//Operation Form:
192
193//conditional moves, int
194
195multiclass cmov_inst<bits<7> fun, string asmstr, PatFrag OpNode> {
196def r : OForm4<0x11, fun, !strconcat(asmstr, " $RCOND,$RTRUE,$RDEST"),
197 [(set GPRC:$RDEST, (select (OpNode GPRC:$RCOND), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>;
198def i : OForm4L<0x11, fun, !strconcat(asmstr, " $RCOND,$RTRUE,$RDEST"),
199 [(set GPRC:$RDEST, (select (OpNode GPRC:$RCOND), immUExt8:$RTRUE, GPRC:$RFALSE))], s_cmov>;
200}
201
202defm CMOVEQ : cmov_inst<0x24, "cmoveq", CmpOpFrag<(seteq node:$R, 0)>>;
203defm CMOVNE : cmov_inst<0x26, "cmovne", CmpOpFrag<(setne node:$R, 0)>>;
204defm CMOVLT : cmov_inst<0x44, "cmovlt", CmpOpFrag<(setlt node:$R, 0)>>;
205defm CMOVLE : cmov_inst<0x64, "cmovle", CmpOpFrag<(setle node:$R, 0)>>;
206defm CMOVGT : cmov_inst<0x66, "cmovgt", CmpOpFrag<(setgt node:$R, 0)>>;
207defm CMOVGE : cmov_inst<0x46, "cmovge", CmpOpFrag<(setge node:$R, 0)>>;
208defm CMOVLBC : cmov_inst<0x16, "cmovlbc", CmpOpFrag<(xor node:$R, 1)>>;
209defm CMOVLBS : cmov_inst<0x14, "cmovlbs", CmpOpFrag<(and node:$R, 1)>>;
210
211//General pattern for cmov
212def : Pat<(select GPRC:$which, GPRC:$src1, GPRC:$src2),
213 (CMOVNEr GPRC:$src2, GPRC:$src1, GPRC:$which)>;
214def : Pat<(select GPRC:$which, GPRC:$src1, immUExt8:$src2),
215 (CMOVEQi GPRC:$src1, immUExt8:$src2, GPRC:$which)>;
216
217//Invert sense when we can for constants:
218def : Pat<(select (setne GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
219 (CMOVEQi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
220def : Pat<(select (setgt GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
221 (CMOVLEi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
222def : Pat<(select (setge GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
223 (CMOVLTi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
224def : Pat<(select (setlt GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
225 (CMOVGEi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
226def : Pat<(select (setle GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
227 (CMOVGTi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
228
229multiclass all_inst<bits<6> opc, bits<7> funl, bits<7> funq,
230 string asmstr, PatFrag OpNode, InstrItinClass itin> {
231 def Lr : OForm< opc, funl, !strconcat(asmstr, "l $RA,$RB,$RC"),
232 [(set GPRC:$RC, (intop (OpNode GPRC:$RA, GPRC:$RB)))], itin>;
233 def Li : OFormL<opc, funl, !strconcat(asmstr, "l $RA,$L,$RC"),
234 [(set GPRC:$RC, (intop (OpNode GPRC:$RA, immUExt8:$L)))], itin>;
235 def Qr : OForm< opc, funq, !strconcat(asmstr, "q $RA,$RB,$RC"),
236 [(set GPRC:$RC, (OpNode GPRC:$RA, GPRC:$RB))], itin>;
237 def Qi : OFormL<opc, funq, !strconcat(asmstr, "q $RA,$L,$RC"),
238 [(set GPRC:$RC, (OpNode GPRC:$RA, immUExt8:$L))], itin>;
239}
240
241defm MUL : all_inst<0x13, 0x00, 0x20, "mul", BinOpFrag<(mul node:$LHS, node:$RHS)>, s_imul>;
242defm ADD : all_inst<0x10, 0x00, 0x20, "add", BinOpFrag<(add node:$LHS, node:$RHS)>, s_iadd>;
243defm S4ADD : all_inst<0x10, 0x02, 0x22, "s4add", add4, s_iadd>;
244defm S8ADD : all_inst<0x10, 0x12, 0x32, "s8add", add8, s_iadd>;
245defm S4SUB : all_inst<0x10, 0x0B, 0x2B, "s4sub", sub4, s_iadd>;
246defm S8SUB : all_inst<0x10, 0x1B, 0x3B, "s8sub", sub8, s_iadd>;
247defm SUB : all_inst<0x10, 0x09, 0x29, "sub", BinOpFrag<(sub node:$LHS, node:$RHS)>, s_iadd>;
248//Const cases since legalize does sub x, int -> add x, inv(int) + 1
249def : Pat<(intop (add GPRC:$RA, immUExt8neg:$L)), (SUBLi GPRC:$RA, immUExt8neg:$L)>;
250def : Pat<(add GPRC:$RA, immUExt8neg:$L), (SUBQi GPRC:$RA, immUExt8neg:$L)>;
251def : Pat<(intop (add4 GPRC:$RA, immUExt8neg:$L)), (S4SUBLi GPRC:$RA, immUExt8neg:$L)>;
252def : Pat<(add4 GPRC:$RA, immUExt8neg:$L), (S4SUBQi GPRC:$RA, immUExt8neg:$L)>;
253def : Pat<(intop (add8 GPRC:$RA, immUExt8neg:$L)), (S8SUBLi GPRC:$RA, immUExt8neg:$L)>;
254def : Pat<(add8 GPRC:$RA, immUExt8neg:$L), (S8SUBQi GPRC:$RA, immUExt8neg:$L)>;
255
256multiclass log_inst<bits<6> opc, bits<7> fun, string asmstr, SDNode OpNode, InstrItinClass itin> {
257def r : OForm<opc, fun, !strconcat(asmstr, " $RA,$RB,$RC"),
258 [(set GPRC:$RC, (OpNode GPRC:$RA, GPRC:$RB))], itin>;
259def i : OFormL<opc, fun, !strconcat(asmstr, " $RA,$L,$RC"),
260 [(set GPRC:$RC, (OpNode GPRC:$RA, immUExt8:$L))], itin>;
261}
262multiclass inv_inst<bits<6> opc, bits<7> fun, string asmstr, SDNode OpNode, InstrItinClass itin> {
263def r : OForm<opc, fun, !strconcat(asmstr, " $RA,$RB,$RC"),
264 [(set GPRC:$RC, (OpNode GPRC:$RA, (not GPRC:$RB)))], itin>;
265def i : OFormL<opc, fun, !strconcat(asmstr, " $RA,$L,$RC"),
266 [(set GPRC:$RC, (OpNode GPRC:$RA, immUExt8inv:$L))], itin>;
267}
268
269defm AND : log_inst<0x11, 0x00, "and", and, s_ilog>;
270defm BIC : inv_inst<0x11, 0x08, "bic", and, s_ilog>;
271defm BIS : log_inst<0x11, 0x20, "bis", or, s_ilog>;
272defm ORNOT : inv_inst<0x11, 0x28, "ornot", or, s_ilog>;
273defm XOR : log_inst<0x11, 0x40, "xor", xor, s_ilog>;
274defm EQV : inv_inst<0x11, 0x48, "eqv", xor, s_ilog>;
275
276defm SL : log_inst<0x12, 0x39, "sll", shl, s_ishf>;
277defm SRA : log_inst<0x12, 0x3c, "sra", sra, s_ishf>;
278defm SRL : log_inst<0x12, 0x34, "srl", srl, s_ishf>;
279defm UMULH : log_inst<0x13, 0x30, "umulh", mulhu, s_imul>;
280
281def CTLZ : OForm2<0x1C, 0x32, "CTLZ $RB,$RC",
282 [(set GPRC:$RC, (ctlz GPRC:$RB))], s_imisc>;
283def CTPOP : OForm2<0x1C, 0x30, "CTPOP $RB,$RC",
284 [(set GPRC:$RC, (ctpop GPRC:$RB))], s_imisc>;
285def CTTZ : OForm2<0x1C, 0x33, "CTTZ $RB,$RC",
286 [(set GPRC:$RC, (cttz GPRC:$RB))], s_imisc>;
287def EXTBL : OForm< 0x12, 0x06, "EXTBL $RA,$RB,$RC",
288 [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 255))], s_ishf>;
289def EXTWL : OForm< 0x12, 0x16, "EXTWL $RA,$RB,$RC",
290 [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 65535))], s_ishf>;
291def EXTLL : OForm< 0x12, 0x26, "EXTLL $RA,$RB,$RC",
292 [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 4294967295))], s_ishf>;
293def SEXTB : OForm2<0x1C, 0x00, "sextb $RB,$RC",
294 [(set GPRC:$RC, (sext_inreg GPRC:$RB, i8))], s_ishf>;
295def SEXTW : OForm2<0x1C, 0x01, "sextw $RB,$RC",
296 [(set GPRC:$RC, (sext_inreg GPRC:$RB, i16))], s_ishf>;
297
298//def EXTBLi : OFormL<0x12, 0x06, "EXTBL $RA,$L,$RC", []>; //Extract byte low
299//def EXTLH : OForm< 0x12, 0x6A, "EXTLH $RA,$RB,$RC", []>; //Extract longword high
300//def EXTLHi : OFormL<0x12, 0x6A, "EXTLH $RA,$L,$RC", []>; //Extract longword high
301//def EXTLLi : OFormL<0x12, 0x26, "EXTLL $RA,$L,$RC", []>; //Extract longword low
302//def EXTQH : OForm< 0x12, 0x7A, "EXTQH $RA,$RB,$RC", []>; //Extract quadword high
303//def EXTQHi : OFormL<0x12, 0x7A, "EXTQH $RA,$L,$RC", []>; //Extract quadword high
304//def EXTQ : OForm< 0x12, 0x36, "EXTQ $RA,$RB,$RC", []>; //Extract quadword low
305//def EXTQi : OFormL<0x12, 0x36, "EXTQ $RA,$L,$RC", []>; //Extract quadword low
306//def EXTWH : OForm< 0x12, 0x5A, "EXTWH $RA,$RB,$RC", []>; //Extract word high
307//def EXTWHi : OFormL<0x12, 0x5A, "EXTWH $RA,$L,$RC", []>; //Extract word high
308//def EXTWLi : OFormL<0x12, 0x16, "EXTWL $RA,$L,$RC", []>; //Extract word low
309
310//def INSBL : OForm< 0x12, 0x0B, "INSBL $RA,$RB,$RC", []>; //Insert byte low
311//def INSBLi : OFormL<0x12, 0x0B, "INSBL $RA,$L,$RC", []>; //Insert byte low
312//def INSLH : OForm< 0x12, 0x67, "INSLH $RA,$RB,$RC", []>; //Insert longword high
313//def INSLHi : OFormL<0x12, 0x67, "INSLH $RA,$L,$RC", []>; //Insert longword high
314//def INSLL : OForm< 0x12, 0x2B, "INSLL $RA,$RB,$RC", []>; //Insert longword low
315//def INSLLi : OFormL<0x12, 0x2B, "INSLL $RA,$L,$RC", []>; //Insert longword low
316//def INSQH : OForm< 0x12, 0x77, "INSQH $RA,$RB,$RC", []>; //Insert quadword high
317//def INSQHi : OFormL<0x12, 0x77, "INSQH $RA,$L,$RC", []>; //Insert quadword high
318//def INSQL : OForm< 0x12, 0x3B, "INSQL $RA,$RB,$RC", []>; //Insert quadword low
319//def INSQLi : OFormL<0x12, 0x3B, "INSQL $RA,$L,$RC", []>; //Insert quadword low
320//def INSWH : OForm< 0x12, 0x57, "INSWH $RA,$RB,$RC", []>; //Insert word high
321//def INSWHi : OFormL<0x12, 0x57, "INSWH $RA,$L,$RC", []>; //Insert word high
322//def INSWL : OForm< 0x12, 0x1B, "INSWL $RA,$RB,$RC", []>; //Insert word low
323//def INSWLi : OFormL<0x12, 0x1B, "INSWL $RA,$L,$RC", []>; //Insert word low
324
325//def MSKBL : OForm< 0x12, 0x02, "MSKBL $RA,$RB,$RC", []>; //Mask byte low
326//def MSKBLi : OFormL<0x12, 0x02, "MSKBL $RA,$L,$RC", []>; //Mask byte low
327//def MSKLH : OForm< 0x12, 0x62, "MSKLH $RA,$RB,$RC", []>; //Mask longword high
328//def MSKLHi : OFormL<0x12, 0x62, "MSKLH $RA,$L,$RC", []>; //Mask longword high
329//def MSKLL : OForm< 0x12, 0x22, "MSKLL $RA,$RB,$RC", []>; //Mask longword low
330//def MSKLLi : OFormL<0x12, 0x22, "MSKLL $RA,$L,$RC", []>; //Mask longword low
331//def MSKQH : OForm< 0x12, 0x72, "MSKQH $RA,$RB,$RC", []>; //Mask quadword high
332//def MSKQHi : OFormL<0x12, 0x72, "MSKQH $RA,$L,$RC", []>; //Mask quadword high
333//def MSKQL : OForm< 0x12, 0x32, "MSKQL $RA,$RB,$RC", []>; //Mask quadword low
334//def MSKQLi : OFormL<0x12, 0x32, "MSKQL $RA,$L,$RC", []>; //Mask quadword low
335//def MSKWH : OForm< 0x12, 0x52, "MSKWH $RA,$RB,$RC", []>; //Mask word high
336//def MSKWHi : OFormL<0x12, 0x52, "MSKWH $RA,$L,$RC", []>; //Mask word high
337//def MSKWL : OForm< 0x12, 0x12, "MSKWL $RA,$RB,$RC", []>; //Mask word low
338//def MSKWLi : OFormL<0x12, 0x12, "MSKWL $RA,$L,$RC", []>; //Mask word low
339
340def ZAPNOTi : OFormL<0x12, 0x31, "zapnot $RA,$L,$RC", [], s_ishf>;
341
342// Define the pattern that produces ZAPNOTi.
343def : Pat<(i64 (zappat GPRC:$RA):$imm),
344 (ZAPNOTi GPRC:$RA, (iZAPX GPRC:$imm))>;
345
346
347//Comparison, int
348//So this is a waste of what this instruction can do, but it still saves something
349def CMPBGE : OForm< 0x10, 0x0F, "cmpbge $RA,$RB,$RC",
350 [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), (and GPRC:$RB, 255)))], s_ilog>;
351def CMPBGEi : OFormL<0x10, 0x0F, "cmpbge $RA,$L,$RC",
352 [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), immUExt8:$L))], s_ilog>;
353def CMPEQ : OForm< 0x10, 0x2D, "cmpeq $RA,$RB,$RC",
354 [(set GPRC:$RC, (seteq GPRC:$RA, GPRC:$RB))], s_iadd>;
355def CMPEQi : OFormL<0x10, 0x2D, "cmpeq $RA,$L,$RC",
356 [(set GPRC:$RC, (seteq GPRC:$RA, immUExt8:$L))], s_iadd>;
357def CMPLE : OForm< 0x10, 0x6D, "cmple $RA,$RB,$RC",
358 [(set GPRC:$RC, (setle GPRC:$RA, GPRC:$RB))], s_iadd>;
359def CMPLEi : OFormL<0x10, 0x6D, "cmple $RA,$L,$RC",
360 [(set GPRC:$RC, (setle GPRC:$RA, immUExt8:$L))], s_iadd>;
361def CMPLT : OForm< 0x10, 0x4D, "cmplt $RA,$RB,$RC",
362 [(set GPRC:$RC, (setlt GPRC:$RA, GPRC:$RB))], s_iadd>;
363def CMPLTi : OFormL<0x10, 0x4D, "cmplt $RA,$L,$RC",
364 [(set GPRC:$RC, (setlt GPRC:$RA, immUExt8:$L))], s_iadd>;
365def CMPULE : OForm< 0x10, 0x3D, "cmpule $RA,$RB,$RC",
366 [(set GPRC:$RC, (setule GPRC:$RA, GPRC:$RB))], s_iadd>;
367def CMPULEi : OFormL<0x10, 0x3D, "cmpule $RA,$L,$RC",
368 [(set GPRC:$RC, (setule GPRC:$RA, immUExt8:$L))], s_iadd>;
369def CMPULT : OForm< 0x10, 0x1D, "cmpult $RA,$RB,$RC",
370 [(set GPRC:$RC, (setult GPRC:$RA, GPRC:$RB))], s_iadd>;
371def CMPULTi : OFormL<0x10, 0x1D, "cmpult $RA,$L,$RC",
372 [(set GPRC:$RC, (setult GPRC:$RA, immUExt8:$L))], s_iadd>;
373
374//Patterns for unsupported int comparisons
375def : Pat<(setueq GPRC:$X, GPRC:$Y), (CMPEQ GPRC:$X, GPRC:$Y)>;
376def : Pat<(setueq GPRC:$X, immUExt8:$Y), (CMPEQi GPRC:$X, immUExt8:$Y)>;
377
378def : Pat<(setugt GPRC:$X, GPRC:$Y), (CMPULT GPRC:$Y, GPRC:$X)>;
379def : Pat<(setugt immUExt8:$X, GPRC:$Y), (CMPULTi GPRC:$Y, immUExt8:$X)>;
380
381def : Pat<(setuge GPRC:$X, GPRC:$Y), (CMPULE GPRC:$Y, GPRC:$X)>;
382def : Pat<(setuge immUExt8:$X, GPRC:$Y), (CMPULEi GPRC:$Y, immUExt8:$X)>;
383
384def : Pat<(setgt GPRC:$X, GPRC:$Y), (CMPLT GPRC:$Y, GPRC:$X)>;
385def : Pat<(setgt immUExt8:$X, GPRC:$Y), (CMPLTi GPRC:$Y, immUExt8:$X)>;
386
387def : Pat<(setge GPRC:$X, GPRC:$Y), (CMPLE GPRC:$Y, GPRC:$X)>;
388def : Pat<(setge immUExt8:$X, GPRC:$Y), (CMPLEi GPRC:$Y, immUExt8:$X)>;
389
390def : Pat<(setne GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>;
391def : Pat<(setne GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQi GPRC:$X, immUExt8:$Y), 0)>;
392
393def : Pat<(setune GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>;
394def : Pat<(setune GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQ GPRC:$X, immUExt8:$Y), 0)>;
395
396
Evan Cheng37e7c752007-07-21 00:34:19 +0000397let isReturn = 1, isTerminator = 1, Ra = 31, Rb = 26, disp = 1, Uses = [R26] in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000398 def RETDAG : MbrForm< 0x1A, 0x02, (ops), "ret $$31,($$26),1", s_jsr>; //Return from subroutine
399 def RETDAGp : MbrpForm< 0x1A, 0x02, (ops), "ret $$31,($$26),1", [(retflag)], s_jsr>; //Return from subroutine
400}
401
Owen Andersonf8053082007-11-12 07:39:39 +0000402let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1, Ra = 31, disp = 0 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000403def JMP : MbrpForm< 0x1A, 0x00, (ops GPRC:$RS), "jmp $$31,($RS),0",
404 [(brind GPRC:$RS)], s_jsr>; //Jump
405
Evan Cheng37e7c752007-07-21 00:34:19 +0000406let isCall = 1, Ra = 26,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000407 Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19,
408 R20, R21, R22, R23, R24, R25, R26, R27, R28, R29,
409 F0, F1,
410 F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
411 F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R29] in {
412 def BSR : BFormD<0x34, "bsr $$26,$$$DISP..ng", [], s_jsr>; //Branch to subroutine
413}
Evan Cheng37e7c752007-07-21 00:34:19 +0000414let isCall = 1, Ra = 26, Rb = 27, disp = 0,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000415 Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19,
416 R20, R21, R22, R23, R24, R25, R26, R27, R28, R29,
417 F0, F1,
418 F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
419 F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R27, R29] in {
420 def JSR : MbrForm< 0x1A, 0x01, (ops ), "jsr $$26,($$27),0", s_jsr>; //Jump to subroutine
421}
422
Evan Cheng37e7c752007-07-21 00:34:19 +0000423let isCall = 1, Ra = 23, Rb = 27, disp = 0,
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000424 Defs = [R23, R24, R25, R27, R28], Uses = [R24, R25, R27] in
425 def JSRs : MbrForm< 0x1A, 0x01, (ops ), "jsr $$23,($$27),0", s_jsr>; //Jump to div or rem
426
427
428def JSR_COROUTINE : MbrForm< 0x1A, 0x03, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr_coroutine $RD,($RS),$DISP", s_jsr>; //Jump to subroutine return
429
430
Evan Chengb783fa32007-07-19 01:14:50 +0000431let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
Chris Lattneref8d6082008-01-06 06:44:58 +0000432def LDQ : MForm<0x29, 1, "ldq $RA,$DISP($RB)",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000433 [(set GPRC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
Chris Lattneref8d6082008-01-06 06:44:58 +0000434def LDQr : MForm<0x29, 1, "ldq $RA,$DISP($RB)\t\t!gprellow",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000435 [(set GPRC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>;
Chris Lattneref8d6082008-01-06 06:44:58 +0000436def LDL : MForm<0x28, 1, "ldl $RA,$DISP($RB)",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000437 [(set GPRC:$RA, (sextloadi32 (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
Chris Lattneref8d6082008-01-06 06:44:58 +0000438def LDLr : MForm<0x28, 1, "ldl $RA,$DISP($RB)\t\t!gprellow",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000439 [(set GPRC:$RA, (sextloadi32 (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>;
Chris Lattneref8d6082008-01-06 06:44:58 +0000440def LDBU : MForm<0x0A, 1, "ldbu $RA,$DISP($RB)",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000441 [(set GPRC:$RA, (zextloadi8 (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
Chris Lattneref8d6082008-01-06 06:44:58 +0000442def LDBUr : MForm<0x0A, 1, "ldbu $RA,$DISP($RB)\t\t!gprellow",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000443 [(set GPRC:$RA, (zextloadi8 (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>;
Chris Lattneref8d6082008-01-06 06:44:58 +0000444def LDWU : MForm<0x0C, 1, "ldwu $RA,$DISP($RB)",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000445 [(set GPRC:$RA, (zextloadi16 (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
Chris Lattneref8d6082008-01-06 06:44:58 +0000446def LDWUr : MForm<0x0C, 1, "ldwu $RA,$DISP($RB)\t\t!gprellow",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000447 [(set GPRC:$RA, (zextloadi16 (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>;
Evan Chengb783fa32007-07-19 01:14:50 +0000448}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000449
450
Evan Chengb783fa32007-07-19 01:14:50 +0000451let OutOperandList = (ops), InOperandList = (ops GPRC:$RA, s64imm:$DISP, GPRC:$RB) in {
Chris Lattneref8d6082008-01-06 06:44:58 +0000452def STB : MForm<0x0E, 0, "stb $RA,$DISP($RB)",
Bill Wendling6c02cd22008-02-27 06:33:05 +0000453 [(truncstorei8 GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
Chris Lattneref8d6082008-01-06 06:44:58 +0000454def STBr : MForm<0x0E, 0, "stb $RA,$DISP($RB)\t\t!gprellow",
Bill Wendling6c02cd22008-02-27 06:33:05 +0000455 [(truncstorei8 GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
Chris Lattneref8d6082008-01-06 06:44:58 +0000456def STW : MForm<0x0D, 0, "stw $RA,$DISP($RB)",
Bill Wendling6c02cd22008-02-27 06:33:05 +0000457 [(truncstorei16 GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
Chris Lattneref8d6082008-01-06 06:44:58 +0000458def STWr : MForm<0x0D, 0, "stw $RA,$DISP($RB)\t\t!gprellow",
Bill Wendling6c02cd22008-02-27 06:33:05 +0000459 [(truncstorei16 GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
Chris Lattneref8d6082008-01-06 06:44:58 +0000460def STL : MForm<0x2C, 0, "stl $RA,$DISP($RB)",
Bill Wendling6c02cd22008-02-27 06:33:05 +0000461 [(truncstorei32 GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
Chris Lattneref8d6082008-01-06 06:44:58 +0000462def STLr : MForm<0x2C, 0, "stl $RA,$DISP($RB)\t\t!gprellow",
Bill Wendling6c02cd22008-02-27 06:33:05 +0000463 [(truncstorei32 GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
Chris Lattneref8d6082008-01-06 06:44:58 +0000464def STQ : MForm<0x2D, 0, "stq $RA,$DISP($RB)",
Bill Wendling6c02cd22008-02-27 06:33:05 +0000465 [(store GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
Chris Lattneref8d6082008-01-06 06:44:58 +0000466def STQr : MForm<0x2D, 0, "stq $RA,$DISP($RB)\t\t!gprellow",
Bill Wendling6c02cd22008-02-27 06:33:05 +0000467 [(store GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
Evan Chengb783fa32007-07-19 01:14:50 +0000468}
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000469
470//Load address
Evan Chengb783fa32007-07-19 01:14:50 +0000471let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
Chris Lattneref8d6082008-01-06 06:44:58 +0000472def LDA : MForm<0x08, 0, "lda $RA,$DISP($RB)",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000473 [(set GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_lda>;
Chris Lattneref8d6082008-01-06 06:44:58 +0000474def LDAr : MForm<0x08, 0, "lda $RA,$DISP($RB)\t\t!gprellow",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000475 [(set GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_lda>; //Load address
Chris Lattneref8d6082008-01-06 06:44:58 +0000476def LDAH : MForm<0x09, 0, "ldah $RA,$DISP($RB)",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000477 [], s_lda>; //Load address high
Chris Lattneref8d6082008-01-06 06:44:58 +0000478def LDAHr : MForm<0x09, 0, "ldah $RA,$DISP($RB)\t\t!gprelhigh",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000479 [(set GPRC:$RA, (Alpha_gprelhi tglobaladdr:$DISP, GPRC:$RB))], s_lda>; //Load address high
480}
481
Evan Chengb783fa32007-07-19 01:14:50 +0000482let OutOperandList = (ops), InOperandList = (ops F4RC:$RA, s64imm:$DISP, GPRC:$RB) in {
Chris Lattneref8d6082008-01-06 06:44:58 +0000483def STS : MForm<0x26, 0, "sts $RA,$DISP($RB)",
Bill Wendling6c02cd22008-02-27 06:33:05 +0000484 [(store F4RC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_fst>;
Chris Lattneref8d6082008-01-06 06:44:58 +0000485def STSr : MForm<0x26, 0, "sts $RA,$DISP($RB)\t\t!gprellow",
Bill Wendling6c02cd22008-02-27 06:33:05 +0000486 [(store F4RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_fst>;
Evan Chengb783fa32007-07-19 01:14:50 +0000487}
488let OutOperandList = (ops F4RC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
Chris Lattneref8d6082008-01-06 06:44:58 +0000489def LDS : MForm<0x22, 1, "lds $RA,$DISP($RB)",
Bill Wendling6c02cd22008-02-27 06:33:05 +0000490 [(set F4RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_fld>;
Chris Lattneref8d6082008-01-06 06:44:58 +0000491def LDSr : MForm<0x22, 1, "lds $RA,$DISP($RB)\t\t!gprellow",
Bill Wendling6c02cd22008-02-27 06:33:05 +0000492 [(set F4RC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_fld>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000493}
Evan Chengb783fa32007-07-19 01:14:50 +0000494let OutOperandList = (ops), InOperandList = (ops F8RC:$RA, s64imm:$DISP, GPRC:$RB) in {
Chris Lattneref8d6082008-01-06 06:44:58 +0000495def STT : MForm<0x27, 0, "stt $RA,$DISP($RB)",
Bill Wendling6c02cd22008-02-27 06:33:05 +0000496 [(store F8RC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_fst>;
Chris Lattneref8d6082008-01-06 06:44:58 +0000497def STTr : MForm<0x27, 0, "stt $RA,$DISP($RB)\t\t!gprellow",
Bill Wendling6c02cd22008-02-27 06:33:05 +0000498 [(store F8RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_fst>;
Evan Chengb783fa32007-07-19 01:14:50 +0000499}
500let OutOperandList = (ops F8RC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
Chris Lattneref8d6082008-01-06 06:44:58 +0000501def LDT : MForm<0x23, 1, "ldt $RA,$DISP($RB)",
Bill Wendling6c02cd22008-02-27 06:33:05 +0000502 [(set F8RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_fld>;
Chris Lattneref8d6082008-01-06 06:44:58 +0000503def LDTr : MForm<0x23, 1, "ldt $RA,$DISP($RB)\t\t!gprellow",
Bill Wendling6c02cd22008-02-27 06:33:05 +0000504 [(set F8RC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_fld>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000505}
506
507
508//constpool rels
509def : Pat<(i64 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
510 (LDQr tconstpool:$DISP, GPRC:$RB)>;
511def : Pat<(i64 (sextloadi32 (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
512 (LDLr tconstpool:$DISP, GPRC:$RB)>;
513def : Pat<(i64 (zextloadi8 (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
514 (LDBUr tconstpool:$DISP, GPRC:$RB)>;
515def : Pat<(i64 (zextloadi16 (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
516 (LDWUr tconstpool:$DISP, GPRC:$RB)>;
517def : Pat<(i64 (Alpha_gprello tconstpool:$DISP, GPRC:$RB)),
518 (LDAr tconstpool:$DISP, GPRC:$RB)>;
519def : Pat<(i64 (Alpha_gprelhi tconstpool:$DISP, GPRC:$RB)),
520 (LDAHr tconstpool:$DISP, GPRC:$RB)>;
521def : Pat<(f32 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
522 (LDSr tconstpool:$DISP, GPRC:$RB)>;
523def : Pat<(f64 (load (Alpha_gprello tconstpool:$DISP, GPRC:$RB))),
524 (LDTr tconstpool:$DISP, GPRC:$RB)>;
525
526//jumptable rels
527def : Pat<(i64 (Alpha_gprelhi tjumptable:$DISP, GPRC:$RB)),
528 (LDAHr tjumptable:$DISP, GPRC:$RB)>;
529def : Pat<(i64 (Alpha_gprello tjumptable:$DISP, GPRC:$RB)),
530 (LDAr tjumptable:$DISP, GPRC:$RB)>;
531
532
533//misc ext patterns
534def : Pat<(i64 (extloadi8 (add GPRC:$RB, immSExt16:$DISP))),
535 (LDBU immSExt16:$DISP, GPRC:$RB)>;
536def : Pat<(i64 (extloadi16 (add GPRC:$RB, immSExt16:$DISP))),
537 (LDWU immSExt16:$DISP, GPRC:$RB)>;
538def : Pat<(i64 (extloadi32 (add GPRC:$RB, immSExt16:$DISP))),
539 (LDL immSExt16:$DISP, GPRC:$RB)>;
540
541//0 disp patterns
542def : Pat<(i64 (load GPRC:$addr)),
543 (LDQ 0, GPRC:$addr)>;
544def : Pat<(f64 (load GPRC:$addr)),
545 (LDT 0, GPRC:$addr)>;
546def : Pat<(f32 (load GPRC:$addr)),
547 (LDS 0, GPRC:$addr)>;
548def : Pat<(i64 (sextloadi32 GPRC:$addr)),
549 (LDL 0, GPRC:$addr)>;
550def : Pat<(i64 (zextloadi16 GPRC:$addr)),
551 (LDWU 0, GPRC:$addr)>;
552def : Pat<(i64 (zextloadi8 GPRC:$addr)),
553 (LDBU 0, GPRC:$addr)>;
554def : Pat<(i64 (extloadi8 GPRC:$addr)),
555 (LDBU 0, GPRC:$addr)>;
556def : Pat<(i64 (extloadi16 GPRC:$addr)),
557 (LDWU 0, GPRC:$addr)>;
558def : Pat<(i64 (extloadi32 GPRC:$addr)),
559 (LDL 0, GPRC:$addr)>;
560
561def : Pat<(store GPRC:$DATA, GPRC:$addr),
562 (STQ GPRC:$DATA, 0, GPRC:$addr)>;
563def : Pat<(store F8RC:$DATA, GPRC:$addr),
564 (STT F8RC:$DATA, 0, GPRC:$addr)>;
565def : Pat<(store F4RC:$DATA, GPRC:$addr),
566 (STS F4RC:$DATA, 0, GPRC:$addr)>;
567def : Pat<(truncstorei32 GPRC:$DATA, GPRC:$addr),
568 (STL GPRC:$DATA, 0, GPRC:$addr)>;
569def : Pat<(truncstorei16 GPRC:$DATA, GPRC:$addr),
570 (STW GPRC:$DATA, 0, GPRC:$addr)>;
571def : Pat<(truncstorei8 GPRC:$DATA, GPRC:$addr),
572 (STB GPRC:$DATA, 0, GPRC:$addr)>;
573
574
575//load address, rellocated gpdist form
Evan Chengb783fa32007-07-19 01:14:50 +0000576let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s16imm:$DISP, GPRC:$RB, s16imm:$NUM) in {
Chris Lattneref8d6082008-01-06 06:44:58 +0000577def LDAg : MForm<0x08, 1, "lda $RA,0($RB)\t\t!gpdisp!$NUM", [], s_lda>; //Load address
578def LDAHg : MForm<0x09, 1, "ldah $RA,0($RB)\t\t!gpdisp!$NUM", [], s_lda>; //Load address
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000579}
580
581//Load quad, rellocated literal form
Evan Chengb783fa32007-07-19 01:14:50 +0000582let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in
Chris Lattneref8d6082008-01-06 06:44:58 +0000583def LDQl : MForm<0x29, 1, "ldq $RA,$DISP($RB)\t\t!literal",
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000584 [(set GPRC:$RA, (Alpha_rellit tglobaladdr:$DISP, GPRC:$RB))], s_ild>;
585def : Pat<(Alpha_rellit texternalsym:$ext, GPRC:$RB),
586 (LDQl texternalsym:$ext, GPRC:$RB)>;
587
Andrew Lenharthe44f3902008-02-21 06:45:13 +0000588let OutOperandList = (outs GPRC:$RR),
589 InOperandList = (ins GPRC:$RA, s64imm:$DISP, GPRC:$RB),
590 Constraints = "$RA = $RR",
591 DisableEncoding = "$RR" in {
592def STQ_C : MForm<0x2F, 0, "stq_l $RA,$DISP($RB)", [], s_ist>;
593def STL_C : MForm<0x2E, 0, "stl_l $RA,$DISP($RB)", [], s_ist>;
594}
595let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
596def LDQ_L : MForm<0x2B, 1, "ldq_l $RA,$DISP($RB)", [], s_ild>;
597def LDL_L : MForm<0x2A, 1, "ldl_l $RA,$DISP($RB)", [], s_ild>;
598}
599
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000600def RPCC : MfcForm<0x18, 0xC000, "rpcc $RA", s_rpcc>; //Read process cycle counter
Andrew Lenharth785610d2008-02-16 01:24:58 +0000601def MB : MfcPForm<0x18, 0x4000, "mb", s_imisc>; //memory barrier
602def WMB : MfcPForm<0x18, 0x4400, "wmb", s_imisc>; //write memory barrier
603
604def : Pat<(membarrier (i64 imm:$ll), (i64 imm:$ls), (i64 imm:$sl), (i64 1), (i64 imm:$dev)),
605 (WMB)>;
606def : Pat<(membarrier (i64 imm:$ll), (i64 imm:$ls), (i64 imm:$sl), (i64 imm:$ss), (i64 imm:$dev)),
607 (MB)>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000608
609//Basic Floating point ops
610
611//Floats
612
Evan Chengb783fa32007-07-19 01:14:50 +0000613let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F4RC:$RB), Fa = 31 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000614def SQRTS : FPForm<0x14, 0x58B, "sqrts/su $RB,$RC",
615 [(set F4RC:$RC, (fsqrt F4RC:$RB))], s_fsqrts>;
616
Evan Chengb783fa32007-07-19 01:14:50 +0000617let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F4RC:$RA, F4RC:$RB) in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000618def ADDS : FPForm<0x16, 0x580, "adds/su $RA,$RB,$RC",
619 [(set F4RC:$RC, (fadd F4RC:$RA, F4RC:$RB))], s_fadd>;
620def SUBS : FPForm<0x16, 0x581, "subs/su $RA,$RB,$RC",
621 [(set F4RC:$RC, (fsub F4RC:$RA, F4RC:$RB))], s_fadd>;
622def DIVS : FPForm<0x16, 0x583, "divs/su $RA,$RB,$RC",
623 [(set F4RC:$RC, (fdiv F4RC:$RA, F4RC:$RB))], s_fdivs>;
624def MULS : FPForm<0x16, 0x582, "muls/su $RA,$RB,$RC",
625 [(set F4RC:$RC, (fmul F4RC:$RA, F4RC:$RB))], s_fmul>;
626
627def CPYSS : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
628 [(set F4RC:$RC, (fcopysign F4RC:$RB, F4RC:$RA))], s_fadd>;
629def CPYSES : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent
630def CPYSNS : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
631 [(set F4RC:$RC, (fneg (fcopysign F4RC:$RB, F4RC:$RA)))], s_fadd>;
632}
633
634//Doubles
635
Evan Chengb783fa32007-07-19 01:14:50 +0000636let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000637def SQRTT : FPForm<0x14, 0x5AB, "sqrtt/su $RB,$RC",
638 [(set F8RC:$RC, (fsqrt F8RC:$RB))], s_fsqrtt>;
639
Evan Chengb783fa32007-07-19 01:14:50 +0000640let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F8RC:$RA, F8RC:$RB) in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000641def ADDT : FPForm<0x16, 0x5A0, "addt/su $RA,$RB,$RC",
642 [(set F8RC:$RC, (fadd F8RC:$RA, F8RC:$RB))], s_fadd>;
643def SUBT : FPForm<0x16, 0x5A1, "subt/su $RA,$RB,$RC",
644 [(set F8RC:$RC, (fsub F8RC:$RA, F8RC:$RB))], s_fadd>;
645def DIVT : FPForm<0x16, 0x5A3, "divt/su $RA,$RB,$RC",
646 [(set F8RC:$RC, (fdiv F8RC:$RA, F8RC:$RB))], s_fdivt>;
647def MULT : FPForm<0x16, 0x5A2, "mult/su $RA,$RB,$RC",
648 [(set F8RC:$RC, (fmul F8RC:$RA, F8RC:$RB))], s_fmul>;
649
650def CPYST : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
651 [(set F8RC:$RC, (fcopysign F8RC:$RB, F8RC:$RA))], s_fadd>;
652def CPYSET : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent
653def CPYSNT : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
654 [(set F8RC:$RC, (fneg (fcopysign F8RC:$RB, F8RC:$RA)))], s_fadd>;
655
656def CMPTEQ : FPForm<0x16, 0x5A5, "cmpteq/su $RA,$RB,$RC", [], s_fadd>;
657// [(set F8RC:$RC, (seteq F8RC:$RA, F8RC:$RB))]>;
658def CMPTLE : FPForm<0x16, 0x5A7, "cmptle/su $RA,$RB,$RC", [], s_fadd>;
659// [(set F8RC:$RC, (setle F8RC:$RA, F8RC:$RB))]>;
660def CMPTLT : FPForm<0x16, 0x5A6, "cmptlt/su $RA,$RB,$RC", [], s_fadd>;
661// [(set F8RC:$RC, (setlt F8RC:$RA, F8RC:$RB))]>;
662def CMPTUN : FPForm<0x16, 0x5A4, "cmptun/su $RA,$RB,$RC", [], s_fadd>;
663// [(set F8RC:$RC, (setuo F8RC:$RA, F8RC:$RB))]>;
664}
665
666//More CPYS forms:
Evan Chengb783fa32007-07-19 01:14:50 +0000667let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F4RC:$RA, F8RC:$RB) in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000668def CPYSTs : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
669 [(set F8RC:$RC, (fcopysign F8RC:$RB, F4RC:$RA))], s_fadd>;
670def CPYSNTs : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
671 [(set F8RC:$RC, (fneg (fcopysign F8RC:$RB, F4RC:$RA)))], s_fadd>;
672}
Evan Chengb783fa32007-07-19 01:14:50 +0000673let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F8RC:$RA, F4RC:$RB) in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000674def CPYSSt : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
675 [(set F4RC:$RC, (fcopysign F4RC:$RB, F8RC:$RA))], s_fadd>;
676def CPYSESt : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent
677def CPYSNSt : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
678 [(set F4RC:$RC, (fneg (fcopysign F4RC:$RB, F8RC:$RA)))], s_fadd>;
679}
680
681//conditional moves, floats
Evan Chengb783fa32007-07-19 01:14:50 +0000682let OutOperandList = (ops F4RC:$RDEST), InOperandList = (ops F4RC:$RFALSE, F4RC:$RTRUE, F8RC:$RCOND),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000683 isTwoAddress = 1 in {
684def FCMOVEQS : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if = zero
685def FCMOVGES : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if >= zero
686def FCMOVGTS : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if > zero
687def FCMOVLES : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if <= zero
688def FCMOVLTS : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST",[], s_fcmov>; // FCMOVE if < zero
689def FCMOVNES : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if != zero
690}
691//conditional moves, doubles
Evan Chengb783fa32007-07-19 01:14:50 +0000692let OutOperandList = (ops F8RC:$RDEST), InOperandList = (ops F8RC:$RFALSE, F8RC:$RTRUE, F8RC:$RCOND),
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000693 isTwoAddress = 1 in {
694def FCMOVEQT : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
695def FCMOVGET : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
696def FCMOVGTT : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
697def FCMOVLET : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
698def FCMOVLTT : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
699def FCMOVNET : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
700}
701
702//misc FP selects
703//Select double
704
705def : Pat<(select (seteq F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
706 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
707def : Pat<(select (setoeq F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
708 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
709def : Pat<(select (setueq F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
710 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
711
712def : Pat<(select (setne F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
713 (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
714def : Pat<(select (setone F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
715 (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
716def : Pat<(select (setune F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
717 (FCMOVEQT F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
718
719def : Pat<(select (setgt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
720 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
721def : Pat<(select (setogt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
722 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
723def : Pat<(select (setugt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
724 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
725
726def : Pat<(select (setge F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
727 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
728def : Pat<(select (setoge F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
729 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
730def : Pat<(select (setuge F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
731 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
732
733def : Pat<(select (setlt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
734 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
735def : Pat<(select (setolt F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
736 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
737def : Pat<(select (setult F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
738 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
739
740def : Pat<(select (setle F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
741 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
742def : Pat<(select (setole F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
743 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
744def : Pat<(select (setule F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf),
745 (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
746
747//Select single
748def : Pat<(select (seteq F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
749 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
750def : Pat<(select (setoeq F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
751 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
752def : Pat<(select (setueq F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
753 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
754
755def : Pat<(select (setne F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
756 (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
757def : Pat<(select (setone F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
758 (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
759def : Pat<(select (setune F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
760 (FCMOVEQS F4RC:$sf, F4RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>;
761
762def : Pat<(select (setgt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
763 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
764def : Pat<(select (setogt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
765 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
766def : Pat<(select (setugt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
767 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RB, F8RC:$RA))>;
768
769def : Pat<(select (setge F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
770 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
771def : Pat<(select (setoge F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
772 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
773def : Pat<(select (setuge F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
774 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RB, F8RC:$RA))>;
775
776def : Pat<(select (setlt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
777 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
778def : Pat<(select (setolt F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
779 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
780def : Pat<(select (setult F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
781 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLT F8RC:$RA, F8RC:$RB))>;
782
783def : Pat<(select (setle F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
784 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
785def : Pat<(select (setole F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
786 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
787def : Pat<(select (setule F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
788 (FCMOVNES F4RC:$sf, F4RC:$st, (CMPTLE F8RC:$RA, F8RC:$RB))>;
789
790
791
Evan Chengb783fa32007-07-19 01:14:50 +0000792let OutOperandList = (ops GPRC:$RC), InOperandList = (ops F4RC:$RA), Fb = 31 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000793def FTOIS : FPForm<0x1C, 0x078, "ftois $RA,$RC",[], s_ftoi>; //Floating to integer move, S_floating
Evan Chengb783fa32007-07-19 01:14:50 +0000794let OutOperandList = (ops GPRC:$RC), InOperandList = (ops F8RC:$RA), Fb = 31 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000795def FTOIT : FPForm<0x1C, 0x070, "ftoit $RA,$RC",
796 [(set GPRC:$RC, (bitconvert F8RC:$RA))], s_ftoi>; //Floating to integer move
Evan Chengb783fa32007-07-19 01:14:50 +0000797let OutOperandList = (ops F4RC:$RC), InOperandList = (ops GPRC:$RA), Fb = 31 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000798def ITOFS : FPForm<0x14, 0x004, "itofs $RA,$RC",[], s_itof>; //Integer to floating move, S_floating
Evan Chengb783fa32007-07-19 01:14:50 +0000799let OutOperandList = (ops F8RC:$RC), InOperandList = (ops GPRC:$RA), Fb = 31 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000800def ITOFT : FPForm<0x14, 0x024, "itoft $RA,$RC",
801 [(set F8RC:$RC, (bitconvert GPRC:$RA))], s_itof>; //Integer to floating move
802
803
Evan Chengb783fa32007-07-19 01:14:50 +0000804let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000805def CVTQS : FPForm<0x16, 0x7BC, "cvtqs/sui $RB,$RC",
806 [(set F4RC:$RC, (Alpha_cvtqs F8RC:$RB))], s_fadd>;
Evan Chengb783fa32007-07-19 01:14:50 +0000807let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000808def CVTQT : FPForm<0x16, 0x7BE, "cvtqt/sui $RB,$RC",
809 [(set F8RC:$RC, (Alpha_cvtqt F8RC:$RB))], s_fadd>;
Evan Chengb783fa32007-07-19 01:14:50 +0000810let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000811def CVTTQ : FPForm<0x16, 0x52F, "cvttq/svc $RB,$RC",
812 [(set F8RC:$RC, (Alpha_cvttq F8RC:$RB))], s_fadd>;
Evan Chengb783fa32007-07-19 01:14:50 +0000813let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F4RC:$RB), Fa = 31 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000814def CVTST : FPForm<0x16, 0x6AC, "cvtst/s $RB,$RC",
815 [(set F8RC:$RC, (fextend F4RC:$RB))], s_fadd>;
Evan Chengb783fa32007-07-19 01:14:50 +0000816let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000817def CVTTS : FPForm<0x16, 0x7AC, "cvtts/sui $RB,$RC",
818 [(set F4RC:$RC, (fround F8RC:$RB))], s_fadd>;
819
820
821/////////////////////////////////////////////////////////
822//Branching
823/////////////////////////////////////////////////////////
824class br_icc<bits<6> opc, string asmstr>
825 : BFormN<opc, (ops u64imm:$opc, GPRC:$R, target:$dst),
826 !strconcat(asmstr, " $R,$dst"), s_icbr>;
827class br_fcc<bits<6> opc, string asmstr>
828 : BFormN<opc, (ops u64imm:$opc, F8RC:$R, target:$dst),
829 !strconcat(asmstr, " $R,$dst"), s_fbr>;
830
Evan Cheng37e7c752007-07-21 00:34:19 +0000831let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000832let Ra = 31 in
833def BR : BFormD<0x30, "br $$31,$DISP", [(br bb:$DISP)], s_ubr>;
834
835def COND_BRANCH_I : BFormN<0, (ops u64imm:$opc, GPRC:$R, target:$dst),
836 "{:comment} COND_BRANCH imm:$opc, GPRC:$R, bb:$dst",
837 s_icbr>;
838def COND_BRANCH_F : BFormN<0, (ops u64imm:$opc, F8RC:$R, target:$dst),
839 "{:comment} COND_BRANCH imm:$opc, F8RC:$R, bb:$dst",
840 s_fbr>;
841//Branches, int
842def BEQ : br_icc<0x39, "beq">;
843def BGE : br_icc<0x3E, "bge">;
844def BGT : br_icc<0x3F, "bgt">;
845def BLBC : br_icc<0x38, "blbc">;
846def BLBS : br_icc<0x3C, "blbs">;
847def BLE : br_icc<0x3B, "ble">;
848def BLT : br_icc<0x3A, "blt">;
849def BNE : br_icc<0x3D, "bne">;
850
851//Branches, float
852def FBEQ : br_fcc<0x31, "fbeq">;
853def FBGE : br_fcc<0x36, "fbge">;
854def FBGT : br_fcc<0x37, "fbgt">;
855def FBLE : br_fcc<0x33, "fble">;
856def FBLT : br_fcc<0x32, "fblt">;
857def FBNE : br_fcc<0x36, "fbne">;
858}
859
860//An ugly trick to get the opcode as an imm I can use
861def immBRCond : SDNodeXForm<imm, [{
862 switch((uint64_t)N->getValue()) {
863 case 0: return getI64Imm(Alpha::BEQ);
864 case 1: return getI64Imm(Alpha::BNE);
865 case 2: return getI64Imm(Alpha::BGE);
866 case 3: return getI64Imm(Alpha::BGT);
867 case 4: return getI64Imm(Alpha::BLE);
868 case 5: return getI64Imm(Alpha::BLT);
869 case 6: return getI64Imm(Alpha::BLBS);
870 case 7: return getI64Imm(Alpha::BLBC);
871 case 20: return getI64Imm(Alpha::FBEQ);
872 case 21: return getI64Imm(Alpha::FBNE);
873 case 22: return getI64Imm(Alpha::FBGE);
874 case 23: return getI64Imm(Alpha::FBGT);
875 case 24: return getI64Imm(Alpha::FBLE);
876 case 25: return getI64Imm(Alpha::FBLT);
877 default: assert(0 && "Unknown branch type");
878 }
879}]>;
880
881//Int cond patterns
882def : Pat<(brcond (seteq GPRC:$RA, 0), bb:$DISP),
883 (COND_BRANCH_I (immBRCond 0), GPRC:$RA, bb:$DISP)>;
884def : Pat<(brcond (setge GPRC:$RA, 0), bb:$DISP),
885 (COND_BRANCH_I (immBRCond 2), GPRC:$RA, bb:$DISP)>;
886def : Pat<(brcond (setgt GPRC:$RA, 0), bb:$DISP),
887 (COND_BRANCH_I (immBRCond 3), GPRC:$RA, bb:$DISP)>;
888def : Pat<(brcond (and GPRC:$RA, 1), bb:$DISP),
889 (COND_BRANCH_I (immBRCond 6), GPRC:$RA, bb:$DISP)>;
890def : Pat<(brcond (setle GPRC:$RA, 0), bb:$DISP),
891 (COND_BRANCH_I (immBRCond 4), GPRC:$RA, bb:$DISP)>;
892def : Pat<(brcond (setlt GPRC:$RA, 0), bb:$DISP),
893 (COND_BRANCH_I (immBRCond 5), GPRC:$RA, bb:$DISP)>;
894def : Pat<(brcond (setne GPRC:$RA, 0), bb:$DISP),
895 (COND_BRANCH_I (immBRCond 1), GPRC:$RA, bb:$DISP)>;
896
897def : Pat<(brcond GPRC:$RA, bb:$DISP),
898 (COND_BRANCH_I (immBRCond 1), GPRC:$RA, bb:$DISP)>;
899def : Pat<(brcond (setne GPRC:$RA, GPRC:$RB), bb:$DISP),
900 (COND_BRANCH_I (immBRCond 0), (CMPEQ GPRC:$RA, GPRC:$RB), bb:$DISP)>;
901def : Pat<(brcond (setne GPRC:$RA, immUExt8:$L), bb:$DISP),
902 (COND_BRANCH_I (immBRCond 0), (CMPEQi GPRC:$RA, immUExt8:$L), bb:$DISP)>;
903
904//FP cond patterns
905def : Pat<(brcond (seteq F8RC:$RA, immFPZ), bb:$DISP),
906 (COND_BRANCH_F (immBRCond 20), F8RC:$RA, bb:$DISP)>;
907def : Pat<(brcond (setne F8RC:$RA, immFPZ), bb:$DISP),
908 (COND_BRANCH_F (immBRCond 21), F8RC:$RA, bb:$DISP)>;
909def : Pat<(brcond (setge F8RC:$RA, immFPZ), bb:$DISP),
910 (COND_BRANCH_F (immBRCond 22), F8RC:$RA, bb:$DISP)>;
911def : Pat<(brcond (setgt F8RC:$RA, immFPZ), bb:$DISP),
912 (COND_BRANCH_F (immBRCond 23), F8RC:$RA, bb:$DISP)>;
913def : Pat<(brcond (setle F8RC:$RA, immFPZ), bb:$DISP),
914 (COND_BRANCH_F (immBRCond 24), F8RC:$RA, bb:$DISP)>;
915def : Pat<(brcond (setlt F8RC:$RA, immFPZ), bb:$DISP),
916 (COND_BRANCH_F (immBRCond 25), F8RC:$RA, bb:$DISP)>;
917
918
919def : Pat<(brcond (seteq F8RC:$RA, F8RC:$RB), bb:$DISP),
920 (COND_BRANCH_F (immBRCond 21), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
921def : Pat<(brcond (setoeq F8RC:$RA, F8RC:$RB), bb:$DISP),
922 (COND_BRANCH_F (immBRCond 21), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
923def : Pat<(brcond (setueq F8RC:$RA, F8RC:$RB), bb:$DISP),
924 (COND_BRANCH_F (immBRCond 21), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
925
926def : Pat<(brcond (setlt F8RC:$RA, F8RC:$RB), bb:$DISP),
927 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
928def : Pat<(brcond (setolt F8RC:$RA, F8RC:$RB), bb:$DISP),
929 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
930def : Pat<(brcond (setult F8RC:$RA, F8RC:$RB), bb:$DISP),
931 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RA, F8RC:$RB), bb:$DISP)>;
932
933def : Pat<(brcond (setle F8RC:$RA, F8RC:$RB), bb:$DISP),
934 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
935def : Pat<(brcond (setole F8RC:$RA, F8RC:$RB), bb:$DISP),
936 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
937def : Pat<(brcond (setule F8RC:$RA, F8RC:$RB), bb:$DISP),
938 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RA, F8RC:$RB), bb:$DISP)>;
939
940def : Pat<(brcond (setgt F8RC:$RA, F8RC:$RB), bb:$DISP),
941 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
942def : Pat<(brcond (setogt F8RC:$RA, F8RC:$RB), bb:$DISP),
943 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
944def : Pat<(brcond (setugt F8RC:$RA, F8RC:$RB), bb:$DISP),
945 (COND_BRANCH_F (immBRCond 21), (CMPTLT F8RC:$RB, F8RC:$RA), bb:$DISP)>;
946
947def : Pat<(brcond (setge F8RC:$RA, F8RC:$RB), bb:$DISP),
948 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
949def : Pat<(brcond (setoge F8RC:$RA, F8RC:$RB), bb:$DISP),
950 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
951def : Pat<(brcond (setuge F8RC:$RA, F8RC:$RB), bb:$DISP),
952 (COND_BRANCH_F (immBRCond 21), (CMPTLE F8RC:$RB, F8RC:$RA), bb:$DISP)>;
953
954def : Pat<(brcond (setne F8RC:$RA, F8RC:$RB), bb:$DISP),
955 (COND_BRANCH_F (immBRCond 20), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
956def : Pat<(brcond (setone F8RC:$RA, F8RC:$RB), bb:$DISP),
957 (COND_BRANCH_F (immBRCond 20), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
958def : Pat<(brcond (setune F8RC:$RA, F8RC:$RB), bb:$DISP),
959 (COND_BRANCH_F (immBRCond 20), (CMPTEQ F8RC:$RA, F8RC:$RB), bb:$DISP)>;
960
961
962def : Pat<(brcond (setoeq F8RC:$RA, immFPZ), bb:$DISP),
963 (COND_BRANCH_F (immBRCond 20), F8RC:$RA,bb:$DISP)>;
964def : Pat<(brcond (setueq F8RC:$RA, immFPZ), bb:$DISP),
965 (COND_BRANCH_F (immBRCond 20), F8RC:$RA,bb:$DISP)>;
966
967def : Pat<(brcond (setoge F8RC:$RA, immFPZ), bb:$DISP),
968 (COND_BRANCH_F (immBRCond 22), F8RC:$RA,bb:$DISP)>;
969def : Pat<(brcond (setuge F8RC:$RA, immFPZ), bb:$DISP),
970 (COND_BRANCH_F (immBRCond 22), F8RC:$RA,bb:$DISP)>;
971
972def : Pat<(brcond (setogt F8RC:$RA, immFPZ), bb:$DISP),
973 (COND_BRANCH_F (immBRCond 23), F8RC:$RA,bb:$DISP)>;
974def : Pat<(brcond (setugt F8RC:$RA, immFPZ), bb:$DISP),
975 (COND_BRANCH_F (immBRCond 23), F8RC:$RA,bb:$DISP)>;
976
977def : Pat<(brcond (setole F8RC:$RA, immFPZ), bb:$DISP),
978 (COND_BRANCH_F (immBRCond 24), F8RC:$RA,bb:$DISP)>;
979def : Pat<(brcond (setule F8RC:$RA, immFPZ), bb:$DISP),
980 (COND_BRANCH_F (immBRCond 24), F8RC:$RA,bb:$DISP)>;
981
982def : Pat<(brcond (setolt F8RC:$RA, immFPZ), bb:$DISP),
983 (COND_BRANCH_F (immBRCond 25), F8RC:$RA,bb:$DISP)>;
984def : Pat<(brcond (setult F8RC:$RA, immFPZ), bb:$DISP),
985 (COND_BRANCH_F (immBRCond 25), F8RC:$RA,bb:$DISP)>;
986
987def : Pat<(brcond (setone F8RC:$RA, immFPZ), bb:$DISP),
988 (COND_BRANCH_F (immBRCond 21), F8RC:$RA,bb:$DISP)>;
989def : Pat<(brcond (setune F8RC:$RA, immFPZ), bb:$DISP),
990 (COND_BRANCH_F (immBRCond 21), F8RC:$RA,bb:$DISP)>;
991
992//End Branches
993
994//S_floating : IEEE Single
995//T_floating : IEEE Double
996
997//Unused instructions
998//Mnemonic Format Opcode Description
999//CALL_PAL Pcd 00 Trap to PALcode
1000//ECB Mfc 18.E800 Evict cache block
1001//EXCB Mfc 18.0400 Exception barrier
1002//FETCH Mfc 18.8000 Prefetch data
1003//FETCH_M Mfc 18.A000 Prefetch data, modify intent
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001004//LDQ_U Mem 0B Load unaligned quadword
1005//MB Mfc 18.4000 Memory barrier
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001006//STQ_U Mem 0F Store unaligned quadword
1007//TRAPB Mfc 18.0000 Trap barrier
1008//WH64 Mfc 18.F800 Write hint  64 bytes
1009//WMB Mfc 18.4400 Write memory barrier
1010//MF_FPCR F-P 17.025 Move from FPCR
1011//MT_FPCR F-P 17.024 Move to FPCR
1012//There are in the Multimedia extentions, so let's not use them yet
1013//def MAXSB8 : OForm<0x1C, 0x3E, "MAXSB8 $RA,$RB,$RC">; //Vector signed byte maximum
1014//def MAXSW4 : OForm< 0x1C, 0x3F, "MAXSW4 $RA,$RB,$RC">; //Vector signed word maximum
1015//def MAXUB8 : OForm<0x1C, 0x3C, "MAXUB8 $RA,$RB,$RC">; //Vector unsigned byte maximum
1016//def MAXUW4 : OForm< 0x1C, 0x3D, "MAXUW4 $RA,$RB,$RC">; //Vector unsigned word maximum
1017//def MINSB8 : OForm< 0x1C, 0x38, "MINSB8 $RA,$RB,$RC">; //Vector signed byte minimum
1018//def MINSW4 : OForm< 0x1C, 0x39, "MINSW4 $RA,$RB,$RC">; //Vector signed word minimum
1019//def MINUB8 : OForm< 0x1C, 0x3A, "MINUB8 $RA,$RB,$RC">; //Vector unsigned byte minimum
1020//def MINUW4 : OForm< 0x1C, 0x3B, "MINUW4 $RA,$RB,$RC">; //Vector unsigned word minimum
1021//def PERR : OForm< 0x1C, 0x31, "PERR $RA,$RB,$RC">; //Pixel error
1022//def PKLB : OForm< 0x1C, 0x37, "PKLB $RA,$RB,$RC">; //Pack longwords to bytes
1023//def PKWB : OForm<0x1C, 0x36, "PKWB $RA,$RB,$RC">; //Pack words to bytes
1024//def UNPKBL : OForm< 0x1C, 0x35, "UNPKBL $RA,$RB,$RC">; //Unpack bytes to longwords
1025//def UNPKBW : OForm< 0x1C, 0x34, "UNPKBW $RA,$RB,$RC">; //Unpack bytes to words
1026//CVTLQ F-P 17.010 Convert longword to quadword
1027//CVTQL F-P 17.030 Convert quadword to longword
1028
1029
1030//Constant handling
1031
1032def immConst2Part : PatLeaf<(imm), [{
1033 //true if imm fits in a LDAH LDA pair
1034 int64_t val = (int64_t)N->getValue();
1035 return (val <= IMM_FULLHIGH && val >= IMM_FULLLOW);
1036}]>;
1037def immConst2PartInt : PatLeaf<(imm), [{
1038 //true if imm fits in a LDAH LDA pair with zeroext
1039 uint64_t uval = N->getValue();
1040 int32_t val32 = (int32_t)uval;
1041 return ((uval >> 32) == 0 && //empty upper bits
1042 val32 <= IMM_FULLHIGH);
1043// val32 >= IMM_FULLLOW + IMM_LOW * IMM_MULT); //Always True
1044}], SExt32>;
1045
1046def : Pat<(i64 immConst2Part:$imm),
1047 (LDA (LL16 immConst2Part:$imm), (LDAH (LH16 immConst2Part:$imm), R31))>;
1048
1049def : Pat<(i64 immSExt16:$imm),
1050 (LDA immSExt16:$imm, R31)>;
1051
1052def : Pat<(i64 immSExt16int:$imm),
1053 (ZAPNOTi (LDA (SExt16 immSExt16int:$imm), R31), 15)>;
1054def : Pat<(i64 immConst2PartInt:$imm),
1055 (ZAPNOTi (LDA (LL16 (SExt32 immConst2PartInt:$imm)),
1056 (LDAH (LH16 (SExt32 immConst2PartInt:$imm)), R31)), 15)>;
1057
1058
1059//TODO: I want to just define these like this!
1060//def : Pat<(i64 0),
1061// (R31)>;
1062//def : Pat<(f64 0.0),
1063// (F31)>;
1064//def : Pat<(f64 -0.0),
1065// (CPYSNT F31, F31)>;
1066//def : Pat<(f32 0.0),
1067// (F31)>;
1068//def : Pat<(f32 -0.0),
1069// (CPYSNS F31, F31)>;
1070
1071//Misc Patterns:
1072
1073def : Pat<(sext_inreg GPRC:$RB, i32),
1074 (ADDLi GPRC:$RB, 0)>;
1075
1076def : Pat<(fabs F8RC:$RB),
1077 (CPYST F31, F8RC:$RB)>;
1078def : Pat<(fabs F4RC:$RB),
1079 (CPYSS F31, F4RC:$RB)>;
1080def : Pat<(fneg F8RC:$RB),
1081 (CPYSNT F8RC:$RB, F8RC:$RB)>;
1082def : Pat<(fneg F4RC:$RB),
1083 (CPYSNS F4RC:$RB, F4RC:$RB)>;
1084
1085def : Pat<(fcopysign F4RC:$A, (fneg F4RC:$B)),
1086 (CPYSNS F4RC:$B, F4RC:$A)>;
1087def : Pat<(fcopysign F8RC:$A, (fneg F8RC:$B)),
1088 (CPYSNT F8RC:$B, F8RC:$A)>;
1089def : Pat<(fcopysign F4RC:$A, (fneg F8RC:$B)),
1090 (CPYSNSt F8RC:$B, F4RC:$A)>;
1091def : Pat<(fcopysign F8RC:$A, (fneg F4RC:$B)),
1092 (CPYSNTs F4RC:$B, F8RC:$A)>;
1093
1094//Yes, signed multiply high is ugly
1095def : Pat<(mulhs GPRC:$RA, GPRC:$RB),
1096 (SUBQr (UMULHr GPRC:$RA, GPRC:$RB), (ADDQr (CMOVGEr GPRC:$RB, R31, GPRC:$RA),
1097 (CMOVGEr GPRC:$RA, R31, GPRC:$RB)))>;
1098
1099//Stupid crazy arithmetic stuff:
1100let AddedComplexity = 1 in {
1101def : Pat<(mul GPRC:$RA, 5), (S4ADDQr GPRC:$RA, GPRC:$RA)>;
1102def : Pat<(mul GPRC:$RA, 9), (S8ADDQr GPRC:$RA, GPRC:$RA)>;
1103def : Pat<(mul GPRC:$RA, 3), (S4SUBQr GPRC:$RA, GPRC:$RA)>;
1104def : Pat<(mul GPRC:$RA, 7), (S8SUBQr GPRC:$RA, GPRC:$RA)>;
1105
1106//slight tree expansion if we are multiplying near to a power of 2
1107//n is above a power of 2
1108def : Pat<(mul GPRC:$RA, immRem1:$imm),
1109 (ADDQr (SLr GPRC:$RA, (nearP2X immRem1:$imm)), GPRC:$RA)>;
1110def : Pat<(mul GPRC:$RA, immRem2:$imm),
1111 (ADDQr (SLr GPRC:$RA, (nearP2X immRem2:$imm)), (ADDQr GPRC:$RA, GPRC:$RA))>;
1112def : Pat<(mul GPRC:$RA, immRem3:$imm),
1113 (ADDQr (SLr GPRC:$RA, (nearP2X immRem3:$imm)), (S4SUBQr GPRC:$RA, GPRC:$RA))>;
1114def : Pat<(mul GPRC:$RA, immRem4:$imm),
1115 (S4ADDQr GPRC:$RA, (SLr GPRC:$RA, (nearP2X immRem4:$imm)))>;
1116def : Pat<(mul GPRC:$RA, immRem5:$imm),
1117 (ADDQr (SLr GPRC:$RA, (nearP2X immRem5:$imm)), (S4ADDQr GPRC:$RA, GPRC:$RA))>;
1118def : Pat<(mul GPRC:$RA, immRemP2:$imm),
1119 (ADDQr (SLr GPRC:$RA, (nearP2X immRemP2:$imm)), (SLi GPRC:$RA, (nearP2RemX immRemP2:$imm)))>;
1120
1121//n is below a power of 2
Andrew Lenharthd0ac96e2007-11-27 18:31:30 +00001122//FIXME: figure out why something is truncating the imm to 32bits
1123// this will fix 2007-11-27-mulneg3
1124//def : Pat<(mul GPRC:$RA, immRem1n:$imm),
1125// (SUBQr (SLr GPRC:$RA, (nearP2X immRem1n:$imm)), GPRC:$RA)>;
1126//def : Pat<(mul GPRC:$RA, immRem2n:$imm),
1127// (SUBQr (SLr GPRC:$RA, (nearP2X immRem2n:$imm)), (ADDQr GPRC:$RA, GPRC:$RA))>;
1128//def : Pat<(mul GPRC:$RA, immRem3n:$imm),
1129// (SUBQr (SLr GPRC:$RA, (nearP2X immRem3n:$imm)), (S4SUBQr GPRC:$RA, GPRC:$RA))>;
1130//def : Pat<(mul GPRC:$RA, immRem4n:$imm),
1131// (SUBQr (SLr GPRC:$RA, (nearP2X immRem4n:$imm)), (SLi GPRC:$RA, 2))>;
1132//def : Pat<(mul GPRC:$RA, immRem5n:$imm),
1133// (SUBQr (SLr GPRC:$RA, (nearP2X immRem5n:$imm)), (S4ADDQr GPRC:$RA, GPRC:$RA))>;
1134//def : Pat<(mul GPRC:$RA, immRemP2n:$imm),
1135// (SUBQr (SLr GPRC:$RA, (nearP2X immRemP2n:$imm)), (SLi GPRC:$RA, (nearP2RemX immRemP2n:$imm)))>;
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001136} //Added complexity