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