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