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