byte zap not immediate goodness
[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 //Paterns for matching
17 //********************
18
19 def iZAPX : SDNodeXForm<imm, [{
20   // Transformation function: get the imm to ZAPi
21   uint64_t UImm = (uint64_t)N->getValue();
22   unsigned int build = 0;
23   for(int i = 0; i < 8; ++i)
24   {
25     if ((UImm & 0x00FF) == 0x00FF)
26       build |= 1 << i;
27     else if ((UImm & 0x00FF) != 0)
28     { build = 0; break; }
29     UImm >>= 8;
30   }
31   return getI64Imm(build);
32 }]>;
33
34 def immUExt8  : PatLeaf<(imm), [{
35   // immUExt8 predicate - True if the immediate fits in a 8-bit zero extended
36   // field.  Used by instructions like 'addi'.
37   return (unsigned long)N->getValue() == (unsigned char)N->getValue();
38 }]>;
39
40 def immZAP  : PatLeaf<(imm), [{
41   // immZAP predicate - True if the immediate fits is suitable for use in a
42   // ZAP instruction
43   uint64_t UImm = (uint64_t)N->getValue();
44   unsigned int build = 0;
45   for(int i = 0; i < 8; ++i)
46   {
47     if ((UImm & 0x00FF) == 0x00FF)
48       build |= 1 << i;
49     else if ((UImm & 0x00FF) != 0)
50     { build = 0; break; }
51     UImm >>= 8;
52   }
53   return build != 0;
54 }]>;
55
56
57 def intop : PatFrag<(ops node:$op), (sext_inreg node:$op, i32)>;
58 def add4  : PatFrag<(ops node:$op1, node:$op2),
59                     (add (shl node:$op1, 2), node:$op2)>;
60 def sub4  : PatFrag<(ops node:$op1, node:$op2),
61                     (sub (shl node:$op1, 2), node:$op2)>;
62 def add8  : PatFrag<(ops node:$op1, node:$op2),
63                     (add (shl node:$op1, 3), node:$op2)>;
64 def sub8  : PatFrag<(ops node:$op1, node:$op2),
65                     (sub (shl node:$op1, 3), node:$op2)>;
66
67   // //#define FP    $15
68   // //#define RA    $26
69   // //#define PV    $27
70   // //#define GP    $29
71   // //#define SP    $30
72
73 def PHI : PseudoInstAlpha<(ops variable_ops), "#phi">;
74 def IDEF : PseudoInstAlpha<(ops GPRC:$RA), "#idef $RA">;
75 def WTF : PseudoInstAlpha<(ops variable_ops), "#wtf">;
76 def ADJUSTSTACKUP : PseudoInstAlpha<(ops variable_ops), "ADJUP">;
77 def ADJUSTSTACKDOWN : PseudoInstAlpha<(ops variable_ops), "ADJDOWN">;
78 def ALTENT : PseudoInstAlpha<(ops s64imm:$TARGET), "$TARGET:\n">;
79 def PCLABEL : PseudoInstAlpha<(ops s64imm:$num), "PCMARKER_$num:\n">;
80 def MEMLABEL : PseudoInstAlpha<(ops s64imm:$i, s64imm:$j, s64imm:$k, s64imm:$m),
81          "LSMARKER$$$i$$$j$$$k$$$m:\n">;
82
83 //*****************
84 //These are shortcuts, the assembler expands them
85 //*****************
86 //AT = R28
87 //T0-T7 = R1 - R8
88 //T8-T11 = R22-R25
89
90 //An even better improvement on the Int = SetCC(FP):  SelectCC!
91 //These are evil because they hide control flow in a MBB
92 //really the ISel should emit multiple MBB
93 let isTwoAddress = 1 in {
94 //Conditional move of an int based on a FP CC
95   def CMOVEQ_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, FPRC:$RCOND),
96                                   "fbne $RCOND, 42f\n\tbis $RSRC_T,$RSRC_T,$RDEST\n42:\n">;
97   def CMOVEQi_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, u8imm:$L, FPRC:$RCOND),
98                                   "fbne $RCOND, 42f\n\taddq $$31,$L,$RDEST\n42:\n">;
99
100   def CMOVNE_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, FPRC:$RCOND),
101                                   "fbeq $RCOND, 42f\n\tbis $RSRC_T,$RSRC_T,$RDEST\n42:\n">;
102   def CMOVNEi_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, u8imm:$L, FPRC:$RCOND),
103                                   "fbeq $RCOND, 42f\n\taddq $$31,$L,$RDEST\n42:\n">;
104 //Conditional move of an FP based on a Int CC
105   def FCMOVEQ_INT : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, FPRC:$RCOND),
106                                   "bne $RCOND, 42f\n\tcpys $RSRC_T,$RSRC_T,$RDEST\n42:\n">;
107   def FCMOVNE_INT : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, FPRC:$RCOND),
108                                   "beq $RCOND, 42f\n\tcpys $RSRC_T,$RSRC_T,$RDEST\n42:\n">;
109 }
110
111 //***********************
112 //Real instructions
113 //***********************
114
115 //Operation Form:
116
117 //conditional moves, int
118 def CMOVEQ   : OForm4<  0x11, 0x24, "cmoveq $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND =  zero
119 def CMOVEQi  : OForm4L< 0x11, 0x24, "cmoveq $RCOND,$L,$RDEST">; //CMOVE if RCOND =  zero
120 def CMOVGE   : OForm4<  0x11, 0x46, "cmovge $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND >= zero
121 def CMOVGEi  : OForm4L< 0x11, 0x46, "cmovge $RCOND,$L,$RDEST">; //CMOVE if RCOND >= zero
122 def CMOVGT   : OForm4<  0x11, 0x66, "cmovgt $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND > zero
123 def CMOVGTi  : OForm4L< 0x11, 0x66, "cmovgt $RCOND,$L,$RDEST">; //CMOVE if RCOND > zero
124 def CMOVLBC  : OForm4<  0x11, 0x16, "cmovlbc $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND low bit clear
125 def CMOVLBCi : OForm4L< 0x11, 0x16, "cmovlbc $RCOND,$L,$RDEST">; //CMOVE if RCOND low bit clear
126 def CMOVLBS  : OForm4<  0x11, 0x14, "cmovlbs $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND low bit set
127 def CMOVLBSi : OForm4L< 0x11, 0x14, "cmovlbs $RCOND,$L,$RDEST">; //CMOVE if RCOND low bit set
128 def CMOVLE   : OForm4<  0x11, 0x64, "cmovle $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND <= zero
129 def CMOVLEi  : OForm4L< 0x11, 0x64, "cmovle $RCOND,$L,$RDEST">; //CMOVE if RCOND <= zero
130 def CMOVLT   : OForm4<  0x11, 0x44, "cmovlt $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND < zero
131 def CMOVLTi  : OForm4L< 0x11, 0x44, "cmovlt $RCOND,$L,$RDEST">; //CMOVE if RCOND < zero
132 def CMOVNE   : OForm4<  0x11, 0x26, "cmovne $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND != zero
133 def CMOVNEi  : OForm4L< 0x11, 0x26, "cmovne $RCOND,$L,$RDEST">; //CMOVE if RCOND != zero
134
135 let isTwoAddress = 1 in {
136 //conditional moves, fp
137  def FCMOVEQ : FPFormCM<0x17, 0x02A, (ops FPRC:$RDEST, FPRC:$RSRC2, FPRC:$RSRC, FPRC:$RCOND),
138         "fcmoveq $RCOND,$RSRC,$RDEST">; //FCMOVE if = zero
139  def FCMOVGE : FPFormCM<0x17, 0x02D, (ops FPRC:$RDEST, FPRC:$RSRC2, FPRC:$RSRC, FPRC:$RCOND),
140         "fcmovge $RCOND,$RSRC,$RDEST">; //FCMOVE if >= zero
141  def FCMOVGT : FPFormCM<0x17, 0x02F, (ops FPRC:$RDEST, FPRC:$RSRC2, FPRC:$RSRC, FPRC:$RCOND),
142         "fcmovgt $RCOND,$RSRC,$RDEST">; //FCMOVE if > zero
143  def FCMOVLE : FPFormCM<0x17, 0x02E, (ops FPRC:$RDEST, FPRC:$RSRC2, FPRC:$RSRC, FPRC:$RCOND),
144         "fcmovle $RCOND,$RSRC,$RDEST">; //FCMOVE if <= zero
145  def FCMOVLT : FPFormCM<0x17, 0x02, (ops FPRC:$RDEST, FPRC:$RSRC2, FPRC:$RSRC, FPRC:$RCOND),
146         "fcmovlt $RCOND,$RSRC,$RDEST">; // FCMOVE if < zero
147  def FCMOVNE : FPFormCM<0x17, 0x02B, (ops FPRC:$RDEST, FPRC:$RSRC2, FPRC:$RSRC, FPRC:$RCOND),
148         "fcmovne $RCOND,$RSRC,$RDEST">; //FCMOVE if != zero
149 }
150
151 def ADDL     : OForm< 0x10, 0x00, "addl $RA,$RB,$RC",
152                       [(set GPRC:$RC, (intop (add GPRC:$RA, GPRC:$RB)))]>;
153 def ADDLi    : OFormL<0x10, 0x00, "addl $RA,$L,$RC",
154                       [(set GPRC:$RC, (intop (add GPRC:$RA, immUExt8:$L)))]>;
155 def ADDQ     : OForm< 0x10, 0x20, "addq $RA,$RB,$RC",
156                       [(set GPRC:$RC, (add GPRC:$RA, GPRC:$RB))]>;
157 def ADDQi    : OFormL<0x10, 0x20, "addq $RA,$L,$RC",
158                       [(set GPRC:$RC, (add GPRC:$RA, immUExt8:$L))]>;
159 //def AMASK    : OForm< 0x11, 0x61, "AMASK $RA,$RB,$RC", []>; //Architecture mask
160 //def AMASKi   : OFormL<0x11, 0x61, "AMASK $RA,$L,$RC", []>; //Architecture mask
161 def AND      : OForm< 0x11, 0x00, "and $RA,$RB,$RC",
162                       [(set GPRC:$RC, (and GPRC:$RA, GPRC:$RB))]>;
163 def ANDi     : OFormL<0x11, 0x00, "and $RA,$L,$RC",
164                       [(set GPRC:$RC, (and GPRC:$RA, immUExt8:$L))]>;
165 def BIC      : OForm< 0x11, 0x08, "bic $RA,$RB,$RC",
166                       [(set GPRC:$RC, (and GPRC:$RA, (not GPRC:$RB)))]>;
167 def BICi     : OFormL<0x11, 0x08, "bic $RA,$L,$RC", []>;
168 //                      [(set GPRC:$RC, (and GPRC:$RA, (not immUExt8:$L)))]>; //FIXME?
169 def BIS      : OForm< 0x11, 0x20, "bis $RA,$RB,$RC",
170                       [(set GPRC:$RC, (or GPRC:$RA, GPRC:$RB))]>;
171 def BISi     : OFormL<0x11, 0x20, "bis $RA,$L,$RC",
172                       [(set GPRC:$RC, (or GPRC:$RA, immUExt8:$L))]>;
173 def CTLZ     : OForm2<0x1C, 0x32, "CTLZ $RB,$RC", 
174                       [(set GPRC:$RC, (ctlz GPRC:$RB))]>;
175 def CTPOP    : OForm2<0x1C, 0x30, "CTPOP $RB,$RC", 
176                       [(set GPRC:$RC, (ctpop GPRC:$RB))]>;
177 def CTTZ     : OForm2<0x1C, 0x33, "CTTZ $RB,$RC", 
178                       [(set GPRC:$RC, (cttz GPRC:$RB))]>;
179 def EQV      : OForm< 0x11, 0x48, "eqv $RA,$RB,$RC",
180                       [(set GPRC:$RC, (xor GPRC:$RA, (not GPRC:$RB)))]>;
181 def EQVi     : OFormL<0x11, 0x48, "eqv $RA,$L,$RC", []>;
182 //                      [(set GPRC:$RC, (xor GPRC:$RA, (not immUExt8:$L)))]>;
183 //def EXTBL    : OForm< 0x12, 0x06, "EXTBL $RA,$RB,$RC", []>; //Extract byte low
184 //def EXTBLi   : OFormL<0x12, 0x06, "EXTBL $RA,$L,$RC", []>; //Extract byte low
185 //def EXTLH    : OForm< 0x12, 0x6A, "EXTLH $RA,$RB,$RC", []>; //Extract longword high
186 //def EXTLHi   : OFormL<0x12, 0x6A, "EXTLH $RA,$L,$RC", []>; //Extract longword high
187 //def EXTLL    : OForm< 0x12, 0x26, "EXTLL $RA,$RB,$RC", []>; //Extract longword low
188 //def EXTLLi   : OFormL<0x12, 0x26, "EXTLL $RA,$L,$RC", []>; //Extract longword low
189 //def EXTQH    : OForm< 0x12, 0x7A, "EXTQH $RA,$RB,$RC", []>; //Extract quadword high
190 //def EXTQHi   : OFormL<0x12, 0x7A, "EXTQH $RA,$L,$RC", []>; //Extract quadword high
191 //def EXTQ     : OForm< 0x12, 0x36, "EXTQ $RA,$RB,$RC", []>; //Extract quadword low
192 //def EXTQi    : OFormL<0x12, 0x36, "EXTQ $RA,$L,$RC", []>; //Extract quadword low
193 //def EXTWH    : OForm< 0x12, 0x5A, "EXTWH $RA,$RB,$RC", []>; //Extract word high
194 //def EXTWHi   : OFormL<0x12, 0x5A, "EXTWH $RA,$L,$RC", []>; //Extract word high
195 //def EXTWL    : OForm< 0x12, 0x16, "EXTWL $RA,$RB,$RC", []>; //Extract word low
196 //def EXTWLi   : OFormL<0x12, 0x16, "EXTWL $RA,$L,$RC", []>; //Extract word low
197 //def IMPLVER  : OForm< 0x11, 0x6C, "IMPLVER $RA,$RB,$RC", []>; //Implementation version
198 //def IMPLVERi : OFormL<0x11, 0x6C, "IMPLVER $RA,$L,$RC", []>; //Implementation version
199 //def INSBL    : OForm< 0x12, 0x0B, "INSBL $RA,$RB,$RC", []>; //Insert byte low
200 //def INSBLi   : OFormL<0x12, 0x0B, "INSBL $RA,$L,$RC", []>; //Insert byte low
201 //def INSLH    : OForm< 0x12, 0x67, "INSLH $RA,$RB,$RC", []>; //Insert longword high
202 //def INSLHi   : OFormL<0x12, 0x67, "INSLH $RA,$L,$RC", []>; //Insert longword high
203 //def INSLL    : OForm< 0x12, 0x2B, "INSLL $RA,$RB,$RC", []>; //Insert longword low
204 //def INSLLi   : OFormL<0x12, 0x2B, "INSLL $RA,$L,$RC", []>; //Insert longword low
205 //def INSQH    : OForm< 0x12, 0x77, "INSQH $RA,$RB,$RC", []>; //Insert quadword high
206 //def INSQHi   : OFormL<0x12, 0x77, "INSQH $RA,$L,$RC", []>; //Insert quadword high
207 //def INSQL    : OForm< 0x12, 0x3B, "INSQL $RA,$RB,$RC", []>; //Insert quadword low
208 //def INSQLi   : OFormL<0x12, 0x3B, "INSQL $RA,$L,$RC", []>; //Insert quadword low
209 //def INSWH    : OForm< 0x12, 0x57, "INSWH $RA,$RB,$RC", []>; //Insert word high
210 //def INSWHi   : OFormL<0x12, 0x57, "INSWH $RA,$L,$RC", []>; //Insert word high
211 //def INSWL    : OForm< 0x12, 0x1B, "INSWL $RA,$RB,$RC", []>; //Insert word low
212 //def INSWLi   : OFormL<0x12, 0x1B, "INSWL $RA,$L,$RC", []>; //Insert word low
213 //def MSKBL    : OForm< 0x12, 0x02, "MSKBL $RA,$RB,$RC", []>; //Mask byte low
214 //def MSKBLi   : OFormL<0x12, 0x02, "MSKBL $RA,$L,$RC", []>; //Mask byte low
215 //def MSKLH    : OForm< 0x12, 0x62, "MSKLH $RA,$RB,$RC", []>; //Mask longword high
216 //def MSKLHi   : OFormL<0x12, 0x62, "MSKLH $RA,$L,$RC", []>; //Mask longword high
217 //def MSKLL    : OForm< 0x12, 0x22, "MSKLL $RA,$RB,$RC", []>; //Mask longword low
218 //def MSKLLi   : OFormL<0x12, 0x22, "MSKLL $RA,$L,$RC", []>; //Mask longword low
219 //def MSKQH    : OForm< 0x12, 0x72, "MSKQH $RA,$RB,$RC", []>; //Mask quadword high
220 //def MSKQHi   : OFormL<0x12, 0x72, "MSKQH $RA,$L,$RC", []>; //Mask quadword high
221 //def MSKQL    : OForm< 0x12, 0x32, "MSKQL $RA,$RB,$RC", []>; //Mask quadword low
222 //def MSKQLi   : OFormL<0x12, 0x32, "MSKQL $RA,$L,$RC", []>; //Mask quadword low
223 //def MSKWH    : OForm< 0x12, 0x52, "MSKWH $RA,$RB,$RC", []>; //Mask word high
224 //def MSKWHi   : OFormL<0x12, 0x52, "MSKWH $RA,$L,$RC", []>; //Mask word high
225 //def MSKWL    : OForm< 0x12, 0x12, "MSKWL $RA,$RB,$RC", []>; //Mask word low
226 //def MSKWLi   : OFormL<0x12, 0x12, "MSKWL $RA,$L,$RC", []>; //Mask word low
227
228 def MULL     : OForm< 0x13, 0x00, "mull $RA,$RB,$RC",
229                       [(set GPRC:$RC, (intop (mul GPRC:$RA, GPRC:$RB)))]>;
230 def MULLi    : OFormL<0x13, 0x00, "mull $RA,$L,$RC",
231                       [(set GPRC:$RC, (intop (mul GPRC:$RA, immUExt8:$L)))]>;
232 def MULQ     : OForm< 0x13, 0x20, "mulq $RA,$RB,$RC",
233                       [(set GPRC:$RC, (mul GPRC:$RA, GPRC:$RB))]>;
234 def MULQi    : OFormL<0x13, 0x20, "mulq $RA,$L,$RC",
235                       [(set GPRC:$RC, (mul GPRC:$RA, immUExt8:$L))]>;
236 def ORNOT    : OForm< 0x11, 0x28, "ornot $RA,$RB,$RC",
237                       [(set GPRC:$RC, (or GPRC:$RA, (not GPRC:$RB)))]>;
238 def ORNOTi   : OFormL<0x11, 0x28, "ornot $RA,$L,$RC", []>;
239 //                      [(set GPRC:$RC, (or GPRC:$RA, (not immUExt8:$L)))]>;
240 def S4ADDL   : OForm< 0x10, 0x02, "s4addl $RA,$RB,$RC", 
241                       [(set GPRC:$RC, (intop (add4 GPRC:$RA, GPRC:$RB)))]>;
242 def S4ADDLi  : OFormL<0x10, 0x02, "s4addl $RA,$L,$RC", 
243                       [(set GPRC:$RC, (intop (add4 GPRC:$RA, immUExt8:$L)))]>;
244 def S4ADDQ   : OForm< 0x10, 0x22, "s4addq $RA,$RB,$RC", 
245                       [(set GPRC:$RC, (add4 GPRC:$RA, GPRC:$RB))]>;
246 def S4ADDQi  : OFormL<0x10, 0x22, "s4addq $RA,$L,$RC", 
247                       [(set GPRC:$RC, (add4 GPRC:$RA, immUExt8:$L))]>;
248 def S4SUBL   : OForm< 0x10, 0x0B, "s4subl $RA,$RB,$RC",
249                       [(set GPRC:$RC, (intop (sub4 GPRC:$RA, GPRC:$RB)))]>;
250 def S4SUBLi  : OFormL<0x10, 0x0B, "s4subl $RA,$L,$RC",
251                       [(set GPRC:$RC, (intop (sub4 GPRC:$RA, immUExt8:$L)))]>;
252 def S4SUBQ   : OForm< 0x10, 0x2B, "s4subq $RA,$RB,$RC", 
253                       [(set GPRC:$RC, (sub4 GPRC:$RA, GPRC:$RB))]>;
254 def S4SUBQi  : OFormL<0x10, 0x2B, "s4subq $RA,$L,$RC", 
255                       [(set GPRC:$RC, (sub4 GPRC:$RA, immUExt8:$L))]>;
256 def S8ADDL   : OForm< 0x10, 0x12, "s8addl $RA,$RB,$RC", 
257                       [(set GPRC:$RC, (intop (add8 GPRC:$RA, GPRC:$RB)))]>;
258 def S8ADDLi  : OFormL<0x10, 0x12, "s8addl $RA,$L,$RC", 
259                       [(set GPRC:$RC, (intop (add8 GPRC:$RA, immUExt8:$L)))]>;
260 def S8ADDQ   : OForm< 0x10, 0x32, "s8addq $RA,$RB,$RC", 
261                       [(set GPRC:$RC, (add8 GPRC:$RA, GPRC:$RB))]>;
262 def S8ADDQi  : OFormL<0x10, 0x32, "s8addq $RA,$L,$RC", 
263                       [(set GPRC:$RC, (add8 GPRC:$RA, immUExt8:$L))]>;
264 def S8SUBL   : OForm< 0x10, 0x1B, "s8subl $RA,$RB,$RC", 
265                       [(set GPRC:$RC, (intop (sub8 GPRC:$RA, GPRC:$RB)))]>;
266 def S8SUBLi  : OFormL<0x10, 0x1B, "s8subl $RA,$L,$RC", 
267                       [(set GPRC:$RC, (intop (sub8 GPRC:$RA, immUExt8:$L)))]>;
268 def S8SUBQ   : OForm< 0x10, 0x3B, "s8subq $RA,$RB,$RC", 
269                       [(set GPRC:$RC, (sub8 GPRC:$RA, GPRC:$RB))]>;
270 def S8SUBQi  : OFormL<0x10, 0x3B, "s8subq $RA,$L,$RC", 
271                       [(set GPRC:$RC, (sub8 GPRC:$RA, immUExt8:$L))]>;
272 def SEXTB    : OForm2<0x1C, 0x00, "sextb $RB,$RC", 
273                       [(set GPRC:$RC, (sext_inreg GPRC:$RB, i8))]>;
274 def SEXTW    : OForm2<0x1C, 0x01, "sextw $RB,$RC", 
275                       [(set GPRC:$RC, (sext_inreg GPRC:$RB, i16))]>;
276 def SL       : OForm< 0x12, 0x39, "sll $RA,$RB,$RC",
277                       [(set GPRC:$RC, (shl GPRC:$RA, GPRC:$RB))]>;
278 def SLi      : OFormL<0x12, 0x39, "sll $RA,$L,$RC",
279                       [(set GPRC:$RC, (shl GPRC:$RA, immUExt8:$L))]>;
280 def SRA      : OForm< 0x12, 0x3C, "sra $RA,$RB,$RC",
281                       [(set GPRC:$RC, (sra GPRC:$RA, GPRC:$RB))]>;
282 def SRAi     : OFormL<0x12, 0x3C, "sra $RA,$L,$RC",
283                       [(set GPRC:$RC, (sra GPRC:$RA, immUExt8:$L))]>;
284 def SRL      : OForm< 0x12, 0x34, "srl $RA,$RB,$RC",
285                       [(set GPRC:$RC, (srl GPRC:$RA, GPRC:$RB))]>;
286 def SRLi     : OFormL<0x12, 0x34, "srl $RA,$L,$RC",
287                       [(set GPRC:$RC, (srl GPRC:$RA, immUExt8:$L))]>;
288 def SUBL     : OForm< 0x10, 0x09, "subl $RA,$RB,$RC",
289                       [(set GPRC:$RC, (intop (sub GPRC:$RA, GPRC:$RB)))]>;
290 def SUBLi    : OFormL<0x10, 0x09, "subl $RA,$L,$RC",
291                       [(set GPRC:$RC, (intop (sub GPRC:$RA, immUExt8:$L)))]>;
292 def SUBQ     : OForm< 0x10, 0x29, "subq $RA,$RB,$RC",
293                       [(set GPRC:$RC, (sub GPRC:$RA, GPRC:$RB))]>;
294 def SUBQi    : OFormL<0x10, 0x29, "subq $RA,$L,$RC",
295                       [(set GPRC:$RC, (sub GPRC:$RA, immUExt8:$L))]>;
296 def UMULH    : OForm< 0x13, 0x30, "umulh $RA,$RB,$RC",
297                       [(set GPRC:$RC, (mulhu GPRC:$RA, GPRC:$RB))]>;                     
298 def UMULHi   : OFormL<0x13, 0x30, "umulh $RA,$L,$RC", 
299                       [(set GPRC:$RC, (mulhu GPRC:$RA, immUExt8:$L))]>;
300 def XOR      : OForm< 0x11, 0x40, "xor $RA,$RB,$RC",
301                       [(set GPRC:$RC, (xor GPRC:$RA, GPRC:$RB))]>;
302 def XORi     : OFormL<0x11, 0x40, "xor $RA,$L,$RC",
303                       [(set GPRC:$RC, (xor GPRC:$RA, immUExt8:$L))]>;
304 //FIXME: what to do about zap? the cases it catches are very complex
305 def ZAP      : OForm< 0x12, 0x30, "zap $RA,$RB,$RC", []>; //Zero bytes
306 //ZAPi is useless give ZAPNOTi
307 def ZAPi     : OFormL<0x12, 0x30, "zap $RA,$L,$RC", []>; //Zero bytes
308 //FIXME: what to do about zapnot? see ZAP :)
309 def ZAPNOT   : OForm< 0x12, 0x31, "zapnot $RA,$RB,$RC", []>; //Zero bytes not
310 def ZAPNOTi  : OFormL<0x12, 0x31, "zapnot $RA,$L,$RC", []>; 
311 def : Pat<(and GPRC:$OP1, immZAP:$OP2), (ZAPNOTi GPRC:$OP1, (iZAPX immZAP:$OP2))>;
312
313 //Comparison, int
314 def CMPBGE   : OForm< 0x10, 0x0F, "cmpbge $RA,$RB,$RC", []>; //Compare byte
315 def CMPBGEi  : OFormL<0x10, 0x0F, "cmpbge $RA,$L,$RC", []>; //Compare byte
316 def CMPEQ    : OForm< 0x10, 0x2D, "cmpeq $RA,$RB,$RC", []>; //Compare signed quadword equal
317 def CMPEQi   : OFormL<0x10, 0x2D, "cmpeq $RA,$L,$RC", []>; //Compare signed quadword equal
318 def CMPLE    : OForm< 0x10, 0x6D, "cmple $RA,$RB,$RC", []>; //Compare signed quadword less than or equal
319 def CMPLEi   : OFormL<0x10, 0x6D, "cmple $RA,$L,$RC", []>; //Compare signed quadword less than or equal
320 def CMPLT    : OForm< 0x10, 0x4D, "cmplt $RA,$RB,$RC", []>; //Compare signed quadword less than
321 def CMPLTi   : OFormL<0x10, 0x4D, "cmplt $RA,$L,$RC", []>; //Compare signed quadword less than
322 def CMPULE   : OForm< 0x10, 0x3D, "cmpule $RA,$RB,$RC", []>; //Compare unsigned quadword less than or equal
323 def CMPULEi  : OFormL<0x10, 0x3D, "cmpule $RA,$L,$RC", []>; //Compare unsigned quadword less than or equal
324 def CMPULT   : OForm< 0x10, 0x1D, "cmpult $RA,$RB,$RC", []>; //Compare unsigned quadword less than
325 def CMPULTi  : OFormL<0x10, 0x1D, "cmpult $RA,$L,$RC", []>; //Compare unsigned quadword less than
326
327 //Comparison, FP
328 def CMPTEQ : FPForm<0x16, 0x0A5, "cmpteq/su $RA,$RB,$RC">;  //Compare T_floating equal
329 def CMPTLE : FPForm<0x16, 0x0A7, "cmptle/su $RA,$RB,$RC">;  //Compare T_floating less than or equal
330 def CMPTLT : FPForm<0x16, 0x0A6, "cmptlt/su $RA,$RB,$RC">;  //Compare T_floating less than
331 def CMPTUN : FPForm<0x16, 0x0A4, "cmptun/su $RA,$RB,$RC">;  //Compare T_floating unordered
332
333 //There are in the Multimedia extentions, so let's not use them yet
334 //def MAXSB8  : OForm<0x1C, 0x3E, "MAXSB8 $RA,$RB,$RC">; //Vector signed byte maximum
335 //def MAXSW4 : OForm< 0x1C, 0x3F, "MAXSW4 $RA,$RB,$RC">; //Vector signed word maximum
336 //def MAXUB8  : OForm<0x1C, 0x3C, "MAXUB8 $RA,$RB,$RC">; //Vector unsigned byte maximum
337 //def MAXUW4 : OForm< 0x1C, 0x3D, "MAXUW4 $RA,$RB,$RC">; //Vector unsigned word maximum
338 //def MINSB8 : OForm< 0x1C, 0x38, "MINSB8 $RA,$RB,$RC">; //Vector signed byte minimum
339 //def MINSW4 : OForm< 0x1C, 0x39, "MINSW4 $RA,$RB,$RC">; //Vector signed word minimum
340 //def MINUB8 : OForm< 0x1C, 0x3A, "MINUB8 $RA,$RB,$RC">; //Vector unsigned byte minimum
341 //def MINUW4 : OForm< 0x1C, 0x3B, "MINUW4 $RA,$RB,$RC">; //Vector unsigned word minimum
342 //def PERR : OForm< 0x1C, 0x31, "PERR $RA,$RB,$RC">; //Pixel error
343 //def PKLB : OForm< 0x1C, 0x37, "PKLB $RA,$RB,$RC">; //Pack longwords to bytes
344 //def PKWB  : OForm<0x1C, 0x36, "PKWB $RA,$RB,$RC">; //Pack words to bytes
345 //def UNPKBL : OForm< 0x1C, 0x35, "UNPKBL $RA,$RB,$RC">; //Unpack bytes to longwords
346 //def UNPKBW : OForm< 0x1C, 0x34, "UNPKBW $RA,$RB,$RC">; //Unpack bytes to words
347
348 //End operate
349
350 let isReturn = 1, isTerminator = 1 in 
351   def RET : MbrForm< 0x1A, 0x02, (ops GPRC:$RD, GPRC:$RS, s64imm:$DISP), "ret $RD,($RS),$DISP">; //Return from subroutine
352 //DAG Version:
353 let isReturn = 1, isTerminator = 1, Ra = 31, Rb = 26, disp = 1, Uses = [R26] in 
354   def RETDAG : MbrForm< 0x1A, 0x02, (ops), "ret $$31,($$26),1">; //Return from subroutine
355
356 def JMP : MbrForm< 0x1A, 0x00, (ops GPRC:$RD, GPRC:$RS, GPRC:$DISP), "jmp $RD,($RS),$DISP">; //Jump
357 let isCall = 1,
358     Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19,
359             R20, R21, R22, R23, R24, R25, R27, R28, R29,
360             F0, F1,
361             F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
362             F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R29] in {
363     def JSR : MbrForm< 0x1A, 0x01, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr $RD,($RS),$DISP">; //Jump to subroutine
364     def BSR : BForm<0x34, "bsr $RA,$DISP">; //Branch to subroutine
365 }
366 let isCall = 1, Defs = [R24, R25, R27, R28], Uses = [R24, R25] in
367   def JSRs : MbrForm< 0x1A, 0x01, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr $RD,($RS),$DISP">; //Jump to div or rem
368
369 def JSR_COROUTINE : MbrForm< 0x1A, 0x03, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr_coroutine $RD,($RS),$DISP">; //Jump to subroutine return
370 def BR : BForm<0x30, "br $RA,$DISP">; //Branch
371
372 //Stores, int
373 def STB : MForm<0x0E, "stb $RA,$DISP($RB)">; // Store byte
374 def STW : MForm<0x0D, "stw $RA,$DISP($RB)">; // Store word
375 def STL : MForm<0x2C, "stl $RA,$DISP($RB)">; // Store longword
376 def STQ : MForm<0x2D, "stq $RA,$DISP($RB)">; //Store quadword
377
378 //Loads, int
379 def LDL : MForm<0x28,  "ldl $RA,$DISP($RB)">; // Load sign-extended longword
380 def LDQ : MForm<0x29,  "ldq $RA,$DISP($RB)">; //Load quadword
381 def LDBU : MForm<0x0A, "ldbu $RA,$DISP($RB)">; //Load zero-extended byte
382 def LDWU : MForm<0x0C, "ldwu $RA,$DISP($RB)">; //Load zero-extended word
383
384 //Stores, float
385 def STS : MForm<0x26, "sts $RA,$DISP($RB)">; //Store S_floating
386 def STT : MForm<0x27, "stt $RA,$DISP($RB)">; //Store T_floating
387
388 //Loads, float
389 def LDS : MForm<0x22, "lds $RA,$DISP($RB)">; //Load S_floating
390 def LDT : MForm<0x23, "ldt $RA,$DISP($RB)">; //Load T_floating
391
392 //Load address
393 def LDA : MForm<0x08,  "lda $RA,$DISP($RB)">;  //Load address
394 def LDAH : MForm<0x09, "ldah $RA,$DISP($RB)">;  //Load address high
395
396
397 //Loads, int, Rellocated Low form
398 def LDLr : MForm<0x28,  "ldl $RA,$DISP($RB)\t\t!gprellow">; // Load sign-extended longword
399 def LDQr : MForm<0x29,  "ldq $RA,$DISP($RB)\t\t!gprellow">; //Load quadword
400 def LDBUr : MForm<0x0A, "ldbu $RA,$DISP($RB)\t\t!gprellow">; //Load zero-extended byte
401 def LDWUr : MForm<0x0C, "ldwu $RA,$DISP($RB)\t\t!gprellow">; //Load zero-extended word
402
403 //Loads, float, Rellocated Low form
404 def LDSr : MForm<0x22, "lds $RA,$DISP($RB)\t\t!gprellow">; //Load S_floating
405 def LDTr : MForm<0x23, "ldt $RA,$DISP($RB)\t\t!gprellow">; //Load T_floating
406
407 //Load address, rellocated low and high form
408 def LDAr : MForm<0x08,  "lda $RA,$DISP($RB)\t\t!gprellow">;  //Load address
409 def LDAHr : MForm<0x09, "ldah $RA,$DISP($RB)\t\t!gprelhigh">;  //Load address high
410
411 //load address, rellocated gpdist form
412 def LDAg : MgForm<0x08,  "lda $RA,0($RB)\t\t!gpdisp!$NUM">;  //Load address
413 def LDAHg : MgForm<0x09, "ldah $RA,0($RB)\t\t!gpdisp!$NUM">;  //Load address
414
415
416 //Load quad, rellocated literal form
417 def LDQl : MForm<0x29, "ldq $RA,$DISP($RB)\t\t!literal">; //Load quadword
418
419 //Stores, int
420 def STBr : MForm<0x0E, "stb $RA,$DISP($RB)\t\t!gprellow">; // Store byte
421 def STWr : MForm<0x0D, "stw $RA,$DISP($RB)\t\t!gprellow">; // Store word
422 def STLr : MForm<0x2C, "stl $RA,$DISP($RB)\t\t!gprellow">; // Store longword
423 def STQr : MForm<0x2D, "stq $RA,$DISP($RB)\t\t!gprellow">; //Store quadword
424
425 //Stores, float
426 def STSr : MForm<0x26, "sts $RA,$DISP($RB)\t\t!gprellow">; //Store S_floating
427 def STTr : MForm<0x27, "stt $RA,$DISP($RB)\t\t!gprellow">; //Store T_floating
428
429
430 //Branches, int
431 def BEQ : BForm<0x39,  "beq $RA,$DISP">; //Branch if = zero
432 def BGE : BForm<0x3E,  "bge $RA,$DISP">; //Branch if >= zero
433 def BGT : BForm<0x3F,  "bgt $RA,$DISP">; //Branch if > zero
434 def BLBC : BForm<0x38, "blbc $RA,$DISP">; //Branch if low bit clear
435 def BLBS : BForm<0x3C, "blbs $RA,$DISP">; //Branch if low bit set
436 def BLE : BForm<0x3B,  "ble $RA,$DISP">; //Branch if <= zero
437 def BLT : BForm<0x3A,  "blt $RA,$DISP">; //Branch if < zero
438 def BNE : BForm<0x3D,  "bne $RA,$DISP">; //Branch if != zero
439
440 //Branches, float
441 def FBEQ : FBForm<0x31, "fbeq $RA,$DISP">; //Floating branch if =  zero
442 def FBGE : FBForm<0x36, "fbge $RA,$DISP">; //Floating branch if >= zero
443 def FBGT : FBForm<0x37, "fbgt $RA,$DISP">; //Floating branch if > zero
444 def FBLE : FBForm<0x33, "fble $RA,$DISP">; //Floating branch if <= zero
445 def FBLT : FBForm<0x32, "fblt $RA,$DISP">; //Floating branch if < zero
446 def FBNE : FBForm<0x35, "fbne $RA,$DISP">; //Floating branch if != zero
447
448 //Funky Floating point ops
449 def CPYS  : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC">;  //Copy sign
450 def CPYSE : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC">; //Copy sign and exponent
451 def CPYSN : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC">; //Copy sign negate
452
453 //Basic Floating point ops
454 def ADDS  : FPForm<0x16, 0x580, "adds/su $RA,$RB,$RC">;  //Add S_floating
455 def ADDT  : FPForm<0x16, 0x5A0, "addt/su $RA,$RB,$RC">;  //Add T_floating
456 def SUBS  : FPForm<0x16, 0x581, "subs/su $RA,$RB,$RC">;  //Subtract S_floating
457 def SUBT  : FPForm<0x16, 0x5A1, "subt/su $RA,$RB,$RC">;  //Subtract T_floating
458 def DIVS  : FPForm<0x16, 0x583, "divs/su $RA,$RB,$RC">;  //Divide S_floating
459 def DIVT  : FPForm<0x16, 0x5A3, "divt/su $RA,$RB,$RC">;  //Divide T_floating
460 def MULS  : FPForm<0x16, 0x582, "muls/su $RA,$RB,$RC">;  //Multiply S_floating
461 def MULT  : FPForm<0x16, 0x5A2, "mult/su $RA,$RB,$RC">;  //Multiply T_floating
462 def SQRTS : FPForm<0x14, 0x58B, "sqrts/su $RA,$RB,$RC">;  //Square root S_floating
463 def SQRTT : FPForm<0x14, 0x5AB, "sqrtt/su $RA,$RB,$RC">;  //Square root T_floating
464
465 //INT reg to FP reg and back again
466 //not supported on 21164
467 def FTOIS : FPForm<0x1C, 0x078, "ftois $RA,$RC">; //Floating to integer move, S_floating
468 def FTOIT : FPForm<0x1C, 0x070, "ftoit $RA,$RC">; //Floating to integer move, T_floating
469 def ITOFS : FPForm<0x14, 0x004, "itofs $RA,$RC">; //Integer to floating move, S_floating
470 def ITOFT : FPForm<0x14, 0x024, "itoft $RA,$RC">; //Integer to floating move, T_floating
471
472 //CVTLQ F-P 17.010 Convert longword to quadword
473 //CVTQL F-P 17.030 Convert quadword to longword
474 //These use SW completion, may not have function code for that set right (matters for JIT)
475 def CVTQS : FPForm<0x16, 0x0BC, "cvtqs $RB,$RC">; //Convert quadword to S_floating
476 def CVTQT : FPForm<0x16, 0x0BE, "cvtqt $RB,$RC">; //Convert quadword to T_floating
477 def CVTST : FPForm<0x16, 0x2AC, "cvtsts $RB,$RC">; //Convert S_floating to T_floating
478 def CVTTQ : FPForm<0x16, 0x52F, "cvttq/svc $RB,$RC">; //Convert T_floating to quadword
479 def CVTTS : FPForm<0x16, 0x5AC, "cvtts/su $RB,$RC">; //Convert T_floating to S_floating
480
481 //S_floating : IEEE Single
482 //T_floating : IEEE Double
483
484 //Mnemonic Format Opcode Description
485
486 //CALL_PAL Pcd 00 Trap to PALcode
487 //ECB Mfc 18.E800 Evict cache block
488 //EXCB Mfc 18.0400 Exception barrier
489 //FETCH Mfc 18.8000 Prefetch data
490 //FETCH_M Mfc 18.A000 Prefetch data, modify intent
491
492 //LDL_L Mem 2A Load sign-extended longword locked
493 //LDQ_L Mem 2B Load quadword locked
494 //LDQ_U Mem 0B Load unaligned quadword
495 //MB Mfc 18.4000 Memory barrier
496 //RPCC Mfc 18.C000 Read process cycle counter
497
498 //STL_C Mem 2E Store longword conditional
499 //STQ_C Mem 2F Store quadword conditional
500 //STQ_U Mem 0F Store unaligned quadword
501
502 //TRAPB Mfc 18.0000 Trap barrier
503 //WH64 Mfc 18.F800 Write hint \14 64 bytes
504 //WMB Mfc 18.4400 Write memory barrier
505
506
507 //MF_FPCR F-P 17.025 Move from FPCR
508 //MT_FPCR F-P 17.024 Move to FPCR