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