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