[mips][microMIPS] Implement SWP and LWP instructions
[oota-llvm.git] / lib / Target / Mips / MicroMipsInstrInfo.td
1 def addrimm12 : ComplexPattern<iPTR, 2, "selectIntAddrMM", [frameindex]>;
2
3 def simm4 : Operand<i32> {
4   let DecoderMethod = "DecodeSimm4";
5 }
6 def li_simm7 : Operand<i32> {
7   let DecoderMethod = "DecodeLiSimm7";
8 }
9
10 def simm12 : Operand<i32> {
11   let DecoderMethod = "DecodeSimm12";
12 }
13
14 def uimm5_lsl2 : Operand<OtherVT> {
15   let EncoderMethod = "getUImm5Lsl2Encoding";
16   let DecoderMethod = "DecodeUImm5lsl2";
17 }
18
19 def uimm6_lsl2 : Operand<i32> {
20   let EncoderMethod = "getUImm6Lsl2Encoding";
21   let DecoderMethod = "DecodeUImm6Lsl2";
22 }
23
24 def simm9_addiusp : Operand<i32> {
25   let EncoderMethod = "getSImm9AddiuspValue";
26   let DecoderMethod = "DecodeSimm9SP";
27 }
28
29 def uimm3_shift : Operand<i32> {
30   let EncoderMethod = "getUImm3Mod8Encoding";
31 }
32
33 def simm3_lsa2 : Operand<i32> {
34   let EncoderMethod = "getSImm3Lsa2Value";
35   let DecoderMethod = "DecodeAddiur2Simm7";
36 }
37
38 def uimm4_andi : Operand<i32> {
39   let EncoderMethod = "getUImm4AndValue";
40   let DecoderMethod = "DecodeANDI16Imm";
41 }
42
43 def immSExtAddiur2 : ImmLeaf<i32, [{return Imm == 1 || Imm == -1 ||
44                                            ((Imm % 4 == 0) &&
45                                             Imm < 28 && Imm > 0);}]>;
46
47 def immSExtAddius5 : ImmLeaf<i32, [{return Imm >= -8 && Imm <= 7;}]>;
48
49 def immZExtAndi16 : ImmLeaf<i32,
50   [{return (Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
51             Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
52             Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535 );}]>;
53
54 def immZExt2Shift : ImmLeaf<i32, [{return Imm >= 1 && Imm <= 8;}]>;
55
56 def immLi16 : ImmLeaf<i32, [{return Imm >= -1 && Imm <= 126;}]>;
57
58 def MicroMipsMemGPRMM16AsmOperand : AsmOperandClass {
59   let Name = "MicroMipsMem";
60   let RenderMethod = "addMicroMipsMemOperands";
61   let ParserMethod = "parseMemOperand";
62   let PredicateMethod = "isMemWithGRPMM16Base";
63 }
64
65 class mem_mm_4_generic : Operand<i32> {
66   let PrintMethod = "printMemOperand";
67   let MIOperandInfo = (ops ptr_rc, simm4);
68   let OperandType = "OPERAND_MEMORY";
69   let ParserMatchClass = MicroMipsMemGPRMM16AsmOperand;
70 }
71
72 def mem_mm_4 : mem_mm_4_generic {
73   let EncoderMethod = "getMemEncodingMMImm4";
74 }
75
76 def mem_mm_4_lsl1 : mem_mm_4_generic {
77   let EncoderMethod = "getMemEncodingMMImm4Lsl1";
78 }
79
80 def mem_mm_4_lsl2 : mem_mm_4_generic {
81   let EncoderMethod = "getMemEncodingMMImm4Lsl2";
82 }
83
84 def mem_mm_12 : Operand<i32> {
85   let PrintMethod = "printMemOperand";
86   let MIOperandInfo = (ops GPR32, simm12);
87   let EncoderMethod = "getMemEncodingMMImm12";
88   let ParserMatchClass = MipsMemAsmOperand;
89   let OperandType = "OPERAND_MEMORY";
90 }
91
92 def MipsMemUimm4AsmOperand : AsmOperandClass {
93   let Name = "MemOffsetUimm4";
94   let SuperClasses = [MipsMemAsmOperand];
95   let RenderMethod = "addMemOperands";
96   let ParserMethod = "parseMemOperand";
97   let PredicateMethod = "isMemWithUimmOffsetSP<6>";
98 }
99
100 def mem_mm_4sp : Operand<i32> {
101   let PrintMethod = "printMemOperand";
102   let MIOperandInfo = (ops GPR32, uimm8);
103   let EncoderMethod = "getMemEncodingMMImm4sp";
104   let ParserMatchClass = MipsMemUimm4AsmOperand;
105   let OperandType = "OPERAND_MEMORY";
106 }
107
108 def jmptarget_mm : Operand<OtherVT> {
109   let EncoderMethod = "getJumpTargetOpValueMM";
110 }
111
112 def calltarget_mm : Operand<iPTR> {
113   let EncoderMethod = "getJumpTargetOpValueMM";
114 }
115
116 def brtarget_mm : Operand<OtherVT> {
117   let EncoderMethod = "getBranchTargetOpValueMM";
118   let OperandType   = "OPERAND_PCREL";
119   let DecoderMethod = "DecodeBranchTargetMM";
120 }
121
122 class CompactBranchMM<string opstr, DAGOperand opnd, PatFrag cond_op,
123                       RegisterOperand RO> :
124   InstSE<(outs), (ins RO:$rs, opnd:$offset),
125          !strconcat(opstr, "\t$rs, $offset"), [], IIBranch, FrmI> {
126   let isBranch = 1;
127   let isTerminator = 1;
128   let hasDelaySlot = 0;
129   let Defs = [AT];
130 }
131
132 let canFoldAsLoad = 1 in
133 class LoadLeftRightMM<string opstr, SDNode OpNode, RegisterOperand RO,
134                       Operand MemOpnd> :
135   InstSE<(outs RO:$rt), (ins MemOpnd:$addr, RO:$src),
136          !strconcat(opstr, "\t$rt, $addr"),
137          [(set RO:$rt, (OpNode addrimm12:$addr, RO:$src))],
138          NoItinerary, FrmI> {
139   let DecoderMethod = "DecodeMemMMImm12";
140   string Constraints = "$src = $rt";
141 }
142
143 class StoreLeftRightMM<string opstr, SDNode OpNode, RegisterOperand RO,
144                        Operand MemOpnd>:
145   InstSE<(outs), (ins RO:$rt, MemOpnd:$addr),
146          !strconcat(opstr, "\t$rt, $addr"),
147          [(OpNode RO:$rt, addrimm12:$addr)], NoItinerary, FrmI> {
148   let DecoderMethod = "DecodeMemMMImm12";
149 }
150
151 /// A register pair used by load/store pair instructions.
152 def RegPairAsmOperand : AsmOperandClass {
153   let Name = "RegPair";
154   let ParserMethod = "parseRegisterPair";
155 }
156
157 def regpair : Operand<i32> {
158   let EncoderMethod = "getRegisterPairOpValue";
159   let ParserMatchClass = RegPairAsmOperand;
160   let PrintMethod = "printRegisterPair";
161   let DecoderMethod = "DecodeRegPairOperand";
162   let MIOperandInfo = (ops GPR32Opnd, GPR32Opnd);
163 }
164
165 class StorePairMM<string opstr, InstrItinClass Itin = NoItinerary,
166                   ComplexPattern Addr = addr> :
167   InstSE<(outs), (ins regpair:$rt, mem_mm_12:$addr),
168          !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI, opstr> {
169   let DecoderMethod = "DecodeMemMMImm12";
170   let mayStore = 1;
171 }
172
173 class LoadPairMM<string opstr, InstrItinClass Itin = NoItinerary,
174                  ComplexPattern Addr = addr> :
175   InstSE<(outs regpair:$rt), (ins mem_mm_12:$addr),
176           !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI, opstr> {
177   let DecoderMethod = "DecodeMemMMImm12";
178   let mayLoad = 1;
179 }
180
181 class LLBaseMM<string opstr, RegisterOperand RO> :
182   InstSE<(outs RO:$rt), (ins mem_mm_12:$addr),
183          !strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> {
184   let DecoderMethod = "DecodeMemMMImm12";
185   let mayLoad = 1;
186 }
187
188 class SCBaseMM<string opstr, RegisterOperand RO> :
189   InstSE<(outs RO:$dst), (ins RO:$rt, mem_mm_12:$addr),
190          !strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> {
191   let DecoderMethod = "DecodeMemMMImm12";
192   let mayStore = 1;
193   let Constraints = "$rt = $dst";
194 }
195
196 class LoadMM<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
197              InstrItinClass Itin = NoItinerary> :
198   InstSE<(outs RO:$rt), (ins mem_mm_12:$addr),
199          !strconcat(opstr, "\t$rt, $addr"),
200          [(set RO:$rt, (OpNode addrimm12:$addr))], Itin, FrmI> {
201   let DecoderMethod = "DecodeMemMMImm12";
202   let canFoldAsLoad = 1;
203   let mayLoad = 1;
204 }
205
206 class ArithRMM16<string opstr, RegisterOperand RO, bit isComm = 0,
207                  InstrItinClass Itin = NoItinerary,
208                  SDPatternOperator OpNode = null_frag> :
209   MicroMipsInst16<(outs RO:$rd), (ins RO:$rs, RO:$rt),
210                   !strconcat(opstr, "\t$rd, $rs, $rt"),
211                   [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR> {
212   let isCommutable = isComm;
213 }
214
215 class AndImmMM16<string opstr, RegisterOperand RO,
216                  InstrItinClass Itin = NoItinerary> :
217   MicroMipsInst16<(outs RO:$rd), (ins RO:$rs, uimm4_andi:$imm),
218                   !strconcat(opstr, "\t$rd, $rs, $imm"), [], Itin, FrmI>;
219
220 class LogicRMM16<string opstr, RegisterOperand RO,
221                  InstrItinClass Itin = NoItinerary,
222                  SDPatternOperator OpNode = null_frag> :
223   MicroMipsInst16<(outs RO:$dst), (ins RO:$rs, RO:$rt),
224          !strconcat(opstr, "\t$rt, $rs"),
225          [(set RO:$dst, (OpNode RO:$rs, RO:$rt))], Itin, FrmR> {
226   let isCommutable = 1;
227   let Constraints = "$rt = $dst";
228 }
229
230 class NotMM16<string opstr, RegisterOperand RO> :
231   MicroMipsInst16<(outs RO:$rt), (ins RO:$rs),
232          !strconcat(opstr, "\t$rt, $rs"),
233          [(set RO:$rt, (not RO:$rs))], NoItinerary, FrmR>;
234
235 class ShiftIMM16<string opstr, Operand ImmOpnd, RegisterOperand RO,
236                  InstrItinClass Itin = NoItinerary> :
237   MicroMipsInst16<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt),
238                   !strconcat(opstr, "\t$rd, $rt, $shamt"), [], Itin, FrmR>;
239
240 class LoadMM16<string opstr, DAGOperand RO, SDPatternOperator OpNode,
241                InstrItinClass Itin, Operand MemOpnd> :
242   MicroMipsInst16<(outs RO:$rt), (ins MemOpnd:$addr),
243                   !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI> {
244   let DecoderMethod = "DecodeMemMMImm4";
245   let canFoldAsLoad = 1;
246   let mayLoad = 1;
247 }
248
249 class StoreMM16<string opstr, DAGOperand RTOpnd, DAGOperand RO,
250                 SDPatternOperator OpNode, InstrItinClass Itin,
251                 Operand MemOpnd> :
252   MicroMipsInst16<(outs), (ins RTOpnd:$rt, MemOpnd:$addr),
253                   !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI> {
254   let DecoderMethod = "DecodeMemMMImm4";
255   let mayStore = 1;
256 }
257
258 class AddImmUR2<string opstr, RegisterOperand RO> :
259   MicroMipsInst16<(outs RO:$rd), (ins RO:$rs, simm3_lsa2:$imm),
260                   !strconcat(opstr, "\t$rd, $rs, $imm"),
261                   [], NoItinerary, FrmR> {
262   let isCommutable = 1;
263 }
264
265 class AddImmUS5<string opstr, RegisterOperand RO> :
266   MicroMipsInst16<(outs RO:$dst), (ins RO:$rd, simm4:$imm),
267                   !strconcat(opstr, "\t$rd, $imm"), [], NoItinerary, FrmR> {
268   let Constraints = "$rd = $dst";
269 }
270
271 class AddImmUR1SP<string opstr, RegisterOperand RO> :
272   MicroMipsInst16<(outs RO:$rd), (ins uimm6_lsl2:$imm),
273                   !strconcat(opstr, "\t$rd, $imm"), [], NoItinerary, FrmR>;
274
275 class AddImmUSP<string opstr> :
276   MicroMipsInst16<(outs), (ins simm9_addiusp:$imm),
277                   !strconcat(opstr, "\t$imm"), [], NoItinerary, FrmI>;
278
279 class MoveFromHILOMM<string opstr, RegisterOperand RO, Register UseReg> :
280       MicroMipsInst16<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"),
281   [], II_MFHI_MFLO, FrmR> {
282   let Uses = [UseReg];
283   let hasSideEffects = 0;
284 }
285
286 class MoveMM16<string opstr, RegisterOperand RO, bit isComm = 0,
287                InstrItinClass Itin = NoItinerary> :
288   MicroMipsInst16<(outs RO:$rd), (ins RO:$rs),
289                   !strconcat(opstr, "\t$rd, $rs"), [], Itin, FrmR> {
290   let isCommutable = isComm;
291   let isReMaterializable = 1;
292 }
293
294 class LoadImmMM16<string opstr, Operand Od, RegisterOperand RO> :
295   MicroMipsInst16<(outs RO:$rd), (ins Od:$imm),
296                   !strconcat(opstr, "\t$rd, $imm"), [], NoItinerary, FrmI> {
297   let isReMaterializable = 1;
298 }
299
300 // 16-bit Jump and Link (Call)
301 class JumpLinkRegMM16<string opstr, RegisterOperand RO> :
302   MicroMipsInst16<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"),
303            [(MipsJmpLink RO:$rs)], IIBranch, FrmR> {
304   let isCall = 1;
305   let hasDelaySlot = 1;
306   let Defs = [RA];
307 }
308
309 // 16-bit Jump Reg
310 class JumpRegMM16<string opstr, RegisterOperand RO> :
311   MicroMipsInst16<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"),
312            [], IIBranch, FrmR> {
313   let hasDelaySlot = 1;
314   let isBranch = 1;
315   let isIndirectBranch = 1;
316 }
317
318 // Base class for JRADDIUSP instruction.
319 class JumpRAddiuStackMM16 :
320   MicroMipsInst16<(outs), (ins uimm5_lsl2:$imm), "jraddiusp\t$imm",
321                   [], IIBranch, FrmR> {
322   let isTerminator = 1;
323   let isBarrier = 1;
324   let isBranch = 1;
325   let isIndirectBranch = 1;
326 }
327
328 // 16-bit Jump and Link (Call) - Short Delay Slot
329 class JumpLinkRegSMM16<string opstr, RegisterOperand RO> :
330   MicroMipsInst16<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"),
331            [], IIBranch, FrmR> {
332   let isCall = 1;
333   let hasDelaySlot = 1;
334   let Defs = [RA];
335 }
336
337 // 16-bit Jump Register Compact - No delay slot
338 class JumpRegCMM16<string opstr, RegisterOperand RO> :
339   MicroMipsInst16<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"),
340                   [], IIBranch, FrmR> {
341   let isTerminator = 1;
342   let isBarrier = 1;
343   let isBranch = 1;
344   let isIndirectBranch = 1;
345 }
346
347 // Break16 and Sdbbp16
348 class BrkSdbbp16MM<string opstr> :
349   MicroMipsInst16<(outs), (ins uimm4:$code_),
350                   !strconcat(opstr, "\t$code_"),
351                   [], NoItinerary, FrmOther>;
352
353 // MicroMIPS Jump and Link (Call) - Short Delay Slot
354 let isCall = 1, hasDelaySlot = 1, Defs = [RA] in {
355   class JumpLinkMM<string opstr, DAGOperand opnd> :
356     InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
357            [], IIBranch, FrmJ, opstr> {
358     let DecoderMethod = "DecodeJumpTargetMM";
359   }
360
361   class JumpLinkRegMM<string opstr, RegisterOperand RO>:
362     InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
363             [], IIBranch, FrmR>;
364
365   class BranchCompareToZeroLinkMM<string opstr, DAGOperand opnd,
366                                   RegisterOperand RO> :
367     InstSE<(outs), (ins RO:$rs, opnd:$offset),
368            !strconcat(opstr, "\t$rs, $offset"), [], IIBranch, FrmI, opstr>;
369 }
370
371 class LoadWordIndexedScaledMM<string opstr, RegisterOperand RO,
372                               InstrItinClass Itin = NoItinerary,
373                               SDPatternOperator OpNode = null_frag> :
374   InstSE<(outs RO:$rd), (ins PtrRC:$base, PtrRC:$index),
375          !strconcat(opstr, "\t$rd, ${index}(${base})"), [], Itin, FrmFI>;
376
377 /// A list of registers used by load/store multiple instructions.
378 def RegListAsmOperand : AsmOperandClass {
379   let Name = "RegList";
380   let ParserMethod = "parseRegisterList";
381 }
382
383 def reglist : Operand<i32> {
384   let EncoderMethod = "getRegisterListOpValue";
385   let ParserMatchClass = RegListAsmOperand;
386   let PrintMethod = "printRegisterList";
387   let DecoderMethod = "DecodeRegListOperand";
388 }
389
390 def RegList16AsmOperand : AsmOperandClass {
391   let Name = "RegList16";
392   let ParserMethod = "parseRegisterList";
393   let PredicateMethod = "isRegList16";
394   let RenderMethod = "addRegListOperands";
395 }
396
397 def reglist16 : Operand<i32> {
398   let EncoderMethod = "getRegisterListOpValue16";
399   let DecoderMethod = "DecodeRegListOperand16";
400   let PrintMethod = "printRegisterList";
401   let ParserMatchClass = RegList16AsmOperand;
402 }
403
404 class StoreMultMM<string opstr,
405             InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
406   InstSE<(outs), (ins reglist:$rt, mem_mm_12:$addr),
407          !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI, opstr> {
408   let DecoderMethod = "DecodeMemMMImm12";
409   let mayStore = 1;
410 }
411
412 class LoadMultMM<string opstr,
413             InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
414   InstSE<(outs reglist:$rt), (ins mem_mm_12:$addr),
415           !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI, opstr> {
416   let DecoderMethod = "DecodeMemMMImm12";
417   let mayLoad = 1;
418 }
419
420 class StoreMultMM16<string opstr,
421                     InstrItinClass Itin = NoItinerary,
422                     ComplexPattern Addr = addr> :
423   MicroMipsInst16<(outs), (ins reglist16:$rt, mem_mm_4sp:$addr),
424                   !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI> {
425   let mayStore = 1;
426 }
427
428 class LoadMultMM16<string opstr,
429                    InstrItinClass Itin = NoItinerary,
430                    ComplexPattern Addr = addr> :
431   MicroMipsInst16<(outs reglist16:$rt), (ins mem_mm_4sp:$addr),
432                   !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI> {
433   let mayLoad = 1;
434 }
435
436 def ADDU16_MM : ArithRMM16<"addu16", GPRMM16Opnd, 1, II_ADDU, add>,
437                 ARITH_FM_MM16<0>;
438 def SUBU16_MM : ArithRMM16<"subu16", GPRMM16Opnd, 0, II_SUBU, sub>,
439                 ARITH_FM_MM16<1>;
440 def ANDI16_MM : AndImmMM16<"andi16", GPRMM16Opnd, II_AND>, ANDI_FM_MM16<0x0b>;
441 def AND16_MM : LogicRMM16<"and16", GPRMM16Opnd, II_AND, and>,
442                LOGIC_FM_MM16<0x2>;
443 def OR16_MM  : LogicRMM16<"or16", GPRMM16Opnd, II_OR, or>,
444                LOGIC_FM_MM16<0x3>;
445 def XOR16_MM : LogicRMM16<"xor16", GPRMM16Opnd, II_XOR, xor>,
446                LOGIC_FM_MM16<0x1>;
447 def NOT16_MM : NotMM16<"not16", GPRMM16Opnd>, LOGIC_FM_MM16<0x0>;
448 def SLL16_MM : ShiftIMM16<"sll16", uimm3_shift, GPRMM16Opnd, II_SLL>,
449                SHIFT_FM_MM16<0>;
450 def SRL16_MM : ShiftIMM16<"srl16", uimm3_shift, GPRMM16Opnd, II_SRL>,
451                SHIFT_FM_MM16<1>;
452 def LBU16_MM : LoadMM16<"lbu16", GPRMM16Opnd, zextloadi8, II_LBU,
453                         mem_mm_4>, LOAD_STORE_FM_MM16<0x02>;
454 def LHU16_MM : LoadMM16<"lhu16", GPRMM16Opnd, zextloadi16, II_LHU,
455                         mem_mm_4_lsl1>, LOAD_STORE_FM_MM16<0x0a>;
456 def LW16_MM : LoadMM16<"lw16", GPRMM16Opnd, load, II_LW, mem_mm_4_lsl2>,
457                       LOAD_STORE_FM_MM16<0x1a>;
458 def SB16_MM : StoreMM16<"sb16", GPRMM16OpndZero, GPRMM16Opnd, truncstorei8,
459                         II_SB, mem_mm_4>, LOAD_STORE_FM_MM16<0x22>;
460 def SH16_MM : StoreMM16<"sh16", GPRMM16OpndZero, GPRMM16Opnd, truncstorei16,
461                         II_SH, mem_mm_4_lsl1>,
462                         LOAD_STORE_FM_MM16<0x2a>;
463 def SW16_MM : StoreMM16<"sw16", GPRMM16OpndZero, GPRMM16Opnd, store, II_SW,
464                         mem_mm_4_lsl2>, LOAD_STORE_FM_MM16<0x3a>;
465 def ADDIUR1SP_MM : AddImmUR1SP<"addiur1sp", GPRMM16Opnd>, ADDIUR1SP_FM_MM16;
466 def ADDIUR2_MM : AddImmUR2<"addiur2", GPRMM16Opnd>, ADDIUR2_FM_MM16;
467 def ADDIUS5_MM : AddImmUS5<"addius5", GPR32Opnd>, ADDIUS5_FM_MM16;
468 def ADDIUSP_MM : AddImmUSP<"addiusp">, ADDIUSP_FM_MM16;
469 def MFHI16_MM : MoveFromHILOMM<"mfhi", GPR32Opnd, AC0>, MFHILO_FM_MM16<0x10>;
470 def MFLO16_MM : MoveFromHILOMM<"mflo", GPR32Opnd, AC0>, MFHILO_FM_MM16<0x12>;
471 def MOVE16_MM : MoveMM16<"move", GPR32Opnd>, MOVE_FM_MM16<0x03>;
472 def LI16_MM : LoadImmMM16<"li16", li_simm7, GPRMM16Opnd>, LI_FM_MM16,
473               IsAsCheapAsAMove;
474 def JALR16_MM : JumpLinkRegMM16<"jalr", GPR32Opnd>, JALR_FM_MM16<0x0e>;
475 def JALRS16_MM : JumpLinkRegSMM16<"jalrs16", GPR32Opnd>, JALR_FM_MM16<0x0f>;
476 def JRC16_MM : JumpRegCMM16<"jrc", GPR32Opnd>, JALR_FM_MM16<0x0d>;
477 def JRADDIUSP : JumpRAddiuStackMM16, JRADDIUSP_FM_MM16<0x18>;
478 def JR16_MM : JumpRegMM16<"jr16", GPR32Opnd>, JALR_FM_MM16<0x0c>;
479 def BREAK16_MM : BrkSdbbp16MM<"break16">, BRKSDBBP16_FM_MM<0x28>;
480 def SDBBP16_MM : BrkSdbbp16MM<"sdbbp16">, BRKSDBBP16_FM_MM<0x2C>;
481
482 class WaitMM<string opstr> :
483   InstSE<(outs), (ins uimm10:$code_), !strconcat(opstr, "\t$code_"), [],
484          NoItinerary, FrmOther, opstr>;
485
486 let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in {
487   /// Compact Branch Instructions
488   def BEQZC_MM : CompactBranchMM<"beqzc", brtarget_mm, seteq, GPR32Opnd>,
489                  COMPACT_BRANCH_FM_MM<0x7>;
490   def BNEZC_MM : CompactBranchMM<"bnezc", brtarget_mm, setne, GPR32Opnd>,
491                  COMPACT_BRANCH_FM_MM<0x5>;
492
493   /// Arithmetic Instructions (ALU Immediate)
494   def ADDiu_MM : MMRel, ArithLogicI<"addiu", simm16, GPR32Opnd>,
495                  ADDI_FM_MM<0xc>;
496   def ADDi_MM  : MMRel, ArithLogicI<"addi", simm16, GPR32Opnd>,
497                  ADDI_FM_MM<0x4>;
498   def SLTi_MM  : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
499                  SLTI_FM_MM<0x24>;
500   def SLTiu_MM : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
501                  SLTI_FM_MM<0x2c>;
502   def ANDi_MM  : MMRel, ArithLogicI<"andi", uimm16, GPR32Opnd>,
503                  ADDI_FM_MM<0x34>;
504   def ORi_MM   : MMRel, ArithLogicI<"ori", uimm16, GPR32Opnd>,
505                  ADDI_FM_MM<0x14>;
506   def XORi_MM  : MMRel, ArithLogicI<"xori", uimm16, GPR32Opnd>,
507                  ADDI_FM_MM<0x1c>;
508   def LUi_MM   : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16>, LUI_FM_MM;
509
510   def LEA_ADDiu_MM : MMRel, EffectiveAddress<"addiu", GPR32Opnd>,
511                      LW_FM_MM<0xc>;
512
513   /// Arithmetic Instructions (3-Operand, R-Type)
514   def ADDu_MM  : MMRel, ArithLogicR<"addu", GPR32Opnd>, ADD_FM_MM<0, 0x150>;
515   def SUBu_MM  : MMRel, ArithLogicR<"subu", GPR32Opnd>, ADD_FM_MM<0, 0x1d0>;
516   def MUL_MM   : MMRel, ArithLogicR<"mul", GPR32Opnd>, ADD_FM_MM<0, 0x210>;
517   def ADD_MM   : MMRel, ArithLogicR<"add", GPR32Opnd>, ADD_FM_MM<0, 0x110>;
518   def SUB_MM   : MMRel, ArithLogicR<"sub", GPR32Opnd>, ADD_FM_MM<0, 0x190>;
519   def SLT_MM   : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM_MM<0, 0x350>;
520   def SLTu_MM  : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>,
521                  ADD_FM_MM<0, 0x390>;
522   def AND_MM   : MMRel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
523                  ADD_FM_MM<0, 0x250>;
524   def OR_MM    : MMRel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
525                  ADD_FM_MM<0, 0x290>;
526   def XOR_MM   : MMRel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
527                  ADD_FM_MM<0, 0x310>;
528   def NOR_MM   : MMRel, LogicNOR<"nor", GPR32Opnd>, ADD_FM_MM<0, 0x2d0>;
529   def MULT_MM  : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
530                  MULT_FM_MM<0x22c>;
531   def MULTu_MM : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
532                  MULT_FM_MM<0x26c>;
533   def SDIV_MM  : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
534                  MULT_FM_MM<0x2ac>;
535   def UDIV_MM  : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
536                  MULT_FM_MM<0x2ec>;
537
538   /// Shift Instructions
539   def SLL_MM   : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL>,
540                  SRA_FM_MM<0, 0>;
541   def SRL_MM   : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL>,
542                  SRA_FM_MM<0x40, 0>;
543   def SRA_MM   : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA>,
544                  SRA_FM_MM<0x80, 0>;
545   def SLLV_MM  : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV>,
546                  SRLV_FM_MM<0x10, 0>;
547   def SRLV_MM  : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV>,
548                  SRLV_FM_MM<0x50, 0>;
549   def SRAV_MM  : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV>,
550                  SRLV_FM_MM<0x90, 0>;
551   def ROTR_MM  : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR>,
552                  SRA_FM_MM<0xc0, 0>;
553   def ROTRV_MM : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV>,
554                  SRLV_FM_MM<0xd0, 0>;
555
556   /// Load and Store Instructions - aligned
557   let DecoderMethod = "DecodeMemMMImm16" in {
558     def LB_MM  : Load<"lb", GPR32Opnd>, MMRel, LW_FM_MM<0x7>;
559     def LBu_MM : Load<"lbu", GPR32Opnd>, MMRel, LW_FM_MM<0x5>;
560     def LH_MM  : Load<"lh", GPR32Opnd>, MMRel, LW_FM_MM<0xf>;
561     def LHu_MM : Load<"lhu", GPR32Opnd>, MMRel, LW_FM_MM<0xd>;
562     def LW_MM  : Load<"lw", GPR32Opnd>, MMRel, LW_FM_MM<0x3f>;
563     def SB_MM  : Store<"sb", GPR32Opnd>, MMRel, LW_FM_MM<0x6>;
564     def SH_MM  : Store<"sh", GPR32Opnd>, MMRel, LW_FM_MM<0xe>;
565     def SW_MM  : Store<"sw", GPR32Opnd>, MMRel, LW_FM_MM<0x3e>;
566   }
567
568   def LWXS_MM : LoadWordIndexedScaledMM<"lwxs", GPR32Opnd>, LWXS_FM_MM<0x118>;
569
570   def LWU_MM : LoadMM<"lwu", GPR32Opnd, zextloadi32, II_LWU>, LL_FM_MM<0xe>;
571
572   /// Load and Store Instructions - unaligned
573   def LWL_MM : LoadLeftRightMM<"lwl", MipsLWL, GPR32Opnd, mem_mm_12>,
574                LWL_FM_MM<0x0>;
575   def LWR_MM : LoadLeftRightMM<"lwr", MipsLWR, GPR32Opnd, mem_mm_12>,
576                LWL_FM_MM<0x1>;
577   def SWL_MM : StoreLeftRightMM<"swl", MipsSWL, GPR32Opnd, mem_mm_12>,
578                LWL_FM_MM<0x8>;
579   def SWR_MM : StoreLeftRightMM<"swr", MipsSWR, GPR32Opnd, mem_mm_12>,
580                LWL_FM_MM<0x9>;
581
582   /// Load and Store Instructions - multiple
583   def SWM32_MM  : StoreMultMM<"swm32">, LWM_FM_MM<0xd>;
584   def LWM32_MM  : LoadMultMM<"lwm32">, LWM_FM_MM<0x5>;
585   def SWM16_MM : StoreMultMM16<"swm16">, LWM_FM_MM16<0x5>;
586   def LWM16_MM : LoadMultMM16<"lwm16">, LWM_FM_MM16<0x4>;
587
588   /// Load and Store Pair Instructions
589   def SWP_MM  : StorePairMM<"swp">, LWM_FM_MM<0x9>;
590   def LWP_MM  : LoadPairMM<"lwp">, LWM_FM_MM<0x1>;
591
592   /// Move Conditional
593   def MOVZ_I_MM : MMRel, CMov_I_I_FT<"movz", GPR32Opnd, GPR32Opnd,
594                   NoItinerary>, ADD_FM_MM<0, 0x58>;
595   def MOVN_I_MM : MMRel, CMov_I_I_FT<"movn", GPR32Opnd, GPR32Opnd,
596                   NoItinerary>, ADD_FM_MM<0, 0x18>;
597   def MOVT_I_MM : MMRel, CMov_F_I_FT<"movt", GPR32Opnd, II_MOVT>,
598                   CMov_F_I_FM_MM<0x25>;
599   def MOVF_I_MM : MMRel, CMov_F_I_FT<"movf", GPR32Opnd, II_MOVF>,
600                   CMov_F_I_FM_MM<0x5>;
601
602   /// Move to/from HI/LO
603   def MTHI_MM : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>,
604                 MTLO_FM_MM<0x0b5>;
605   def MTLO_MM : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>,
606                 MTLO_FM_MM<0x0f5>;
607   def MFHI_MM : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>,
608                 MFLO_FM_MM<0x035>;
609   def MFLO_MM : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>,
610                 MFLO_FM_MM<0x075>;
611
612   /// Multiply Add/Sub Instructions
613   def MADD_MM  : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM_MM<0x32c>;
614   def MADDU_MM : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM_MM<0x36c>;
615   def MSUB_MM  : MMRel, MArithR<"msub", II_MSUB>, MULT_FM_MM<0x3ac>;
616   def MSUBU_MM : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM_MM<0x3ec>;
617
618   /// Count Leading
619   def CLZ_MM : MMRel, CountLeading0<"clz", GPR32Opnd>, CLO_FM_MM<0x16c>,
620                ISA_MIPS32;
621   def CLO_MM : MMRel, CountLeading1<"clo", GPR32Opnd>, CLO_FM_MM<0x12c>,
622                ISA_MIPS32;
623
624   /// Sign Ext In Register Instructions.
625   def SEB_MM : MMRel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,
626                SEB_FM_MM<0x0ac>, ISA_MIPS32R2;
627   def SEH_MM : MMRel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
628                SEB_FM_MM<0x0ec>, ISA_MIPS32R2;
629
630   /// Word Swap Bytes Within Halfwords
631   def WSBH_MM : MMRel, SubwordSwap<"wsbh", GPR32Opnd>, SEB_FM_MM<0x1ec>,
632                 ISA_MIPS32R2;
633
634   def EXT_MM : MMRel, ExtBase<"ext", GPR32Opnd, uimm5, MipsExt>,
635                EXT_FM_MM<0x2c>;
636   def INS_MM : MMRel, InsBase<"ins", GPR32Opnd, uimm5, MipsIns>,
637                EXT_FM_MM<0x0c>;
638
639   /// Jump Instructions
640   let DecoderMethod = "DecodeJumpTargetMM" in {
641     def J_MM        : MMRel, JumpFJ<jmptarget_mm, "j", br, bb, "j">,
642                       J_FM_MM<0x35>;
643     def JAL_MM      : MMRel, JumpLink<"jal", calltarget_mm>, J_FM_MM<0x3d>;
644   }
645   def JR_MM   : MMRel, IndirectBranch<"jr", GPR32Opnd>, JR_FM_MM<0x3c>;
646   def JALR_MM : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM_MM<0x03c>;
647
648   /// Jump Instructions - Short Delay Slot
649   def JALS_MM   : JumpLinkMM<"jals", calltarget_mm>, J_FM_MM<0x1d>;
650   def JALRS_MM  : JumpLinkRegMM<"jalrs", GPR32Opnd>, JALR_FM_MM<0x13c>;
651
652   /// Branch Instructions
653   def BEQ_MM  : MMRel, CBranch<"beq", brtarget_mm, seteq, GPR32Opnd>,
654                 BEQ_FM_MM<0x25>;
655   def BNE_MM  : MMRel, CBranch<"bne", brtarget_mm, setne, GPR32Opnd>,
656                 BEQ_FM_MM<0x2d>;
657   def BGEZ_MM : MMRel, CBranchZero<"bgez", brtarget_mm, setge, GPR32Opnd>,
658                 BGEZ_FM_MM<0x2>;
659   def BGTZ_MM : MMRel, CBranchZero<"bgtz", brtarget_mm, setgt, GPR32Opnd>,
660                 BGEZ_FM_MM<0x6>;
661   def BLEZ_MM : MMRel, CBranchZero<"blez", brtarget_mm, setle, GPR32Opnd>,
662                 BGEZ_FM_MM<0x4>;
663   def BLTZ_MM : MMRel, CBranchZero<"bltz", brtarget_mm, setlt, GPR32Opnd>,
664                 BGEZ_FM_MM<0x0>;
665   def BGEZAL_MM : MMRel, BGEZAL_FT<"bgezal", brtarget_mm, GPR32Opnd>,
666                   BGEZAL_FM_MM<0x03>;
667   def BLTZAL_MM : MMRel, BGEZAL_FT<"bltzal", brtarget_mm, GPR32Opnd>,
668                   BGEZAL_FM_MM<0x01>;
669
670   /// Branch Instructions - Short Delay Slot
671   def BGEZALS_MM : BranchCompareToZeroLinkMM<"bgezals", brtarget_mm,
672                                              GPR32Opnd>, BGEZAL_FM_MM<0x13>;
673   def BLTZALS_MM : BranchCompareToZeroLinkMM<"bltzals", brtarget_mm,
674                                              GPR32Opnd>, BGEZAL_FM_MM<0x11>;
675
676   /// Control Instructions
677   def SYNC_MM    : MMRel, SYNC_FT<"sync">, SYNC_FM_MM;
678   def BREAK_MM   : MMRel, BRK_FT<"break">, BRK_FM_MM;
679   def SYSCALL_MM : MMRel, SYS_FT<"syscall">, SYS_FM_MM;
680   def WAIT_MM    : WaitMM<"wait">, WAIT_FM_MM;
681   def ERET_MM    : MMRel, ER_FT<"eret">, ER_FM_MM<0x3cd>;
682   def DERET_MM   : MMRel, ER_FT<"deret">, ER_FM_MM<0x38d>;
683   def EI_MM      : MMRel, DEI_FT<"ei", GPR32Opnd>, EI_FM_MM<0x15d>,
684                    ISA_MIPS32R2;
685   def DI_MM      : MMRel, DEI_FT<"di", GPR32Opnd>, EI_FM_MM<0x11d>,
686                    ISA_MIPS32R2;
687
688   /// Trap Instructions
689   def TEQ_MM  : MMRel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM_MM<0x0>;
690   def TGE_MM  : MMRel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM_MM<0x08>;
691   def TGEU_MM : MMRel, TEQ_FT<"tgeu", GPR32Opnd>, TEQ_FM_MM<0x10>;
692   def TLT_MM  : MMRel, TEQ_FT<"tlt", GPR32Opnd>, TEQ_FM_MM<0x20>;
693   def TLTU_MM : MMRel, TEQ_FT<"tltu", GPR32Opnd>, TEQ_FM_MM<0x28>;
694   def TNE_MM  : MMRel, TEQ_FT<"tne", GPR32Opnd>, TEQ_FM_MM<0x30>;
695
696   def TEQI_MM  : MMRel, TEQI_FT<"teqi", GPR32Opnd>, TEQI_FM_MM<0x0e>;
697   def TGEI_MM  : MMRel, TEQI_FT<"tgei", GPR32Opnd>, TEQI_FM_MM<0x09>;
698   def TGEIU_MM : MMRel, TEQI_FT<"tgeiu", GPR32Opnd>, TEQI_FM_MM<0x0b>;
699   def TLTI_MM  : MMRel, TEQI_FT<"tlti", GPR32Opnd>, TEQI_FM_MM<0x08>;
700   def TLTIU_MM : MMRel, TEQI_FT<"tltiu", GPR32Opnd>, TEQI_FM_MM<0x0a>;
701   def TNEI_MM  : MMRel, TEQI_FT<"tnei", GPR32Opnd>, TEQI_FM_MM<0x0c>;
702
703   /// Load-linked, Store-conditional
704   def LL_MM : LLBaseMM<"ll", GPR32Opnd>, LL_FM_MM<0x3>;
705   def SC_MM : SCBaseMM<"sc", GPR32Opnd>, LL_FM_MM<0xb>;
706
707   def TLBP_MM : MMRel, TLB<"tlbp">, COP0_TLB_FM_MM<0x0d>;
708   def TLBR_MM : MMRel, TLB<"tlbr">, COP0_TLB_FM_MM<0x4d>;
709   def TLBWI_MM : MMRel, TLB<"tlbwi">, COP0_TLB_FM_MM<0x8d>;
710   def TLBWR_MM : MMRel, TLB<"tlbwr">, COP0_TLB_FM_MM<0xcd>;
711
712   def SDBBP_MM : MMRel, SYS_FT<"sdbbp">, SDBBP_FM_MM;
713   def RDHWR_MM : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM_MM;
714 }
715
716 let Predicates = [InMicroMips] in {
717
718 //===----------------------------------------------------------------------===//
719 // MicroMips arbitrary patterns that map to one or more instructions
720 //===----------------------------------------------------------------------===//
721
722 def : MipsPat<(i32 immLi16:$imm),
723               (LI16_MM immLi16:$imm)>;
724 def : MipsPat<(i32 immSExt16:$imm),
725               (ADDiu_MM ZERO, immSExt16:$imm)>;
726 def : MipsPat<(i32 immZExt16:$imm),
727               (ORi_MM ZERO, immZExt16:$imm)>;
728
729 def : MipsPat<(add GPRMM16:$src, immSExtAddiur2:$imm),
730               (ADDIUR2_MM GPRMM16:$src, immSExtAddiur2:$imm)>;
731 def : MipsPat<(add GPR32:$src, immSExtAddius5:$imm),
732               (ADDIUS5_MM GPR32:$src, immSExtAddius5:$imm)>;
733 def : MipsPat<(add GPR32:$src, immSExt16:$imm),
734               (ADDiu_MM GPR32:$src, immSExt16:$imm)>;
735
736 def : MipsPat<(and GPRMM16:$src, immZExtAndi16:$imm),
737               (ANDI16_MM GPRMM16:$src, immZExtAndi16:$imm)>;
738 def : MipsPat<(and GPR32:$src, immZExt16:$imm),
739               (ANDi_MM GPR32:$src, immZExt16:$imm)>;
740
741 def : MipsPat<(shl GPRMM16:$src, immZExt2Shift:$imm),
742               (SLL16_MM GPRMM16:$src, immZExt2Shift:$imm)>;
743 def : MipsPat<(shl GPR32:$src, immZExt5:$imm),
744               (SLL_MM GPR32:$src, immZExt5:$imm)>;
745
746 def : MipsPat<(srl GPRMM16:$src, immZExt2Shift:$imm),
747               (SRL16_MM GPRMM16:$src, immZExt2Shift:$imm)>;
748 def : MipsPat<(srl GPR32:$src, immZExt5:$imm),
749               (SRL_MM GPR32:$src, immZExt5:$imm)>;
750
751 //===----------------------------------------------------------------------===//
752 // MicroMips instruction aliases
753 //===----------------------------------------------------------------------===//
754
755   def : MipsInstAlias<"wait", (WAIT_MM 0x0), 1>;
756   def : MipsInstAlias<"nop", (SLL_MM ZERO, ZERO, 0), 1>;
757   def : MipsInstAlias<"nop", (MOVE16_MM ZERO, ZERO), 1>;
758 }