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