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