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