1 //===- AlphaInstrInfo.td - The Alpha Instruction Set -------*- tablegen -*-===//
3 // The LLVM Compiler Infrastructure
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.
8 //===----------------------------------------------------------------------===//
11 //===----------------------------------------------------------------------===//
13 include "AlphaInstrFormats.td"
15 //********************
17 //********************
19 def SDTFPUnaryOpUnC : SDTypeProfile<1, 1, [
20 SDTCisFP<1>, SDTCisFP<0>
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, []>;
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]>;
35 //********************
36 //Paterns for matching
37 //********************
38 def invX : SDNodeXForm<imm, [{
39 return getI64Imm(~N->getValue());
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();
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();
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();
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)
63 if ((UImm & 0x00FF) == 0x00FF)
65 else if ((UImm & 0x00FF) != 0)
69 return getI64Imm(build);
71 def immZAP : PatLeaf<(imm), [{
72 // immZAP predicate - True if the immediate fits is suitable for use in a
74 uint64_t UImm = (uint64_t)N->getValue();
75 unsigned int build = 0;
76 for(int i = 0; i < 8; ++i)
78 if ((UImm & 0x00FF) == 0x00FF)
80 else if ((UImm & 0x00FF) != 0)
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)>;
103 def PHI : PseudoInstAlpha<(ops variable_ops), "#phi", []>;
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))]>;
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)]>;
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",[]>;
125 //These are shortcuts, the assembler expands them
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", []>;
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", []>;
152 //***********************
154 //***********************
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
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))]>;
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)>;
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
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))]>;
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))]>;
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)>;
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)>;
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)>;
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)>;
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)>;
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)>;
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)>;
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
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
410 def JMP : MbrForm< 0x1A, 0x00, (ops GPRC:$RD, GPRC:$RS, GPRC:$DISP), "jmp $RD,($RS),$DISP">; //Jump
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,
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
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,
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
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
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
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
437 def BR_DAG : BFormD<0x30, "br $$31,$DISP">; //Branch
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
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
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
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
464 def LDA : MForm<0x08, "lda $RA,$DISP($RB)">; //Load address
465 def LDAH : MForm<0x09, "ldah $RA,$DISP($RB)">; //Load address high
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
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
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
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
489 //Load quad, rellocated literal form
490 def LDQl : MForm<0x29, "ldq $RA,$DISP($RB)\t\t!literal">; //Load quadword
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
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
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
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
523 def RPCC : MfcForm<0x18, 0xC000, "rpcc $RA">; //Read process cycle counter
525 //Basic Floating point ops
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))]>;
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))]>;
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
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))]>;
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))]>;
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
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))]>;
577 //TODO: Add lots more FP patterns
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
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", []>;
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))>;
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))>;
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
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))]>;
658 //S_floating : IEEE Single
659 //T_floating : IEEE Double
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
702 def immConst2Part : PatLeaf<(imm), [{
703 // immZAP predicate - True if the immediate fits is suitable for use in a
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);
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)
716 return getI64Imm(l - y * IMM_MULT);
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)
727 def : Pat<(i64 immConst2Part:$imm),
728 (LDA (LL16 immConst2Part:$imm), (LDAH (LH16 immConst2Part:$imm), R31))>;
730 def : Pat<(i64 immSExt16:$imm),
731 (LDA immSExt16:$imm, R31)>;
733 //TODO: I want to just define these like this!
736 //def : Pat<(f64 0.0),
738 //def : Pat<(f64 -0.0),
739 // (CPYSNT F31, F31)>;
740 //def : Pat<(f32 0.0),
742 //def : Pat<(f32 -0.0),
743 // (CPYSNS F31, F31)>;
747 def : Pat<(sext_inreg GPRC:$RB, i32),
748 (ADDLi GPRC:$RB, 0)>;
750 def : Pat<(select GPRC:$which, GPRC:$src1, GPRC:$src2),
751 (CMOVEQ GPRC:$src1, GPRC:$src2, GPRC:$which)>; //may be CMOVNE
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)))>;