Fixed operand of SC microMIPS instruction.
[oota-llvm.git] / lib / Target / Mips / MicroMipsInstrInfo.td
1 def addrimm12 : ComplexPattern<iPTR, 2, "selectIntAddrMM", [frameindex]>;
2
3 def simm12 : Operand<i32> {
4   let DecoderMethod = "DecodeSimm12";
5 }
6
7 def mem_mm_12 : Operand<i32> {
8   let PrintMethod = "printMemOperand";
9   let MIOperandInfo = (ops GPR32, simm12);
10   let EncoderMethod = "getMemEncodingMMImm12";
11   let ParserMatchClass = MipsMemAsmOperand;
12   let OperandType = "OPERAND_MEMORY";
13 }
14
15 def jmptarget_mm : Operand<OtherVT> {
16   let EncoderMethod = "getJumpTargetOpValueMM";
17 }
18
19 def calltarget_mm : Operand<iPTR> {
20   let EncoderMethod = "getJumpTargetOpValueMM";
21 }
22
23 def brtarget_mm : Operand<OtherVT> {
24   let EncoderMethod = "getBranchTargetOpValueMM";
25   let OperandType   = "OPERAND_PCREL";
26   let DecoderMethod = "DecodeBranchTargetMM";
27 }
28
29 let canFoldAsLoad = 1 in
30 class LoadLeftRightMM<string opstr, SDNode OpNode, RegisterOperand RO,
31                       Operand MemOpnd> :
32   InstSE<(outs RO:$rt), (ins MemOpnd:$addr, RO:$src),
33          !strconcat(opstr, "\t$rt, $addr"),
34          [(set RO:$rt, (OpNode addrimm12:$addr, RO:$src))],
35          NoItinerary, FrmI> {
36   let DecoderMethod = "DecodeMemMMImm12";
37   string Constraints = "$src = $rt";
38 }
39
40 class StoreLeftRightMM<string opstr, SDNode OpNode, RegisterOperand RO,
41                        Operand MemOpnd>:
42   InstSE<(outs), (ins RO:$rt, MemOpnd:$addr),
43          !strconcat(opstr, "\t$rt, $addr"),
44          [(OpNode RO:$rt, addrimm12:$addr)], NoItinerary, FrmI> {
45   let DecoderMethod = "DecodeMemMMImm12";
46 }
47
48 class LLBaseMM<string opstr, RegisterOperand RO> :
49   InstSE<(outs RO:$rt), (ins mem_mm_12:$addr),
50          !strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> {
51   let DecoderMethod = "DecodeMemMMImm12";
52   let mayLoad = 1;
53 }
54
55 class SCBaseMM<string opstr, RegisterOperand RO> :
56   InstSE<(outs RO:$dst), (ins RO:$rt, mem_mm_12:$addr),
57          !strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> {
58   let DecoderMethod = "DecodeMemMMImm12";
59   let mayStore = 1;
60   let Constraints = "$rt = $dst";
61 }
62
63 class LoadMM<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
64              InstrItinClass Itin = NoItinerary> :
65   InstSE<(outs RO:$rt), (ins mem_mm_12:$addr),
66          !strconcat(opstr, "\t$rt, $addr"),
67          [(set RO:$rt, (OpNode addrimm12:$addr))], Itin, FrmI> {
68   let DecoderMethod = "DecodeMemMMImm12";
69   let canFoldAsLoad = 1;
70   let mayLoad = 1;
71 }
72
73 let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in {
74   /// Arithmetic Instructions (ALU Immediate)
75   def ADDiu_MM : MMRel, ArithLogicI<"addiu", simm16, GPR32Opnd>,
76                  ADDI_FM_MM<0xc>;
77   def ADDi_MM  : MMRel, ArithLogicI<"addi", simm16, GPR32Opnd>,
78                  ADDI_FM_MM<0x4>;
79   def SLTi_MM  : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
80                  SLTI_FM_MM<0x24>;
81   def SLTiu_MM : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
82                  SLTI_FM_MM<0x2c>;
83   def ANDi_MM  : MMRel, ArithLogicI<"andi", uimm16, GPR32Opnd>,
84                  ADDI_FM_MM<0x34>;
85   def ORi_MM   : MMRel, ArithLogicI<"ori", uimm16, GPR32Opnd>,
86                  ADDI_FM_MM<0x14>;
87   def XORi_MM  : MMRel, ArithLogicI<"xori", uimm16, GPR32Opnd>,
88                  ADDI_FM_MM<0x1c>;
89   def LUi_MM   : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16>, LUI_FM_MM;
90
91   def LEA_ADDiu_MM : MMRel, EffectiveAddress<"addiu", GPR32Opnd>,
92                      LW_FM_MM<0xc>;
93
94   /// Arithmetic Instructions (3-Operand, R-Type)
95   def ADDu_MM  : MMRel, ArithLogicR<"addu", GPR32Opnd>, ADD_FM_MM<0, 0x150>;
96   def SUBu_MM  : MMRel, ArithLogicR<"subu", GPR32Opnd>, ADD_FM_MM<0, 0x1d0>;
97   def MUL_MM   : MMRel, ArithLogicR<"mul", GPR32Opnd>, ADD_FM_MM<0, 0x210>;
98   def ADD_MM   : MMRel, ArithLogicR<"add", GPR32Opnd>, ADD_FM_MM<0, 0x110>;
99   def SUB_MM   : MMRel, ArithLogicR<"sub", GPR32Opnd>, ADD_FM_MM<0, 0x190>;
100   def SLT_MM   : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM_MM<0, 0x350>;
101   def SLTu_MM  : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>,
102                  ADD_FM_MM<0, 0x390>;
103   def AND_MM   : MMRel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
104                  ADD_FM_MM<0, 0x250>;
105   def OR_MM    : MMRel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
106                  ADD_FM_MM<0, 0x290>;
107   def XOR_MM   : MMRel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
108                  ADD_FM_MM<0, 0x310>;
109   def NOR_MM   : MMRel, LogicNOR<"nor", GPR32Opnd>, ADD_FM_MM<0, 0x2d0>;
110   def MULT_MM  : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
111                  MULT_FM_MM<0x22c>;
112   def MULTu_MM : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
113                  MULT_FM_MM<0x26c>;
114   def SDIV_MM  : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
115                  MULT_FM_MM<0x2ac>;
116   def UDIV_MM  : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
117                  MULT_FM_MM<0x2ec>;
118
119   /// Shift Instructions
120   def SLL_MM   : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL>,
121                  SRA_FM_MM<0, 0>;
122   def SRL_MM   : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL>,
123                  SRA_FM_MM<0x40, 0>;
124   def SRA_MM   : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA>,
125                  SRA_FM_MM<0x80, 0>;
126   def SLLV_MM  : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV>,
127                  SRLV_FM_MM<0x10, 0>;
128   def SRLV_MM  : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV>,
129                  SRLV_FM_MM<0x50, 0>;
130   def SRAV_MM  : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV>,
131                  SRLV_FM_MM<0x90, 0>;
132   def ROTR_MM  : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR>,
133                  SRA_FM_MM<0xc0, 0>;
134   def ROTRV_MM : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV>,
135                  SRLV_FM_MM<0xd0, 0>;
136
137   /// Load and Store Instructions - aligned
138   let DecoderMethod = "DecodeMemMMImm16" in {
139     def LB_MM  : Load<"lb", GPR32Opnd>, MMRel, LW_FM_MM<0x7>;
140     def LBu_MM : Load<"lbu", GPR32Opnd>, MMRel, LW_FM_MM<0x5>;
141     def LH_MM  : Load<"lh", GPR32Opnd>, MMRel, LW_FM_MM<0xf>;
142     def LHu_MM : Load<"lhu", GPR32Opnd>, MMRel, LW_FM_MM<0xd>;
143     def LW_MM  : Load<"lw", GPR32Opnd>, MMRel, LW_FM_MM<0x3f>;
144     def SB_MM  : Store<"sb", GPR32Opnd>, MMRel, LW_FM_MM<0x6>;
145     def SH_MM  : Store<"sh", GPR32Opnd>, MMRel, LW_FM_MM<0xe>;
146     def SW_MM  : Store<"sw", GPR32Opnd>, MMRel, LW_FM_MM<0x3e>;
147   }
148
149   def LWU_MM : LoadMM<"lwu", GPR32Opnd, zextloadi32, II_LWU>, LL_FM_MM<0xe>;
150
151   /// Load and Store Instructions - unaligned
152   def LWL_MM : LoadLeftRightMM<"lwl", MipsLWL, GPR32Opnd, mem_mm_12>,
153                LWL_FM_MM<0x0>;
154   def LWR_MM : LoadLeftRightMM<"lwr", MipsLWR, GPR32Opnd, mem_mm_12>,
155                LWL_FM_MM<0x1>;
156   def SWL_MM : StoreLeftRightMM<"swl", MipsSWL, GPR32Opnd, mem_mm_12>,
157                LWL_FM_MM<0x8>;
158   def SWR_MM : StoreLeftRightMM<"swr", MipsSWR, GPR32Opnd, mem_mm_12>,
159                LWL_FM_MM<0x9>;
160
161   /// Move Conditional
162   def MOVZ_I_MM : MMRel, CMov_I_I_FT<"movz", GPR32Opnd, GPR32Opnd,
163                   NoItinerary>, ADD_FM_MM<0, 0x58>;
164   def MOVN_I_MM : MMRel, CMov_I_I_FT<"movn", GPR32Opnd, GPR32Opnd,
165                   NoItinerary>, ADD_FM_MM<0, 0x18>;
166   def MOVT_I_MM : MMRel, CMov_F_I_FT<"movt", GPR32Opnd, II_MOVT>,
167                   CMov_F_I_FM_MM<0x25>;
168   def MOVF_I_MM : MMRel, CMov_F_I_FT<"movf", GPR32Opnd, II_MOVF>,
169                   CMov_F_I_FM_MM<0x5>;
170
171   /// Move to/from HI/LO
172   def MTHI_MM : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>,
173                 MTLO_FM_MM<0x0b5>;
174   def MTLO_MM : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>,
175                 MTLO_FM_MM<0x0f5>;
176   def MFHI_MM : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>,
177                 MFLO_FM_MM<0x035>;
178   def MFLO_MM : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>,
179                 MFLO_FM_MM<0x075>;
180
181   /// Multiply Add/Sub Instructions
182   def MADD_MM  : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM_MM<0x32c>;
183   def MADDU_MM : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM_MM<0x36c>;
184   def MSUB_MM  : MMRel, MArithR<"msub", II_MSUB>, MULT_FM_MM<0x3ac>;
185   def MSUBU_MM : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM_MM<0x3ec>;
186
187   /// Count Leading
188   def CLZ_MM : MMRel, CountLeading0<"clz", GPR32Opnd>, CLO_FM_MM<0x16c>;
189   def CLO_MM : MMRel, CountLeading1<"clo", GPR32Opnd>, CLO_FM_MM<0x12c>;
190
191   /// Sign Ext In Register Instructions.
192   def SEB_MM : MMRel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>, SEB_FM_MM<0x0ac>;
193   def SEH_MM : MMRel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>, SEB_FM_MM<0x0ec>;
194
195   /// Word Swap Bytes Within Halfwords
196   def WSBH_MM : MMRel, SubwordSwap<"wsbh", GPR32Opnd>, SEB_FM_MM<0x1ec>;
197
198   def EXT_MM : MMRel, ExtBase<"ext", GPR32Opnd, uimm5, MipsExt>,
199                EXT_FM_MM<0x2c>;
200   def INS_MM : MMRel, InsBase<"ins", GPR32Opnd, uimm5, MipsIns>,
201                EXT_FM_MM<0x0c>;
202
203   /// Jump Instructions
204   let DecoderMethod = "DecodeJumpTargetMM" in {
205     def J_MM        : MMRel, JumpFJ<jmptarget_mm, "j", br, bb, "j">,
206                       J_FM_MM<0x35>;
207     def JAL_MM      : MMRel, JumpLink<"jal", calltarget_mm>, J_FM_MM<0x3d>;
208   }
209   def JR_MM   : MMRel, IndirectBranch<"jr", GPR32Opnd>, JR_FM_MM<0x3c>;
210   def JALR_MM : MMRel, JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM_MM<0x03c>;
211   def RET_MM : MMRel, RetBase<"ret", GPR32Opnd>, JR_FM_MM<0x3c>;
212
213   /// Branch Instructions
214   def BEQ_MM  : MMRel, CBranch<"beq", brtarget_mm, seteq, GPR32Opnd>,
215                 BEQ_FM_MM<0x25>;
216   def BNE_MM  : MMRel, CBranch<"bne", brtarget_mm, setne, GPR32Opnd>,
217                 BEQ_FM_MM<0x2d>;
218   def BGEZ_MM : MMRel, CBranchZero<"bgez", brtarget_mm, setge, GPR32Opnd>,
219                 BGEZ_FM_MM<0x2>;
220   def BGTZ_MM : MMRel, CBranchZero<"bgtz", brtarget_mm, setgt, GPR32Opnd>,
221                 BGEZ_FM_MM<0x6>;
222   def BLEZ_MM : MMRel, CBranchZero<"blez", brtarget_mm, setle, GPR32Opnd>,
223                 BGEZ_FM_MM<0x4>;
224   def BLTZ_MM : MMRel, CBranchZero<"bltz", brtarget_mm, setlt, GPR32Opnd>,
225                 BGEZ_FM_MM<0x0>;
226   def BGEZAL_MM : MMRel, BGEZAL_FT<"bgezal", brtarget_mm, GPR32Opnd>,
227                   BGEZAL_FM_MM<0x03>;
228   def BLTZAL_MM : MMRel, BGEZAL_FT<"bltzal", brtarget_mm, GPR32Opnd>,
229                   BGEZAL_FM_MM<0x01>;
230
231   /// Control Instructions
232   def SYNC_MM    : MMRel, SYNC_FT<"sync">, SYNC_FM_MM;
233   def BREAK_MM   : MMRel, BRK_FT<"break">, BRK_FM_MM;
234   def SYSCALL_MM : MMRel, SYS_FT<"syscall">, SYS_FM_MM;
235   def WAIT_MM    : MMRel, WAIT_FT<"wait">, WAIT_FM_MM;
236   def ERET_MM    : MMRel, ER_FT<"eret">, ER_FM_MM<0x3cd>;
237   def DERET_MM   : MMRel, ER_FT<"deret">, ER_FM_MM<0x38d>;
238   def EI_MM      : MMRel, DEI_FT<"ei", GPR32Opnd>, EI_FM_MM<0x15d>;
239   def DI_MM      : MMRel, DEI_FT<"di", GPR32Opnd>, EI_FM_MM<0x11d>;
240
241   /// Trap Instructions
242   def TEQ_MM  : MMRel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM_MM<0x0>;
243   def TGE_MM  : MMRel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM_MM<0x08>;
244   def TGEU_MM : MMRel, TEQ_FT<"tgeu", GPR32Opnd>, TEQ_FM_MM<0x10>;
245   def TLT_MM  : MMRel, TEQ_FT<"tlt", GPR32Opnd>, TEQ_FM_MM<0x20>;
246   def TLTU_MM : MMRel, TEQ_FT<"tltu", GPR32Opnd>, TEQ_FM_MM<0x28>;
247   def TNE_MM  : MMRel, TEQ_FT<"tne", GPR32Opnd>, TEQ_FM_MM<0x30>;
248
249   def TEQI_MM  : MMRel, TEQI_FT<"teqi", GPR32Opnd>, TEQI_FM_MM<0x0e>;
250   def TGEI_MM  : MMRel, TEQI_FT<"tgei", GPR32Opnd>, TEQI_FM_MM<0x09>;
251   def TGEIU_MM : MMRel, TEQI_FT<"tgeiu", GPR32Opnd>, TEQI_FM_MM<0x0b>;
252   def TLTI_MM  : MMRel, TEQI_FT<"tlti", GPR32Opnd>, TEQI_FM_MM<0x08>;
253   def TLTIU_MM : MMRel, TEQI_FT<"tltiu", GPR32Opnd>, TEQI_FM_MM<0x0a>;
254   def TNEI_MM  : MMRel, TEQI_FT<"tnei", GPR32Opnd>, TEQI_FM_MM<0x0c>;
255
256   /// Load-linked, Store-conditional
257   def LL_MM : LLBaseMM<"ll", GPR32Opnd>, LL_FM_MM<0x3>;
258   def SC_MM : SCBaseMM<"sc", GPR32Opnd>, LL_FM_MM<0xb>;
259 }