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