blob: a1f520a3c6e8eb77ddb98cdb8af317c320ec42ad [file] [log] [blame]
Misha Brukmanbc9ccf62005-02-04 20:25:52 +00001//===- AlphaInstrInfo.td - The Alpha Instruction Set -------*- tablegen -*-===//
Andrew Lenharth304d0f32005-01-22 23:41:55 +00002//
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
13include "AlphaInstrFormats.td"
14
Andrew Lenharth4907d222005-10-20 00:28:31 +000015//********************
Andrew Lenharth7f0db912005-11-30 07:19:56 +000016//Custom DAG Nodes
17//********************
18
19def SDTFPUnaryOpUnC : SDTypeProfile<1, 1, [
20 SDTCisFP<1>, SDTCisFP<0>
21]>;
22
23def Alpha_itoft : SDNode<"AlphaISD::ITOFT_", SDTIntToFPOp, []>;
24def Alpha_ftoit : SDNode<"AlphaISD::FTOIT_", SDTFPToIntOp, []>;
25def Alpha_cvtqt : SDNode<"AlphaISD::CVTQT_", SDTFPUnaryOpUnC, []>;
26def Alpha_cvtqs : SDNode<"AlphaISD::CVTQS_", SDTFPUnaryOpUnC, []>;
Andrew Lenharthcd804962005-11-30 16:10:29 +000027def Alpha_cvttq : SDNode<"AlphaISD::CVTTQ_", SDTFPUnaryOp, []>;
Andrew Lenharth7f0db912005-11-30 07:19:56 +000028
29
30//********************
Andrew Lenharth4907d222005-10-20 00:28:31 +000031//Paterns for matching
32//********************
Andrew Lenharthfe9234d2005-10-21 01:24:05 +000033
Andrew Lenharth756fbeb2005-10-22 22:06:58 +000034def 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}]>;
39def immSExt16 : PatLeaf<(imm), [{
40 // immSExt16 predicate - True if the immediate fits in a 16-bit sign extended
41 // field. Used by instructions like 'lda'.
42 return (int)N->getValue() == (short)N->getValue();
43}]>;
44
Andrew Lenharthfe9234d2005-10-21 01:24:05 +000045def iZAPX : SDNodeXForm<imm, [{
46 // Transformation function: get the imm to ZAPi
47 uint64_t UImm = (uint64_t)N->getValue();
48 unsigned int build = 0;
49 for(int i = 0; i < 8; ++i)
50 {
51 if ((UImm & 0x00FF) == 0x00FF)
52 build |= 1 << i;
53 else if ((UImm & 0x00FF) != 0)
54 { build = 0; break; }
55 UImm >>= 8;
56 }
57 return getI64Imm(build);
58}]>;
Andrew Lenharthfe9234d2005-10-21 01:24:05 +000059def immZAP : PatLeaf<(imm), [{
60 // immZAP predicate - True if the immediate fits is suitable for use in a
61 // ZAP instruction
62 uint64_t UImm = (uint64_t)N->getValue();
63 unsigned int build = 0;
64 for(int i = 0; i < 8; ++i)
65 {
66 if ((UImm & 0x00FF) == 0x00FF)
67 build |= 1 << i;
68 else if ((UImm & 0x00FF) != 0)
69 { build = 0; break; }
70 UImm >>= 8;
71 }
72 return build != 0;
Andrew Lenharth8b7f14e2005-10-23 03:43:48 +000073}], iZAPX>;
Andrew Lenharthfe9234d2005-10-21 01:24:05 +000074
75
76def intop : PatFrag<(ops node:$op), (sext_inreg node:$op, i32)>;
77def add4 : PatFrag<(ops node:$op1, node:$op2),
78 (add (shl node:$op1, 2), node:$op2)>;
79def sub4 : PatFrag<(ops node:$op1, node:$op2),
80 (sub (shl node:$op1, 2), node:$op2)>;
81def add8 : PatFrag<(ops node:$op1, node:$op2),
82 (add (shl node:$op1, 3), node:$op2)>;
83def sub8 : PatFrag<(ops node:$op1, node:$op2),
84 (sub (shl node:$op1, 3), node:$op2)>;
Andrew Lenharth4907d222005-10-20 00:28:31 +000085
Andrew Lenharth304d0f32005-01-22 23:41:55 +000086 // //#define FP $15
87 // //#define RA $26
88 // //#define PV $27
89 // //#define GP $29
90 // //#define SP $30
91
Andrew Lenharth50b37842005-11-22 04:20:06 +000092def PHI : PseudoInstAlpha<(ops variable_ops), "#phi", []>;
93
94def IDEF_I : PseudoInstAlpha<(ops GPRC:$RA), "#idef $RA",
95 [(set GPRC:$RA, (undef))]>;
96def IDEF_F32 : PseudoInstAlpha<(ops F4RC:$RA), "#idef $RA",
97 [(set F4RC:$RA, (undef))]>;
98def IDEF_F64 : PseudoInstAlpha<(ops F8RC:$RA), "#idef $RA",
99 [(set F8RC:$RA, (undef))]>;
100
101def WTF : PseudoInstAlpha<(ops variable_ops), "#wtf", []>;
102def ADJUSTSTACKUP : PseudoInstAlpha<(ops variable_ops), "ADJUP", []>;
103def ADJUSTSTACKDOWN : PseudoInstAlpha<(ops variable_ops), "ADJDOWN", []>;
104def ALTENT : PseudoInstAlpha<(ops s64imm:$TARGET), "$TARGET:\n", []>;
105def PCLABEL : PseudoInstAlpha<(ops s64imm:$num), "PCMARKER_$num:\n",[]>;
Andrew Lenharth06ef8842005-06-29 18:54:02 +0000106def MEMLABEL : PseudoInstAlpha<(ops s64imm:$i, s64imm:$j, s64imm:$k, s64imm:$m),
Andrew Lenharth50b37842005-11-22 04:20:06 +0000107 "LSMARKER$$$i$$$j$$$k$$$m:\n",[]>;
Andrew Lenharth95762122005-03-31 21:24:06 +0000108
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000109//*****************
110//These are shortcuts, the assembler expands them
111//*****************
112//AT = R28
113//T0-T7 = R1 - R8
114//T8-T11 = R22-R25
115
Andrew Lenharthdc0b71b2005-03-22 00:24:07 +0000116//An even better improvement on the Int = SetCC(FP): SelectCC!
Andrew Lenharth0eaf6ce2005-04-02 21:06:51 +0000117//These are evil because they hide control flow in a MBB
118//really the ISel should emit multiple MBB
Andrew Lenharthdc0b71b2005-03-22 00:24:07 +0000119let isTwoAddress = 1 in {
Andrew Lenharth0eaf6ce2005-04-02 21:06:51 +0000120//Conditional move of an int based on a FP CC
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000121 def CMOVEQ_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, F8RC:$RCOND),
Andrew Lenharth50b37842005-11-22 04:20:06 +0000122 "fbne $RCOND, 42f\n\tbis $RSRC_T,$RSRC_T,$RDEST\n42:\n", []>;
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000123 def CMOVEQi_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, u8imm:$L, F8RC:$RCOND),
Andrew Lenharth50b37842005-11-22 04:20:06 +0000124 "fbne $RCOND, 42f\n\taddq $$31,$L,$RDEST\n42:\n", []>;
Andrew Lenharthdc0b71b2005-03-22 00:24:07 +0000125
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000126 def CMOVNE_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, F8RC:$RCOND),
Andrew Lenharth50b37842005-11-22 04:20:06 +0000127 "fbeq $RCOND, 42f\n\tbis $RSRC_T,$RSRC_T,$RDEST\n42:\n", []>;
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000128 def CMOVNEi_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, u8imm:$L, F8RC:$RCOND),
Andrew Lenharth50b37842005-11-22 04:20:06 +0000129 "fbeq $RCOND, 42f\n\taddq $$31,$L,$RDEST\n42:\n", []>;
Andrew Lenharth0eaf6ce2005-04-02 21:06:51 +0000130//Conditional move of an FP based on a Int CC
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000131 def FCMOVEQ_INT : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, F8RC:$RCOND),
Andrew Lenharth50b37842005-11-22 04:20:06 +0000132 "bne $RCOND, 42f\n\tcpys $RSRC_T,$RSRC_T,$RDEST\n42:\n", []>;
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000133 def FCMOVNE_INT : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, F8RC:$RCOND),
Andrew Lenharth50b37842005-11-22 04:20:06 +0000134 "beq $RCOND, 42f\n\tcpys $RSRC_T,$RSRC_T,$RDEST\n42:\n", []>;
Andrew Lenharthdc0b71b2005-03-22 00:24:07 +0000135}
Andrew Lenharthca3d59b2005-03-14 19:23:45 +0000136
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000137//***********************
138//Real instructions
139//***********************
140
141//Operation Form:
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000142
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000143//conditional moves, int
Andrew Lenharth1f347a32005-10-20 23:58:36 +0000144def CMOVEQ : OForm4< 0x11, 0x24, "cmoveq $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND = zero
145def CMOVEQi : OForm4L< 0x11, 0x24, "cmoveq $RCOND,$L,$RDEST">; //CMOVE if RCOND = zero
146def CMOVGE : OForm4< 0x11, 0x46, "cmovge $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND >= zero
147def CMOVGEi : OForm4L< 0x11, 0x46, "cmovge $RCOND,$L,$RDEST">; //CMOVE if RCOND >= zero
148def CMOVGT : OForm4< 0x11, 0x66, "cmovgt $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND > zero
149def CMOVGTi : OForm4L< 0x11, 0x66, "cmovgt $RCOND,$L,$RDEST">; //CMOVE if RCOND > zero
150def CMOVLBC : OForm4< 0x11, 0x16, "cmovlbc $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND low bit clear
151def CMOVLBCi : OForm4L< 0x11, 0x16, "cmovlbc $RCOND,$L,$RDEST">; //CMOVE if RCOND low bit clear
152def CMOVLBS : OForm4< 0x11, 0x14, "cmovlbs $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND low bit set
153def CMOVLBSi : OForm4L< 0x11, 0x14, "cmovlbs $RCOND,$L,$RDEST">; //CMOVE if RCOND low bit set
154def CMOVLE : OForm4< 0x11, 0x64, "cmovle $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND <= zero
155def CMOVLEi : OForm4L< 0x11, 0x64, "cmovle $RCOND,$L,$RDEST">; //CMOVE if RCOND <= zero
156def CMOVLT : OForm4< 0x11, 0x44, "cmovlt $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND < zero
157def CMOVLTi : OForm4L< 0x11, 0x44, "cmovlt $RCOND,$L,$RDEST">; //CMOVE if RCOND < zero
158def CMOVNE : OForm4< 0x11, 0x26, "cmovne $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND != zero
159def CMOVNEi : OForm4L< 0x11, 0x26, "cmovne $RCOND,$L,$RDEST">; //CMOVE if RCOND != zero
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000160
Andrew Lenharth7f0db912005-11-30 07:19:56 +0000161//FIXME: fold setcc with select
162def : Pat<(select GPRC:$which, GPRC:$src1, GPRC:$src2),
163 (CMOVEQ GPRC:$src1, GPRC:$src2, GPRC:$which)>;
164
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000165
Andrew Lenharth4907d222005-10-20 00:28:31 +0000166def ADDL : OForm< 0x10, 0x00, "addl $RA,$RB,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000167 [(set GPRC:$RC, (intop (add GPRC:$RA, GPRC:$RB)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000168def ADDLi : OFormL<0x10, 0x00, "addl $RA,$L,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000169 [(set GPRC:$RC, (intop (add GPRC:$RA, immUExt8:$L)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000170def ADDQ : OForm< 0x10, 0x20, "addq $RA,$RB,$RC",
171 [(set GPRC:$RC, (add GPRC:$RA, GPRC:$RB))]>;
172def ADDQi : OFormL<0x10, 0x20, "addq $RA,$L,$RC",
173 [(set GPRC:$RC, (add GPRC:$RA, immUExt8:$L))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000174def AND : OForm< 0x11, 0x00, "and $RA,$RB,$RC",
175 [(set GPRC:$RC, (and GPRC:$RA, GPRC:$RB))]>;
176def ANDi : OFormL<0x11, 0x00, "and $RA,$L,$RC",
177 [(set GPRC:$RC, (and GPRC:$RA, immUExt8:$L))]>;
178def BIC : OForm< 0x11, 0x08, "bic $RA,$RB,$RC",
179 [(set GPRC:$RC, (and GPRC:$RA, (not GPRC:$RB)))]>;
180def BICi : OFormL<0x11, 0x08, "bic $RA,$L,$RC", []>;
181// [(set GPRC:$RC, (and GPRC:$RA, (not immUExt8:$L)))]>; //FIXME?
182def BIS : OForm< 0x11, 0x20, "bis $RA,$RB,$RC",
183 [(set GPRC:$RC, (or GPRC:$RA, GPRC:$RB))]>;
184def BISi : OFormL<0x11, 0x20, "bis $RA,$L,$RC",
185 [(set GPRC:$RC, (or GPRC:$RA, immUExt8:$L))]>;
Andrew Lenharth1f347a32005-10-20 23:58:36 +0000186def CTLZ : OForm2<0x1C, 0x32, "CTLZ $RB,$RC",
Andrew Lenharth964b6aa2005-10-20 19:39:24 +0000187 [(set GPRC:$RC, (ctlz GPRC:$RB))]>;
Andrew Lenharth1f347a32005-10-20 23:58:36 +0000188def CTPOP : OForm2<0x1C, 0x30, "CTPOP $RB,$RC",
Andrew Lenharth964b6aa2005-10-20 19:39:24 +0000189 [(set GPRC:$RC, (ctpop GPRC:$RB))]>;
Andrew Lenharth1f347a32005-10-20 23:58:36 +0000190def CTTZ : OForm2<0x1C, 0x33, "CTTZ $RB,$RC",
Andrew Lenharth964b6aa2005-10-20 19:39:24 +0000191 [(set GPRC:$RC, (cttz GPRC:$RB))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000192def EQV : OForm< 0x11, 0x48, "eqv $RA,$RB,$RC",
193 [(set GPRC:$RC, (xor GPRC:$RA, (not GPRC:$RB)))]>;
194def EQVi : OFormL<0x11, 0x48, "eqv $RA,$L,$RC", []>;
195// [(set GPRC:$RC, (xor GPRC:$RA, (not immUExt8:$L)))]>;
196//def EXTBL : OForm< 0x12, 0x06, "EXTBL $RA,$RB,$RC", []>; //Extract byte low
197//def EXTBLi : OFormL<0x12, 0x06, "EXTBL $RA,$L,$RC", []>; //Extract byte low
198//def EXTLH : OForm< 0x12, 0x6A, "EXTLH $RA,$RB,$RC", []>; //Extract longword high
199//def EXTLHi : OFormL<0x12, 0x6A, "EXTLH $RA,$L,$RC", []>; //Extract longword high
200//def EXTLL : OForm< 0x12, 0x26, "EXTLL $RA,$RB,$RC", []>; //Extract longword low
201//def EXTLLi : OFormL<0x12, 0x26, "EXTLL $RA,$L,$RC", []>; //Extract longword low
202//def EXTQH : OForm< 0x12, 0x7A, "EXTQH $RA,$RB,$RC", []>; //Extract quadword high
203//def EXTQHi : OFormL<0x12, 0x7A, "EXTQH $RA,$L,$RC", []>; //Extract quadword high
204//def EXTQ : OForm< 0x12, 0x36, "EXTQ $RA,$RB,$RC", []>; //Extract quadword low
205//def EXTQi : OFormL<0x12, 0x36, "EXTQ $RA,$L,$RC", []>; //Extract quadword low
206//def EXTWH : OForm< 0x12, 0x5A, "EXTWH $RA,$RB,$RC", []>; //Extract word high
207//def EXTWHi : OFormL<0x12, 0x5A, "EXTWH $RA,$L,$RC", []>; //Extract word high
208//def EXTWL : OForm< 0x12, 0x16, "EXTWL $RA,$RB,$RC", []>; //Extract word low
209//def EXTWLi : OFormL<0x12, 0x16, "EXTWL $RA,$L,$RC", []>; //Extract word low
210//def IMPLVER : OForm< 0x11, 0x6C, "IMPLVER $RA,$RB,$RC", []>; //Implementation version
211//def IMPLVERi : OFormL<0x11, 0x6C, "IMPLVER $RA,$L,$RC", []>; //Implementation version
212//def INSBL : OForm< 0x12, 0x0B, "INSBL $RA,$RB,$RC", []>; //Insert byte low
213//def INSBLi : OFormL<0x12, 0x0B, "INSBL $RA,$L,$RC", []>; //Insert byte low
214//def INSLH : OForm< 0x12, 0x67, "INSLH $RA,$RB,$RC", []>; //Insert longword high
215//def INSLHi : OFormL<0x12, 0x67, "INSLH $RA,$L,$RC", []>; //Insert longword high
216//def INSLL : OForm< 0x12, 0x2B, "INSLL $RA,$RB,$RC", []>; //Insert longword low
217//def INSLLi : OFormL<0x12, 0x2B, "INSLL $RA,$L,$RC", []>; //Insert longword low
218//def INSQH : OForm< 0x12, 0x77, "INSQH $RA,$RB,$RC", []>; //Insert quadword high
219//def INSQHi : OFormL<0x12, 0x77, "INSQH $RA,$L,$RC", []>; //Insert quadword high
220//def INSQL : OForm< 0x12, 0x3B, "INSQL $RA,$RB,$RC", []>; //Insert quadword low
221//def INSQLi : OFormL<0x12, 0x3B, "INSQL $RA,$L,$RC", []>; //Insert quadword low
222//def INSWH : OForm< 0x12, 0x57, "INSWH $RA,$RB,$RC", []>; //Insert word high
223//def INSWHi : OFormL<0x12, 0x57, "INSWH $RA,$L,$RC", []>; //Insert word high
224//def INSWL : OForm< 0x12, 0x1B, "INSWL $RA,$RB,$RC", []>; //Insert word low
225//def INSWLi : OFormL<0x12, 0x1B, "INSWL $RA,$L,$RC", []>; //Insert word low
226//def MSKBL : OForm< 0x12, 0x02, "MSKBL $RA,$RB,$RC", []>; //Mask byte low
227//def MSKBLi : OFormL<0x12, 0x02, "MSKBL $RA,$L,$RC", []>; //Mask byte low
228//def MSKLH : OForm< 0x12, 0x62, "MSKLH $RA,$RB,$RC", []>; //Mask longword high
229//def MSKLHi : OFormL<0x12, 0x62, "MSKLH $RA,$L,$RC", []>; //Mask longword high
230//def MSKLL : OForm< 0x12, 0x22, "MSKLL $RA,$RB,$RC", []>; //Mask longword low
231//def MSKLLi : OFormL<0x12, 0x22, "MSKLL $RA,$L,$RC", []>; //Mask longword low
232//def MSKQH : OForm< 0x12, 0x72, "MSKQH $RA,$RB,$RC", []>; //Mask quadword high
233//def MSKQHi : OFormL<0x12, 0x72, "MSKQH $RA,$L,$RC", []>; //Mask quadword high
234//def MSKQL : OForm< 0x12, 0x32, "MSKQL $RA,$RB,$RC", []>; //Mask quadword low
235//def MSKQLi : OFormL<0x12, 0x32, "MSKQL $RA,$L,$RC", []>; //Mask quadword low
236//def MSKWH : OForm< 0x12, 0x52, "MSKWH $RA,$RB,$RC", []>; //Mask word high
237//def MSKWHi : OFormL<0x12, 0x52, "MSKWH $RA,$L,$RC", []>; //Mask word high
238//def MSKWL : OForm< 0x12, 0x12, "MSKWL $RA,$RB,$RC", []>; //Mask word low
239//def MSKWLi : OFormL<0x12, 0x12, "MSKWL $RA,$L,$RC", []>; //Mask word low
Chris Lattnerae4be982005-10-20 04:21:06 +0000240
Andrew Lenharth4907d222005-10-20 00:28:31 +0000241def MULL : OForm< 0x13, 0x00, "mull $RA,$RB,$RC",
Chris Lattnerae4be982005-10-20 04:21:06 +0000242 [(set GPRC:$RC, (intop (mul GPRC:$RA, GPRC:$RB)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000243def MULLi : OFormL<0x13, 0x00, "mull $RA,$L,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000244 [(set GPRC:$RC, (intop (mul GPRC:$RA, immUExt8:$L)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000245def MULQ : OForm< 0x13, 0x20, "mulq $RA,$RB,$RC",
246 [(set GPRC:$RC, (mul GPRC:$RA, GPRC:$RB))]>;
247def MULQi : OFormL<0x13, 0x20, "mulq $RA,$L,$RC",
248 [(set GPRC:$RC, (mul GPRC:$RA, immUExt8:$L))]>;
249def ORNOT : OForm< 0x11, 0x28, "ornot $RA,$RB,$RC",
250 [(set GPRC:$RC, (or GPRC:$RA, (not GPRC:$RB)))]>;
251def ORNOTi : OFormL<0x11, 0x28, "ornot $RA,$L,$RC", []>;
252// [(set GPRC:$RC, (or GPRC:$RA, (not immUExt8:$L)))]>;
253def S4ADDL : OForm< 0x10, 0x02, "s4addl $RA,$RB,$RC",
Chris Lattnerae4be982005-10-20 04:21:06 +0000254 [(set GPRC:$RC, (intop (add4 GPRC:$RA, GPRC:$RB)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000255def S4ADDLi : OFormL<0x10, 0x02, "s4addl $RA,$L,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000256 [(set GPRC:$RC, (intop (add4 GPRC:$RA, immUExt8:$L)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000257def S4ADDQ : OForm< 0x10, 0x22, "s4addq $RA,$RB,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000258 [(set GPRC:$RC, (add4 GPRC:$RA, GPRC:$RB))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000259def S4ADDQi : OFormL<0x10, 0x22, "s4addq $RA,$L,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000260 [(set GPRC:$RC, (add4 GPRC:$RA, immUExt8:$L))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000261def S4SUBL : OForm< 0x10, 0x0B, "s4subl $RA,$RB,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000262 [(set GPRC:$RC, (intop (sub4 GPRC:$RA, GPRC:$RB)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000263def S4SUBLi : OFormL<0x10, 0x0B, "s4subl $RA,$L,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000264 [(set GPRC:$RC, (intop (sub4 GPRC:$RA, immUExt8:$L)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000265def S4SUBQ : OForm< 0x10, 0x2B, "s4subq $RA,$RB,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000266 [(set GPRC:$RC, (sub4 GPRC:$RA, GPRC:$RB))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000267def S4SUBQi : OFormL<0x10, 0x2B, "s4subq $RA,$L,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000268 [(set GPRC:$RC, (sub4 GPRC:$RA, immUExt8:$L))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000269def S8ADDL : OForm< 0x10, 0x12, "s8addl $RA,$RB,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000270 [(set GPRC:$RC, (intop (add8 GPRC:$RA, GPRC:$RB)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000271def S8ADDLi : OFormL<0x10, 0x12, "s8addl $RA,$L,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000272 [(set GPRC:$RC, (intop (add8 GPRC:$RA, immUExt8:$L)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000273def S8ADDQ : OForm< 0x10, 0x32, "s8addq $RA,$RB,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000274 [(set GPRC:$RC, (add8 GPRC:$RA, GPRC:$RB))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000275def S8ADDQi : OFormL<0x10, 0x32, "s8addq $RA,$L,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000276 [(set GPRC:$RC, (add8 GPRC:$RA, immUExt8:$L))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000277def S8SUBL : OForm< 0x10, 0x1B, "s8subl $RA,$RB,$RC",
Chris Lattnerae4be982005-10-20 04:21:06 +0000278 [(set GPRC:$RC, (intop (sub8 GPRC:$RA, GPRC:$RB)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000279def S8SUBLi : OFormL<0x10, 0x1B, "s8subl $RA,$L,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000280 [(set GPRC:$RC, (intop (sub8 GPRC:$RA, immUExt8:$L)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000281def S8SUBQ : OForm< 0x10, 0x3B, "s8subq $RA,$RB,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000282 [(set GPRC:$RC, (sub8 GPRC:$RA, GPRC:$RB))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000283def S8SUBQi : OFormL<0x10, 0x3B, "s8subq $RA,$L,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000284 [(set GPRC:$RC, (sub8 GPRC:$RA, immUExt8:$L))]>;
Andrew Lenharth1f347a32005-10-20 23:58:36 +0000285def SEXTB : OForm2<0x1C, 0x00, "sextb $RB,$RC",
Andrew Lenharth964b6aa2005-10-20 19:39:24 +0000286 [(set GPRC:$RC, (sext_inreg GPRC:$RB, i8))]>;
Andrew Lenharth1f347a32005-10-20 23:58:36 +0000287def SEXTW : OForm2<0x1C, 0x01, "sextw $RB,$RC",
Andrew Lenharth964b6aa2005-10-20 19:39:24 +0000288 [(set GPRC:$RC, (sext_inreg GPRC:$RB, i16))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000289def SL : OForm< 0x12, 0x39, "sll $RA,$RB,$RC",
290 [(set GPRC:$RC, (shl GPRC:$RA, GPRC:$RB))]>;
291def SLi : OFormL<0x12, 0x39, "sll $RA,$L,$RC",
292 [(set GPRC:$RC, (shl GPRC:$RA, immUExt8:$L))]>;
293def SRA : OForm< 0x12, 0x3C, "sra $RA,$RB,$RC",
294 [(set GPRC:$RC, (sra GPRC:$RA, GPRC:$RB))]>;
295def SRAi : OFormL<0x12, 0x3C, "sra $RA,$L,$RC",
296 [(set GPRC:$RC, (sra GPRC:$RA, immUExt8:$L))]>;
297def SRL : OForm< 0x12, 0x34, "srl $RA,$RB,$RC",
298 [(set GPRC:$RC, (srl GPRC:$RA, GPRC:$RB))]>;
299def SRLi : OFormL<0x12, 0x34, "srl $RA,$L,$RC",
300 [(set GPRC:$RC, (srl GPRC:$RA, immUExt8:$L))]>;
301def SUBL : OForm< 0x10, 0x09, "subl $RA,$RB,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000302 [(set GPRC:$RC, (intop (sub GPRC:$RA, GPRC:$RB)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000303def SUBLi : OFormL<0x10, 0x09, "subl $RA,$L,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000304 [(set GPRC:$RC, (intop (sub GPRC:$RA, immUExt8:$L)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000305def SUBQ : OForm< 0x10, 0x29, "subq $RA,$RB,$RC",
306 [(set GPRC:$RC, (sub GPRC:$RA, GPRC:$RB))]>;
307def SUBQi : OFormL<0x10, 0x29, "subq $RA,$L,$RC",
308 [(set GPRC:$RC, (sub GPRC:$RA, immUExt8:$L))]>;
Andrew Lenharth964b6aa2005-10-20 19:39:24 +0000309def UMULH : OForm< 0x13, 0x30, "umulh $RA,$RB,$RC",
310 [(set GPRC:$RC, (mulhu GPRC:$RA, GPRC:$RB))]>;
311def UMULHi : OFormL<0x13, 0x30, "umulh $RA,$L,$RC",
312 [(set GPRC:$RC, (mulhu GPRC:$RA, immUExt8:$L))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000313def XOR : OForm< 0x11, 0x40, "xor $RA,$RB,$RC",
314 [(set GPRC:$RC, (xor GPRC:$RA, GPRC:$RB))]>;
315def XORi : OFormL<0x11, 0x40, "xor $RA,$L,$RC",
316 [(set GPRC:$RC, (xor GPRC:$RA, immUExt8:$L))]>;
Andrew Lenharthfe9234d2005-10-21 01:24:05 +0000317//FIXME: what to do about zap? the cases it catches are very complex
Andrew Lenharth4907d222005-10-20 00:28:31 +0000318def ZAP : OForm< 0x12, 0x30, "zap $RA,$RB,$RC", []>; //Zero bytes
Andrew Lenharthfe9234d2005-10-21 01:24:05 +0000319//ZAPi is useless give ZAPNOTi
Andrew Lenharth4907d222005-10-20 00:28:31 +0000320def ZAPi : OFormL<0x12, 0x30, "zap $RA,$L,$RC", []>; //Zero bytes
Andrew Lenharthfe9234d2005-10-21 01:24:05 +0000321//FIXME: what to do about zapnot? see ZAP :)
Andrew Lenharth4907d222005-10-20 00:28:31 +0000322def ZAPNOT : OForm< 0x12, 0x31, "zapnot $RA,$RB,$RC", []>; //Zero bytes not
Andrew Lenharth8b7f14e2005-10-23 03:43:48 +0000323def ZAPNOTi : OFormL<0x12, 0x31, "zapnot $RA,$L,$RC",
324 [(set GPRC:$RC, (and GPRC:$RA, immZAP:$L))]>;
Andrew Lenharth2d6f0222005-01-24 19:44:07 +0000325
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000326//Comparison, int
Andrew Lenharth2012cc02005-10-26 18:44:45 +0000327//So this is a waste of what this instruction can do, but it still saves something
328def CMPBGE : OForm< 0x10, 0x0F, "cmpbge $RA,$RB,$RC",
329 [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), (and GPRC:$RB, 255)))]>;
330def CMPBGEi : OFormL<0x10, 0x0F, "cmpbge $RA,$L,$RC",
331 [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), immUExt8:$L))]>;
332def CMPEQ : OForm< 0x10, 0x2D, "cmpeq $RA,$RB,$RC",
333 [(set GPRC:$RC, (seteq GPRC:$RA, GPRC:$RB))]>;
334def CMPEQi : OFormL<0x10, 0x2D, "cmpeq $RA,$L,$RC",
335 [(set GPRC:$RC, (seteq GPRC:$RA, immUExt8:$L))]>;
336def CMPLE : OForm< 0x10, 0x6D, "cmple $RA,$RB,$RC",
337 [(set GPRC:$RC, (setle GPRC:$RA, GPRC:$RB))]>;
338def CMPLEi : OFormL<0x10, 0x6D, "cmple $RA,$L,$RC",
339 [(set GPRC:$RC, (setle GPRC:$RA, immUExt8:$L))]>;
340def CMPLT : OForm< 0x10, 0x4D, "cmplt $RA,$RB,$RC",
341 [(set GPRC:$RC, (setlt GPRC:$RA, GPRC:$RB))]>;
342def CMPLTi : OFormL<0x10, 0x4D, "cmplt $RA,$L,$RC",
343 [(set GPRC:$RC, (setlt GPRC:$RA, immUExt8:$L))]>;
344def CMPULE : OForm< 0x10, 0x3D, "cmpule $RA,$RB,$RC",
345 [(set GPRC:$RC, (setule GPRC:$RA, GPRC:$RB))]>;
346def CMPULEi : OFormL<0x10, 0x3D, "cmpule $RA,$L,$RC",
347 [(set GPRC:$RC, (setule GPRC:$RA, immUExt8:$L))]>;
348def CMPULT : OForm< 0x10, 0x1D, "cmpult $RA,$RB,$RC",
Andrew Lenharth50b37842005-11-22 04:20:06 +0000349 [(set GPRC:$RC, (setult GPRC:$RA, GPRC:$RB))]>;
Andrew Lenharth2012cc02005-10-26 18:44:45 +0000350def CMPULTi : OFormL<0x10, 0x1D, "cmpult $RA,$L,$RC",
Andrew Lenharth50b37842005-11-22 04:20:06 +0000351 [(set GPRC:$RC, (setult GPRC:$RA, immUExt8:$L))]>;
Andrew Lenharth2012cc02005-10-26 18:44:45 +0000352
353//Patterns for unsupported int comparisons
354def : Pat<(setueq GPRC:$X, GPRC:$Y), (CMPEQ GPRC:$X, GPRC:$Y)>;
355def : Pat<(setueq GPRC:$X, immUExt8:$Y), (CMPEQi GPRC:$X, immUExt8:$Y)>;
356
357def : Pat<(setugt GPRC:$X, GPRC:$Y), (CMPULT GPRC:$Y, GPRC:$X)>;
358def : Pat<(setugt immUExt8:$X, GPRC:$Y), (CMPULTi GPRC:$Y, immUExt8:$X)>;
359
360def : Pat<(setuge GPRC:$X, GPRC:$Y), (CMPULE GPRC:$Y, GPRC:$X)>;
361def : Pat<(setuge immUExt8:$X, GPRC:$Y), (CMPULEi GPRC:$Y, immUExt8:$X)>;
362
363def : Pat<(setgt GPRC:$X, GPRC:$Y), (CMPLT GPRC:$Y, GPRC:$X)>;
364def : Pat<(setgt immUExt8:$X, GPRC:$Y), (CMPLTi GPRC:$Y, immUExt8:$X)>;
365
366def : Pat<(setge GPRC:$X, GPRC:$Y), (CMPLE GPRC:$Y, GPRC:$X)>;
367def : Pat<(setge immUExt8:$X, GPRC:$Y), (CMPLEi GPRC:$Y, immUExt8:$X)>;
368
369def : Pat<(setne GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>;
370def : Pat<(setne GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQi GPRC:$X, immUExt8:$Y), 0)>;
371
372def : Pat<(setune GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>;
373def : Pat<(setune GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQ GPRC:$X, immUExt8:$Y), 0)>;
374
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000375
Andrew Lenharth4907d222005-10-20 00:28:31 +0000376let isReturn = 1, isTerminator = 1 in
Andrew Lenharthf3f951a2005-07-22 20:50:29 +0000377 def RET : MbrForm< 0x1A, 0x02, (ops GPRC:$RD, GPRC:$RS, s64imm:$DISP), "ret $RD,($RS),$DISP">; //Return from subroutine
Andrew Lenharth4907d222005-10-20 00:28:31 +0000378//DAG Version:
379let isReturn = 1, isTerminator = 1, Ra = 31, Rb = 26, disp = 1, Uses = [R26] in
380 def RETDAG : MbrForm< 0x1A, 0x02, (ops), "ret $$31,($$26),1">; //Return from subroutine
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000381
Andrew Lenharthf3f951a2005-07-22 20:50:29 +0000382def JMP : MbrForm< 0x1A, 0x00, (ops GPRC:$RD, GPRC:$RS, GPRC:$DISP), "jmp $RD,($RS),$DISP">; //Jump
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000383let isCall = 1,
384 Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19,
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000385 R20, R21, R22, R23, R24, R25, R27, R28, R29,
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000386 F0, F1,
387 F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
Andrew Lenharth1e0d9bd2005-04-14 17:34:20 +0000388 F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R29] in {
Andrew Lenharthf3f951a2005-07-22 20:50:29 +0000389 def JSR : MbrForm< 0x1A, 0x01, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr $RD,($RS),$DISP">; //Jump to subroutine
390 def BSR : BForm<0x34, "bsr $RA,$DISP">; //Branch to subroutine
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000391}
Andrew Lenharth8b7f14e2005-10-23 03:43:48 +0000392let isCall = 1,
393 Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19,
394 R20, R21, R22, R23, R24, R25, R26, R27, R28, R29,
395 F0, F1,
396 F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
397 F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R27, R29] in {
398 def JSRDAG : MbrForm< 0x1A, 0x01, (ops ), "jsr $$26,($$27),0">; //Jump to subroutine
399}
Andrew Lenharthcf8bf382005-07-01 19:12:13 +0000400let isCall = 1, Defs = [R24, R25, R27, R28], Uses = [R24, R25] in
Andrew Lenharthf3f951a2005-07-22 20:50:29 +0000401 def JSRs : MbrForm< 0x1A, 0x01, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr $RD,($RS),$DISP">; //Jump to div or rem
Andrew Lenharthcf8bf382005-07-01 19:12:13 +0000402
Andrew Lenharthf3f951a2005-07-22 20:50:29 +0000403def JSR_COROUTINE : MbrForm< 0x1A, 0x03, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr_coroutine $RD,($RS),$DISP">; //Jump to subroutine return
404def BR : BForm<0x30, "br $RA,$DISP">; //Branch
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000405
Andrew Lenharth756fbeb2005-10-22 22:06:58 +0000406def BR_DAG : BFormD<0x30, "br $$31,$DISP">; //Branch
407
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000408//Stores, int
Andrew Lenharthf3f951a2005-07-22 20:50:29 +0000409def STB : MForm<0x0E, "stb $RA,$DISP($RB)">; // Store byte
410def STW : MForm<0x0D, "stw $RA,$DISP($RB)">; // Store word
411def STL : MForm<0x2C, "stl $RA,$DISP($RB)">; // Store longword
412def STQ : MForm<0x2D, "stq $RA,$DISP($RB)">; //Store quadword
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000413
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000414//Loads, int
Andrew Lenharthf3f951a2005-07-22 20:50:29 +0000415def LDL : MForm<0x28, "ldl $RA,$DISP($RB)">; // Load sign-extended longword
416def LDQ : MForm<0x29, "ldq $RA,$DISP($RB)">; //Load quadword
417def LDBU : MForm<0x0A, "ldbu $RA,$DISP($RB)">; //Load zero-extended byte
418def LDWU : MForm<0x0C, "ldwu $RA,$DISP($RB)">; //Load zero-extended word
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000419
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000420//Stores, float
Andrew Lenharth7f0db912005-11-30 07:19:56 +0000421let OperandList = (ops F4RC:$RA, s16imm:$DISP, GPRC:$RB) in
422def STS : MFormAlt<0x26, "sts $RA,$DISP($RB)">; //Store S_floating
423let OperandList = (ops F8RC:$RA, s16imm:$DISP, GPRC:$RB) in
424def STT : MFormAlt<0x27, "stt $RA,$DISP($RB)">; //Store T_floating
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000425
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000426//Loads, float
Andrew Lenharth7f0db912005-11-30 07:19:56 +0000427let OperandList = (ops F4RC:$RA, s16imm:$DISP, GPRC:$RB) in
428def LDS : MFormAlt<0x22, "lds $RA,$DISP($RB)">; //Load S_floating
429let OperandList = (ops F8RC:$RA, s16imm:$DISP, GPRC:$RB) in
430def LDT : MFormAlt<0x23, "ldt $RA,$DISP($RB)">; //Load T_floating
Andrew Lenharthc1faced2005-02-01 01:37:24 +0000431
432//Load address
Andrew Lenharthf3f951a2005-07-22 20:50:29 +0000433def LDA : MForm<0x08, "lda $RA,$DISP($RB)">; //Load address
434def LDAH : MForm<0x09, "ldah $RA,$DISP($RB)">; //Load address high
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000435
436
Andrew Lenharthc7989ce2005-06-29 00:31:08 +0000437//Loads, int, Rellocated Low form
Andrew Lenharth1f3e8082005-08-12 16:14:08 +0000438def LDLr : MForm<0x28, "ldl $RA,$DISP($RB)\t\t!gprellow">; // Load sign-extended longword
439def LDQr : MForm<0x29, "ldq $RA,$DISP($RB)\t\t!gprellow">; //Load quadword
440def LDBUr : MForm<0x0A, "ldbu $RA,$DISP($RB)\t\t!gprellow">; //Load zero-extended byte
441def LDWUr : MForm<0x0C, "ldwu $RA,$DISP($RB)\t\t!gprellow">; //Load zero-extended word
Andrew Lenharthfe895e32005-06-27 17:15:36 +0000442
Andrew Lenharthc7989ce2005-06-29 00:31:08 +0000443//Loads, float, Rellocated Low form
Andrew Lenharth7f0db912005-11-30 07:19:56 +0000444let OperandList = (ops F4RC:$RA, s16imm:$DISP, GPRC:$RB) in
445def LDSr : MFormAlt<0x22, "lds $RA,$DISP($RB)\t\t!gprellow">; //Load S_floating
446let OperandList = (ops F8RC:$RA, s16imm:$DISP, GPRC:$RB) in
447def LDTr : MFormAlt<0x23, "ldt $RA,$DISP($RB)\t\t!gprellow">; //Load T_floating
Andrew Lenharthfe895e32005-06-27 17:15:36 +0000448
Andrew Lenharthc7989ce2005-06-29 00:31:08 +0000449//Load address, rellocated low and high form
Andrew Lenharth1f3e8082005-08-12 16:14:08 +0000450def LDAr : MForm<0x08, "lda $RA,$DISP($RB)\t\t!gprellow">; //Load address
451def LDAHr : MForm<0x09, "ldah $RA,$DISP($RB)\t\t!gprelhigh">; //Load address high
Andrew Lenharthf3f951a2005-07-22 20:50:29 +0000452
453//load address, rellocated gpdist form
Andrew Lenharth1f3e8082005-08-12 16:14:08 +0000454def LDAg : MgForm<0x08, "lda $RA,0($RB)\t\t!gpdisp!$NUM">; //Load address
455def LDAHg : MgForm<0x09, "ldah $RA,0($RB)\t\t!gpdisp!$NUM">; //Load address
Andrew Lenharthf3f951a2005-07-22 20:50:29 +0000456
Andrew Lenharthfe895e32005-06-27 17:15:36 +0000457
Andrew Lenharthc7989ce2005-06-29 00:31:08 +0000458//Load quad, rellocated literal form
Andrew Lenharth1f3e8082005-08-12 16:14:08 +0000459def LDQl : MForm<0x29, "ldq $RA,$DISP($RB)\t\t!literal">; //Load quadword
Andrew Lenharthfe895e32005-06-27 17:15:36 +0000460
Andrew Lenharthfce587e2005-06-29 00:39:17 +0000461//Stores, int
Andrew Lenharth1f3e8082005-08-12 16:14:08 +0000462def STBr : MForm<0x0E, "stb $RA,$DISP($RB)\t\t!gprellow">; // Store byte
463def STWr : MForm<0x0D, "stw $RA,$DISP($RB)\t\t!gprellow">; // Store word
464def STLr : MForm<0x2C, "stl $RA,$DISP($RB)\t\t!gprellow">; // Store longword
465def STQr : MForm<0x2D, "stq $RA,$DISP($RB)\t\t!gprellow">; //Store quadword
Andrew Lenharthfce587e2005-06-29 00:39:17 +0000466
467//Stores, float
Andrew Lenharth7f0db912005-11-30 07:19:56 +0000468let OperandList = (ops F4RC:$RA, s16imm:$DISP, GPRC:$RB) in
469def STSr : MFormAlt<0x26, "sts $RA,$DISP($RB)\t\t!gprellow">; //Store S_floating
470let OperandList = (ops F8RC:$RA, s16imm:$DISP, GPRC:$RB) in
471def STTr : MFormAlt<0x27, "stt $RA,$DISP($RB)\t\t!gprellow">; //Store T_floating
Andrew Lenharthfce587e2005-06-29 00:39:17 +0000472
473
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000474//Branches, int
Andrew Lenharthf3f951a2005-07-22 20:50:29 +0000475def BEQ : BForm<0x39, "beq $RA,$DISP">; //Branch if = zero
476def BGE : BForm<0x3E, "bge $RA,$DISP">; //Branch if >= zero
477def BGT : BForm<0x3F, "bgt $RA,$DISP">; //Branch if > zero
478def BLBC : BForm<0x38, "blbc $RA,$DISP">; //Branch if low bit clear
479def BLBS : BForm<0x3C, "blbs $RA,$DISP">; //Branch if low bit set
480def BLE : BForm<0x3B, "ble $RA,$DISP">; //Branch if <= zero
481def BLT : BForm<0x3A, "blt $RA,$DISP">; //Branch if < zero
482def BNE : BForm<0x3D, "bne $RA,$DISP">; //Branch if != zero
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000483
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000484//Branches, float
Andrew Lenharthf3f951a2005-07-22 20:50:29 +0000485def FBEQ : FBForm<0x31, "fbeq $RA,$DISP">; //Floating branch if = zero
486def FBGE : FBForm<0x36, "fbge $RA,$DISP">; //Floating branch if >= zero
487def FBGT : FBForm<0x37, "fbgt $RA,$DISP">; //Floating branch if > zero
488def FBLE : FBForm<0x33, "fble $RA,$DISP">; //Floating branch if <= zero
489def FBLT : FBForm<0x32, "fblt $RA,$DISP">; //Floating branch if < zero
490def FBNE : FBForm<0x35, "fbne $RA,$DISP">; //Floating branch if != zero
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000491
Andrew Lenharth51b8d542005-11-11 16:47:30 +0000492def RPCC : MfcForm<0x18, 0xC000, "rpcc $RA">; //Read process cycle counter
493
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000494//Basic Floating point ops
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000495
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000496//Floats
Andrew Lenharth98a32d02005-01-26 23:56:48 +0000497
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000498let OperandList = (ops F4RC:$RC, F4RC:$RB), Fa = 31 in
499def SQRTS : FPForm<0x14, 0x58B, "sqrts/su $RB,$RC",
500 [(set F4RC:$RC, (fsqrt F4RC:$RB))]>;
501
502let OperandList = (ops F4RC:$RC, F4RC:$RA, F4RC:$RB) in {
503def ADDS : FPForm<0x16, 0x580, "adds/su $RA,$RB,$RC",
504 [(set F4RC:$RC, (fadd F4RC:$RA, F4RC:$RB))]>;
505def SUBS : FPForm<0x16, 0x581, "subs/su $RA,$RB,$RC",
506 [(set F4RC:$RC, (fsub F4RC:$RA, F4RC:$RB))]>;
507def DIVS : FPForm<0x16, 0x583, "divs/su $RA,$RB,$RC",
508 [(set F4RC:$RC, (fdiv F4RC:$RA, F4RC:$RB))]>;
509def MULS : FPForm<0x16, 0x582, "muls/su $RA,$RB,$RC",
510 [(set F4RC:$RC, (fmul F4RC:$RA, F4RC:$RB))]>;
511
512def CPYSS : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",[]>; //Copy sign
513def CPYSES : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[]>; //Copy sign and exponent
514def CPYSNS : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",[]>; //Copy sign negate
515}
516
517//Doubles
518
519let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in
520def SQRTT : FPForm<0x14, 0x5AB, "sqrtt/su $RB,$RC",
521 [(set F8RC:$RC, (fsqrt F8RC:$RB))]>;
522
523let OperandList = (ops F8RC:$RC, F8RC:$RA, F8RC:$RB) in {
524def ADDT : FPForm<0x16, 0x5A0, "addt/su $RA,$RB,$RC",
525 [(set F8RC:$RC, (fadd F8RC:$RA, F8RC:$RB))]>;
526def SUBT : FPForm<0x16, 0x5A1, "subt/su $RA,$RB,$RC",
527 [(set F8RC:$RC, (fsub F8RC:$RA, F8RC:$RB))]>;
528def DIVT : FPForm<0x16, 0x5A3, "divt/su $RA,$RB,$RC",
529 [(set F8RC:$RC, (fdiv F8RC:$RA, F8RC:$RB))]>;
530def MULT : FPForm<0x16, 0x5A2, "mult/su $RA,$RB,$RC",
531 [(set F8RC:$RC, (fmul F8RC:$RA, F8RC:$RB))]>;
532
533def CPYST : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",[]>; //Copy sign
534def CPYSET : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[]>; //Copy sign and exponent
535def CPYSNT : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",[]>; //Copy sign negate
536
537def CMPTEQ : FPForm<0x16, 0x5A5, "cmpteq/su $RA,$RB,$RC", []>;
538// [(set F8RC:$RC, (seteq F8RC:$RA, F8RC:$RB))]>;
539def CMPTLE : FPForm<0x16, 0x5A7, "cmptle/su $RA,$RB,$RC", []>;
540// [(set F8RC:$RC, (setle F8RC:$RA, F8RC:$RB))]>;
541def CMPTLT : FPForm<0x16, 0x5A6, "cmptlt/su $RA,$RB,$RC", []>;
542// [(set F8RC:$RC, (setlt F8RC:$RA, F8RC:$RB))]>;
543def CMPTUN : FPForm<0x16, 0x5A4, "cmptun/su $RA,$RB,$RC", []>;
544// [(set F8RC:$RC, (setuo F8RC:$RA, F8RC:$RB))]>;
545}
546//TODO: Add lots more FP patterns
547
Andrew Lenharthb2156f92005-11-30 17:11:20 +0000548//conditional moves, floats
549let OperandList = (ops F4RC:$RDEST, F4RC:$RSRC2, F4RC:$RSRC, F8RC:$RCOND),
550 isTwoAddress = 1 in {
551def FCMOVEQS : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if = zero
552def FCMOVGES : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if >= zero
553def FCMOVGTS : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if > zero
554def FCMOVLES : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if <= zero
555def FCMOVLTS : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RSRC,$RDEST",[]>; // FCMOVE if < zero
556def FCMOVNES : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if != zero
557}
558//conditional moves, doubles
559let OperandList = (ops F8RC:$RDEST, F8RC:$RSRC2, F8RC:$RSRC, F8RC:$RCOND),
560 isTwoAddress = 1 in {
561def FCMOVEQT : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if = zero
562def FCMOVGET : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if >= zero
563def FCMOVGTT : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if > zero
564def FCMOVLET : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if <= zero
565def FCMOVLTT : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RSRC,$RDEST",[]>; // FCMOVE if < zero
566def FCMOVNET : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if != zero
567}
568
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000569
570
571let OperandList = (ops GPRC:$RC, F4RC:$RA), Fb = 31 in
572def FTOIS : FPForm<0x1C, 0x078, "ftois $RA,$RC",[]>; //Floating to integer move, S_floating
573let OperandList = (ops GPRC:$RC, F8RC:$RA), Fb = 31 in
Andrew Lenharth7f0db912005-11-30 07:19:56 +0000574def FTOIT : FPForm<0x1C, 0x070, "ftoit $RA,$RC",
575 [(set GPRC:$RC, (Alpha_ftoit F8RC:$RA))]>; //Floating to integer move
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000576let OperandList = (ops F4RC:$RC, GPRC:$RA), Fb = 31 in
577def ITOFS : FPForm<0x14, 0x004, "itofs $RA,$RC",[]>; //Integer to floating move, S_floating
578let OperandList = (ops F8RC:$RC, GPRC:$RA), Fb = 31 in
Andrew Lenharth7f0db912005-11-30 07:19:56 +0000579def ITOFT : FPForm<0x14, 0x024, "itoft $RA,$RC",
580 [(set F8RC:$RC, (Alpha_itoft GPRC:$RA))]>; //Integer to floating move
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000581
582
583let OperandList = (ops F4RC:$RC, F8RC:$RB), Fa = 31 in
Andrew Lenharth7f0db912005-11-30 07:19:56 +0000584def CVTQS : FPForm<0x16, 0x7BC, "cvtqs/sui $RB,$RC",
585 [(set F4RC:$RC, (Alpha_cvtqs F8RC:$RB))]>;
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000586let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in
Andrew Lenharth7f0db912005-11-30 07:19:56 +0000587def CVTQT : FPForm<0x16, 0x7BE, "cvtqt/sui $RB,$RC",
588 [(set F8RC:$RC, (Alpha_cvtqt F8RC:$RB))]>;
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000589let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in
Andrew Lenharthcd804962005-11-30 16:10:29 +0000590def CVTTQ : FPForm<0x16, 0x52F, "cvttq/svc $RB,$RC",
591 [(set F8RC:$RC, (Alpha_cvttq F8RC:$RB))]>;
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000592let OperandList = (ops F8RC:$RC, F4RC:$RB), Fa = 31 in
593def CVTST : FPForm<0x16, 0x6AC, "cvtst/s $RB,$RC",
594 [(set F8RC:$RC, (fextend F4RC:$RB))]>;
595let OperandList = (ops F4RC:$RC, F8RC:$RB), Fa = 31 in
596def CVTTS : FPForm<0x16, 0x7AC, "cvtts/sui $RB,$RC",
597 [(set F4RC:$RC, (fround F8RC:$RB))]>;
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000598
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000599//S_floating : IEEE Single
600//T_floating : IEEE Double
601
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000602//Unused instructions
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000603//Mnemonic Format Opcode Description
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000604//CALL_PAL Pcd 00 Trap to PALcode
605//ECB Mfc 18.E800 Evict cache block
606//EXCB Mfc 18.0400 Exception barrier
607//FETCH Mfc 18.8000 Prefetch data
608//FETCH_M Mfc 18.A000 Prefetch data, modify intent
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000609//LDL_L Mem 2A Load sign-extended longword locked
610//LDQ_L Mem 2B Load quadword locked
611//LDQ_U Mem 0B Load unaligned quadword
612//MB Mfc 18.4000 Memory barrier
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000613//STL_C Mem 2E Store longword conditional
614//STQ_C Mem 2F Store quadword conditional
615//STQ_U Mem 0F Store unaligned quadword
616//TRAPB Mfc 18.0000 Trap barrier
617//WH64 Mfc 18.F800 Write hint  64 bytes
618//WMB Mfc 18.4400 Write memory barrier
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000619//MF_FPCR F-P 17.025 Move from FPCR
620//MT_FPCR F-P 17.024 Move to FPCR
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000621//There are in the Multimedia extentions, so let's not use them yet
622//def MAXSB8 : OForm<0x1C, 0x3E, "MAXSB8 $RA,$RB,$RC">; //Vector signed byte maximum
623//def MAXSW4 : OForm< 0x1C, 0x3F, "MAXSW4 $RA,$RB,$RC">; //Vector signed word maximum
624//def MAXUB8 : OForm<0x1C, 0x3C, "MAXUB8 $RA,$RB,$RC">; //Vector unsigned byte maximum
625//def MAXUW4 : OForm< 0x1C, 0x3D, "MAXUW4 $RA,$RB,$RC">; //Vector unsigned word maximum
626//def MINSB8 : OForm< 0x1C, 0x38, "MINSB8 $RA,$RB,$RC">; //Vector signed byte minimum
627//def MINSW4 : OForm< 0x1C, 0x39, "MINSW4 $RA,$RB,$RC">; //Vector signed word minimum
628//def MINUB8 : OForm< 0x1C, 0x3A, "MINUB8 $RA,$RB,$RC">; //Vector unsigned byte minimum
629//def MINUW4 : OForm< 0x1C, 0x3B, "MINUW4 $RA,$RB,$RC">; //Vector unsigned word minimum
630//def PERR : OForm< 0x1C, 0x31, "PERR $RA,$RB,$RC">; //Pixel error
631//def PKLB : OForm< 0x1C, 0x37, "PKLB $RA,$RB,$RC">; //Pack longwords to bytes
632//def PKWB : OForm<0x1C, 0x36, "PKWB $RA,$RB,$RC">; //Pack words to bytes
633//def UNPKBL : OForm< 0x1C, 0x35, "UNPKBL $RA,$RB,$RC">; //Unpack bytes to longwords
634//def UNPKBW : OForm< 0x1C, 0x34, "UNPKBW $RA,$RB,$RC">; //Unpack bytes to words
635//CVTLQ F-P 17.010 Convert longword to quadword
636//CVTQL F-P 17.030 Convert quadword to longword
637//def AMASK : OForm< 0x11, 0x61, "AMASK $RA,$RB,$RC", []>; //Architecture mask
638//def AMASKi : OFormL<0x11, 0x61, "AMASK $RA,$L,$RC", []>; //Architecture mask
639
640
Andrew Lenharth50b37842005-11-22 04:20:06 +0000641//Constant handling
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000642
Andrew Lenharth50b37842005-11-22 04:20:06 +0000643def immConst2Part : PatLeaf<(imm), [{
644 // immZAP predicate - True if the immediate fits is suitable for use in a
645 // ZAP instruction
646 int64_t val = (int64_t)N->getValue();
647 return (val <= (int64_t)IMM_HIGH +(int64_t)IMM_HIGH* (int64_t)IMM_MULT &
648 val >= (int64_t)IMM_LOW + (int64_t)IMM_LOW * (int64_t)IMM_MULT);
649}]>;
650
651//TODO: factor this out
652def LL16 : SDNodeXForm<imm, [{
653int64_t l = N->getValue();
654 int64_t y = l / IMM_MULT;
655 if (l % IMM_MULT > IMM_HIGH)
656 ++y;
657 return getI64Imm(l - y * IMM_MULT);
658}]>;
659//TODO: factor this out
660def LH16 : SDNodeXForm<imm, [{
661int64_t l = N->getValue();
662 int64_t y = l / IMM_MULT;
663 if (l % IMM_MULT > IMM_HIGH)
664 ++y;
665 return getI64Imm(y);
666}]>;
667
668def : Pat<(i64 immConst2Part:$imm),
669 (LDA (LL16 immConst2Part:$imm), (LDAH (LH16 immConst2Part:$imm), R31))>;
Andrew Lenharth756fbeb2005-10-22 22:06:58 +0000670
671def : Pat<(i64 immSExt16:$imm),
672 (LDA immSExt16:$imm, R31)>;
Andrew Lenharth50b37842005-11-22 04:20:06 +0000673
674//TODO: I want to just define these like this!
675//def : Pat<(i64 0),
676// (R31)>;
677//def : Pat<(f64 0.0),
678// (F31)>;
679//def : Pat<(f64 -0.0),
680// (CPYSNT F31, F31)>;
681//def : Pat<(f32 0.0),
682// (F31)>;
683//def : Pat<(f32 -0.0),
684// (CPYSNS F31, F31)>;
685
686//Misc Patterns:
687
688def : Pat<(sext_inreg GPRC:$RB, i32),
689 (ADDLi GPRC:$RB, 0)>;
690
691def : Pat<(select GPRC:$which, GPRC:$src1, GPRC:$src2),
692 (CMOVEQ GPRC:$src1, GPRC:$src2, GPRC:$which)>; //may be CMOVNE
693
Andrew Lenharth7f0db912005-11-30 07:19:56 +0000694def : Pat<(fabs F8RC:$RB),
695 (CPYST F31, F8RC:$RB)>;
696def : Pat<(fabs F4RC:$RB),
697 (CPYSS F31, F4RC:$RB)>;
698def : Pat<(fneg F8RC:$RB),
699 (CPYSNT F8RC:$RB, F8RC:$RB)>;
700def : Pat<(fneg F4RC:$RB),
701 (CPYSNS F4RC:$RB, F4RC:$RB)>;
Andrew Lenharthcd804962005-11-30 16:10:29 +0000702//Yes, signed multiply high is ugly
703def : Pat<(mulhs GPRC:$RA, GPRC:$RB),
704 (SUBQ (UMULH GPRC:$RA, GPRC:$RB), (ADDQ (CMOVGE GPRC:$RB, R31, GPRC:$RA),
705 (CMOVGE GPRC:$RA, R31, GPRC:$RB)))>;