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