blob: 1530b660745f0a20ef8ab9581f5e55f581dd0915 [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
Andrew Lenharth79620652005-12-05 20:50:53 +000029// These are target-independent nodes, but have target-specific formats.
30def SDT_AlphaCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i64> ]>;
31def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_AlphaCallSeq,[SDNPHasChain]>;
32def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_AlphaCallSeq,[SDNPHasChain]>;
33
Andrew Lenharth7f0db912005-11-30 07:19:56 +000034
35//********************
Andrew Lenharth4907d222005-10-20 00:28:31 +000036//Paterns for matching
37//********************
Andrew Lenharthfe9234d2005-10-21 01:24:05 +000038
Andrew Lenharth756fbeb2005-10-22 22:06:58 +000039def immUExt8 : PatLeaf<(imm), [{
40 // immUExt8 predicate - True if the immediate fits in a 8-bit zero extended
41 // field. Used by instructions like 'addi'.
42 return (unsigned long)N->getValue() == (unsigned char)N->getValue();
43}]>;
44def immSExt16 : PatLeaf<(imm), [{
45 // immSExt16 predicate - True if the immediate fits in a 16-bit sign extended
46 // field. Used by instructions like 'lda'.
47 return (int)N->getValue() == (short)N->getValue();
48}]>;
49
Andrew Lenharthfe9234d2005-10-21 01:24:05 +000050def iZAPX : SDNodeXForm<imm, [{
51 // Transformation function: get the imm to ZAPi
52 uint64_t UImm = (uint64_t)N->getValue();
53 unsigned int build = 0;
54 for(int i = 0; i < 8; ++i)
55 {
56 if ((UImm & 0x00FF) == 0x00FF)
57 build |= 1 << i;
58 else if ((UImm & 0x00FF) != 0)
59 { build = 0; break; }
60 UImm >>= 8;
61 }
62 return getI64Imm(build);
63}]>;
Andrew Lenharthfe9234d2005-10-21 01:24:05 +000064def immZAP : PatLeaf<(imm), [{
65 // immZAP predicate - True if the immediate fits is suitable for use in a
66 // ZAP instruction
67 uint64_t UImm = (uint64_t)N->getValue();
68 unsigned int build = 0;
69 for(int i = 0; i < 8; ++i)
70 {
71 if ((UImm & 0x00FF) == 0x00FF)
72 build |= 1 << i;
73 else if ((UImm & 0x00FF) != 0)
74 { build = 0; break; }
75 UImm >>= 8;
76 }
77 return build != 0;
Andrew Lenharth8b7f14e2005-10-23 03:43:48 +000078}], iZAPX>;
Andrew Lenharthfe9234d2005-10-21 01:24:05 +000079
80
81def intop : PatFrag<(ops node:$op), (sext_inreg node:$op, i32)>;
82def add4 : PatFrag<(ops node:$op1, node:$op2),
83 (add (shl node:$op1, 2), node:$op2)>;
84def sub4 : PatFrag<(ops node:$op1, node:$op2),
85 (sub (shl node:$op1, 2), node:$op2)>;
86def add8 : PatFrag<(ops node:$op1, node:$op2),
87 (add (shl node:$op1, 3), node:$op2)>;
88def sub8 : PatFrag<(ops node:$op1, node:$op2),
89 (sub (shl node:$op1, 3), node:$op2)>;
Andrew Lenharth4907d222005-10-20 00:28:31 +000090
Andrew Lenharth304d0f32005-01-22 23:41:55 +000091 // //#define FP $15
92 // //#define RA $26
93 // //#define PV $27
94 // //#define GP $29
95 // //#define SP $30
96
Andrew Lenharth50b37842005-11-22 04:20:06 +000097def PHI : PseudoInstAlpha<(ops variable_ops), "#phi", []>;
98
99def IDEF_I : PseudoInstAlpha<(ops GPRC:$RA), "#idef $RA",
100 [(set GPRC:$RA, (undef))]>;
101def IDEF_F32 : PseudoInstAlpha<(ops F4RC:$RA), "#idef $RA",
102 [(set F4RC:$RA, (undef))]>;
103def IDEF_F64 : PseudoInstAlpha<(ops F8RC:$RA), "#idef $RA",
104 [(set F8RC:$RA, (undef))]>;
105
106def WTF : PseudoInstAlpha<(ops variable_ops), "#wtf", []>;
Andrew Lenharth8a3a5fc2005-12-05 23:41:45 +0000107let isLoad = 1, hasCtrlDep = 1 in {
108def ADJUSTSTACKUP : PseudoInstAlpha<(ops s64imm:$amt), "; ADJUP $amt",
Andrew Lenharth79620652005-12-05 20:50:53 +0000109 [(callseq_start imm:$amt)]>;
Andrew Lenharth8a3a5fc2005-12-05 23:41:45 +0000110def ADJUSTSTACKDOWN : PseudoInstAlpha<(ops s64imm:$amt), "; ADJDOWN $amt",
Andrew Lenharth79620652005-12-05 20:50:53 +0000111 [(callseq_end imm:$amt)]>;
Andrew Lenharth8a3a5fc2005-12-05 23:41:45 +0000112}
Andrew Lenharth50b37842005-11-22 04:20:06 +0000113def ALTENT : PseudoInstAlpha<(ops s64imm:$TARGET), "$TARGET:\n", []>;
114def PCLABEL : PseudoInstAlpha<(ops s64imm:$num), "PCMARKER_$num:\n",[]>;
Andrew Lenharth06ef8842005-06-29 18:54:02 +0000115def MEMLABEL : PseudoInstAlpha<(ops s64imm:$i, s64imm:$j, s64imm:$k, s64imm:$m),
Andrew Lenharth50b37842005-11-22 04:20:06 +0000116 "LSMARKER$$$i$$$j$$$k$$$m:\n",[]>;
Andrew Lenharth95762122005-03-31 21:24:06 +0000117
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000118//*****************
119//These are shortcuts, the assembler expands them
120//*****************
121//AT = R28
122//T0-T7 = R1 - R8
123//T8-T11 = R22-R25
124
Andrew Lenharthdc0b71b2005-03-22 00:24:07 +0000125//An even better improvement on the Int = SetCC(FP): SelectCC!
Andrew Lenharth0eaf6ce2005-04-02 21:06:51 +0000126//These are evil because they hide control flow in a MBB
127//really the ISel should emit multiple MBB
Andrew Lenharthdc0b71b2005-03-22 00:24:07 +0000128let isTwoAddress = 1 in {
Andrew Lenharth0eaf6ce2005-04-02 21:06:51 +0000129//Conditional move of an int based on a FP CC
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000130 def CMOVEQ_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, F8RC:$RCOND),
Andrew Lenharth50b37842005-11-22 04:20:06 +0000131 "fbne $RCOND, 42f\n\tbis $RSRC_T,$RSRC_T,$RDEST\n42:\n", []>;
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000132 def CMOVEQi_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, u8imm:$L, F8RC:$RCOND),
Andrew Lenharth50b37842005-11-22 04:20:06 +0000133 "fbne $RCOND, 42f\n\taddq $$31,$L,$RDEST\n42:\n", []>;
Andrew Lenharthdc0b71b2005-03-22 00:24:07 +0000134
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000135 def CMOVNE_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, F8RC:$RCOND),
Andrew Lenharth50b37842005-11-22 04:20:06 +0000136 "fbeq $RCOND, 42f\n\tbis $RSRC_T,$RSRC_T,$RDEST\n42:\n", []>;
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000137 def CMOVNEi_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, u8imm:$L, F8RC:$RCOND),
Andrew Lenharth50b37842005-11-22 04:20:06 +0000138 "fbeq $RCOND, 42f\n\taddq $$31,$L,$RDEST\n42:\n", []>;
Andrew Lenharth0eaf6ce2005-04-02 21:06:51 +0000139//Conditional move of an FP based on a Int CC
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000140 def FCMOVEQ_INT : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, F8RC:$RCOND),
Andrew Lenharth50b37842005-11-22 04:20:06 +0000141 "bne $RCOND, 42f\n\tcpys $RSRC_T,$RSRC_T,$RDEST\n42:\n", []>;
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000142 def FCMOVNE_INT : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, F8RC:$RCOND),
Andrew Lenharth50b37842005-11-22 04:20:06 +0000143 "beq $RCOND, 42f\n\tcpys $RSRC_T,$RSRC_T,$RDEST\n42:\n", []>;
Andrew Lenharthdc0b71b2005-03-22 00:24:07 +0000144}
Andrew Lenharthca3d59b2005-03-14 19:23:45 +0000145
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000146//***********************
147//Real instructions
148//***********************
149
150//Operation Form:
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000151
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000152//conditional moves, int
Andrew Lenharth1f347a32005-10-20 23:58:36 +0000153def CMOVEQi : OForm4L< 0x11, 0x24, "cmoveq $RCOND,$L,$RDEST">; //CMOVE if RCOND = zero
Andrew Lenharth1f347a32005-10-20 23:58:36 +0000154def CMOVGEi : OForm4L< 0x11, 0x46, "cmovge $RCOND,$L,$RDEST">; //CMOVE if RCOND >= zero
Andrew Lenharth1f347a32005-10-20 23:58:36 +0000155def CMOVGTi : OForm4L< 0x11, 0x66, "cmovgt $RCOND,$L,$RDEST">; //CMOVE if RCOND > zero
Andrew Lenharth1f347a32005-10-20 23:58:36 +0000156def CMOVLBCi : OForm4L< 0x11, 0x16, "cmovlbc $RCOND,$L,$RDEST">; //CMOVE if RCOND low bit clear
Andrew Lenharth1f347a32005-10-20 23:58:36 +0000157def CMOVLBSi : OForm4L< 0x11, 0x14, "cmovlbs $RCOND,$L,$RDEST">; //CMOVE if RCOND low bit set
Andrew Lenharth1f347a32005-10-20 23:58:36 +0000158def CMOVLEi : OForm4L< 0x11, 0x64, "cmovle $RCOND,$L,$RDEST">; //CMOVE if RCOND <= zero
Andrew Lenharth1f347a32005-10-20 23:58:36 +0000159def CMOVLTi : OForm4L< 0x11, 0x44, "cmovlt $RCOND,$L,$RDEST">; //CMOVE if RCOND < zero
Andrew Lenharth1f347a32005-10-20 23:58:36 +0000160def CMOVNEi : OForm4L< 0x11, 0x26, "cmovne $RCOND,$L,$RDEST">; //CMOVE if RCOND != zero
Andrew Lenharthd4bdd542005-02-05 16:41:03 +0000161
Andrew Lenharth5de36f92005-12-05 23:19:44 +0000162let OperandList = (ops GPRC:$RDEST, GPRC:$RTRUE, GPRC:$RFALSE, GPRC:$RCOND) in {
163def CMOVLBC : OForm4A< 0x11, 0x16, "cmovlbc $RCOND,$RFALSE,$RDEST",
164 [(set GPRC:$RDEST, (select (xor GPRC:$RCOND, 1), GPRC:$RTRUE, GPRC:$RFALSE))]>;
165def CMOVLBS : OForm4A< 0x11, 0x14, "cmovlbs $RCOND,$RFALSE,$RDEST",
166 [(set GPRC:$RDEST, (select (and GPRC:$RCOND, 1), GPRC:$RTRUE, GPRC:$RFALSE))]>;
167def CMOVEQ : OForm4A< 0x11, 0x24, "cmoveq $RCOND,$RFALSE,$RDEST",
168 [(set GPRC:$RDEST, (select (seteq GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>;
169def CMOVGE : OForm4A< 0x11, 0x46, "cmovge $RCOND,$RFALSE,$RDEST",
170 [(set GPRC:$RDEST, (select (setge GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>;
171def CMOVGT : OForm4A< 0x11, 0x66, "cmovgt $RCOND,$RFALSE,$RDEST",
172 [(set GPRC:$RDEST, (select (setgt GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>;
173def CMOVLE : OForm4A< 0x11, 0x64, "cmovle $RCOND,$RFALSE,$RDEST",
174 [(set GPRC:$RDEST, (select (setlt GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>;
175def CMOVLT : OForm4A< 0x11, 0x44, "cmovlt $RCOND,$RFALSE,$RDEST",
176 [(set GPRC:$RDEST, (select (setlt GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>;
177def CMOVNE : OForm4A< 0x11, 0x26, "cmovne $RCOND,$RFALSE,$RDEST",
178 [(set GPRC:$RDEST, (select (setne GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>;
179}
180
181//FIXME: fold setcc with select for all cases. clearly I need patterns for inverted conditions
182// and constants (which require inverted conditions as legalize puts the constant in the
183// wrong field for the instruction definition
Andrew Lenharth7f0db912005-11-30 07:19:56 +0000184def : Pat<(select GPRC:$which, GPRC:$src1, GPRC:$src2),
185 (CMOVEQ GPRC:$src1, GPRC:$src2, GPRC:$which)>;
186
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000187
Andrew Lenharth4907d222005-10-20 00:28:31 +0000188def ADDL : OForm< 0x10, 0x00, "addl $RA,$RB,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000189 [(set GPRC:$RC, (intop (add GPRC:$RA, GPRC:$RB)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000190def ADDLi : OFormL<0x10, 0x00, "addl $RA,$L,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000191 [(set GPRC:$RC, (intop (add GPRC:$RA, immUExt8:$L)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000192def ADDQ : OForm< 0x10, 0x20, "addq $RA,$RB,$RC",
193 [(set GPRC:$RC, (add GPRC:$RA, GPRC:$RB))]>;
194def ADDQi : OFormL<0x10, 0x20, "addq $RA,$L,$RC",
195 [(set GPRC:$RC, (add GPRC:$RA, immUExt8:$L))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000196def AND : OForm< 0x11, 0x00, "and $RA,$RB,$RC",
197 [(set GPRC:$RC, (and GPRC:$RA, GPRC:$RB))]>;
198def ANDi : OFormL<0x11, 0x00, "and $RA,$L,$RC",
199 [(set GPRC:$RC, (and GPRC:$RA, immUExt8:$L))]>;
200def BIC : OForm< 0x11, 0x08, "bic $RA,$RB,$RC",
201 [(set GPRC:$RC, (and GPRC:$RA, (not GPRC:$RB)))]>;
202def BICi : OFormL<0x11, 0x08, "bic $RA,$L,$RC", []>;
203// [(set GPRC:$RC, (and GPRC:$RA, (not immUExt8:$L)))]>; //FIXME?
204def BIS : OForm< 0x11, 0x20, "bis $RA,$RB,$RC",
205 [(set GPRC:$RC, (or GPRC:$RA, GPRC:$RB))]>;
206def BISi : OFormL<0x11, 0x20, "bis $RA,$L,$RC",
207 [(set GPRC:$RC, (or GPRC:$RA, immUExt8:$L))]>;
Andrew Lenharth1f347a32005-10-20 23:58:36 +0000208def CTLZ : OForm2<0x1C, 0x32, "CTLZ $RB,$RC",
Andrew Lenharth964b6aa2005-10-20 19:39:24 +0000209 [(set GPRC:$RC, (ctlz GPRC:$RB))]>;
Andrew Lenharth1f347a32005-10-20 23:58:36 +0000210def CTPOP : OForm2<0x1C, 0x30, "CTPOP $RB,$RC",
Andrew Lenharth964b6aa2005-10-20 19:39:24 +0000211 [(set GPRC:$RC, (ctpop GPRC:$RB))]>;
Andrew Lenharth1f347a32005-10-20 23:58:36 +0000212def CTTZ : OForm2<0x1C, 0x33, "CTTZ $RB,$RC",
Andrew Lenharth964b6aa2005-10-20 19:39:24 +0000213 [(set GPRC:$RC, (cttz GPRC:$RB))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000214def EQV : OForm< 0x11, 0x48, "eqv $RA,$RB,$RC",
215 [(set GPRC:$RC, (xor GPRC:$RA, (not GPRC:$RB)))]>;
216def EQVi : OFormL<0x11, 0x48, "eqv $RA,$L,$RC", []>;
217// [(set GPRC:$RC, (xor GPRC:$RA, (not immUExt8:$L)))]>;
218//def EXTBL : OForm< 0x12, 0x06, "EXTBL $RA,$RB,$RC", []>; //Extract byte low
219//def EXTBLi : OFormL<0x12, 0x06, "EXTBL $RA,$L,$RC", []>; //Extract byte low
220//def EXTLH : OForm< 0x12, 0x6A, "EXTLH $RA,$RB,$RC", []>; //Extract longword high
221//def EXTLHi : OFormL<0x12, 0x6A, "EXTLH $RA,$L,$RC", []>; //Extract longword high
222//def EXTLL : OForm< 0x12, 0x26, "EXTLL $RA,$RB,$RC", []>; //Extract longword low
223//def EXTLLi : OFormL<0x12, 0x26, "EXTLL $RA,$L,$RC", []>; //Extract longword low
224//def EXTQH : OForm< 0x12, 0x7A, "EXTQH $RA,$RB,$RC", []>; //Extract quadword high
225//def EXTQHi : OFormL<0x12, 0x7A, "EXTQH $RA,$L,$RC", []>; //Extract quadword high
226//def EXTQ : OForm< 0x12, 0x36, "EXTQ $RA,$RB,$RC", []>; //Extract quadword low
227//def EXTQi : OFormL<0x12, 0x36, "EXTQ $RA,$L,$RC", []>; //Extract quadword low
228//def EXTWH : OForm< 0x12, 0x5A, "EXTWH $RA,$RB,$RC", []>; //Extract word high
229//def EXTWHi : OFormL<0x12, 0x5A, "EXTWH $RA,$L,$RC", []>; //Extract word high
230//def EXTWL : OForm< 0x12, 0x16, "EXTWL $RA,$RB,$RC", []>; //Extract word low
231//def EXTWLi : OFormL<0x12, 0x16, "EXTWL $RA,$L,$RC", []>; //Extract word low
232//def IMPLVER : OForm< 0x11, 0x6C, "IMPLVER $RA,$RB,$RC", []>; //Implementation version
233//def IMPLVERi : OFormL<0x11, 0x6C, "IMPLVER $RA,$L,$RC", []>; //Implementation version
234//def INSBL : OForm< 0x12, 0x0B, "INSBL $RA,$RB,$RC", []>; //Insert byte low
235//def INSBLi : OFormL<0x12, 0x0B, "INSBL $RA,$L,$RC", []>; //Insert byte low
236//def INSLH : OForm< 0x12, 0x67, "INSLH $RA,$RB,$RC", []>; //Insert longword high
237//def INSLHi : OFormL<0x12, 0x67, "INSLH $RA,$L,$RC", []>; //Insert longword high
238//def INSLL : OForm< 0x12, 0x2B, "INSLL $RA,$RB,$RC", []>; //Insert longword low
239//def INSLLi : OFormL<0x12, 0x2B, "INSLL $RA,$L,$RC", []>; //Insert longword low
240//def INSQH : OForm< 0x12, 0x77, "INSQH $RA,$RB,$RC", []>; //Insert quadword high
241//def INSQHi : OFormL<0x12, 0x77, "INSQH $RA,$L,$RC", []>; //Insert quadword high
242//def INSQL : OForm< 0x12, 0x3B, "INSQL $RA,$RB,$RC", []>; //Insert quadword low
243//def INSQLi : OFormL<0x12, 0x3B, "INSQL $RA,$L,$RC", []>; //Insert quadword low
244//def INSWH : OForm< 0x12, 0x57, "INSWH $RA,$RB,$RC", []>; //Insert word high
245//def INSWHi : OFormL<0x12, 0x57, "INSWH $RA,$L,$RC", []>; //Insert word high
246//def INSWL : OForm< 0x12, 0x1B, "INSWL $RA,$RB,$RC", []>; //Insert word low
247//def INSWLi : OFormL<0x12, 0x1B, "INSWL $RA,$L,$RC", []>; //Insert word low
248//def MSKBL : OForm< 0x12, 0x02, "MSKBL $RA,$RB,$RC", []>; //Mask byte low
249//def MSKBLi : OFormL<0x12, 0x02, "MSKBL $RA,$L,$RC", []>; //Mask byte low
250//def MSKLH : OForm< 0x12, 0x62, "MSKLH $RA,$RB,$RC", []>; //Mask longword high
251//def MSKLHi : OFormL<0x12, 0x62, "MSKLH $RA,$L,$RC", []>; //Mask longword high
252//def MSKLL : OForm< 0x12, 0x22, "MSKLL $RA,$RB,$RC", []>; //Mask longword low
253//def MSKLLi : OFormL<0x12, 0x22, "MSKLL $RA,$L,$RC", []>; //Mask longword low
254//def MSKQH : OForm< 0x12, 0x72, "MSKQH $RA,$RB,$RC", []>; //Mask quadword high
255//def MSKQHi : OFormL<0x12, 0x72, "MSKQH $RA,$L,$RC", []>; //Mask quadword high
256//def MSKQL : OForm< 0x12, 0x32, "MSKQL $RA,$RB,$RC", []>; //Mask quadword low
257//def MSKQLi : OFormL<0x12, 0x32, "MSKQL $RA,$L,$RC", []>; //Mask quadword low
258//def MSKWH : OForm< 0x12, 0x52, "MSKWH $RA,$RB,$RC", []>; //Mask word high
259//def MSKWHi : OFormL<0x12, 0x52, "MSKWH $RA,$L,$RC", []>; //Mask word high
260//def MSKWL : OForm< 0x12, 0x12, "MSKWL $RA,$RB,$RC", []>; //Mask word low
261//def MSKWLi : OFormL<0x12, 0x12, "MSKWL $RA,$L,$RC", []>; //Mask word low
Chris Lattnerae4be982005-10-20 04:21:06 +0000262
Andrew Lenharth4907d222005-10-20 00:28:31 +0000263def MULL : OForm< 0x13, 0x00, "mull $RA,$RB,$RC",
Chris Lattnerae4be982005-10-20 04:21:06 +0000264 [(set GPRC:$RC, (intop (mul GPRC:$RA, GPRC:$RB)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000265def MULLi : OFormL<0x13, 0x00, "mull $RA,$L,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000266 [(set GPRC:$RC, (intop (mul GPRC:$RA, immUExt8:$L)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000267def MULQ : OForm< 0x13, 0x20, "mulq $RA,$RB,$RC",
268 [(set GPRC:$RC, (mul GPRC:$RA, GPRC:$RB))]>;
269def MULQi : OFormL<0x13, 0x20, "mulq $RA,$L,$RC",
270 [(set GPRC:$RC, (mul GPRC:$RA, immUExt8:$L))]>;
271def ORNOT : OForm< 0x11, 0x28, "ornot $RA,$RB,$RC",
272 [(set GPRC:$RC, (or GPRC:$RA, (not GPRC:$RB)))]>;
273def ORNOTi : OFormL<0x11, 0x28, "ornot $RA,$L,$RC", []>;
274// [(set GPRC:$RC, (or GPRC:$RA, (not immUExt8:$L)))]>;
275def S4ADDL : OForm< 0x10, 0x02, "s4addl $RA,$RB,$RC",
Chris Lattnerae4be982005-10-20 04:21:06 +0000276 [(set GPRC:$RC, (intop (add4 GPRC:$RA, GPRC:$RB)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000277def S4ADDLi : OFormL<0x10, 0x02, "s4addl $RA,$L,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000278 [(set GPRC:$RC, (intop (add4 GPRC:$RA, immUExt8:$L)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000279def S4ADDQ : OForm< 0x10, 0x22, "s4addq $RA,$RB,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000280 [(set GPRC:$RC, (add4 GPRC:$RA, GPRC:$RB))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000281def S4ADDQi : OFormL<0x10, 0x22, "s4addq $RA,$L,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000282 [(set GPRC:$RC, (add4 GPRC:$RA, immUExt8:$L))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000283def S4SUBL : OForm< 0x10, 0x0B, "s4subl $RA,$RB,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000284 [(set GPRC:$RC, (intop (sub4 GPRC:$RA, GPRC:$RB)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000285def S4SUBLi : OFormL<0x10, 0x0B, "s4subl $RA,$L,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000286 [(set GPRC:$RC, (intop (sub4 GPRC:$RA, immUExt8:$L)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000287def S4SUBQ : OForm< 0x10, 0x2B, "s4subq $RA,$RB,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000288 [(set GPRC:$RC, (sub4 GPRC:$RA, GPRC:$RB))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000289def S4SUBQi : OFormL<0x10, 0x2B, "s4subq $RA,$L,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000290 [(set GPRC:$RC, (sub4 GPRC:$RA, immUExt8:$L))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000291def S8ADDL : OForm< 0x10, 0x12, "s8addl $RA,$RB,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000292 [(set GPRC:$RC, (intop (add8 GPRC:$RA, GPRC:$RB)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000293def S8ADDLi : OFormL<0x10, 0x12, "s8addl $RA,$L,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000294 [(set GPRC:$RC, (intop (add8 GPRC:$RA, immUExt8:$L)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000295def S8ADDQ : OForm< 0x10, 0x32, "s8addq $RA,$RB,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000296 [(set GPRC:$RC, (add8 GPRC:$RA, GPRC:$RB))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000297def S8ADDQi : OFormL<0x10, 0x32, "s8addq $RA,$L,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000298 [(set GPRC:$RC, (add8 GPRC:$RA, immUExt8:$L))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000299def S8SUBL : OForm< 0x10, 0x1B, "s8subl $RA,$RB,$RC",
Chris Lattnerae4be982005-10-20 04:21:06 +0000300 [(set GPRC:$RC, (intop (sub8 GPRC:$RA, GPRC:$RB)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000301def S8SUBLi : OFormL<0x10, 0x1B, "s8subl $RA,$L,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000302 [(set GPRC:$RC, (intop (sub8 GPRC:$RA, immUExt8:$L)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000303def S8SUBQ : OForm< 0x10, 0x3B, "s8subq $RA,$RB,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000304 [(set GPRC:$RC, (sub8 GPRC:$RA, GPRC:$RB))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000305def S8SUBQi : OFormL<0x10, 0x3B, "s8subq $RA,$L,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000306 [(set GPRC:$RC, (sub8 GPRC:$RA, immUExt8:$L))]>;
Andrew Lenharth1f347a32005-10-20 23:58:36 +0000307def SEXTB : OForm2<0x1C, 0x00, "sextb $RB,$RC",
Andrew Lenharth964b6aa2005-10-20 19:39:24 +0000308 [(set GPRC:$RC, (sext_inreg GPRC:$RB, i8))]>;
Andrew Lenharth1f347a32005-10-20 23:58:36 +0000309def SEXTW : OForm2<0x1C, 0x01, "sextw $RB,$RC",
Andrew Lenharth964b6aa2005-10-20 19:39:24 +0000310 [(set GPRC:$RC, (sext_inreg GPRC:$RB, i16))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000311def SL : OForm< 0x12, 0x39, "sll $RA,$RB,$RC",
312 [(set GPRC:$RC, (shl GPRC:$RA, GPRC:$RB))]>;
313def SLi : OFormL<0x12, 0x39, "sll $RA,$L,$RC",
314 [(set GPRC:$RC, (shl GPRC:$RA, immUExt8:$L))]>;
315def SRA : OForm< 0x12, 0x3C, "sra $RA,$RB,$RC",
316 [(set GPRC:$RC, (sra GPRC:$RA, GPRC:$RB))]>;
317def SRAi : OFormL<0x12, 0x3C, "sra $RA,$L,$RC",
318 [(set GPRC:$RC, (sra GPRC:$RA, immUExt8:$L))]>;
319def SRL : OForm< 0x12, 0x34, "srl $RA,$RB,$RC",
320 [(set GPRC:$RC, (srl GPRC:$RA, GPRC:$RB))]>;
321def SRLi : OFormL<0x12, 0x34, "srl $RA,$L,$RC",
322 [(set GPRC:$RC, (srl GPRC:$RA, immUExt8:$L))]>;
323def SUBL : OForm< 0x10, 0x09, "subl $RA,$RB,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000324 [(set GPRC:$RC, (intop (sub GPRC:$RA, GPRC:$RB)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000325def SUBLi : OFormL<0x10, 0x09, "subl $RA,$L,$RC",
Andrew Lenharth892ade72005-10-20 14:42:48 +0000326 [(set GPRC:$RC, (intop (sub GPRC:$RA, immUExt8:$L)))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000327def SUBQ : OForm< 0x10, 0x29, "subq $RA,$RB,$RC",
328 [(set GPRC:$RC, (sub GPRC:$RA, GPRC:$RB))]>;
329def SUBQi : OFormL<0x10, 0x29, "subq $RA,$L,$RC",
330 [(set GPRC:$RC, (sub GPRC:$RA, immUExt8:$L))]>;
Andrew Lenharth964b6aa2005-10-20 19:39:24 +0000331def UMULH : OForm< 0x13, 0x30, "umulh $RA,$RB,$RC",
332 [(set GPRC:$RC, (mulhu GPRC:$RA, GPRC:$RB))]>;
333def UMULHi : OFormL<0x13, 0x30, "umulh $RA,$L,$RC",
334 [(set GPRC:$RC, (mulhu GPRC:$RA, immUExt8:$L))]>;
Andrew Lenharth4907d222005-10-20 00:28:31 +0000335def XOR : OForm< 0x11, 0x40, "xor $RA,$RB,$RC",
336 [(set GPRC:$RC, (xor GPRC:$RA, GPRC:$RB))]>;
337def XORi : OFormL<0x11, 0x40, "xor $RA,$L,$RC",
338 [(set GPRC:$RC, (xor GPRC:$RA, immUExt8:$L))]>;
Andrew Lenharthfe9234d2005-10-21 01:24:05 +0000339//FIXME: what to do about zap? the cases it catches are very complex
Andrew Lenharth4907d222005-10-20 00:28:31 +0000340def ZAP : OForm< 0x12, 0x30, "zap $RA,$RB,$RC", []>; //Zero bytes
Andrew Lenharthfe9234d2005-10-21 01:24:05 +0000341//ZAPi is useless give ZAPNOTi
Andrew Lenharth4907d222005-10-20 00:28:31 +0000342def ZAPi : OFormL<0x12, 0x30, "zap $RA,$L,$RC", []>; //Zero bytes
Andrew Lenharthfe9234d2005-10-21 01:24:05 +0000343//FIXME: what to do about zapnot? see ZAP :)
Andrew Lenharth4907d222005-10-20 00:28:31 +0000344def ZAPNOT : OForm< 0x12, 0x31, "zapnot $RA,$RB,$RC", []>; //Zero bytes not
Andrew Lenharth8b7f14e2005-10-23 03:43:48 +0000345def ZAPNOTi : OFormL<0x12, 0x31, "zapnot $RA,$L,$RC",
346 [(set GPRC:$RC, (and GPRC:$RA, immZAP:$L))]>;
Andrew Lenharth2d6f0222005-01-24 19:44:07 +0000347
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000348//Comparison, int
Andrew Lenharth2012cc02005-10-26 18:44:45 +0000349//So this is a waste of what this instruction can do, but it still saves something
350def CMPBGE : OForm< 0x10, 0x0F, "cmpbge $RA,$RB,$RC",
351 [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), (and GPRC:$RB, 255)))]>;
352def CMPBGEi : OFormL<0x10, 0x0F, "cmpbge $RA,$L,$RC",
353 [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), immUExt8:$L))]>;
354def CMPEQ : OForm< 0x10, 0x2D, "cmpeq $RA,$RB,$RC",
355 [(set GPRC:$RC, (seteq GPRC:$RA, GPRC:$RB))]>;
356def CMPEQi : OFormL<0x10, 0x2D, "cmpeq $RA,$L,$RC",
357 [(set GPRC:$RC, (seteq GPRC:$RA, immUExt8:$L))]>;
358def CMPLE : OForm< 0x10, 0x6D, "cmple $RA,$RB,$RC",
359 [(set GPRC:$RC, (setle GPRC:$RA, GPRC:$RB))]>;
360def CMPLEi : OFormL<0x10, 0x6D, "cmple $RA,$L,$RC",
361 [(set GPRC:$RC, (setle GPRC:$RA, immUExt8:$L))]>;
362def CMPLT : OForm< 0x10, 0x4D, "cmplt $RA,$RB,$RC",
363 [(set GPRC:$RC, (setlt GPRC:$RA, GPRC:$RB))]>;
364def CMPLTi : OFormL<0x10, 0x4D, "cmplt $RA,$L,$RC",
365 [(set GPRC:$RC, (setlt GPRC:$RA, immUExt8:$L))]>;
366def CMPULE : OForm< 0x10, 0x3D, "cmpule $RA,$RB,$RC",
367 [(set GPRC:$RC, (setule GPRC:$RA, GPRC:$RB))]>;
368def CMPULEi : OFormL<0x10, 0x3D, "cmpule $RA,$L,$RC",
369 [(set GPRC:$RC, (setule GPRC:$RA, immUExt8:$L))]>;
370def CMPULT : OForm< 0x10, 0x1D, "cmpult $RA,$RB,$RC",
Andrew Lenharth50b37842005-11-22 04:20:06 +0000371 [(set GPRC:$RC, (setult GPRC:$RA, GPRC:$RB))]>;
Andrew Lenharth2012cc02005-10-26 18:44:45 +0000372def CMPULTi : OFormL<0x10, 0x1D, "cmpult $RA,$L,$RC",
Andrew Lenharth50b37842005-11-22 04:20:06 +0000373 [(set GPRC:$RC, (setult GPRC:$RA, immUExt8:$L))]>;
Andrew Lenharth2012cc02005-10-26 18:44:45 +0000374
375//Patterns for unsupported int comparisons
376def : Pat<(setueq GPRC:$X, GPRC:$Y), (CMPEQ GPRC:$X, GPRC:$Y)>;
377def : Pat<(setueq GPRC:$X, immUExt8:$Y), (CMPEQi GPRC:$X, immUExt8:$Y)>;
378
379def : Pat<(setugt GPRC:$X, GPRC:$Y), (CMPULT GPRC:$Y, GPRC:$X)>;
380def : Pat<(setugt immUExt8:$X, GPRC:$Y), (CMPULTi GPRC:$Y, immUExt8:$X)>;
381
382def : Pat<(setuge GPRC:$X, GPRC:$Y), (CMPULE GPRC:$Y, GPRC:$X)>;
383def : Pat<(setuge immUExt8:$X, GPRC:$Y), (CMPULEi GPRC:$Y, immUExt8:$X)>;
384
385def : Pat<(setgt GPRC:$X, GPRC:$Y), (CMPLT GPRC:$Y, GPRC:$X)>;
386def : Pat<(setgt immUExt8:$X, GPRC:$Y), (CMPLTi GPRC:$Y, immUExt8:$X)>;
387
388def : Pat<(setge GPRC:$X, GPRC:$Y), (CMPLE GPRC:$Y, GPRC:$X)>;
389def : Pat<(setge immUExt8:$X, GPRC:$Y), (CMPLEi GPRC:$Y, immUExt8:$X)>;
390
391def : Pat<(setne GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>;
392def : Pat<(setne GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQi GPRC:$X, immUExt8:$Y), 0)>;
393
394def : Pat<(setune GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>;
395def : Pat<(setune GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQ GPRC:$X, immUExt8:$Y), 0)>;
396
Andrew Lenharth3d65d312005-01-27 03:49:45 +0000397
Andrew Lenharth4907d222005-10-20 00:28:31 +0000398let isReturn = 1, isTerminator = 1 in
Andrew Lenharthf3f951a2005-07-22 20:50:29 +0000399 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 +0000400//DAG Version:
401let isReturn = 1, isTerminator = 1, Ra = 31, Rb = 26, disp = 1, Uses = [R26] in
402 def RETDAG : MbrForm< 0x1A, 0x02, (ops), "ret $$31,($$26),1">; //Return from subroutine
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000403
Andrew Lenharthf3f951a2005-07-22 20:50:29 +0000404def JMP : MbrForm< 0x1A, 0x00, (ops GPRC:$RD, GPRC:$RS, GPRC:$DISP), "jmp $RD,($RS),$DISP">; //Jump
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000405let isCall = 1,
406 Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19,
Andrew Lenharth63f2ab22005-02-10 06:25:22 +0000407 R20, R21, R22, R23, R24, R25, R27, R28, R29,
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000408 F0, F1,
409 F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
Andrew Lenharth1e0d9bd2005-04-14 17:34:20 +0000410 F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R29] in {
Andrew Lenharthf3f951a2005-07-22 20:50:29 +0000411 def JSR : MbrForm< 0x1A, 0x01, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr $RD,($RS),$DISP">; //Jump to subroutine
412 def BSR : BForm<0x34, "bsr $RA,$DISP">; //Branch to subroutine
Andrew Lenharth7b2a5272005-01-30 20:42:36 +0000413}
Andrew Lenharth8b7f14e2005-10-23 03:43:48 +0000414let isCall = 1,
415 Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19,
416 R20, R21, R22, R23, R24, R25, R26, R27, R28, R29,
417 F0, F1,
418 F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
419 F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R27, R29] in {
420 def JSRDAG : MbrForm< 0x1A, 0x01, (ops ), "jsr $$26,($$27),0">; //Jump to subroutine
421}
Andrew Lenharthcf8bf382005-07-01 19:12:13 +0000422let isCall = 1, Defs = [R24, R25, R27, R28], Uses = [R24, R25] in
Andrew Lenharthf3f951a2005-07-22 20:50:29 +0000423 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 +0000424
Andrew Lenharthf3f951a2005-07-22 20:50:29 +0000425def JSR_COROUTINE : MbrForm< 0x1A, 0x03, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr_coroutine $RD,($RS),$DISP">; //Jump to subroutine return
426def BR : BForm<0x30, "br $RA,$DISP">; //Branch
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000427
Andrew Lenharth756fbeb2005-10-22 22:06:58 +0000428def BR_DAG : BFormD<0x30, "br $$31,$DISP">; //Branch
429
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000430//Stores, int
Andrew Lenharthf3f951a2005-07-22 20:50:29 +0000431def STB : MForm<0x0E, "stb $RA,$DISP($RB)">; // Store byte
432def STW : MForm<0x0D, "stw $RA,$DISP($RB)">; // Store word
433def STL : MForm<0x2C, "stl $RA,$DISP($RB)">; // Store longword
434def STQ : MForm<0x2D, "stq $RA,$DISP($RB)">; //Store quadword
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000435
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000436//Loads, int
Andrew Lenharthf3f951a2005-07-22 20:50:29 +0000437def LDL : MForm<0x28, "ldl $RA,$DISP($RB)">; // Load sign-extended longword
438def LDQ : MForm<0x29, "ldq $RA,$DISP($RB)">; //Load quadword
439def LDBU : MForm<0x0A, "ldbu $RA,$DISP($RB)">; //Load zero-extended byte
440def LDWU : MForm<0x0C, "ldwu $RA,$DISP($RB)">; //Load zero-extended word
Andrew Lenharth2f8fb772005-01-25 00:35:34 +0000441
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000442//Stores, float
Andrew Lenharth7f0db912005-11-30 07:19:56 +0000443let OperandList = (ops F4RC:$RA, s16imm:$DISP, GPRC:$RB) in
444def STS : MFormAlt<0x26, "sts $RA,$DISP($RB)">; //Store S_floating
445let OperandList = (ops F8RC:$RA, s16imm:$DISP, GPRC:$RB) in
446def STT : MFormAlt<0x27, "stt $RA,$DISP($RB)">; //Store T_floating
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000447
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000448//Loads, float
Andrew Lenharth7f0db912005-11-30 07:19:56 +0000449let OperandList = (ops F4RC:$RA, s16imm:$DISP, GPRC:$RB) in
450def LDS : MFormAlt<0x22, "lds $RA,$DISP($RB)">; //Load S_floating
451let OperandList = (ops F8RC:$RA, s16imm:$DISP, GPRC:$RB) in
452def LDT : MFormAlt<0x23, "ldt $RA,$DISP($RB)">; //Load T_floating
Andrew Lenharthc1faced2005-02-01 01:37:24 +0000453
454//Load address
Andrew Lenharthf3f951a2005-07-22 20:50:29 +0000455def LDA : MForm<0x08, "lda $RA,$DISP($RB)">; //Load address
456def LDAH : MForm<0x09, "ldah $RA,$DISP($RB)">; //Load address high
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000457
458
Andrew Lenharthc7989ce2005-06-29 00:31:08 +0000459//Loads, int, Rellocated Low form
Andrew Lenharth1f3e8082005-08-12 16:14:08 +0000460def LDLr : MForm<0x28, "ldl $RA,$DISP($RB)\t\t!gprellow">; // Load sign-extended longword
461def LDQr : MForm<0x29, "ldq $RA,$DISP($RB)\t\t!gprellow">; //Load quadword
462def LDBUr : MForm<0x0A, "ldbu $RA,$DISP($RB)\t\t!gprellow">; //Load zero-extended byte
463def LDWUr : MForm<0x0C, "ldwu $RA,$DISP($RB)\t\t!gprellow">; //Load zero-extended word
Andrew Lenharthfe895e32005-06-27 17:15:36 +0000464
Andrew Lenharthc7989ce2005-06-29 00:31:08 +0000465//Loads, float, Rellocated Low form
Andrew Lenharth7f0db912005-11-30 07:19:56 +0000466let OperandList = (ops F4RC:$RA, s16imm:$DISP, GPRC:$RB) in
467def LDSr : MFormAlt<0x22, "lds $RA,$DISP($RB)\t\t!gprellow">; //Load S_floating
468let OperandList = (ops F8RC:$RA, s16imm:$DISP, GPRC:$RB) in
469def LDTr : MFormAlt<0x23, "ldt $RA,$DISP($RB)\t\t!gprellow">; //Load T_floating
Andrew Lenharthfe895e32005-06-27 17:15:36 +0000470
Andrew Lenharthc7989ce2005-06-29 00:31:08 +0000471//Load address, rellocated low and high form
Andrew Lenharth1f3e8082005-08-12 16:14:08 +0000472def LDAr : MForm<0x08, "lda $RA,$DISP($RB)\t\t!gprellow">; //Load address
473def LDAHr : MForm<0x09, "ldah $RA,$DISP($RB)\t\t!gprelhigh">; //Load address high
Andrew Lenharthf3f951a2005-07-22 20:50:29 +0000474
475//load address, rellocated gpdist form
Andrew Lenharth1f3e8082005-08-12 16:14:08 +0000476def LDAg : MgForm<0x08, "lda $RA,0($RB)\t\t!gpdisp!$NUM">; //Load address
477def LDAHg : MgForm<0x09, "ldah $RA,0($RB)\t\t!gpdisp!$NUM">; //Load address
Andrew Lenharthf3f951a2005-07-22 20:50:29 +0000478
Andrew Lenharthfe895e32005-06-27 17:15:36 +0000479
Andrew Lenharthc7989ce2005-06-29 00:31:08 +0000480//Load quad, rellocated literal form
Andrew Lenharth1f3e8082005-08-12 16:14:08 +0000481def LDQl : MForm<0x29, "ldq $RA,$DISP($RB)\t\t!literal">; //Load quadword
Andrew Lenharthfe895e32005-06-27 17:15:36 +0000482
Andrew Lenharthfce587e2005-06-29 00:39:17 +0000483//Stores, int
Andrew Lenharth1f3e8082005-08-12 16:14:08 +0000484def STBr : MForm<0x0E, "stb $RA,$DISP($RB)\t\t!gprellow">; // Store byte
485def STWr : MForm<0x0D, "stw $RA,$DISP($RB)\t\t!gprellow">; // Store word
486def STLr : MForm<0x2C, "stl $RA,$DISP($RB)\t\t!gprellow">; // Store longword
487def STQr : MForm<0x2D, "stq $RA,$DISP($RB)\t\t!gprellow">; //Store quadword
Andrew Lenharthfce587e2005-06-29 00:39:17 +0000488
489//Stores, float
Andrew Lenharth7f0db912005-11-30 07:19:56 +0000490let OperandList = (ops F4RC:$RA, s16imm:$DISP, GPRC:$RB) in
491def STSr : MFormAlt<0x26, "sts $RA,$DISP($RB)\t\t!gprellow">; //Store S_floating
492let OperandList = (ops F8RC:$RA, s16imm:$DISP, GPRC:$RB) in
493def STTr : MFormAlt<0x27, "stt $RA,$DISP($RB)\t\t!gprellow">; //Store T_floating
Andrew Lenharthfce587e2005-06-29 00:39:17 +0000494
495
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000496//Branches, int
Andrew Lenharthf3f951a2005-07-22 20:50:29 +0000497def BEQ : BForm<0x39, "beq $RA,$DISP">; //Branch if = zero
498def BGE : BForm<0x3E, "bge $RA,$DISP">; //Branch if >= zero
499def BGT : BForm<0x3F, "bgt $RA,$DISP">; //Branch if > zero
500def BLBC : BForm<0x38, "blbc $RA,$DISP">; //Branch if low bit clear
501def BLBS : BForm<0x3C, "blbs $RA,$DISP">; //Branch if low bit set
502def BLE : BForm<0x3B, "ble $RA,$DISP">; //Branch if <= zero
503def BLT : BForm<0x3A, "blt $RA,$DISP">; //Branch if < zero
504def BNE : BForm<0x3D, "bne $RA,$DISP">; //Branch if != zero
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000505
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000506//Branches, float
Andrew Lenharthf3f951a2005-07-22 20:50:29 +0000507def FBEQ : FBForm<0x31, "fbeq $RA,$DISP">; //Floating branch if = zero
508def FBGE : FBForm<0x36, "fbge $RA,$DISP">; //Floating branch if >= zero
509def FBGT : FBForm<0x37, "fbgt $RA,$DISP">; //Floating branch if > zero
510def FBLE : FBForm<0x33, "fble $RA,$DISP">; //Floating branch if <= zero
511def FBLT : FBForm<0x32, "fblt $RA,$DISP">; //Floating branch if < zero
512def FBNE : FBForm<0x35, "fbne $RA,$DISP">; //Floating branch if != zero
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000513
Andrew Lenharth51b8d542005-11-11 16:47:30 +0000514def RPCC : MfcForm<0x18, 0xC000, "rpcc $RA">; //Read process cycle counter
515
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000516//Basic Floating point ops
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000517
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000518//Floats
Andrew Lenharth98a32d02005-01-26 23:56:48 +0000519
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000520let OperandList = (ops F4RC:$RC, F4RC:$RB), Fa = 31 in
521def SQRTS : FPForm<0x14, 0x58B, "sqrts/su $RB,$RC",
522 [(set F4RC:$RC, (fsqrt F4RC:$RB))]>;
523
524let OperandList = (ops F4RC:$RC, F4RC:$RA, F4RC:$RB) in {
525def ADDS : FPForm<0x16, 0x580, "adds/su $RA,$RB,$RC",
526 [(set F4RC:$RC, (fadd F4RC:$RA, F4RC:$RB))]>;
527def SUBS : FPForm<0x16, 0x581, "subs/su $RA,$RB,$RC",
528 [(set F4RC:$RC, (fsub F4RC:$RA, F4RC:$RB))]>;
529def DIVS : FPForm<0x16, 0x583, "divs/su $RA,$RB,$RC",
530 [(set F4RC:$RC, (fdiv F4RC:$RA, F4RC:$RB))]>;
531def MULS : FPForm<0x16, 0x582, "muls/su $RA,$RB,$RC",
532 [(set F4RC:$RC, (fmul F4RC:$RA, F4RC:$RB))]>;
533
534def CPYSS : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",[]>; //Copy sign
535def CPYSES : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[]>; //Copy sign and exponent
536def CPYSNS : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",[]>; //Copy sign negate
537}
538
539//Doubles
540
541let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in
542def SQRTT : FPForm<0x14, 0x5AB, "sqrtt/su $RB,$RC",
543 [(set F8RC:$RC, (fsqrt F8RC:$RB))]>;
544
545let OperandList = (ops F8RC:$RC, F8RC:$RA, F8RC:$RB) in {
546def ADDT : FPForm<0x16, 0x5A0, "addt/su $RA,$RB,$RC",
547 [(set F8RC:$RC, (fadd F8RC:$RA, F8RC:$RB))]>;
548def SUBT : FPForm<0x16, 0x5A1, "subt/su $RA,$RB,$RC",
549 [(set F8RC:$RC, (fsub F8RC:$RA, F8RC:$RB))]>;
550def DIVT : FPForm<0x16, 0x5A3, "divt/su $RA,$RB,$RC",
551 [(set F8RC:$RC, (fdiv F8RC:$RA, F8RC:$RB))]>;
552def MULT : FPForm<0x16, 0x5A2, "mult/su $RA,$RB,$RC",
553 [(set F8RC:$RC, (fmul F8RC:$RA, F8RC:$RB))]>;
554
555def CPYST : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",[]>; //Copy sign
556def CPYSET : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[]>; //Copy sign and exponent
557def CPYSNT : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",[]>; //Copy sign negate
558
559def CMPTEQ : FPForm<0x16, 0x5A5, "cmpteq/su $RA,$RB,$RC", []>;
560// [(set F8RC:$RC, (seteq F8RC:$RA, F8RC:$RB))]>;
561def CMPTLE : FPForm<0x16, 0x5A7, "cmptle/su $RA,$RB,$RC", []>;
562// [(set F8RC:$RC, (setle F8RC:$RA, F8RC:$RB))]>;
563def CMPTLT : FPForm<0x16, 0x5A6, "cmptlt/su $RA,$RB,$RC", []>;
564// [(set F8RC:$RC, (setlt F8RC:$RA, F8RC:$RB))]>;
565def CMPTUN : FPForm<0x16, 0x5A4, "cmptun/su $RA,$RB,$RC", []>;
566// [(set F8RC:$RC, (setuo F8RC:$RA, F8RC:$RB))]>;
567}
568//TODO: Add lots more FP patterns
569
Andrew Lenharthb2156f92005-11-30 17:11:20 +0000570//conditional moves, floats
571let OperandList = (ops F4RC:$RDEST, F4RC:$RSRC2, F4RC:$RSRC, F8RC:$RCOND),
572 isTwoAddress = 1 in {
573def FCMOVEQS : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if = zero
574def FCMOVGES : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if >= zero
575def FCMOVGTS : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if > zero
576def FCMOVLES : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if <= zero
577def FCMOVLTS : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RSRC,$RDEST",[]>; // FCMOVE if < zero
578def FCMOVNES : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if != zero
579}
580//conditional moves, doubles
581let OperandList = (ops F8RC:$RDEST, F8RC:$RSRC2, F8RC:$RSRC, F8RC:$RCOND),
582 isTwoAddress = 1 in {
583def FCMOVEQT : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if = zero
584def FCMOVGET : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if >= zero
585def FCMOVGTT : FPForm<0x17, 0x02F, "fcmovgt $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if > zero
586def FCMOVLET : FPForm<0x17, 0x02E, "fcmovle $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if <= zero
587def FCMOVLTT : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RSRC,$RDEST",[]>; // FCMOVE if < zero
588def FCMOVNET : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RSRC,$RDEST",[]>; //FCMOVE if != zero
589}
590
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000591
592
593let OperandList = (ops GPRC:$RC, F4RC:$RA), Fb = 31 in
594def FTOIS : FPForm<0x1C, 0x078, "ftois $RA,$RC",[]>; //Floating to integer move, S_floating
595let OperandList = (ops GPRC:$RC, F8RC:$RA), Fb = 31 in
Andrew Lenharth7f0db912005-11-30 07:19:56 +0000596def FTOIT : FPForm<0x1C, 0x070, "ftoit $RA,$RC",
597 [(set GPRC:$RC, (Alpha_ftoit F8RC:$RA))]>; //Floating to integer move
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000598let OperandList = (ops F4RC:$RC, GPRC:$RA), Fb = 31 in
599def ITOFS : FPForm<0x14, 0x004, "itofs $RA,$RC",[]>; //Integer to floating move, S_floating
600let OperandList = (ops F8RC:$RC, GPRC:$RA), Fb = 31 in
Andrew Lenharth7f0db912005-11-30 07:19:56 +0000601def ITOFT : FPForm<0x14, 0x024, "itoft $RA,$RC",
602 [(set F8RC:$RC, (Alpha_itoft GPRC:$RA))]>; //Integer to floating move
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000603
604
605let OperandList = (ops F4RC:$RC, F8RC:$RB), Fa = 31 in
Andrew Lenharth7f0db912005-11-30 07:19:56 +0000606def CVTQS : FPForm<0x16, 0x7BC, "cvtqs/sui $RB,$RC",
607 [(set F4RC:$RC, (Alpha_cvtqs F8RC:$RB))]>;
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000608let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in
Andrew Lenharth7f0db912005-11-30 07:19:56 +0000609def CVTQT : FPForm<0x16, 0x7BE, "cvtqt/sui $RB,$RC",
610 [(set F8RC:$RC, (Alpha_cvtqt F8RC:$RB))]>;
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000611let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in
Andrew Lenharthcd804962005-11-30 16:10:29 +0000612def CVTTQ : FPForm<0x16, 0x52F, "cvttq/svc $RB,$RC",
613 [(set F8RC:$RC, (Alpha_cvttq F8RC:$RB))]>;
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000614let OperandList = (ops F8RC:$RC, F4RC:$RB), Fa = 31 in
615def CVTST : FPForm<0x16, 0x6AC, "cvtst/s $RB,$RC",
616 [(set F8RC:$RC, (fextend F4RC:$RB))]>;
617let OperandList = (ops F4RC:$RC, F8RC:$RB), Fa = 31 in
618def CVTTS : FPForm<0x16, 0x7AC, "cvtts/sui $RB,$RC",
619 [(set F4RC:$RC, (fround F8RC:$RB))]>;
Andrew Lenharthd2bb9602005-01-27 07:50:35 +0000620
Andrew Lenharth3e98fde2005-01-26 21:54:09 +0000621//S_floating : IEEE Single
622//T_floating : IEEE Double
623
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000624//Unused instructions
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000625//Mnemonic Format Opcode Description
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000626//CALL_PAL Pcd 00 Trap to PALcode
627//ECB Mfc 18.E800 Evict cache block
628//EXCB Mfc 18.0400 Exception barrier
629//FETCH Mfc 18.8000 Prefetch data
630//FETCH_M Mfc 18.A000 Prefetch data, modify intent
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000631//LDL_L Mem 2A Load sign-extended longword locked
632//LDQ_L Mem 2B Load quadword locked
633//LDQ_U Mem 0B Load unaligned quadword
634//MB Mfc 18.4000 Memory barrier
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000635//STL_C Mem 2E Store longword conditional
636//STQ_C Mem 2F Store quadword conditional
637//STQ_U Mem 0F Store unaligned quadword
638//TRAPB Mfc 18.0000 Trap barrier
639//WH64 Mfc 18.F800 Write hint  64 bytes
640//WMB Mfc 18.4400 Write memory barrier
Andrew Lenharth304d0f32005-01-22 23:41:55 +0000641//MF_FPCR F-P 17.025 Move from FPCR
642//MT_FPCR F-P 17.024 Move to FPCR
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000643//There are in the Multimedia extentions, so let's not use them yet
644//def MAXSB8 : OForm<0x1C, 0x3E, "MAXSB8 $RA,$RB,$RC">; //Vector signed byte maximum
645//def MAXSW4 : OForm< 0x1C, 0x3F, "MAXSW4 $RA,$RB,$RC">; //Vector signed word maximum
646//def MAXUB8 : OForm<0x1C, 0x3C, "MAXUB8 $RA,$RB,$RC">; //Vector unsigned byte maximum
647//def MAXUW4 : OForm< 0x1C, 0x3D, "MAXUW4 $RA,$RB,$RC">; //Vector unsigned word maximum
648//def MINSB8 : OForm< 0x1C, 0x38, "MINSB8 $RA,$RB,$RC">; //Vector signed byte minimum
649//def MINSW4 : OForm< 0x1C, 0x39, "MINSW4 $RA,$RB,$RC">; //Vector signed word minimum
650//def MINUB8 : OForm< 0x1C, 0x3A, "MINUB8 $RA,$RB,$RC">; //Vector unsigned byte minimum
651//def MINUW4 : OForm< 0x1C, 0x3B, "MINUW4 $RA,$RB,$RC">; //Vector unsigned word minimum
652//def PERR : OForm< 0x1C, 0x31, "PERR $RA,$RB,$RC">; //Pixel error
653//def PKLB : OForm< 0x1C, 0x37, "PKLB $RA,$RB,$RC">; //Pack longwords to bytes
654//def PKWB : OForm<0x1C, 0x36, "PKWB $RA,$RB,$RC">; //Pack words to bytes
655//def UNPKBL : OForm< 0x1C, 0x35, "UNPKBL $RA,$RB,$RC">; //Unpack bytes to longwords
656//def UNPKBW : OForm< 0x1C, 0x34, "UNPKBW $RA,$RB,$RC">; //Unpack bytes to words
657//CVTLQ F-P 17.010 Convert longword to quadword
658//CVTQL F-P 17.030 Convert quadword to longword
659//def AMASK : OForm< 0x11, 0x61, "AMASK $RA,$RB,$RC", []>; //Architecture mask
660//def AMASKi : OFormL<0x11, 0x61, "AMASK $RA,$L,$RC", []>; //Architecture mask
661
662
Andrew Lenharth50b37842005-11-22 04:20:06 +0000663//Constant handling
Andrew Lenharth5cefc5e2005-11-09 19:17:08 +0000664
Andrew Lenharth50b37842005-11-22 04:20:06 +0000665def immConst2Part : PatLeaf<(imm), [{
666 // immZAP predicate - True if the immediate fits is suitable for use in a
667 // ZAP instruction
668 int64_t val = (int64_t)N->getValue();
669 return (val <= (int64_t)IMM_HIGH +(int64_t)IMM_HIGH* (int64_t)IMM_MULT &
670 val >= (int64_t)IMM_LOW + (int64_t)IMM_LOW * (int64_t)IMM_MULT);
671}]>;
672
673//TODO: factor this out
674def LL16 : SDNodeXForm<imm, [{
675int64_t l = N->getValue();
676 int64_t y = l / IMM_MULT;
677 if (l % IMM_MULT > IMM_HIGH)
678 ++y;
679 return getI64Imm(l - y * IMM_MULT);
680}]>;
681//TODO: factor this out
682def LH16 : SDNodeXForm<imm, [{
683int64_t l = N->getValue();
684 int64_t y = l / IMM_MULT;
685 if (l % IMM_MULT > IMM_HIGH)
686 ++y;
687 return getI64Imm(y);
688}]>;
689
690def : Pat<(i64 immConst2Part:$imm),
691 (LDA (LL16 immConst2Part:$imm), (LDAH (LH16 immConst2Part:$imm), R31))>;
Andrew Lenharth756fbeb2005-10-22 22:06:58 +0000692
693def : Pat<(i64 immSExt16:$imm),
694 (LDA immSExt16:$imm, R31)>;
Andrew Lenharth50b37842005-11-22 04:20:06 +0000695
696//TODO: I want to just define these like this!
697//def : Pat<(i64 0),
698// (R31)>;
699//def : Pat<(f64 0.0),
700// (F31)>;
701//def : Pat<(f64 -0.0),
702// (CPYSNT F31, F31)>;
703//def : Pat<(f32 0.0),
704// (F31)>;
705//def : Pat<(f32 -0.0),
706// (CPYSNS F31, F31)>;
707
708//Misc Patterns:
709
710def : Pat<(sext_inreg GPRC:$RB, i32),
711 (ADDLi GPRC:$RB, 0)>;
712
713def : Pat<(select GPRC:$which, GPRC:$src1, GPRC:$src2),
714 (CMOVEQ GPRC:$src1, GPRC:$src2, GPRC:$which)>; //may be CMOVNE
715
Andrew Lenharth7f0db912005-11-30 07:19:56 +0000716def : Pat<(fabs F8RC:$RB),
717 (CPYST F31, F8RC:$RB)>;
718def : Pat<(fabs F4RC:$RB),
719 (CPYSS F31, F4RC:$RB)>;
720def : Pat<(fneg F8RC:$RB),
721 (CPYSNT F8RC:$RB, F8RC:$RB)>;
722def : Pat<(fneg F4RC:$RB),
723 (CPYSNS F4RC:$RB, F4RC:$RB)>;
Andrew Lenharthcd804962005-11-30 16:10:29 +0000724//Yes, signed multiply high is ugly
725def : Pat<(mulhs GPRC:$RA, GPRC:$RB),
726 (SUBQ (UMULH GPRC:$RA, GPRC:$RB), (ADDQ (CMOVGE GPRC:$RB, R31, GPRC:$RA),
727 (CMOVGE GPRC:$RA, R31, GPRC:$RB)))>;