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