1//===- MipsInstrInfo.td - Target Description for Mips Target -*- tablegen -*-=//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains the Mips implementation of the TargetInstrInfo class.
11//
12//===----------------------------------------------------------------------===//
13
14
15//===----------------------------------------------------------------------===//
16// Mips profiles and nodes
17//===----------------------------------------------------------------------===//
18
19def SDT_MipsJmpLink      : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
20def SDT_MipsCMov         : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>,
21                                                SDTCisSameAs<1, 2>,
22                                                SDTCisSameAs<3, 4>,
23                                                SDTCisInt<4>]>;
24def SDT_MipsCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>;
25def SDT_MipsCallSeqEnd   : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
26def SDT_MFLOHI : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisVT<1, untyped>]>;
27def SDT_MTLOHI : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>,
28                                      SDTCisInt<1>, SDTCisSameAs<1, 2>]>;
29def SDT_MipsMultDiv : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>, SDTCisInt<1>,
30                                    SDTCisSameAs<1, 2>]>;
31def SDT_MipsMAddMSub : SDTypeProfile<1, 3,
32                                     [SDTCisVT<0, untyped>, SDTCisSameAs<0, 3>,
33                                      SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>;
34def SDT_MipsDivRem16 : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>]>;
35
36def SDT_MipsThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
37
38def SDT_Sync             : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
39
40def SDT_Ext : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
41                                   SDTCisVT<2, i32>, SDTCisSameAs<2, 3>]>;
42def SDT_Ins : SDTypeProfile<1, 4, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
43                                   SDTCisVT<2, i32>, SDTCisSameAs<2, 3>,
44                                   SDTCisSameAs<0, 4>]>;
45
46def SDTMipsLoadLR  : SDTypeProfile<1, 2,
47                                   [SDTCisInt<0>, SDTCisPtrTy<1>,
48                                    SDTCisSameAs<0, 2>]>;
49
50// Call
51def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink,
52                         [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,
53                          SDNPVariadic]>;
54
55// Tail call
56def MipsTailCall : SDNode<"MipsISD::TailCall", SDT_MipsJmpLink,
57                          [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
58
59// Hi and Lo nodes are used to handle global addresses. Used on
60// MipsISelLowering to lower stuff like GlobalAddress, ExternalSymbol
61// static model. (nothing to do with Mips Registers Hi and Lo)
62def MipsHi    : SDNode<"MipsISD::Hi", SDTIntUnaryOp>;
63def MipsLo    : SDNode<"MipsISD::Lo", SDTIntUnaryOp>;
64def MipsGPRel : SDNode<"MipsISD::GPRel", SDTIntUnaryOp>;
65
66// TlsGd node is used to handle General Dynamic TLS
67def MipsTlsGd : SDNode<"MipsISD::TlsGd", SDTIntUnaryOp>;
68
69// TprelHi and TprelLo nodes are used to handle Local Exec TLS
70def MipsTprelHi    : SDNode<"MipsISD::TprelHi", SDTIntUnaryOp>;
71def MipsTprelLo    : SDNode<"MipsISD::TprelLo", SDTIntUnaryOp>;
72
73// Thread pointer
74def MipsThreadPointer: SDNode<"MipsISD::ThreadPointer", SDT_MipsThreadPointer>;
75
76// Return
77def MipsRet : SDNode<"MipsISD::Ret", SDTNone,
78                     [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
79
80def MipsERet : SDNode<"MipsISD::ERet", SDTNone,
81                      [SDNPHasChain, SDNPOptInGlue, SDNPSideEffect]>;
82
83// These are target-independent nodes, but have target-specific formats.
84def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MipsCallSeqStart,
85                           [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>;
86def callseq_end   : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeqEnd,
87                           [SDNPHasChain, SDNPSideEffect,
88                            SDNPOptInGlue, SDNPOutGlue]>;
89
90// Nodes used to extract LO/HI registers.
91def MipsMFHI : SDNode<"MipsISD::MFHI", SDT_MFLOHI>;
92def MipsMFLO : SDNode<"MipsISD::MFLO", SDT_MFLOHI>;
93
94// Node used to insert 32-bit integers to LOHI register pair.
95def MipsMTLOHI : SDNode<"MipsISD::MTLOHI", SDT_MTLOHI>;
96
97// Mult nodes.
98def MipsMult  : SDNode<"MipsISD::Mult", SDT_MipsMultDiv>;
99def MipsMultu : SDNode<"MipsISD::Multu", SDT_MipsMultDiv>;
100
101// MAdd*/MSub* nodes
102def MipsMAdd  : SDNode<"MipsISD::MAdd", SDT_MipsMAddMSub>;
103def MipsMAddu : SDNode<"MipsISD::MAddu", SDT_MipsMAddMSub>;
104def MipsMSub  : SDNode<"MipsISD::MSub", SDT_MipsMAddMSub>;
105def MipsMSubu : SDNode<"MipsISD::MSubu", SDT_MipsMAddMSub>;
106
107// DivRem(u) nodes
108def MipsDivRem    : SDNode<"MipsISD::DivRem", SDT_MipsMultDiv>;
109def MipsDivRemU   : SDNode<"MipsISD::DivRemU", SDT_MipsMultDiv>;
110def MipsDivRem16  : SDNode<"MipsISD::DivRem16", SDT_MipsDivRem16,
111                           [SDNPOutGlue]>;
112def MipsDivRemU16 : SDNode<"MipsISD::DivRemU16", SDT_MipsDivRem16,
113                           [SDNPOutGlue]>;
114
115// Target constant nodes that are not part of any isel patterns and remain
116// unchanged can cause instructions with illegal operands to be emitted.
117// Wrapper node patterns give the instruction selector a chance to replace
118// target constant nodes that would otherwise remain unchanged with ADDiu
119// nodes. Without these wrapper node patterns, the following conditional move
120// instruction is emitted when function cmov2 in test/CodeGen/Mips/cmov.ll is
121// compiled:
122//  movn  %got(d)($gp), %got(c)($gp), $4
123// This instruction is illegal since movn can take only register operands.
124
125def MipsWrapper    : SDNode<"MipsISD::Wrapper", SDTIntBinOp>;
126
127def MipsSync : SDNode<"MipsISD::Sync", SDT_Sync, [SDNPHasChain,SDNPSideEffect]>;
128
129def MipsExt :  SDNode<"MipsISD::Ext", SDT_Ext>;
130def MipsIns :  SDNode<"MipsISD::Ins", SDT_Ins>;
131
132def MipsLWL : SDNode<"MipsISD::LWL", SDTMipsLoadLR,
133                     [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
134def MipsLWR : SDNode<"MipsISD::LWR", SDTMipsLoadLR,
135                     [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
136def MipsSWL : SDNode<"MipsISD::SWL", SDTStore,
137                     [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
138def MipsSWR : SDNode<"MipsISD::SWR", SDTStore,
139                     [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
140def MipsLDL : SDNode<"MipsISD::LDL", SDTMipsLoadLR,
141                     [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
142def MipsLDR : SDNode<"MipsISD::LDR", SDTMipsLoadLR,
143                     [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
144def MipsSDL : SDNode<"MipsISD::SDL", SDTStore,
145                     [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
146def MipsSDR : SDNode<"MipsISD::SDR", SDTStore,
147                     [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
148
149//===----------------------------------------------------------------------===//
150// Mips Instruction Predicate Definitions.
151//===----------------------------------------------------------------------===//
152def HasMips2     :    Predicate<"Subtarget->hasMips2()">,
153                      AssemblerPredicate<"FeatureMips2">;
154def HasMips3_32  :    Predicate<"Subtarget->hasMips3_32()">,
155                      AssemblerPredicate<"FeatureMips3_32">;
156def HasMips3_32r2 :   Predicate<"Subtarget->hasMips3_32r2()">,
157                      AssemblerPredicate<"FeatureMips3_32r2">;
158def HasMips3     :    Predicate<"Subtarget->hasMips3()">,
159                      AssemblerPredicate<"FeatureMips3">;
160def HasMips4_32  :    Predicate<"Subtarget->hasMips4_32()">,
161                      AssemblerPredicate<"FeatureMips4_32">;
162def NotMips4_32  :    Predicate<"!Subtarget->hasMips4_32()">,
163                      AssemblerPredicate<"!FeatureMips4_32">;
164def HasMips4_32r2 :   Predicate<"Subtarget->hasMips4_32r2()">,
165                      AssemblerPredicate<"FeatureMips4_32r2">;
166def HasMips5_32r2 :   Predicate<"Subtarget->hasMips5_32r2()">,
167                      AssemblerPredicate<"FeatureMips5_32r2">;
168def HasMips32    :    Predicate<"Subtarget->hasMips32()">,
169                      AssemblerPredicate<"FeatureMips32">;
170def HasMips32r2  :    Predicate<"Subtarget->hasMips32r2()">,
171                      AssemblerPredicate<"FeatureMips32r2">;
172def HasMips32r5  :    Predicate<"Subtarget->hasMips32r5()">,
173                      AssemblerPredicate<"FeatureMips32r5">;
174def HasMips32r6  :    Predicate<"Subtarget->hasMips32r6()">,
175                      AssemblerPredicate<"FeatureMips32r6">;
176def NotMips32r6  :    Predicate<"!Subtarget->hasMips32r6()">,
177                      AssemblerPredicate<"!FeatureMips32r6">;
178def IsGP64bit    :    Predicate<"Subtarget->isGP64bit()">,
179                      AssemblerPredicate<"FeatureGP64Bit">;
180def IsGP32bit    :    Predicate<"!Subtarget->isGP64bit()">,
181                      AssemblerPredicate<"!FeatureGP64Bit">;
182def IsPTR64bit    :   Predicate<"Subtarget->isABI_N64()">,
183                      AssemblerPredicate<"FeaturePTR64Bit">;
184def IsPTR32bit    :   Predicate<"!Subtarget->isABI_N64()">,
185                      AssemblerPredicate<"!FeaturePTR64Bit">;
186def HasMips64    :    Predicate<"Subtarget->hasMips64()">,
187                      AssemblerPredicate<"FeatureMips64">;
188def NotMips64    :    Predicate<"!Subtarget->hasMips64()">,
189                      AssemblerPredicate<"!FeatureMips64">;
190def HasMips64r2  :    Predicate<"Subtarget->hasMips64r2()">,
191                      AssemblerPredicate<"FeatureMips64r2">;
192def HasMips64r6  :    Predicate<"Subtarget->hasMips64r6()">,
193                      AssemblerPredicate<"FeatureMips64r6">;
194def NotMips64r6  :    Predicate<"!Subtarget->hasMips64r6()">,
195                      AssemblerPredicate<"!FeatureMips64r6">;
196def HasMicroMips32r6 : Predicate<"Subtarget->inMicroMips32r6Mode()">,
197                       AssemblerPredicate<"FeatureMicroMips,FeatureMips32r6">;
198def HasMicroMips64r6 : Predicate<"Subtarget->inMicroMips64r6Mode()">,
199                       AssemblerPredicate<"FeatureMicroMips,FeatureMips64r6">;
200def InMips16Mode :    Predicate<"Subtarget->inMips16Mode()">,
201                      AssemblerPredicate<"FeatureMips16">;
202def HasCnMips    :    Predicate<"Subtarget->hasCnMips()">,
203                      AssemblerPredicate<"FeatureCnMips">;
204def RelocNotPIC :     Predicate<"!TM.isPositionIndependent()">;
205def RelocPIC    :     Predicate<"TM.isPositionIndependent()">;
206def NoNaNsFPMath :    Predicate<"TM.Options.NoNaNsFPMath">;
207def HasStdEnc :       Predicate<"Subtarget->hasStandardEncoding()">,
208                      AssemblerPredicate<"!FeatureMips16">;
209def NotDSP :          Predicate<"!Subtarget->hasDSP()">;
210def InMicroMips    :  Predicate<"Subtarget->inMicroMipsMode()">,
211                      AssemblerPredicate<"FeatureMicroMips">;
212def NotInMicroMips :  Predicate<"!Subtarget->inMicroMipsMode()">,
213                      AssemblerPredicate<"!FeatureMicroMips">;
214def IsLE           :  Predicate<"Subtarget->isLittle()">;
215def IsBE           :  Predicate<"!Subtarget->isLittle()">;
216def IsNotNaCl    :    Predicate<"!Subtarget->isTargetNaCl()">;
217def UseTCCInDIV    :  AssemblerPredicate<"FeatureUseTCCInDIV">;
218def HasEVA       :    Predicate<"Subtarget->hasEVA()">,
219                      AssemblerPredicate<"FeatureEVA,FeatureMips32r2">;
220def HasMSA : Predicate<"Subtarget->hasMSA()">,
221             AssemblerPredicate<"FeatureMSA">;
222
223
224//===----------------------------------------------------------------------===//
225// Mips GPR size adjectives.
226// They are mutually exclusive.
227//===----------------------------------------------------------------------===//
228
229class GPR_32 { list<Predicate> GPRPredicates = [IsGP32bit]; }
230class GPR_64 { list<Predicate> GPRPredicates = [IsGP64bit]; }
231
232class PTR_32 { list<Predicate> PTRPredicates = [IsPTR32bit]; }
233class PTR_64 { list<Predicate> PTRPredicates = [IsPTR64bit]; }
234
235//===----------------------------------------------------------------------===//
236// Mips ISA/ASE membership and instruction group membership adjectives.
237// They are mutually exclusive.
238//===----------------------------------------------------------------------===//
239
240// FIXME: I'd prefer to use additive predicates to build the instruction sets
241//        but we are short on assembler feature bits at the moment. Using a
242//        subtractive predicate will hopefully keep us under the 32 predicate
243//        limit long enough to develop an alternative way to handle P1||P2
244//        predicates.
245class ISA_MIPS1_NOT_4_32 {
246  list<Predicate> InsnPredicates = [NotMips4_32];
247}
248class ISA_MIPS1_NOT_32R6_64R6 {
249  list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6];
250}
251class ISA_MIPS2    { list<Predicate> InsnPredicates = [HasMips2]; }
252class ISA_MIPS2_NOT_32R6_64R6 {
253  list<Predicate> InsnPredicates = [HasMips2, NotMips32r6, NotMips64r6];
254}
255class ISA_MIPS3    { list<Predicate> InsnPredicates = [HasMips3]; }
256class ISA_MIPS3_NOT_32R6_64R6 {
257  list<Predicate> InsnPredicates = [HasMips3, NotMips32r6, NotMips64r6];
258}
259class ISA_MIPS32   { list<Predicate> InsnPredicates = [HasMips32]; }
260class ISA_MIPS32_NOT_32R6_64R6 {
261  list<Predicate> InsnPredicates = [HasMips32, NotMips32r6, NotMips64r6];
262}
263class ISA_MIPS32R2 { list<Predicate> InsnPredicates = [HasMips32r2]; }
264class ISA_MIPS32R2_NOT_32R6_64R6 {
265  list<Predicate> InsnPredicates = [HasMips32r2, NotMips32r6, NotMips64r6];
266}
267class ISA_MIPS32R5 { list<Predicate> InsnPredicates = [HasMips32r5]; }
268class ISA_MIPS64   { list<Predicate> InsnPredicates = [HasMips64]; }
269class ISA_MIPS64_NOT_64R6 {
270  list<Predicate> InsnPredicates = [HasMips64, NotMips64r6];
271}
272class ISA_MIPS64R2 { list<Predicate> InsnPredicates = [HasMips64r2]; }
273class ISA_MIPS32R6 { list<Predicate> InsnPredicates = [HasMips32r6]; }
274class ISA_MIPS64R6 { list<Predicate> InsnPredicates = [HasMips64r6]; }
275class ISA_MICROMIPS { list<Predicate> InsnPredicates = [InMicroMips]; }
276class ISA_MICROMIPS32R6 {
277  list<Predicate> InsnPredicates = [HasMicroMips32r6];
278}
279class ISA_MICROMIPS64R6 {
280  list<Predicate> InsnPredicates = [HasMicroMips64r6];
281}
282class ISA_MICROMIPS32_NOT_MIPS32R6 {
283  list<Predicate> InsnPredicates = [InMicroMips, NotMips32r6];
284}
285
286class INSN_EVA { list<Predicate> InsnPredicates = [HasEVA]; }
287class INSN_EVA_NOT_32R6_64R6 {
288  list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6, HasEVA];
289}
290
291// The portions of MIPS-III that were also added to MIPS32
292class INSN_MIPS3_32 { list<Predicate> InsnPredicates = [HasMips3_32]; }
293
294// The portions of MIPS-III that were also added to MIPS32 but were removed in
295// MIPS32r6 and MIPS64r6.
296class INSN_MIPS3_32_NOT_32R6_64R6 {
297  list<Predicate> InsnPredicates = [HasMips3_32, NotMips32r6, NotMips64r6];
298}
299
300// The portions of MIPS-III that were also added to MIPS32
301class INSN_MIPS3_32R2 { list<Predicate> InsnPredicates = [HasMips3_32r2]; }
302
303// The portions of MIPS-IV that were also added to MIPS32 but were removed in
304// MIPS32r6 and MIPS64r6.
305class INSN_MIPS4_32_NOT_32R6_64R6 {
306  list<Predicate> InsnPredicates = [HasMips4_32, NotMips32r6, NotMips64r6];
307}
308
309// The portions of MIPS-IV that were also added to MIPS32r2 but were removed in
310// MIPS32r6 and MIPS64r6.
311class INSN_MIPS4_32R2_NOT_32R6_64R6 {
312  list<Predicate> InsnPredicates = [HasMips4_32r2, NotMips32r6, NotMips64r6];
313}
314
315// The portions of MIPS-V that were also added to MIPS32r2 but were removed in
316// MIPS32r6 and MIPS64r6.
317class INSN_MIPS5_32R2_NOT_32R6_64R6 {
318  list<Predicate> InsnPredicates = [HasMips5_32r2, NotMips32r6, NotMips64r6];
319}
320
321class ASE_CNMIPS {
322  list<Predicate> InsnPredicates = [HasCnMips];
323}
324
325class ASE_MIPS64_CNMIPS {
326  list<Predicate> InsnPredicates = [HasMips64, HasCnMips];
327}
328
329class ASE_MSA {
330  list<Predicate> InsnPredicates = [HasMSA];
331}
332
333class ASE_MSA_NOT_MSA64 {
334  list<Predicate> InsnPredicates = [HasMSA, NotMips64];
335}
336
337class ASE_MSA64 {
338  list<Predicate> InsnPredicates = [HasMSA, HasMips64];
339}
340
341// Class used for separating microMIPSr6 and microMIPS (r3) instruction.
342// It can be used only on instructions that doesn't inherit PredicateControl.
343class ISA_MICROMIPS_NOT_32R6_64R6 : PredicateControl {
344  let InsnPredicates = [InMicroMips, NotMips32r6, NotMips64r6];
345}
346
347class ASE_NOT_DSP {
348  list<Predicate> InsnPredicates = [NotDSP];
349}
350
351//===----------------------------------------------------------------------===//
352
353class MipsPat<dag pattern, dag result> : Pat<pattern, result>, PredicateControl {
354  let EncodingPredicates = [HasStdEnc];
355}
356
357class MipsInstAlias<string Asm, dag Result, bit Emit = 0b1> :
358  InstAlias<Asm, Result, Emit>, PredicateControl;
359
360class IsCommutable {
361  bit isCommutable = 1;
362}
363
364class IsBranch {
365  bit isBranch = 1;
366  bit isCTI = 1;
367}
368
369class IsReturn {
370  bit isReturn = 1;
371  bit isCTI = 1;
372}
373
374class IsCall {
375  bit isCall = 1;
376  bit isCTI = 1;
377}
378
379class IsTailCall {
380  bit isCall = 1;
381  bit isTerminator = 1;
382  bit isReturn = 1;
383  bit isBarrier = 1;
384  bit hasExtraSrcRegAllocReq = 1;
385  bit isCodeGenOnly = 1;
386  bit isCTI = 1;
387}
388
389class IsAsCheapAsAMove {
390  bit isAsCheapAsAMove = 1;
391}
392
393class NeverHasSideEffects {
394  bit hasSideEffects = 0;
395}
396
397//===----------------------------------------------------------------------===//
398// Instruction format superclass
399//===----------------------------------------------------------------------===//
400
401include "MipsInstrFormats.td"
402
403//===----------------------------------------------------------------------===//
404// Mips Operand, Complex Patterns and Transformations Definitions.
405//===----------------------------------------------------------------------===//
406
407class ConstantSImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
408                                  int Offset = 0> : AsmOperandClass {
409  let Name = "ConstantSImm" # Bits # "_" # Offset;
410  let RenderMethod = "addConstantSImmOperands<" # Bits # ", " # Offset # ">";
411  let PredicateMethod = "isConstantSImm<" # Bits # ", " # Offset # ">";
412  let SuperClasses = Supers;
413  let DiagnosticType = "SImm" # Bits # "_" # Offset;
414}
415
416class ConstantUImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
417                                  int Offset = 0> : AsmOperandClass {
418  let Name = "ConstantUImm" # Bits # "_" # Offset;
419  let RenderMethod = "addConstantUImmOperands<" # Bits # ", " # Offset # ">";
420  let PredicateMethod = "isConstantUImm<" # Bits # ", " # Offset # ">";
421  let SuperClasses = Supers;
422  let DiagnosticType = "UImm" # Bits # "_" # Offset;
423}
424
425class ConstantUImmRangeAsmOperandClass<int Bottom, int Top,
426                                       list<AsmOperandClass> Supers = []>
427    : AsmOperandClass {
428  let Name = "ConstantUImmRange" # Bottom # "_" # Top;
429  let RenderMethod = "addImmOperands";
430  let PredicateMethod = "isConstantUImmRange<" # Bottom # ", " # Top # ">";
431  let SuperClasses = Supers;
432  let DiagnosticType = "UImmRange" # Bottom # "_" # Top;
433}
434
435class SImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
436    : AsmOperandClass {
437  let Name = "SImm" # Bits;
438  let RenderMethod = "addSImmOperands<" # Bits # ">";
439  let PredicateMethod = "isSImm<" # Bits # ">";
440  let SuperClasses = Supers;
441  let DiagnosticType = "SImm" # Bits;
442}
443
444class UImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
445    : AsmOperandClass {
446  let Name = "UImm" # Bits;
447  let RenderMethod = "addUImmOperands<" # Bits # ">";
448  let PredicateMethod = "isUImm<" # Bits # ">";
449  let SuperClasses = Supers;
450  let DiagnosticType = "UImm" # Bits;
451}
452
453// AsmOperandClasses require a strict ordering which is difficult to manage
454// as a hierarchy. Instead, we use a linear ordering and impose an order that
455// is in some places arbitrary.
456//
457// Here the rules that are in use:
458// * Wider immediates are a superset of narrower immediates:
459//     uimm4 < uimm5 < uimm6
460// * For the same bit-width, unsigned immediates are a superset of signed
461//   immediates::
462//     simm4 < uimm4 < simm5 < uimm5
463// * For the same upper-bound, signed immediates are a superset of unsigned
464//   immediates:
465//     uimm3 < simm4 < uimm4 < simm4
466// * Modified immediates are a superset of ordinary immediates:
467//     uimm5 < uimm5_plus1 (1..32) < uimm5_plus32 (32..63) < uimm6
468//   The term 'superset' starts to break down here since the uimm5_plus* classes
469//   are not true supersets of uimm5 (but they are still subsets of uimm6).
470// * 'Relaxed' immediates are supersets of the corresponding unsigned immediate.
471//     uimm16 < uimm16_relaxed
472// * The codeGen pattern type is arbitrarily ordered.
473//     uimm5 < uimm5_64, and uimm5 < vsplat_uimm5
474//   This is entirely arbitrary. We need an ordering and what we pick is
475//   unimportant since only one is possible for a given mnemonic.
476def SImm32RelaxedAsmOperandClass
477    : SImmAsmOperandClass<32, []> {
478  let Name = "SImm32_Relaxed";
479  let PredicateMethod = "isAnyImm<32>";
480  let DiagnosticType = "SImm32_Relaxed";
481}
482def SImm32AsmOperandClass
483    : SImmAsmOperandClass<32, [SImm32RelaxedAsmOperandClass]>;
484def ConstantUImm26AsmOperandClass
485    : ConstantUImmAsmOperandClass<26, [SImm32AsmOperandClass]>;
486def ConstantUImm20AsmOperandClass
487    : ConstantUImmAsmOperandClass<20, [ConstantUImm26AsmOperandClass]>;
488def UImm16RelaxedAsmOperandClass
489    : UImmAsmOperandClass<16, [ConstantUImm20AsmOperandClass]> {
490  let Name = "UImm16_Relaxed";
491  let PredicateMethod = "isAnyImm<16>";
492  let DiagnosticType = "UImm16_Relaxed";
493}
494def UImm16AsmOperandClass
495    : UImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]>;
496def SImm16RelaxedAsmOperandClass
497    : SImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]> {
498  let Name = "SImm16_Relaxed";
499  let PredicateMethod = "isAnyImm<16>";
500  let DiagnosticType = "SImm16_Relaxed";
501}
502def SImm16AsmOperandClass
503    : SImmAsmOperandClass<16, [SImm16RelaxedAsmOperandClass]>;
504def ConstantSImm10Lsl3AsmOperandClass : AsmOperandClass {
505  let Name = "SImm10Lsl3";
506  let RenderMethod = "addImmOperands";
507  let PredicateMethod = "isScaledSImm<10, 3>";
508  let SuperClasses = [SImm16AsmOperandClass];
509  let DiagnosticType = "SImm10_Lsl3";
510}
511def ConstantSImm10Lsl2AsmOperandClass : AsmOperandClass {
512  let Name = "SImm10Lsl2";
513  let RenderMethod = "addImmOperands";
514  let PredicateMethod = "isScaledSImm<10, 2>";
515  let SuperClasses = [ConstantSImm10Lsl3AsmOperandClass];
516  let DiagnosticType = "SImm10_Lsl2";
517}
518def ConstantSImm11AsmOperandClass
519    : ConstantSImmAsmOperandClass<11, [ConstantSImm10Lsl2AsmOperandClass]>;
520def ConstantSImm10Lsl1AsmOperandClass : AsmOperandClass {
521  let Name = "SImm10Lsl1";
522  let RenderMethod = "addImmOperands";
523  let PredicateMethod = "isScaledSImm<10, 1>";
524  let SuperClasses = [ConstantSImm11AsmOperandClass];
525  let DiagnosticType = "SImm10_Lsl1";
526}
527def ConstantUImm10AsmOperandClass
528    : ConstantUImmAsmOperandClass<10, [ConstantSImm10Lsl1AsmOperandClass]>;
529def ConstantSImm10AsmOperandClass
530    : ConstantSImmAsmOperandClass<10, [ConstantUImm10AsmOperandClass]>;
531def ConstantSImm9AsmOperandClass
532    : ConstantSImmAsmOperandClass<9, [ConstantSImm10AsmOperandClass]>;
533def ConstantSImm7Lsl2AsmOperandClass : AsmOperandClass {
534  let Name = "SImm7Lsl2";
535  let RenderMethod = "addImmOperands";
536  let PredicateMethod = "isScaledSImm<7, 2>";
537  let SuperClasses = [ConstantSImm9AsmOperandClass];
538  let DiagnosticType = "SImm7_Lsl2";
539}
540def ConstantUImm8AsmOperandClass
541    : ConstantUImmAsmOperandClass<8, [ConstantSImm7Lsl2AsmOperandClass]>;
542def ConstantUImm7Sub1AsmOperandClass
543    : ConstantUImmAsmOperandClass<7, [ConstantUImm8AsmOperandClass], -1> {
544  // Specify the names since the -1 offset causes invalid identifiers otherwise.
545  let Name = "UImm7_N1";
546  let DiagnosticType = "UImm7_N1";
547}
548def ConstantUImm7AsmOperandClass
549    : ConstantUImmAsmOperandClass<7, [ConstantUImm7Sub1AsmOperandClass]>;
550def ConstantUImm6Lsl2AsmOperandClass : AsmOperandClass {
551  let Name = "UImm6Lsl2";
552  let RenderMethod = "addImmOperands";
553  let PredicateMethod = "isScaledUImm<6, 2>";
554  let SuperClasses = [ConstantUImm7AsmOperandClass];
555  let DiagnosticType = "UImm6_Lsl2";
556}
557def ConstantUImm6AsmOperandClass
558    : ConstantUImmAsmOperandClass<6, [ConstantUImm6Lsl2AsmOperandClass]>;
559def ConstantSImm6AsmOperandClass
560    : ConstantSImmAsmOperandClass<6, [ConstantUImm6AsmOperandClass]>;
561def ConstantUImm5Lsl2AsmOperandClass : AsmOperandClass {
562  let Name = "UImm5Lsl2";
563  let RenderMethod = "addImmOperands";
564  let PredicateMethod = "isScaledUImm<5, 2>";
565  let SuperClasses = [ConstantSImm6AsmOperandClass];
566  let DiagnosticType = "UImm5_Lsl2";
567}
568def ConstantUImm5_Range2_64AsmOperandClass
569    : ConstantUImmRangeAsmOperandClass<2, 64, [ConstantUImm5Lsl2AsmOperandClass]>;
570def ConstantUImm5Plus33AsmOperandClass
571    : ConstantUImmAsmOperandClass<5, [ConstantUImm5_Range2_64AsmOperandClass],
572                                  33>;
573def ConstantUImm5ReportUImm6AsmOperandClass
574    : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus33AsmOperandClass]> {
575  let Name = "ConstantUImm5_0_Report_UImm6";
576  let DiagnosticType = "UImm5_0_Report_UImm6";
577}
578def ConstantUImm5Plus32AsmOperandClass
579    : ConstantUImmAsmOperandClass<
580          5, [ConstantUImm5ReportUImm6AsmOperandClass], 32>;
581def ConstantUImm5Plus32NormalizeAsmOperandClass
582    : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus32AsmOperandClass], 32> {
583  let Name = "ConstantUImm5_32_Norm";
584  // We must also subtract 32 when we render the operand.
585  let RenderMethod = "addConstantUImmOperands<5, 32, -32>";
586}
587def ConstantUImm5Plus1AsmOperandClass
588    : ConstantUImmAsmOperandClass<
589          5, [ConstantUImm5Plus32NormalizeAsmOperandClass], 1>;
590def ConstantUImm5AsmOperandClass
591    : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus1AsmOperandClass]>;
592def ConstantSImm5AsmOperandClass
593    : ConstantSImmAsmOperandClass<5, [ConstantUImm5AsmOperandClass]>;
594def ConstantUImm4AsmOperandClass
595    : ConstantUImmAsmOperandClass<4, [ConstantSImm5AsmOperandClass]>;
596def ConstantSImm4AsmOperandClass
597    : ConstantSImmAsmOperandClass<4, [ConstantUImm4AsmOperandClass]>;
598def ConstantUImm3AsmOperandClass
599    : ConstantUImmAsmOperandClass<3, [ConstantSImm4AsmOperandClass]>;
600def ConstantUImm2Plus1AsmOperandClass
601    : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass], 1>;
602def ConstantUImm2AsmOperandClass
603    : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass]>;
604def ConstantUImm1AsmOperandClass
605    : ConstantUImmAsmOperandClass<1, [ConstantUImm2AsmOperandClass]>;
606def ConstantImmzAsmOperandClass : AsmOperandClass {
607  let Name = "ConstantImmz";
608  let RenderMethod = "addConstantUImmOperands<1>";
609  let PredicateMethod = "isConstantImmz";
610  let SuperClasses = [ConstantUImm1AsmOperandClass];
611  let DiagnosticType = "Immz";
612}
613
614def MipsJumpTargetAsmOperand : AsmOperandClass {
615  let Name = "JumpTarget";
616  let ParserMethod = "parseJumpTarget";
617  let PredicateMethod = "isImm";
618  let RenderMethod = "addImmOperands";
619}
620
621// Instruction operand types
622def jmptarget   : Operand<OtherVT> {
623  let EncoderMethod = "getJumpTargetOpValue";
624  let ParserMatchClass = MipsJumpTargetAsmOperand;
625}
626def brtarget    : Operand<OtherVT> {
627  let EncoderMethod = "getBranchTargetOpValue";
628  let OperandType = "OPERAND_PCREL";
629  let DecoderMethod = "DecodeBranchTarget";
630  let ParserMatchClass = MipsJumpTargetAsmOperand;
631}
632def brtarget1SImm16 : Operand<OtherVT> {
633  let EncoderMethod = "getBranchTargetOpValue1SImm16";
634  let OperandType = "OPERAND_PCREL";
635  let DecoderMethod = "DecodeBranchTarget1SImm16";
636  let ParserMatchClass = MipsJumpTargetAsmOperand;
637}
638def calltarget  : Operand<iPTR> {
639  let EncoderMethod = "getJumpTargetOpValue";
640  let ParserMatchClass = MipsJumpTargetAsmOperand;
641}
642
643def imm64: Operand<i64>;
644
645def simm19_lsl2 : Operand<i32> {
646  let EncoderMethod = "getSimm19Lsl2Encoding";
647  let DecoderMethod = "DecodeSimm19Lsl2";
648  let ParserMatchClass = MipsJumpTargetAsmOperand;
649}
650
651def simm18_lsl3 : Operand<i32> {
652  let EncoderMethod = "getSimm18Lsl3Encoding";
653  let DecoderMethod = "DecodeSimm18Lsl3";
654  let ParserMatchClass = MipsJumpTargetAsmOperand;
655}
656
657// Zero
658def uimmz       : Operand<i32> {
659  let PrintMethod = "printUImm<0>";
660  let ParserMatchClass = ConstantImmzAsmOperandClass;
661}
662
663// size operand of ins instruction
664def uimm_range_2_64 : Operand<i32> {
665  let PrintMethod = "printUImm<6, 2>";
666  let EncoderMethod = "getSizeInsEncoding";
667  let DecoderMethod = "DecodeInsSize";
668  let ParserMatchClass = ConstantUImm5_Range2_64AsmOperandClass;
669}
670
671// Unsigned Operands
672foreach I = {1, 2, 3, 4, 5, 6, 7, 8, 10, 20, 26} in
673  def uimm # I : Operand<i32> {
674    let PrintMethod = "printUImm<" # I # ">";
675    let ParserMatchClass =
676        !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
677  }
678
679def uimm2_plus1 : Operand<i32> {
680  let PrintMethod = "printUImm<2, 1>";
681  let EncoderMethod = "getUImmWithOffsetEncoding<2, 1>";
682  let DecoderMethod = "DecodeUImmWithOffset<2, 1>";
683  let ParserMatchClass = ConstantUImm2Plus1AsmOperandClass;
684}
685
686def uimm5_plus1 : Operand<i32> {
687  let PrintMethod = "printUImm<5, 1>";
688  let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
689  let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
690  let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass;
691}
692
693def uimm5_plus32 : Operand<i32> {
694  let PrintMethod = "printUImm<5, 32>";
695  let ParserMatchClass = ConstantUImm5Plus32AsmOperandClass;
696}
697
698def uimm5_plus33 : Operand<i32> {
699  let PrintMethod = "printUImm<5, 33>";
700  let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
701  let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
702  let ParserMatchClass = ConstantUImm5Plus33AsmOperandClass;
703}
704
705def uimm5_inssize_plus1 : Operand<i32> {
706  let PrintMethod = "printUImm<6>";
707  let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass;
708  let EncoderMethod = "getSizeInsEncoding";
709  let DecoderMethod = "DecodeInsSize";
710}
711
712def uimm5_plus32_normalize : Operand<i32> {
713  let PrintMethod = "printUImm<5>";
714  let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
715}
716
717def uimm5_lsl2 : Operand<OtherVT> {
718  let EncoderMethod = "getUImm5Lsl2Encoding";
719  let DecoderMethod = "DecodeUImmWithOffsetAndScale<5, 0, 4>";
720  let ParserMatchClass = ConstantUImm5Lsl2AsmOperandClass;
721}
722
723def uimm5_plus32_normalize_64 : Operand<i64> {
724  let PrintMethod = "printUImm<5>";
725  let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
726}
727
728def uimm6_lsl2 : Operand<OtherVT> {
729  let EncoderMethod = "getUImm6Lsl2Encoding";
730  let DecoderMethod = "DecodeUImmWithOffsetAndScale<6, 0, 4>";
731  let ParserMatchClass = ConstantUImm6Lsl2AsmOperandClass;
732}
733
734foreach I = {16} in
735  def uimm # I : Operand<i32> {
736    let PrintMethod = "printUImm<" # I # ">";
737    let ParserMatchClass =
738        !cast<AsmOperandClass>("UImm" # I # "AsmOperandClass");
739  }
740
741// Like uimm16_64 but coerces simm16 to uimm16.
742def uimm16_relaxed : Operand<i32> {
743  let PrintMethod = "printUImm<16>";
744  let ParserMatchClass =
745      !cast<AsmOperandClass>("UImm16RelaxedAsmOperandClass");
746}
747
748foreach I = {5} in
749  def uimm # I # _64 : Operand<i64> {
750    let PrintMethod = "printUImm<" # I # ">";
751    let ParserMatchClass =
752        !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
753  }
754
755foreach I = {16} in
756  def uimm # I # _64 : Operand<i64> {
757    let PrintMethod = "printUImm<" # I # ">";
758    let ParserMatchClass =
759        !cast<AsmOperandClass>("UImm" # I # "AsmOperandClass");
760  }
761
762// Like uimm16_64 but coerces simm16 to uimm16.
763def uimm16_64_relaxed : Operand<i64> {
764  let PrintMethod = "printUImm<16>";
765  let ParserMatchClass =
766      !cast<AsmOperandClass>("UImm16RelaxedAsmOperandClass");
767}
768
769// Like uimm5 but reports a less confusing error for 32-63 when
770// an instruction alias permits that.
771def uimm5_report_uimm6 : Operand<i32> {
772  let PrintMethod = "printUImm<5>";
773  let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
774}
775
776// Like uimm5_64 but reports a less confusing error for 32-63 when
777// an instruction alias permits that.
778def uimm5_64_report_uimm6 : Operand<i64> {
779  let PrintMethod = "printUImm<5>";
780  let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
781}
782
783foreach I = {1, 2, 3, 4} in
784  def uimm # I # _ptr : Operand<iPTR> {
785    let PrintMethod = "printUImm<" # I # ">";
786    let ParserMatchClass =
787        !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
788  }
789
790foreach I = {1, 2, 3, 4, 5, 6, 8} in
791  def vsplat_uimm # I : Operand<vAny> {
792    let PrintMethod = "printUImm<" # I # ">";
793    let ParserMatchClass =
794        !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
795  }
796
797// Signed operands
798foreach I = {4, 5, 6, 9, 10, 11} in
799  def simm # I : Operand<i32> {
800    let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
801    let ParserMatchClass =
802        !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
803  }
804
805foreach I = {1, 2, 3} in
806  def simm10_lsl # I : Operand<i32> {
807    let DecoderMethod = "DecodeSImmWithOffsetAndScale<10, " # I # ">";
808    let ParserMatchClass =
809        !cast<AsmOperandClass>("ConstantSImm10Lsl" # I # "AsmOperandClass");
810  }
811
812foreach I = {10} in
813  def simm # I # _64 : Operand<i64> {
814    let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
815    let ParserMatchClass =
816        !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
817  }
818
819foreach I = {5, 10} in
820  def vsplat_simm # I : Operand<vAny> {
821    let ParserMatchClass =
822        !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
823  }
824
825def simm7_lsl2 : Operand<OtherVT> {
826  let EncoderMethod = "getSImm7Lsl2Encoding";
827  let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ", 0, 4>";
828  let ParserMatchClass = ConstantSImm7Lsl2AsmOperandClass;
829}
830
831foreach I = {16, 32} in
832  def simm # I : Operand<i32> {
833    let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
834    let ParserMatchClass = !cast<AsmOperandClass>("SImm" # I # "AsmOperandClass");
835  }
836
837// Like simm16 but coerces uimm16 to simm16.
838def simm16_relaxed : Operand<i32> {
839  let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
840  let ParserMatchClass = !cast<AsmOperandClass>("SImm16RelaxedAsmOperandClass");
841}
842
843def simm16_64 : Operand<i64> {
844  let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
845  let ParserMatchClass = !cast<AsmOperandClass>("SImm16AsmOperandClass");
846}
847
848// Like simm32 but coerces uimm32 to simm32.
849def simm32_relaxed : Operand<i32> {
850  let DecoderMethod = "DecodeSImmWithOffsetAndScale<32>";
851  let ParserMatchClass = !cast<AsmOperandClass>("SImm32RelaxedAsmOperandClass");
852}
853
854// This is almost the same as a uimm7 but 0x7f is interpreted as -1.
855def li16_imm : Operand<i32> {
856  let DecoderMethod = "DecodeLi16Imm";
857  let ParserMatchClass = ConstantUImm7Sub1AsmOperandClass;
858}
859
860def MipsMemAsmOperand : AsmOperandClass {
861  let Name = "Mem";
862  let ParserMethod = "parseMemOperand";
863}
864
865def MipsMemSimm9AsmOperand : AsmOperandClass {
866  let Name = "MemOffsetSimm9";
867  let SuperClasses = [MipsMemAsmOperand];
868  let RenderMethod = "addMemOperands";
869  let ParserMethod = "parseMemOperand";
870  let PredicateMethod = "isMemWithSimmOffset<9>";
871  let DiagnosticType = "MemSImm9";
872}
873
874def MipsMemSimm10AsmOperand : AsmOperandClass {
875  let Name = "MemOffsetSimm10";
876  let SuperClasses = [MipsMemAsmOperand];
877  let RenderMethod = "addMemOperands";
878  let ParserMethod = "parseMemOperand";
879  let PredicateMethod = "isMemWithSimmOffset<10>";
880  let DiagnosticType = "MemSImm10";
881}
882
883def MipsMemSimm12AsmOperand : AsmOperandClass {
884  let Name = "MemOffsetSimm12";
885  let SuperClasses = [MipsMemAsmOperand];
886  let RenderMethod = "addMemOperands";
887  let ParserMethod = "parseMemOperand";
888  let PredicateMethod = "isMemWithSimmOffset<12>";
889  let DiagnosticType = "MemSImm12";
890}
891
892foreach I = {1, 2, 3} in
893  def MipsMemSimm10Lsl # I # AsmOperand : AsmOperandClass {
894    let Name = "MemOffsetSimm10_" # I;
895    let SuperClasses = [MipsMemAsmOperand];
896    let RenderMethod = "addMemOperands";
897    let ParserMethod = "parseMemOperand";
898    let PredicateMethod = "isMemWithSimmOffset<10, " # I # ">";
899    let DiagnosticType = "MemSImm10Lsl" # I;
900  }
901
902def MipsMemSimm11AsmOperand : AsmOperandClass {
903  let Name = "MemOffsetSimm11";
904  let SuperClasses = [MipsMemAsmOperand];
905  let RenderMethod = "addMemOperands";
906  let ParserMethod = "parseMemOperand";
907  let PredicateMethod = "isMemWithSimmOffset<11>";
908  let DiagnosticType = "MemSImm11";
909}
910
911def MipsMemSimm16AsmOperand : AsmOperandClass {
912  let Name = "MemOffsetSimm16";
913  let SuperClasses = [MipsMemAsmOperand];
914  let RenderMethod = "addMemOperands";
915  let ParserMethod = "parseMemOperand";
916  let PredicateMethod = "isMemWithSimmOffset<16>";
917  let DiagnosticType = "MemSImm16";
918}
919
920def MipsInvertedImmoperand : AsmOperandClass {
921  let Name = "InvNum";
922  let RenderMethod = "addImmOperands";
923  let ParserMethod = "parseInvNum";
924}
925
926def InvertedImOperand : Operand<i32> {
927  let ParserMatchClass = MipsInvertedImmoperand;
928}
929
930def InvertedImOperand64 : Operand<i64> {
931  let ParserMatchClass = MipsInvertedImmoperand;
932}
933
934class mem_generic : Operand<iPTR> {
935  let PrintMethod = "printMemOperand";
936  let MIOperandInfo = (ops ptr_rc, simm16);
937  let EncoderMethod = "getMemEncoding";
938  let ParserMatchClass = MipsMemAsmOperand;
939  let OperandType = "OPERAND_MEMORY";
940}
941
942// Address operand
943def mem : mem_generic;
944
945// MSA specific address operand
946def mem_msa : mem_generic {
947  let MIOperandInfo = (ops ptr_rc, simm10);
948  let EncoderMethod = "getMSAMemEncoding";
949}
950
951def simm12 : Operand<i32> {
952  let DecoderMethod = "DecodeSimm12";
953}
954
955def mem_simm9 : mem_generic {
956  let MIOperandInfo = (ops ptr_rc, simm9);
957  let EncoderMethod = "getMemEncoding";
958  let ParserMatchClass = MipsMemSimm9AsmOperand;
959}
960
961def mem_simm10 : mem_generic {
962  let MIOperandInfo = (ops ptr_rc, simm10);
963  let EncoderMethod = "getMemEncoding";
964  let ParserMatchClass = MipsMemSimm10AsmOperand;
965}
966
967foreach I = {1, 2, 3} in
968  def mem_simm10_lsl # I : mem_generic {
969    let MIOperandInfo = (ops ptr_rc, !cast<Operand>("simm10_lsl" # I));
970    let EncoderMethod = "getMemEncoding<" # I  # ">";
971    let ParserMatchClass =
972            !cast<AsmOperandClass>("MipsMemSimm10Lsl" # I # "AsmOperand");
973  }
974
975def mem_simm11 : mem_generic {
976  let MIOperandInfo = (ops ptr_rc, simm11);
977  let EncoderMethod = "getMemEncoding";
978  let ParserMatchClass = MipsMemSimm11AsmOperand;
979}
980
981def mem_simm12 : mem_generic {
982  let MIOperandInfo = (ops ptr_rc, simm12);
983  let EncoderMethod = "getMemEncoding";
984  let ParserMatchClass = MipsMemSimm12AsmOperand;
985}
986
987def mem_simm16 : mem_generic {
988  let MIOperandInfo = (ops ptr_rc, simm16);
989  let EncoderMethod = "getMemEncoding";
990  let ParserMatchClass = MipsMemSimm16AsmOperand;
991}
992
993def mem_ea : Operand<iPTR> {
994  let PrintMethod = "printMemOperandEA";
995  let MIOperandInfo = (ops ptr_rc, simm16);
996  let EncoderMethod = "getMemEncoding";
997  let OperandType = "OPERAND_MEMORY";
998}
999
1000def PtrRC : Operand<iPTR> {
1001  let MIOperandInfo = (ops ptr_rc);
1002  let DecoderMethod = "DecodePtrRegisterClass";
1003  let ParserMatchClass = GPR32AsmOperand;
1004}
1005
1006// size operand of ins instruction
1007def size_ins : Operand<i32> {
1008  let EncoderMethod = "getSizeInsEncoding";
1009  let DecoderMethod = "DecodeInsSize";
1010}
1011
1012// Transformation Function - get the lower 16 bits.
1013def LO16 : SDNodeXForm<imm, [{
1014  return getImm(N, N->getZExtValue() & 0xFFFF);
1015}]>;
1016
1017// Transformation Function - get the higher 16 bits.
1018def HI16 : SDNodeXForm<imm, [{
1019  return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF);
1020}]>;
1021
1022// Plus 1.
1023def Plus1 : SDNodeXForm<imm, [{ return getImm(N, N->getSExtValue() + 1); }]>;
1024
1025// Node immediate is zero (e.g. insve.d)
1026def immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>;
1027
1028// Node immediate fits as 16-bit sign extended on target immediate.
1029// e.g. addi, andi
1030def immSExt8  : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;
1031
1032// Node immediate fits as 16-bit sign extended on target immediate.
1033// e.g. addi, andi
1034def immSExt16  : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;
1035
1036// Node immediate fits as 15-bit sign extended on target immediate.
1037// e.g. addi, andi
1038def immSExt15  : PatLeaf<(imm), [{ return isInt<15>(N->getSExtValue()); }]>;
1039
1040// Node immediate fits as 7-bit zero extended on target immediate.
1041def immZExt7 : PatLeaf<(imm), [{ return isUInt<7>(N->getZExtValue()); }]>;
1042
1043// Node immediate fits as 16-bit zero extended on target immediate.
1044// The LO16 param means that only the lower 16 bits of the node
1045// immediate are caught.
1046// e.g. addiu, sltiu
1047def immZExt16  : PatLeaf<(imm), [{
1048  if (N->getValueType(0) == MVT::i32)
1049    return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
1050  else
1051    return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
1052}], LO16>;
1053
1054// Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared).
1055def immLow16Zero : PatLeaf<(imm), [{
1056  int64_t Val = N->getSExtValue();
1057  return isInt<32>(Val) && !(Val & 0xffff);
1058}]>;
1059
1060// shamt field must fit in 5 bits.
1061def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
1062
1063def immZExt5Plus1 : PatLeaf<(imm), [{
1064  return isUInt<5>(N->getZExtValue() - 1);
1065}]>;
1066def immZExt5Plus32 : PatLeaf<(imm), [{
1067  return isUInt<5>(N->getZExtValue() - 32);
1068}]>;
1069def immZExt5Plus33 : PatLeaf<(imm), [{
1070  return isUInt<5>(N->getZExtValue() - 33);
1071}]>;
1072
1073// True if (N + 1) fits in 16-bit field.
1074def immSExt16Plus1 : PatLeaf<(imm), [{
1075  return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1);
1076}]>;
1077
1078// Mips Address Mode! SDNode frameindex could possibily be a match
1079// since load and store instructions from stack used it.
1080def addr :
1081  ComplexPattern<iPTR, 2, "selectIntAddr", [frameindex]>;
1082
1083def addrRegImm :
1084  ComplexPattern<iPTR, 2, "selectAddrRegImm", [frameindex]>;
1085
1086def addrDefault :
1087  ComplexPattern<iPTR, 2, "selectAddrDefault", [frameindex]>;
1088
1089def addrimm10 : ComplexPattern<iPTR, 2, "selectIntAddrMSA", [frameindex]>;
1090
1091//===----------------------------------------------------------------------===//
1092// Instructions specific format
1093//===----------------------------------------------------------------------===//
1094
1095// Arithmetic and logical instructions with 3 register operands.
1096class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0,
1097                  InstrItinClass Itin = NoItinerary,
1098                  SDPatternOperator OpNode = null_frag>:
1099  InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
1100         !strconcat(opstr, "\t$rd, $rs, $rt"),
1101         [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> {
1102  let isCommutable = isComm;
1103  let isReMaterializable = 1;
1104  let TwoOperandAliasConstraint = "$rd = $rs";
1105}
1106
1107// Arithmetic and logical instructions with 2 register operands.
1108class ArithLogicI<string opstr, Operand Od, RegisterOperand RO,
1109                  InstrItinClass Itin = NoItinerary,
1110                  SDPatternOperator imm_type = null_frag,
1111                  SDPatternOperator OpNode = null_frag> :
1112  InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16),
1113         !strconcat(opstr, "\t$rt, $rs, $imm16"),
1114         [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))],
1115         Itin, FrmI, opstr> {
1116  let isReMaterializable = 1;
1117  let TwoOperandAliasConstraint = "$rs = $rt";
1118}
1119
1120// Arithmetic Multiply ADD/SUB
1121class MArithR<string opstr, InstrItinClass itin, bit isComm = 0> :
1122  InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1123         !strconcat(opstr, "\t$rs, $rt"), [], itin, FrmR, opstr> {
1124  let Defs = [HI0, LO0];
1125  let Uses = [HI0, LO0];
1126  let isCommutable = isComm;
1127}
1128
1129//  Logical
1130class LogicNOR<string opstr, RegisterOperand RO>:
1131  InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
1132         !strconcat(opstr, "\t$rd, $rs, $rt"),
1133         [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], II_NOR, FrmR, opstr> {
1134  let isCommutable = 1;
1135}
1136
1137// Shifts
1138class shift_rotate_imm<string opstr, Operand ImmOpnd,
1139                       RegisterOperand RO, InstrItinClass itin,
1140                       SDPatternOperator OpNode = null_frag,
1141                       SDPatternOperator PF = null_frag> :
1142  InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt),
1143         !strconcat(opstr, "\t$rd, $rt, $shamt"),
1144         [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], itin, FrmR, opstr> {
1145  let TwoOperandAliasConstraint = "$rt = $rd";
1146}
1147
1148class shift_rotate_reg<string opstr, RegisterOperand RO, InstrItinClass itin,
1149                       SDPatternOperator OpNode = null_frag>:
1150  InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs),
1151         !strconcat(opstr, "\t$rd, $rt, $rs"),
1152         [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], itin, FrmR,
1153         opstr>;
1154
1155// Load Upper Immediate
1156class LoadUpper<string opstr, RegisterOperand RO, Operand Imm>:
1157  InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"),
1158         [], II_LUI, FrmI, opstr>, IsAsCheapAsAMove {
1159  let hasSideEffects = 0;
1160  let isReMaterializable = 1;
1161}
1162
1163// Memory Load/Store
1164class LoadMemory<string opstr, DAGOperand RO, DAGOperand MO,
1165                 SDPatternOperator OpNode = null_frag,
1166                 InstrItinClass Itin = NoItinerary,
1167                 ComplexPattern Addr = addr> :
1168  InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1169         [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> {
1170  let DecoderMethod = "DecodeMem";
1171  let canFoldAsLoad = 1;
1172  let mayLoad = 1;
1173}
1174
1175class Load<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
1176           InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
1177  LoadMemory<opstr, RO, mem, OpNode, Itin, Addr>;
1178
1179class StoreMemory<string opstr, DAGOperand RO, DAGOperand MO,
1180            SDPatternOperator OpNode = null_frag,
1181            InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
1182  InstSE<(outs), (ins RO:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1183         [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> {
1184  let DecoderMethod = "DecodeMem";
1185  let mayStore = 1;
1186}
1187
1188class Store<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
1189            InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr,
1190            DAGOperand MO = mem> :
1191  StoreMemory<opstr, RO, MO, OpNode, Itin, Addr>;
1192
1193// Load/Store Left/Right
1194let canFoldAsLoad = 1 in
1195class LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
1196                    InstrItinClass Itin> :
1197  InstSE<(outs RO:$rt), (ins mem:$addr, RO:$src),
1198         !strconcat(opstr, "\t$rt, $addr"),
1199         [(set RO:$rt, (OpNode addr:$addr, RO:$src))], Itin, FrmI> {
1200  let DecoderMethod = "DecodeMem";
1201  string Constraints = "$src = $rt";
1202}
1203
1204class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
1205                     InstrItinClass Itin> :
1206  InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1207         [(OpNode RO:$rt, addr:$addr)], Itin, FrmI> {
1208  let DecoderMethod = "DecodeMem";
1209}
1210
1211// COP2 Load/Store
1212class LW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
1213             SDPatternOperator OpNode= null_frag> :
1214  InstSE<(outs RC:$rt), (ins mem_simm16:$addr),
1215         !strconcat(opstr, "\t$rt, $addr"),
1216         [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
1217  let DecoderMethod = "DecodeFMem2";
1218  let mayLoad = 1;
1219}
1220
1221class SW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
1222             SDPatternOperator OpNode= null_frag> :
1223  InstSE<(outs), (ins RC:$rt, mem_simm16:$addr),
1224         !strconcat(opstr, "\t$rt, $addr"),
1225         [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
1226  let DecoderMethod = "DecodeFMem2";
1227  let mayStore = 1;
1228}
1229
1230// COP3 Load/Store
1231class LW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
1232             SDPatternOperator OpNode= null_frag> :
1233  InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1234         [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
1235  let DecoderMethod = "DecodeFMem3";
1236  let mayLoad = 1;
1237}
1238
1239class SW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
1240             SDPatternOperator OpNode= null_frag> :
1241  InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1242         [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
1243  let DecoderMethod = "DecodeFMem3";
1244  let mayStore = 1;
1245}
1246
1247// Conditional Branch
1248class CBranch<string opstr, DAGOperand opnd, PatFrag cond_op,
1249              RegisterOperand RO, bit DelaySlot = 1> :
1250  InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
1251         !strconcat(opstr, "\t$rs, $rt, $offset"),
1252         [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], II_BCC,
1253         FrmI, opstr> {
1254  let isBranch = 1;
1255  let isTerminator = 1;
1256  let hasDelaySlot = DelaySlot;
1257  let Defs = [AT];
1258  bit isCTI = 1;
1259}
1260
1261class CBranchZero<string opstr, DAGOperand opnd, PatFrag cond_op,
1262                  RegisterOperand RO, bit DelaySlot = 1> :
1263  InstSE<(outs), (ins RO:$rs, opnd:$offset),
1264         !strconcat(opstr, "\t$rs, $offset"),
1265         [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], II_BCCZ,
1266         FrmI, opstr> {
1267  let isBranch = 1;
1268  let isTerminator = 1;
1269  let hasDelaySlot = DelaySlot;
1270  let Defs = [AT];
1271  bit isCTI = 1;
1272}
1273
1274// SetCC
1275class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> :
1276  InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt),
1277         !strconcat(opstr, "\t$rd, $rs, $rt"),
1278         [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))],
1279         II_SLT_SLTU, FrmR, opstr>;
1280
1281class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
1282              RegisterOperand RO>:
1283  InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16),
1284         !strconcat(opstr, "\t$rt, $rs, $imm16"),
1285         [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))],
1286         II_SLTI_SLTIU, FrmI, opstr>;
1287
1288// Jump
1289class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
1290             SDPatternOperator targetoperator, string bopstr> :
1291  InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
1292         [(operator targetoperator:$target)], II_J, FrmJ, bopstr> {
1293  let isTerminator=1;
1294  let isBarrier=1;
1295  let hasDelaySlot = 1;
1296  let DecoderMethod = "DecodeJumpTarget";
1297  let Defs = [AT];
1298  bit isCTI = 1;
1299}
1300
1301// Unconditional branch
1302class UncondBranch<Instruction BEQInst> :
1303  PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], II_B>,
1304  PseudoInstExpansion<(BEQInst ZERO, ZERO, brtarget:$offset)> {
1305  let isBranch = 1;
1306  let isTerminator = 1;
1307  let isBarrier = 1;
1308  let hasDelaySlot = 1;
1309  let AdditionalPredicates = [RelocPIC];
1310  let Defs = [AT];
1311  bit isCTI = 1;
1312}
1313
1314// Base class for indirect branch and return instruction classes.
1315let isTerminator=1, isBarrier=1, hasDelaySlot = 1, isCTI = 1 in
1316class JumpFR<string opstr, RegisterOperand RO,
1317             SDPatternOperator operator = null_frag>:
1318  InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], II_JR,
1319         FrmR, opstr>;
1320
1321// Indirect branch
1322class IndirectBranch<string opstr, RegisterOperand RO> : JumpFR<opstr, RO> {
1323  let isBranch = 1;
1324  let isIndirectBranch = 1;
1325}
1326
1327// Jump and Link (Call)
1328let isCall=1, hasDelaySlot=1, isCTI=1, Defs = [RA] in {
1329  class JumpLink<string opstr, DAGOperand opnd> :
1330    InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
1331           [(MipsJmpLink tglobaladdr:$target)], II_JAL, FrmJ, opstr> {
1332    let DecoderMethod = "DecodeJumpTarget";
1333  }
1334
1335  class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst,
1336                          Register RetReg, RegisterOperand ResRO = RO>:
1337    PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], II_JALR>,
1338    PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)>;
1339
1340  class JumpLinkReg<string opstr, RegisterOperand RO>:
1341    InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1342           [], II_JALR, FrmR, opstr>;
1343
1344  class BGEZAL_FT<string opstr, DAGOperand opnd,
1345                  RegisterOperand RO, bit DelaySlot = 1> :
1346    InstSE<(outs), (ins RO:$rs, opnd:$offset),
1347           !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZAL, FrmI, opstr> {
1348    let hasDelaySlot = DelaySlot;
1349  }
1350
1351}
1352
1353let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
1354    hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT] in {
1355  class TailCall<Instruction JumpInst> :
1356    PseudoSE<(outs), (ins calltarget:$target), [], II_J>,
1357    PseudoInstExpansion<(JumpInst jmptarget:$target)>;
1358
1359  class TailCallReg<RegisterOperand RO, Instruction JRInst,
1360                    RegisterOperand ResRO = RO> :
1361    PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>,
1362    PseudoInstExpansion<(JRInst ResRO:$rs)>;
1363}
1364
1365class BAL_BR_Pseudo<Instruction RealInst> :
1366  PseudoSE<(outs), (ins brtarget:$offset), [], II_BCCZAL>,
1367  PseudoInstExpansion<(RealInst ZERO, brtarget:$offset)> {
1368  let isBranch = 1;
1369  let isTerminator = 1;
1370  let isBarrier = 1;
1371  let hasDelaySlot = 1;
1372  let Defs = [RA];
1373  bit isCTI = 1;
1374}
1375
1376let isCTI = 1 in {
1377// Syscall
1378class SYS_FT<string opstr, Operand ImmOp, InstrItinClass itin = NoItinerary> :
1379  InstSE<(outs), (ins ImmOp:$code_),
1380         !strconcat(opstr, "\t$code_"), [], itin, FrmI, opstr>;
1381// Break
1382class BRK_FT<string opstr> :
1383  InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
1384         !strconcat(opstr, "\t$code_1, $code_2"), [], II_BREAK,
1385         FrmOther, opstr>;
1386
1387// (D)Eret
1388class ER_FT<string opstr, InstrItinClass itin = NoItinerary> :
1389  InstSE<(outs), (ins),
1390         opstr, [], itin, FrmOther, opstr>;
1391
1392// Wait
1393class WAIT_FT<string opstr> :
1394  InstSE<(outs), (ins), opstr, [], II_WAIT, FrmOther, opstr>;
1395}
1396
1397// Interrupts
1398class DEI_FT<string opstr, RegisterOperand RO,
1399             InstrItinClass itin = NoItinerary> :
1400  InstSE<(outs RO:$rt), (ins),
1401         !strconcat(opstr, "\t$rt"), [], itin, FrmOther, opstr>;
1402
1403// Sync
1404let hasSideEffects = 1 in
1405class SYNC_FT<string opstr> :
1406  InstSE<(outs), (ins uimm5:$stype), "sync $stype",
1407         [(MipsSync immZExt5:$stype)], II_SYNC, FrmOther, opstr>;
1408
1409class SYNCI_FT<string opstr> :
1410  InstSE<(outs), (ins mem_simm16:$addr), !strconcat(opstr, "\t$addr"), [],
1411         II_SYNCI, FrmOther, opstr> {
1412  let hasSideEffects = 1;
1413  let DecoderMethod = "DecodeSyncI";
1414}
1415
1416let hasSideEffects = 1, isCTI = 1 in {
1417class TEQ_FT<string opstr, RegisterOperand RO, Operand ImmOp,
1418             InstrItinClass itin = NoItinerary> :
1419  InstSE<(outs), (ins RO:$rs, RO:$rt, ImmOp:$code_),
1420         !strconcat(opstr, "\t$rs, $rt, $code_"), [], itin, FrmI, opstr>;
1421
1422class TEQI_FT<string opstr, RegisterOperand RO,
1423              InstrItinClass itin = NoItinerary> :
1424  InstSE<(outs), (ins RO:$rs, simm16:$imm16),
1425         !strconcat(opstr, "\t$rs, $imm16"), [], itin, FrmOther, opstr>;
1426}
1427
1428// Mul, Div
1429class Mult<string opstr, InstrItinClass itin, RegisterOperand RO,
1430           list<Register> DefRegs> :
1431  InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [],
1432         itin, FrmR, opstr> {
1433  let isCommutable = 1;
1434  let Defs = DefRegs;
1435  let hasSideEffects = 0;
1436}
1437
1438// Pseudo multiply/divide instruction with explicit accumulator register
1439// operands.
1440class MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1,
1441                    SDPatternOperator OpNode, InstrItinClass Itin,
1442                    bit IsComm = 1, bit HasSideEffects = 0,
1443                    bit UsesCustomInserter = 0> :
1444  PseudoSE<(outs R0:$ac), (ins R1:$rs, R1:$rt),
1445           [(set R0:$ac, (OpNode R1:$rs, R1:$rt))], Itin>,
1446  PseudoInstExpansion<(RealInst R1:$rs, R1:$rt)> {
1447  let isCommutable = IsComm;
1448  let hasSideEffects = HasSideEffects;
1449  let usesCustomInserter = UsesCustomInserter;
1450}
1451
1452// Pseudo multiply add/sub instruction with explicit accumulator register
1453// operands.
1454class MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode,
1455                    InstrItinClass itin>
1456  : PseudoSE<(outs ACC64:$ac),
1457             (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin),
1458             [(set ACC64:$ac,
1459              (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))],
1460             itin>,
1461    PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> {
1462  string Constraints = "$acin = $ac";
1463}
1464
1465class Div<string opstr, InstrItinClass itin, RegisterOperand RO,
1466          list<Register> DefRegs> :
1467  InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$$zero, $rs, $rt"),
1468         [], itin, FrmR, opstr> {
1469  let Defs = DefRegs;
1470}
1471
1472// Move from Hi/Lo
1473class PseudoMFLOHI<RegisterClass DstRC, RegisterClass SrcRC, SDNode OpNode>
1474  : PseudoSE<(outs DstRC:$rd), (ins SrcRC:$hilo),
1475             [(set DstRC:$rd, (OpNode SrcRC:$hilo))], II_MFHI_MFLO>;
1476
1477class MoveFromLOHI<string opstr, RegisterOperand RO, Register UseReg>:
1478  InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO,
1479         FrmR, opstr> {
1480  let Uses = [UseReg];
1481  let hasSideEffects = 0;
1482}
1483
1484class PseudoMTLOHI<RegisterClass DstRC, RegisterClass SrcRC>
1485  : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi),
1486             [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))],
1487             II_MTHI_MTLO>;
1488
1489class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>:
1490  InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO,
1491  FrmR, opstr> {
1492  let Defs = DefRegs;
1493  let hasSideEffects = 0;
1494}
1495
1496class EffectiveAddress<string opstr, RegisterOperand RO> :
1497  InstSE<(outs RO:$rt), (ins mem_ea:$addr), !strconcat(opstr, "\t$rt, $addr"),
1498         [(set RO:$rt, addr:$addr)], II_ADDIU, FrmI,
1499         !strconcat(opstr, "_lea")> {
1500  let isCodeGenOnly = 1;
1501  let hasNoSchedulingInfo = 1;
1502  let DecoderMethod = "DecodeMem";
1503}
1504
1505// Count Leading Ones/Zeros in Word
1506class CountLeading0<string opstr, RegisterOperand RO,
1507                  InstrItinClass itin = NoItinerary>:
1508  InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1509         [(set RO:$rd, (ctlz RO:$rs))], itin, FrmR, opstr>;
1510
1511class CountLeading1<string opstr, RegisterOperand RO,
1512                  InstrItinClass itin = NoItinerary>:
1513  InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1514         [(set RO:$rd, (ctlz (not RO:$rs)))], itin, FrmR, opstr>;
1515
1516// Sign Extend in Register.
1517class SignExtInReg<string opstr, ValueType vt, RegisterOperand RO,
1518                   InstrItinClass itin> :
1519  InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"),
1520         [(set RO:$rd, (sext_inreg RO:$rt, vt))], itin, FrmR, opstr>;
1521
1522// Subword Swap
1523class SubwordSwap<string opstr, RegisterOperand RO,
1524                  InstrItinClass itin = NoItinerary>:
1525  InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [], itin,
1526         FrmR, opstr> {
1527  let hasSideEffects = 0;
1528}
1529
1530// Read Hardware
1531class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> :
1532  InstSE<(outs CPURegOperand:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [],
1533         II_RDHWR, FrmR, "rdhwr">;
1534
1535// Ext and Ins
1536class ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1537              Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm,
1538              SDPatternOperator Op = null_frag> :
1539  InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size),
1540         !strconcat(opstr, " $rt, $rs, $pos, $size"),
1541         [(set RO:$rt, (Op RO:$rs, PosImm:$pos, SizeImm:$size))], II_EXT,
1542         FrmR, opstr>, ISA_MIPS32R2;
1543
1544class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1545              Operand SizeOpnd, SDPatternOperator Op = null_frag>:
1546  InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size, RO:$src),
1547         !strconcat(opstr, " $rt, $rs, $pos, $size"),
1548         [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size, RO:$src))],
1549         II_INS, FrmR, opstr>, ISA_MIPS32R2 {
1550  let Constraints = "$src = $rt";
1551}
1552
1553// Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*).
1554class Atomic2Ops<PatFrag Op, RegisterClass DRC> :
1555  PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr),
1556           [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]>;
1557
1558// Atomic Compare & Swap.
1559class AtomicCmpSwap<PatFrag Op, RegisterClass DRC> :
1560  PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap),
1561           [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]>;
1562
1563class LLBase<string opstr, RegisterOperand RO, DAGOperand MO = mem> :
1564  InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1565         [], II_LL, FrmI, opstr> {
1566  let DecoderMethod = "DecodeMem";
1567  let mayLoad = 1;
1568}
1569
1570class SCBase<string opstr, RegisterOperand RO> :
1571  InstSE<(outs RO:$dst), (ins RO:$rt, mem:$addr),
1572         !strconcat(opstr, "\t$rt, $addr"), [], II_SC, FrmI> {
1573  let DecoderMethod = "DecodeMem";
1574  let mayStore = 1;
1575  let Constraints = "$rt = $dst";
1576}
1577
1578class MFC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
1579             InstrItinClass itin> :
1580  InstSE<(outs RO:$rt), (ins RD:$rd, uimm3:$sel),
1581         !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR>;
1582
1583class MTC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
1584             InstrItinClass itin> :
1585  InstSE<(outs RO:$rd), (ins RD:$rt, uimm3:$sel),
1586         !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR>;
1587
1588class TrapBase<Instruction RealInst>
1589  : PseudoSE<(outs), (ins), [(trap)], II_TRAP>,
1590    PseudoInstExpansion<(RealInst 0, 0)> {
1591  let isBarrier = 1;
1592  let isTerminator = 1;
1593  let isCodeGenOnly = 1;
1594  let isCTI = 1;
1595}
1596
1597//===----------------------------------------------------------------------===//
1598// Pseudo instructions
1599//===----------------------------------------------------------------------===//
1600
1601// Return RA.
1602let isReturn=1, isTerminator=1, isBarrier=1, hasCtrlDep=1, isCTI=1 in {
1603  let hasDelaySlot=1 in
1604  def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
1605
1606  let hasSideEffects=1 in
1607  def ERet : PseudoSE<(outs), (ins), [(MipsERet)]>;
1608}
1609
1610let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
1611def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt),
1612                                  [(callseq_start timm:$amt)]>;
1613def ADJCALLSTACKUP   : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1614                                  [(callseq_end timm:$amt1, timm:$amt2)]>;
1615}
1616
1617let usesCustomInserter = 1 in {
1618  def ATOMIC_LOAD_ADD_I8   : Atomic2Ops<atomic_load_add_8, GPR32>;
1619  def ATOMIC_LOAD_ADD_I16  : Atomic2Ops<atomic_load_add_16, GPR32>;
1620  def ATOMIC_LOAD_ADD_I32  : Atomic2Ops<atomic_load_add_32, GPR32>;
1621  def ATOMIC_LOAD_SUB_I8   : Atomic2Ops<atomic_load_sub_8, GPR32>;
1622  def ATOMIC_LOAD_SUB_I16  : Atomic2Ops<atomic_load_sub_16, GPR32>;
1623  def ATOMIC_LOAD_SUB_I32  : Atomic2Ops<atomic_load_sub_32, GPR32>;
1624  def ATOMIC_LOAD_AND_I8   : Atomic2Ops<atomic_load_and_8, GPR32>;
1625  def ATOMIC_LOAD_AND_I16  : Atomic2Ops<atomic_load_and_16, GPR32>;
1626  def ATOMIC_LOAD_AND_I32  : Atomic2Ops<atomic_load_and_32, GPR32>;
1627  def ATOMIC_LOAD_OR_I8    : Atomic2Ops<atomic_load_or_8, GPR32>;
1628  def ATOMIC_LOAD_OR_I16   : Atomic2Ops<atomic_load_or_16, GPR32>;
1629  def ATOMIC_LOAD_OR_I32   : Atomic2Ops<atomic_load_or_32, GPR32>;
1630  def ATOMIC_LOAD_XOR_I8   : Atomic2Ops<atomic_load_xor_8, GPR32>;
1631  def ATOMIC_LOAD_XOR_I16  : Atomic2Ops<atomic_load_xor_16, GPR32>;
1632  def ATOMIC_LOAD_XOR_I32  : Atomic2Ops<atomic_load_xor_32, GPR32>;
1633  def ATOMIC_LOAD_NAND_I8  : Atomic2Ops<atomic_load_nand_8, GPR32>;
1634  def ATOMIC_LOAD_NAND_I16 : Atomic2Ops<atomic_load_nand_16, GPR32>;
1635  def ATOMIC_LOAD_NAND_I32 : Atomic2Ops<atomic_load_nand_32, GPR32>;
1636
1637  def ATOMIC_SWAP_I8       : Atomic2Ops<atomic_swap_8, GPR32>;
1638  def ATOMIC_SWAP_I16      : Atomic2Ops<atomic_swap_16, GPR32>;
1639  def ATOMIC_SWAP_I32      : Atomic2Ops<atomic_swap_32, GPR32>;
1640
1641  def ATOMIC_CMP_SWAP_I8   : AtomicCmpSwap<atomic_cmp_swap_8, GPR32>;
1642  def ATOMIC_CMP_SWAP_I16  : AtomicCmpSwap<atomic_cmp_swap_16, GPR32>;
1643  def ATOMIC_CMP_SWAP_I32  : AtomicCmpSwap<atomic_cmp_swap_32, GPR32>;
1644}
1645
1646/// Pseudo instructions for loading and storing accumulator registers.
1647let isPseudo = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in {
1648  def LOAD_ACC64  : Load<"", ACC64>;
1649  def STORE_ACC64 : Store<"", ACC64>;
1650}
1651
1652// We need these two pseudo instructions to avoid offset calculation for long
1653// branches.  See the comment in file MipsLongBranch.cpp for detailed
1654// explanation.
1655
1656// Expands to: lui $dst, %hi($tgt - $baltgt)
1657def LONG_BRANCH_LUi : PseudoSE<(outs GPR32Opnd:$dst),
1658  (ins brtarget:$tgt, brtarget:$baltgt), []>;
1659
1660// Expands to: addiu $dst, $src, %lo($tgt - $baltgt)
1661def LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst),
1662  (ins GPR32Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []>;
1663
1664//===----------------------------------------------------------------------===//
1665// Instruction definition
1666//===----------------------------------------------------------------------===//
1667//===----------------------------------------------------------------------===//
1668// MipsI Instructions
1669//===----------------------------------------------------------------------===//
1670
1671/// Arithmetic Instructions (ALU Immediate)
1672let AdditionalPredicates = [NotInMicroMips] in {
1673  def ADDiu : MMRel, StdMMR6Rel, ArithLogicI<"addiu", simm16_relaxed, GPR32Opnd,
1674                                             II_ADDIU, immSExt16, add>,
1675              ADDI_FM<0x9>, IsAsCheapAsAMove;
1676
1677  def ANDi : MMRel, StdMMR6Rel,
1678             ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16, and>,
1679             ADDI_FM<0xc>;
1680  def ORi  : MMRel, StdMMR6Rel,
1681             ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16, or>,
1682             ADDI_FM<0xd>;
1683  def XORi : MMRel, StdMMR6Rel,
1684             ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16, xor>,
1685             ADDI_FM<0xe>;
1686}
1687def ADDi  : MMRel, ArithLogicI<"addi", simm16_relaxed, GPR32Opnd, II_ADDI>, ADDI_FM<0x8>,
1688            ISA_MIPS1_NOT_32R6_64R6;
1689def SLTi  : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
1690            SLTI_FM<0xa>;
1691def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
1692            SLTI_FM<0xb>;
1693def LUi   : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16_relaxed>, LUI_FM;
1694let AdditionalPredicates = [NotInMicroMips] in {
1695/// Arithmetic Instructions (3-Operand, R-Type)
1696def ADDu  : MMRel, StdMMR6Rel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
1697            ADD_FM<0, 0x21>;
1698def SUBu  : MMRel, StdMMR6Rel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
1699            ADD_FM<0, 0x23>;
1700}
1701let Defs = [HI0, LO0] in
1702def MUL   : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>,
1703            ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6;
1704def ADD   : MMRel, StdMMR6Rel, ArithLogicR<"add", GPR32Opnd, 1, II_ADD>, ADD_FM<0, 0x20>;
1705def SUB   : MMRel, StdMMR6Rel, ArithLogicR<"sub", GPR32Opnd, 0, II_SUB>, ADD_FM<0, 0x22>;
1706def SLT   : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>;
1707def SLTu  : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>;
1708let AdditionalPredicates = [NotInMicroMips] in {
1709def AND   : MMRel, StdMMR6Rel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
1710            ADD_FM<0, 0x24>;
1711def OR    : MMRel, StdMMR6Rel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
1712            ADD_FM<0, 0x25>;
1713def XOR   : MMRel, StdMMR6Rel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
1714            ADD_FM<0, 0x26>;
1715def NOR   : MMRel, StdMMR6Rel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>;
1716}
1717
1718/// Shift Instructions
1719let AdditionalPredicates = [NotInMicroMips] in {
1720def SLL  : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl,
1721                                   immZExt5>, SRA_FM<0, 0>;
1722def SRL  : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl,
1723                                   immZExt5>, SRA_FM<2, 0>;
1724def SRA  : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, sra,
1725                                   immZExt5>, SRA_FM<3, 0>;
1726def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, shl>,
1727           SRLV_FM<4, 0>;
1728def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, srl>,
1729           SRLV_FM<6, 0>;
1730def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, sra>,
1731           SRLV_FM<7, 0>;
1732}
1733
1734// Rotate Instructions
1735let AdditionalPredicates = [NotInMicroMips] in {
1736  def ROTR  : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr,
1737                                      immZExt5>,
1738              SRA_FM<2, 1>, ISA_MIPS32R2;
1739  def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>,
1740              SRLV_FM<6, 1>, ISA_MIPS32R2;
1741}
1742
1743/// Load and Store Instructions
1744///  aligned
1745def LB  : LoadMemory<"lb", GPR32Opnd, mem_simm16, sextloadi8, II_LB>, MMRel,
1746          LW_FM<0x20>;
1747def LBu : LoadMemory<"lbu", GPR32Opnd, mem_simm16, zextloadi8, II_LBU,
1748                     addrDefault>, MMRel, LW_FM<0x24>;
1749let AdditionalPredicates = [NotInMicroMips] in {
1750  def LH  : LoadMemory<"lh", GPR32Opnd, mem_simm16, sextloadi16, II_LH,
1751                       addrDefault>, MMRel, LW_FM<0x21>;
1752  def LHu : LoadMemory<"lhu", GPR32Opnd, mem_simm16, zextloadi16, II_LHU>,
1753            MMRel, LW_FM<0x25>;
1754  def LW  : StdMMR6Rel, Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel,
1755            LW_FM<0x23>;
1756}
1757def SB  : StdMMR6Rel, Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel,
1758          LW_FM<0x28>;
1759def SH  : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>;
1760let AdditionalPredicates = [NotInMicroMips] in {
1761def SW  : Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>;
1762}
1763
1764/// load/store left/right
1765let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1766    AdditionalPredicates = [NotInMicroMips] in {
1767def LWL : LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>,
1768          ISA_MIPS1_NOT_32R6_64R6;
1769def LWR : LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>,
1770          ISA_MIPS1_NOT_32R6_64R6;
1771def SWL : StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>,
1772          ISA_MIPS1_NOT_32R6_64R6;
1773def SWR : StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>,
1774          ISA_MIPS1_NOT_32R6_64R6;
1775}
1776
1777let AdditionalPredicates = [NotInMicroMips] in {
1778// COP2 Memory Instructions
1779def LWC2 : StdMMR6Rel, LW_FT2<"lwc2", COP2Opnd, II_LWC2, load>, LW_FM<0x32>,
1780           ISA_MIPS1_NOT_32R6_64R6;
1781def SWC2 : StdMMR6Rel, SW_FT2<"swc2", COP2Opnd, II_SWC2, store>,
1782           LW_FM<0x3a>, ISA_MIPS1_NOT_32R6_64R6;
1783def LDC2 : StdMMR6Rel, LW_FT2<"ldc2", COP2Opnd, II_LDC2, load>, LW_FM<0x36>,
1784           ISA_MIPS2_NOT_32R6_64R6;
1785def SDC2 : StdMMR6Rel, SW_FT2<"sdc2", COP2Opnd, II_SDC2, store>,
1786           LW_FM<0x3e>, ISA_MIPS2_NOT_32R6_64R6;
1787
1788// COP3 Memory Instructions
1789let DecoderNamespace = "COP3_" in {
1790  def LWC3 : LW_FT3<"lwc3", COP3Opnd, II_LWC3, load>, LW_FM<0x33>;
1791  def SWC3 : SW_FT3<"swc3", COP3Opnd, II_SWC3, store>, LW_FM<0x3b>;
1792  def LDC3 : LW_FT3<"ldc3", COP3Opnd, II_LDC3, load>, LW_FM<0x37>,
1793             ISA_MIPS2;
1794  def SDC3 : SW_FT3<"sdc3", COP3Opnd, II_SDC3, store>, LW_FM<0x3f>,
1795             ISA_MIPS2;
1796}
1797}
1798
1799def SYNC : MMRel, StdMMR6Rel, SYNC_FT<"sync">, SYNC_FM,
1800           ISA_MIPS32;
1801def SYNCI : MMRel, StdMMR6Rel, SYNCI_FT<"synci">, SYNCI_FM, ISA_MIPS32R2;
1802
1803let AdditionalPredicates = [NotInMicroMips] in {
1804  def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd, uimm10, II_TEQ>, TEQ_FM<0x34>, ISA_MIPS2;
1805  def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd, uimm10, II_TGE>, TEQ_FM<0x30>, ISA_MIPS2;
1806  def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd, uimm10, II_TGEU>, TEQ_FM<0x31>, ISA_MIPS2;
1807  def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd, uimm10, II_TLT>, TEQ_FM<0x32>, ISA_MIPS2;
1808  def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd, uimm10, II_TLTU>, TEQ_FM<0x33>, ISA_MIPS2;
1809  def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd, uimm10, II_TNE>, TEQ_FM<0x36>, ISA_MIPS2;
1810}
1811
1812def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd, II_TEQI>, TEQI_FM<0xc>,
1813           ISA_MIPS2_NOT_32R6_64R6;
1814def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd, II_TGEI>, TEQI_FM<0x8>,
1815           ISA_MIPS2_NOT_32R6_64R6;
1816def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd, II_TGEIU>, TEQI_FM<0x9>,
1817           ISA_MIPS2_NOT_32R6_64R6;
1818def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd, II_TLTI>, TEQI_FM<0xa>,
1819           ISA_MIPS2_NOT_32R6_64R6;
1820def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd, II_TTLTIU>, TEQI_FM<0xb>,
1821           ISA_MIPS2_NOT_32R6_64R6;
1822def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd, II_TNEI>, TEQI_FM<0xe>,
1823           ISA_MIPS2_NOT_32R6_64R6;
1824
1825let AdditionalPredicates = [NotInMicroMips] in {
1826def BREAK : MMRel, StdMMR6Rel, BRK_FT<"break">, BRK_FM<0xd>;
1827def SYSCALL : MMRel, SYS_FT<"syscall", uimm20, II_SYSCALL>, SYS_FM<0xc>;
1828}
1829def TRAP : TrapBase<BREAK>;
1830let AdditionalPredicates = [NotInMicroMips] in {
1831def SDBBP : MMRel, SYS_FT<"sdbbp", uimm20, II_SDBBP>, SDBBP_FM, ISA_MIPS32_NOT_32R6_64R6;
1832}
1833
1834let AdditionalPredicates = [NotInMicroMips] in {
1835  def ERET : MMRel, ER_FT<"eret", II_ERET>, ER_FM<0x18, 0x0>, INSN_MIPS3_32;
1836  def ERETNC : MMRel, ER_FT<"eretnc", II_ERETNC>, ER_FM<0x18, 0x1>, ISA_MIPS32R5;
1837  def DERET : MMRel, ER_FT<"deret", II_DERET>, ER_FM<0x1f, 0x0>, ISA_MIPS32;
1838}
1839
1840let AdditionalPredicates = [NotInMicroMips] in {
1841  def EI : MMRel, StdMMR6Rel, DEI_FT<"ei", GPR32Opnd, II_EI>, EI_FM<1>, ISA_MIPS32R2;
1842  def DI : MMRel, StdMMR6Rel, DEI_FT<"di", GPR32Opnd, II_DI>, EI_FM<0>, ISA_MIPS32R2;
1843}
1844
1845let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1846    AdditionalPredicates = [NotInMicroMips] in {
1847def WAIT : WAIT_FT<"wait">, WAIT_FM;
1848}
1849
1850let AdditionalPredicates = [NotInMicroMips] in {
1851/// Load-linked, Store-conditional
1852def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
1853def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
1854}
1855
1856/// Jump and Branch Instructions
1857def J       : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
1858              AdditionalRequires<[RelocNotPIC]>, IsBranch;
1859def JR      : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>, ISA_MIPS1_NOT_32R6_64R6;
1860def BEQ     : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>;
1861def BEQL    : MMRel, CBranch<"beql", brtarget, seteq, GPR32Opnd, 0>,
1862              BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6;
1863def BNE     : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>;
1864def BNEL    : MMRel, CBranch<"bnel", brtarget, setne, GPR32Opnd, 0>,
1865              BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6;
1866def BGEZ    : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
1867              BGEZ_FM<1, 1>;
1868def BGEZL   : MMRel, CBranchZero<"bgezl", brtarget, setge, GPR32Opnd, 0>,
1869              BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6;
1870def BGTZ    : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
1871              BGEZ_FM<7, 0>;
1872def BGTZL   : MMRel, CBranchZero<"bgtzl", brtarget, setgt, GPR32Opnd, 0>,
1873              BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6;
1874def BLEZ    : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
1875              BGEZ_FM<6, 0>;
1876def BLEZL   : MMRel, CBranchZero<"blezl", brtarget, setle, GPR32Opnd, 0>,
1877              BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6;
1878def BLTZ    : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
1879              BGEZ_FM<1, 0>;
1880def BLTZL   : MMRel, CBranchZero<"bltzl", brtarget, setlt, GPR32Opnd, 0>,
1881              BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6;
1882def B       : UncondBranch<BEQ>;
1883
1884def JAL  : MMRel, JumpLink<"jal", calltarget>, FJ<3>;
1885let AdditionalPredicates = [NotInMicroMips] in {
1886  def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM;
1887  def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>;
1888}
1889
1890def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>,
1891           ISA_MIPS32_NOT_32R6_64R6;
1892def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>,
1893             ISA_MIPS1_NOT_32R6_64R6;
1894def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd, 0>,
1895              BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6;
1896def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>,
1897             ISA_MIPS1_NOT_32R6_64R6;
1898def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd, 0>,
1899              BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6;
1900def BAL_BR : BAL_BR_Pseudo<BGEZAL>;
1901def TAILCALL : TailCall<J>;
1902def TAILCALL_R : TailCallReg<GPR32Opnd, JR>;
1903
1904// Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64
1905// then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA.
1906class PseudoIndirectBranchBase<RegisterOperand RO> :
1907    MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)],
1908               II_IndirectBranchPseudo> {
1909  let isTerminator=1;
1910  let isBarrier=1;
1911  let hasDelaySlot = 1;
1912  let isBranch = 1;
1913  let isIndirectBranch = 1;
1914  bit isCTI = 1;
1915}
1916
1917def PseudoIndirectBranch : PseudoIndirectBranchBase<GPR32Opnd>;
1918
1919// Return instructions are matched as a RetRA instruction, then are expanded
1920// into PseudoReturn/PseudoReturn64 after register allocation. Finally,
1921// MipsAsmPrinter expands this into JR, JR64, JALR, or JALR64 depending on the
1922// ISA.
1923class PseudoReturnBase<RegisterOperand RO> : MipsPseudo<(outs), (ins RO:$rs),
1924                                                        [], II_ReturnPseudo> {
1925  let isTerminator = 1;
1926  let isBarrier = 1;
1927  let hasDelaySlot = 1;
1928  let isReturn = 1;
1929  let isCodeGenOnly = 1;
1930  let hasCtrlDep = 1;
1931  let hasExtraSrcRegAllocReq = 1;
1932  bit isCTI = 1;
1933}
1934
1935def PseudoReturn : PseudoReturnBase<GPR32Opnd>;
1936
1937// Exception handling related node and instructions.
1938// The conversion sequence is:
1939// ISD::EH_RETURN -> MipsISD::EH_RETURN ->
1940// MIPSeh_return -> (stack change + indirect branch)
1941//
1942// MIPSeh_return takes the place of regular return instruction
1943// but takes two arguments (V1, V0) which are used for storing
1944// the offset and return address respectively.
1945def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
1946
1947def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
1948                      [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
1949
1950let Uses = [V0, V1], isTerminator = 1, isReturn = 1, isBarrier = 1, isCTI = 1 in {
1951  def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
1952                                [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
1953  def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff,
1954                                                GPR64:$dst),
1955                                [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
1956}
1957
1958/// Multiply and Divide Instructions.
1959def MULT  : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
1960            MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6;
1961def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
1962            MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6;
1963let AdditionalPredicates = [NotInMicroMips] in {
1964  def SDIV  : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
1965              MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6;
1966  def UDIV  : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
1967              MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6;
1968}
1969def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>,
1970           ISA_MIPS1_NOT_32R6_64R6;
1971def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>,
1972           ISA_MIPS1_NOT_32R6_64R6;
1973let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1974    AdditionalPredicates = [NotInMicroMips] in {
1975def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>,
1976           ISA_MIPS1_NOT_32R6_64R6;
1977def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>,
1978           ISA_MIPS1_NOT_32R6_64R6;
1979}
1980
1981/// Sign Ext In Register Instructions.
1982def SEB : MMRel, StdMMR6Rel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,
1983          SEB_FM<0x10, 0x20>, ISA_MIPS32R2;
1984def SEH : MMRel, StdMMR6Rel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
1985          SEB_FM<0x18, 0x20>, ISA_MIPS32R2;
1986
1987/// Count Leading
1988def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd, II_CLZ>, CLO_FM<0x20>,
1989          ISA_MIPS32_NOT_32R6_64R6;
1990def CLO : MMRel, CountLeading1<"clo", GPR32Opnd, II_CLO>, CLO_FM<0x21>,
1991          ISA_MIPS32_NOT_32R6_64R6;
1992
1993let AdditionalPredicates = [NotInMicroMips] in {
1994  /// Word Swap Bytes Within Halfwords
1995  def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd, II_WSBH>, SEB_FM<2, 0x20>,
1996             ISA_MIPS32R2;
1997}
1998
1999/// No operation.
2000def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>;
2001
2002// FrameIndexes are legalized when they are operands from load/store
2003// instructions. The same not happens for stack address copies, so an
2004// add op with mem ComplexPattern is used and the stack address copy
2005// can be matched. It's similar to Sparc LEA_ADDRi
2006def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>;
2007
2008// MADD*/MSUB*
2009def MADD  : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>,
2010            ISA_MIPS32_NOT_32R6_64R6;
2011def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>,
2012            ISA_MIPS32_NOT_32R6_64R6;
2013def MSUB  : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>,
2014            ISA_MIPS32_NOT_32R6_64R6;
2015def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>,
2016            ISA_MIPS32_NOT_32R6_64R6;
2017
2018let AdditionalPredicates = [NotDSP] in {
2019def PseudoMULT  : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>,
2020                  ISA_MIPS1_NOT_32R6_64R6;
2021def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>,
2022                  ISA_MIPS1_NOT_32R6_64R6;
2023def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>, ISA_MIPS1_NOT_32R6_64R6;
2024def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>, ISA_MIPS1_NOT_32R6_64R6;
2025def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>, ISA_MIPS1_NOT_32R6_64R6;
2026def PseudoMADD  : MAddSubPseudo<MADD, MipsMAdd, II_MADD>,
2027                  ISA_MIPS32_NOT_32R6_64R6;
2028def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>,
2029                  ISA_MIPS32_NOT_32R6_64R6;
2030def PseudoMSUB  : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>,
2031                  ISA_MIPS32_NOT_32R6_64R6;
2032def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>,
2033                  ISA_MIPS32_NOT_32R6_64R6;
2034}
2035
2036let AdditionalPredicates = [NotInMicroMips] in {
2037  def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV,
2038                                 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
2039  def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU,
2040                                 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
2041  def RDHWR : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM;
2042  // TODO: Add '0 < pos+size <= 32' constraint check to ext instruction
2043  def EXT : MMRel, StdMMR6Rel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1,
2044                                       immZExt5, immZExt5Plus1, MipsExt>,
2045            EXT_FM<0>;
2046  def INS : MMRel, StdMMR6Rel, InsBase<"ins", GPR32Opnd, uimm5,
2047                                       uimm5_inssize_plus1, MipsIns>,
2048            EXT_FM<4>;
2049}
2050/// Move Control Registers From/To CPU Registers
2051let AdditionalPredicates = [NotInMicroMips] in {
2052  def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd, II_MTC0>, MFC3OP_FM<0x10, 4>,
2053             ISA_MIPS32;
2054  def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd, II_MFC0>, MFC3OP_FM<0x10, 0>,
2055             ISA_MIPS32;
2056}
2057def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd, II_MFC2>, MFC3OP_FM<0x12, 0>;
2058def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd, II_MTC2>, MFC3OP_FM<0x12, 4>;
2059
2060class Barrier<string asmstr, InstrItinClass itin = NoItinerary> :
2061  InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2062
2063def SSNOP : MMRel, StdMMR6Rel, Barrier<"ssnop", II_SSNOP>, BARRIER_FM<1>;
2064def EHB : MMRel, Barrier<"ehb", II_EHB>, BARRIER_FM<3>;
2065
2066let isCTI = 1 in
2067def PAUSE : MMRel, StdMMR6Rel, Barrier<"pause", II_PAUSE>, BARRIER_FM<5>,
2068            ISA_MIPS32R2;
2069
2070// JR_HB and JALR_HB are defined here using the new style naming
2071// scheme because some of this code is shared with Mips32r6InstrInfo.td
2072// and because of that it doesn't follow the naming convention of the
2073// rest of the file. To avoid a mixture of old vs new style, the new
2074// style was chosen.
2075class JR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
2076  dag OutOperandList = (outs);
2077  dag InOperandList = (ins GPROpnd:$rs);
2078  string AsmString = !strconcat(instr_asm, "\t$rs");
2079  list<dag> Pattern = [];
2080}
2081
2082class JALR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
2083  dag OutOperandList = (outs GPROpnd:$rd);
2084  dag InOperandList = (ins GPROpnd:$rs);
2085  string AsmString = !strconcat(instr_asm, "\t$rd, $rs");
2086  list<dag> Pattern = [];
2087}
2088
2089class JR_HB_DESC : InstSE<(outs), (ins), "", [], II_JR_HB, FrmJ>,
2090                   JR_HB_DESC_BASE<"jr.hb", GPR32Opnd> {
2091  let isBranch=1;
2092  let isIndirectBranch=1;
2093  let hasDelaySlot=1;
2094  let isTerminator=1;
2095  let isBarrier=1;
2096  bit isCTI = 1;
2097}
2098
2099class JALR_HB_DESC : InstSE<(outs), (ins), "", [], II_JALR_HB, FrmJ>,
2100                     JALR_HB_DESC_BASE<"jalr.hb", GPR32Opnd> {
2101  let isIndirectBranch=1;
2102  let hasDelaySlot=1;
2103  bit isCTI = 1;
2104}
2105
2106class JR_HB_ENC : JR_HB_FM<8>;
2107class JALR_HB_ENC : JALR_HB_FM<9>;
2108
2109def JR_HB : JR_HB_DESC, JR_HB_ENC, ISA_MIPS32_NOT_32R6_64R6;
2110def JALR_HB : JALR_HB_DESC, JALR_HB_ENC, ISA_MIPS32;
2111
2112class TLB<string asmstr, InstrItinClass itin = NoItinerary> :
2113  InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2114let AdditionalPredicates = [NotInMicroMips] in {
2115def TLBP : MMRel, TLB<"tlbp", II_TLBP>, COP0_TLB_FM<0x08>;
2116def TLBR : MMRel, TLB<"tlbr", II_TLBR>, COP0_TLB_FM<0x01>;
2117def TLBWI : MMRel, TLB<"tlbwi", II_TLBWI>, COP0_TLB_FM<0x02>;
2118def TLBWR : MMRel, TLB<"tlbwr", II_TLBWR>, COP0_TLB_FM<0x06>;
2119}
2120class CacheOp<string instr_asm, Operand MemOpnd,
2121              InstrItinClass itin = NoItinerary> :
2122    InstSE<(outs), (ins  MemOpnd:$addr, uimm5:$hint),
2123           !strconcat(instr_asm, "\t$hint, $addr"), [], itin, FrmOther,
2124           instr_asm> {
2125  let DecoderMethod = "DecodeCacheOp";
2126}
2127
2128def CACHE : MMRel, CacheOp<"cache", mem, II_CACHE>, CACHEOP_FM<0b101111>,
2129            INSN_MIPS3_32_NOT_32R6_64R6;
2130def PREF :  MMRel, CacheOp<"pref", mem, II_PREF>, CACHEOP_FM<0b110011>,
2131            INSN_MIPS3_32_NOT_32R6_64R6;
2132
2133def ROL : MipsAsmPseudoInst<(outs),
2134                            (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2135                            "rol\t$rs, $rt, $rd">;
2136def ROLImm : MipsAsmPseudoInst<(outs),
2137                               (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2138                               "rol\t$rs, $rt, $imm">;
2139def : MipsInstAlias<"rol $rd, $rs",
2140                    (ROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2141def : MipsInstAlias<"rol $rd, $imm",
2142                    (ROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2143
2144def ROR : MipsAsmPseudoInst<(outs),
2145                            (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2146                            "ror\t$rs, $rt, $rd">;
2147def RORImm : MipsAsmPseudoInst<(outs),
2148                               (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2149                               "ror\t$rs, $rt, $imm">;
2150def : MipsInstAlias<"ror $rd, $rs",
2151                    (ROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2152def : MipsInstAlias<"ror $rd, $imm",
2153                    (RORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2154
2155def DROL : MipsAsmPseudoInst<(outs),
2156                             (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2157                             "drol\t$rs, $rt, $rd">, ISA_MIPS64;
2158def DROLImm : MipsAsmPseudoInst<(outs),
2159                                (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2160                                "drol\t$rs, $rt, $imm">, ISA_MIPS64;
2161def : MipsInstAlias<"drol $rd, $rs",
2162                    (DROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
2163def : MipsInstAlias<"drol $rd, $imm",
2164                    (DROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
2165
2166def DROR : MipsAsmPseudoInst<(outs),
2167                             (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2168                             "dror\t$rs, $rt, $rd">, ISA_MIPS64;
2169def DRORImm : MipsAsmPseudoInst<(outs),
2170                                (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2171                                "dror\t$rs, $rt, $imm">, ISA_MIPS64;
2172def : MipsInstAlias<"dror $rd, $rs",
2173                    (DROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
2174def : MipsInstAlias<"dror $rd, $imm",
2175                    (DRORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
2176
2177def ABSMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2178                                 "abs\t$rd, $rs">;
2179
2180//===----------------------------------------------------------------------===//
2181// Instruction aliases
2182//===----------------------------------------------------------------------===//
2183def : MipsInstAlias<"move $dst, $src",
2184                    (OR GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2185      GPR_32 {
2186  let AdditionalPredicates = [NotInMicroMips];
2187}
2188def : MipsInstAlias<"move $dst, $src",
2189                    (ADDu GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2190      GPR_32 {
2191  let AdditionalPredicates = [NotInMicroMips];
2192}
2193def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>,
2194      ISA_MIPS1_NOT_32R6_64R6;
2195def : MipsInstAlias<
2196          "addu $rs, $rt, $imm",
2197          (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>;
2198def : MipsInstAlias<
2199          "addu $rs, $imm",
2200          (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>;
2201def : MipsInstAlias<
2202          "add $rs, $rt, $imm",
2203          (ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>,
2204          ISA_MIPS1_NOT_32R6_64R6;
2205def : MipsInstAlias<
2206          "add $rs, $imm",
2207          (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>,
2208          ISA_MIPS1_NOT_32R6_64R6;
2209def : MipsInstAlias<
2210          "and $rs, $rt, $imm",
2211          (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>;
2212def : MipsInstAlias<
2213          "and $rs, $imm",
2214          (ANDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>;
2215def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>;
2216let Predicates = [NotInMicroMips] in {
2217def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
2218}
2219def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>, ISA_MIPS32;
2220def : MipsInstAlias<"neg $rt, $rs",
2221                    (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
2222def : MipsInstAlias<"negu $rt",
2223                    (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 0>;
2224def : MipsInstAlias<"negu $rt, $rs",
2225                    (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
2226def : MipsInstAlias<
2227          "slt $rs, $rt, $imm",
2228          (SLTi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>;
2229def : MipsInstAlias<
2230          "sltu $rt, $rs, $imm",
2231          (SLTiu GPR32Opnd:$rt, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>;
2232let AdditionalPredicates = [NotInMicroMips] in {
2233  def : MipsInstAlias<
2234          "and $rs, $rt, $imm",
2235          (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>;
2236  def : MipsInstAlias<
2237          "and $rs, $imm",
2238          (ANDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>;
2239  def : MipsInstAlias<
2240          "xor $rs, $rt, $imm",
2241          (XORi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>;
2242  def : MipsInstAlias<
2243          "xor $rs, $imm",
2244          (XORi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>;
2245  def : MipsInstAlias<
2246          "or $rs, $rt, $imm",
2247          (ORi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>;
2248  def : MipsInstAlias<
2249          "or $rs, $imm",
2250          (ORi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>;
2251  def : MipsInstAlias<
2252          "not $rt, $rs",
2253          (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>;
2254  def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>;
2255}
2256def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>;
2257def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>;
2258def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, COP2Opnd:$rd, 0), 0>;
2259def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 COP2Opnd:$rd, GPR32Opnd:$rt, 0), 0>;
2260let AdditionalPredicates = [NotInMicroMips] in {
2261def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>;
2262}
2263def : MipsInstAlias<"bnez $rs,$offset",
2264                    (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
2265def : MipsInstAlias<"bnezl $rs,$offset",
2266                    (BNEL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
2267def : MipsInstAlias<"beqz $rs,$offset",
2268                    (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
2269def : MipsInstAlias<"beqzl $rs,$offset",
2270                    (BEQL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
2271let AdditionalPredicates = [NotInMicroMips] in {
2272  def : MipsInstAlias<"syscall", (SYSCALL 0), 1>;
2273}
2274
2275def : MipsInstAlias<"break", (BREAK 0, 0), 1>;
2276def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>;
2277let AdditionalPredicates = [NotInMicroMips] in {
2278  def : MipsInstAlias<"ei", (EI ZERO), 1>, ISA_MIPS32R2;
2279  def : MipsInstAlias<"di", (DI ZERO), 1>, ISA_MIPS32R2;
2280}
2281let AdditionalPredicates = [NotInMicroMips] in {
2282  def : MipsInstAlias<"teq $rs, $rt",
2283                      (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2284  def : MipsInstAlias<"tge $rs, $rt",
2285                      (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2286  def : MipsInstAlias<"tgeu $rs, $rt",
2287                      (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2288  def : MipsInstAlias<"tlt $rs, $rt",
2289                      (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2290  def : MipsInstAlias<"tltu $rs, $rt",
2291                      (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2292  def : MipsInstAlias<"tne $rs, $rt",
2293                      (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2294}
2295def : MipsInstAlias<"sub, $rd, $rs, $imm",
2296                    (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs,
2297                          InvertedImOperand:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6;
2298def : MipsInstAlias<"sub $rs, $imm",
2299                    (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm),
2300                    0>, ISA_MIPS1_NOT_32R6_64R6;
2301def : MipsInstAlias<"subu, $rd, $rs, $imm",
2302                    (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs,
2303                           InvertedImOperand:$imm), 0>;
2304def : MipsInstAlias<"subu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs,
2305                                             InvertedImOperand:$imm), 0>;
2306let AdditionalPredicates = [NotInMicroMips] in {
2307  def : MipsInstAlias<"sll $rd, $rt, $rs",
2308                      (SLLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2309  def : MipsInstAlias<"sra $rd, $rt, $rs",
2310                      (SRAV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2311  def : MipsInstAlias<"srl $rd, $rt, $rs",
2312                      (SRLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2313}
2314def : MipsInstAlias<"sdbbp", (SDBBP 0)>, ISA_MIPS32_NOT_32R6_64R6;
2315def : MipsInstAlias<"sync",
2316                    (SYNC 0), 1>, ISA_MIPS2;
2317//===----------------------------------------------------------------------===//
2318// Assembler Pseudo Instructions
2319//===----------------------------------------------------------------------===//
2320
2321// We use i32imm on li/la to defer range checking to the assembler.
2322class LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> :
2323  MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2324                     !strconcat(instr_asm, "\t$rt, $imm32")> ;
2325def LoadImm32 : LoadImmediate32<"li", i32imm, GPR32Opnd>;
2326
2327class LoadAddressFromReg32<string instr_asm, Operand MemOpnd,
2328                           RegisterOperand RO> :
2329  MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
2330                     !strconcat(instr_asm, "\t$rt, $addr")> ;
2331def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>;
2332
2333class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> :
2334  MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2335                     !strconcat(instr_asm, "\t$rt, $imm32")> ;
2336def LoadAddrImm32 : LoadAddressFromImm32<"la", i32imm, GPR32Opnd>;
2337
2338def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2339                      "jal\t$rd, $rs"> ;
2340def JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs),
2341                      "jal\t$rs"> ;
2342
2343def NORImm : MipsAsmPseudoInst<
2344                 (outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm32:$imm),
2345                 "nor\t$rs, $rt, $imm"> ;
2346
2347let hasDelaySlot = 1, isCTI = 1 in {
2348def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2349                               (ins imm64:$imm64, brtarget:$offset),
2350                               "bne\t$rt, $imm64, $offset">;
2351def BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2352                               (ins imm64:$imm64, brtarget:$offset),
2353                               "beq\t$rt, $imm64, $offset">;
2354
2355class CondBranchPseudo<string instr_asm> :
2356  MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt,
2357                                 brtarget:$offset),
2358                    !strconcat(instr_asm, "\t$rs, $rt, $offset")>;
2359}
2360
2361def BLT : CondBranchPseudo<"blt">;
2362def BLE : CondBranchPseudo<"ble">;
2363def BGE : CondBranchPseudo<"bge">;
2364def BGT : CondBranchPseudo<"bgt">;
2365def BLTU : CondBranchPseudo<"bltu">;
2366def BLEU : CondBranchPseudo<"bleu">;
2367def BGEU : CondBranchPseudo<"bgeu">;
2368def BGTU : CondBranchPseudo<"bgtu">;
2369def BLTL : CondBranchPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2370def BLEL : CondBranchPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2371def BGEL : CondBranchPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2372def BGTL : CondBranchPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2373def BLTUL: CondBranchPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2374def BLEUL: CondBranchPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2375def BGEUL: CondBranchPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2376def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
2377
2378let isCTI = 1 in
2379class CondBranchImmPseudo<string instr_asm> :
2380  MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, imm64:$imm, brtarget:$offset),
2381                    !strconcat(instr_asm, "\t$rs, $imm, $offset")>;
2382
2383def BLTImmMacro  : CondBranchImmPseudo<"blt">;
2384def BLEImmMacro  : CondBranchImmPseudo<"ble">;
2385def BGEImmMacro  : CondBranchImmPseudo<"bge">;
2386def BGTImmMacro  : CondBranchImmPseudo<"bgt">;
2387def BLTUImmMacro : CondBranchImmPseudo<"bltu">;
2388def BLEUImmMacro : CondBranchImmPseudo<"bleu">;
2389def BGEUImmMacro : CondBranchImmPseudo<"bgeu">;
2390def BGTUImmMacro : CondBranchImmPseudo<"bgtu">;
2391def BLTLImmMacro : CondBranchImmPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2392def BLELImmMacro : CondBranchImmPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2393def BGELImmMacro : CondBranchImmPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2394def BGTLImmMacro : CondBranchImmPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2395def BLTULImmMacro : CondBranchImmPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2396def BLEULImmMacro : CondBranchImmPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2397def BGEULImmMacro : CondBranchImmPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2398def BGTULImmMacro : CondBranchImmPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
2399
2400// FIXME: Predicates are removed because instructions are matched regardless of
2401// predicates, because PredicateControl was not in the hierarchy. This was
2402// done to emit more precise error message from expansion function.
2403// Once the tablegen-erated errors are made better, this needs to be fixed and
2404// predicates needs to be restored.
2405
2406def SDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2407                                  (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2408                                  "div\t$rd, $rs, $rt">,
2409                ISA_MIPS1_NOT_32R6_64R6;
2410def UDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2411                                  (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2412                                  "divu\t$rd, $rs, $rt">,
2413                ISA_MIPS1_NOT_32R6_64R6;
2414def : MipsInstAlias<"div $rt, $rs", (SDivMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
2415                                               GPR32Opnd:$rs), 0>,
2416      ISA_MIPS1_NOT_32R6_64R6;
2417def : MipsInstAlias<"divu $rt, $rs", (UDivMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
2418                                                GPR32Opnd:$rs), 0>,
2419      ISA_MIPS1_NOT_32R6_64R6;
2420def DSDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2421                                   (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2422                                   "ddiv\t$rd, $rs, $rt">,
2423                 ISA_MIPS64_NOT_64R6;
2424def DUDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2425                                   (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2426                                   "ddivu\t$rd, $rs, $rt">,
2427                 ISA_MIPS64_NOT_64R6;
2428def : MipsInstAlias<"ddiv $rt, $rs", (DSDivMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
2429                                                 GPR32Opnd:$rs), 0>,
2430      ISA_MIPS64_NOT_64R6;
2431def : MipsInstAlias<"ddivu $rt, $rs", (DUDivMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
2432                                                  GPR32Opnd:$rs), 0>,
2433      ISA_MIPS64_NOT_64R6;
2434
2435def Ulh : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2436                            "ulh\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2437
2438def Ulhu : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2439                             "ulhu\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2440
2441def Ulw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2442                            "ulw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2443
2444//===----------------------------------------------------------------------===//
2445//  Arbitrary patterns that map to one or more instructions
2446//===----------------------------------------------------------------------===//
2447
2448// Load/store pattern templates.
2449class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
2450  MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
2451
2452class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
2453  MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
2454
2455// Small immediates
2456let AdditionalPredicates = [NotInMicroMips] in {
2457def : MipsPat<(i32 immSExt16:$in),
2458              (ADDiu ZERO, imm:$in)>;
2459def : MipsPat<(i32 immZExt16:$in),
2460              (ORi ZERO, imm:$in)>;
2461}
2462def : MipsPat<(i32 immLow16Zero:$in),
2463              (LUi (HI16 imm:$in))>;
2464
2465// Arbitrary immediates
2466def : MipsPat<(i32 imm:$imm),
2467          (ORi (LUi (HI16 imm:$imm)), (LO16 imm:$imm))>;
2468
2469// Carry MipsPatterns
2470let AdditionalPredicates = [NotInMicroMips] in {
2471  def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
2472                (SUBu GPR32:$lhs, GPR32:$rhs)>;
2473}
2474def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
2475              (ADDu GPR32:$lhs, GPR32:$rhs)>, ASE_NOT_DSP;
2476def : MipsPat<(addc  GPR32:$src, immSExt16:$imm),
2477              (ADDiu GPR32:$src, imm:$imm)>, ASE_NOT_DSP;
2478
2479// Support multiplication for pre-Mips32 targets that don't have
2480// the MUL instruction.
2481def : MipsPat<(mul GPR32:$lhs, GPR32:$rhs),
2482              (PseudoMFLO (PseudoMULT GPR32:$lhs, GPR32:$rhs))>,
2483      ISA_MIPS1_NOT_32R6_64R6;
2484
2485// SYNC
2486def : MipsPat<(MipsSync (i32 immz)),
2487              (SYNC 0)>, ISA_MIPS2;
2488
2489// Call
2490def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
2491              (JAL texternalsym:$dst)>;
2492//def : MipsPat<(MipsJmpLink GPR32:$dst),
2493//              (JALR GPR32:$dst)>;
2494
2495// Tail call
2496def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
2497              (TAILCALL tglobaladdr:$dst)>;
2498def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
2499              (TAILCALL texternalsym:$dst)>;
2500// hi/lo relocs
2501def : MipsPat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
2502def : MipsPat<(MipsHi tblockaddress:$in), (LUi tblockaddress:$in)>;
2503def : MipsPat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>;
2504def : MipsPat<(MipsHi tconstpool:$in), (LUi tconstpool:$in)>;
2505def : MipsPat<(MipsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>;
2506def : MipsPat<(MipsHi texternalsym:$in), (LUi texternalsym:$in)>;
2507
2508def : MipsPat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
2509def : MipsPat<(MipsLo tblockaddress:$in), (ADDiu ZERO, tblockaddress:$in)>;
2510def : MipsPat<(MipsLo tjumptable:$in), (ADDiu ZERO, tjumptable:$in)>;
2511def : MipsPat<(MipsLo tconstpool:$in), (ADDiu ZERO, tconstpool:$in)>;
2512def : MipsPat<(MipsLo tglobaltlsaddr:$in), (ADDiu ZERO, tglobaltlsaddr:$in)>;
2513def : MipsPat<(MipsLo texternalsym:$in), (ADDiu ZERO, texternalsym:$in)>;
2514
2515def : MipsPat<(add GPR32:$hi, (MipsLo tglobaladdr:$lo)),
2516              (ADDiu GPR32:$hi, tglobaladdr:$lo)>;
2517def : MipsPat<(add GPR32:$hi, (MipsLo tblockaddress:$lo)),
2518              (ADDiu GPR32:$hi, tblockaddress:$lo)>;
2519def : MipsPat<(add GPR32:$hi, (MipsLo tjumptable:$lo)),
2520              (ADDiu GPR32:$hi, tjumptable:$lo)>;
2521def : MipsPat<(add GPR32:$hi, (MipsLo tconstpool:$lo)),
2522              (ADDiu GPR32:$hi, tconstpool:$lo)>;
2523def : MipsPat<(add GPR32:$hi, (MipsLo tglobaltlsaddr:$lo)),
2524              (ADDiu GPR32:$hi, tglobaltlsaddr:$lo)>;
2525
2526// gp_rel relocs
2527def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
2528              (ADDiu GPR32:$gp, tglobaladdr:$in)>;
2529def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
2530              (ADDiu GPR32:$gp, tconstpool:$in)>;
2531
2532// wrapper_pic
2533class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
2534      MipsPat<(MipsWrapper RC:$gp, node:$in),
2535              (ADDiuOp RC:$gp, node:$in)>;
2536
2537def : WrapperPat<tglobaladdr, ADDiu, GPR32>;
2538def : WrapperPat<tconstpool, ADDiu, GPR32>;
2539def : WrapperPat<texternalsym, ADDiu, GPR32>;
2540def : WrapperPat<tblockaddress, ADDiu, GPR32>;
2541def : WrapperPat<tjumptable, ADDiu, GPR32>;
2542def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>;
2543
2544let AdditionalPredicates = [NotInMicroMips] in {
2545// Mips does not have "not", so we expand our way
2546def : MipsPat<(not GPR32:$in),
2547              (NOR GPR32Opnd:$in, ZERO)>;
2548}
2549
2550// extended loads
2551def : MipsPat<(i32 (extloadi1  addr:$src)), (LBu addr:$src)>;
2552def : MipsPat<(i32 (extloadi8  addr:$src)), (LBu addr:$src)>;
2553let AdditionalPredicates = [NotInMicroMips] in {
2554  def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
2555}
2556
2557// peepholes
2558def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>;
2559
2560// brcond patterns
2561multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BNEOp,
2562                      Instruction SLTOp, Instruction SLTuOp, Instruction SLTiOp,
2563                      Instruction SLTiuOp, Register ZEROReg> {
2564def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
2565              (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
2566def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
2567              (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
2568
2569def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
2570              (BEQ (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
2571def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
2572              (BEQ (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
2573def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
2574              (BEQ (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
2575def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
2576              (BEQ (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
2577def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
2578              (BEQ (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
2579def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
2580              (BEQ (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
2581
2582def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
2583              (BEQ (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
2584def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
2585              (BEQ (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
2586
2587def : MipsPat<(brcond RC:$cond, bb:$dst),
2588              (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
2589}
2590
2591defm : BrcondPats<GPR32, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>;
2592
2593def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
2594              (BLEZ i32:$lhs, bb:$dst)>;
2595def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
2596              (BGEZ i32:$lhs, bb:$dst)>;
2597
2598// setcc patterns
2599multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp,
2600                     Instruction SLTuOp, Register ZEROReg> {
2601  def : MipsPat<(seteq RC:$lhs, 0),
2602                (SLTiuOp RC:$lhs, 1)>;
2603  def : MipsPat<(setne RC:$lhs, 0),
2604                (SLTuOp ZEROReg, RC:$lhs)>;
2605  def : MipsPat<(seteq RC:$lhs, RC:$rhs),
2606                (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>;
2607  def : MipsPat<(setne RC:$lhs, RC:$rhs),
2608                (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
2609}
2610
2611multiclass SetlePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
2612  def : MipsPat<(setle RC:$lhs, RC:$rhs),
2613                (XORi (SLTOp RC:$rhs, RC:$lhs), 1)>;
2614  def : MipsPat<(setule RC:$lhs, RC:$rhs),
2615                (XORi (SLTuOp RC:$rhs, RC:$lhs), 1)>;
2616}
2617
2618multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
2619  def : MipsPat<(setgt RC:$lhs, RC:$rhs),
2620                (SLTOp RC:$rhs, RC:$lhs)>;
2621  def : MipsPat<(setugt RC:$lhs, RC:$rhs),
2622                (SLTuOp RC:$rhs, RC:$lhs)>;
2623}
2624
2625multiclass SetgePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
2626  def : MipsPat<(setge RC:$lhs, RC:$rhs),
2627                (XORi (SLTOp RC:$lhs, RC:$rhs), 1)>;
2628  def : MipsPat<(setuge RC:$lhs, RC:$rhs),
2629                (XORi (SLTuOp RC:$lhs, RC:$rhs), 1)>;
2630}
2631
2632multiclass SetgeImmPats<RegisterClass RC, Instruction SLTiOp,
2633                        Instruction SLTiuOp> {
2634  def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
2635                (XORi (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
2636  def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
2637                (XORi (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
2638}
2639
2640defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>;
2641defm : SetlePats<GPR32, SLT, SLTu>;
2642defm : SetgtPats<GPR32, SLT, SLTu>;
2643defm : SetgePats<GPR32, SLT, SLTu>;
2644defm : SetgeImmPats<GPR32, SLTi, SLTiu>;
2645
2646// bswap pattern
2647def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>;
2648
2649// Load halfword/word patterns.
2650let AddedComplexity = 40 in {
2651  def : LoadRegImmPat<LBu, i32, zextloadi8>;
2652  let AdditionalPredicates = [NotInMicroMips] in {
2653    def : LoadRegImmPat<LH, i32, sextloadi16>;
2654    def : LoadRegImmPat<LW, i32, load>;
2655  }
2656}
2657
2658// Atomic load patterns.
2659def : MipsPat<(atomic_load_8 addr:$a), (LB addr:$a)>;
2660let AdditionalPredicates = [NotInMicroMips] in {
2661  def : MipsPat<(atomic_load_16 addr:$a), (LH addr:$a)>;
2662}
2663def : MipsPat<(atomic_load_32 addr:$a), (LW addr:$a)>;
2664
2665// Atomic store patterns.
2666def : MipsPat<(atomic_store_8 addr:$a, GPR32:$v), (SB GPR32:$v, addr:$a)>;
2667def : MipsPat<(atomic_store_16 addr:$a, GPR32:$v), (SH GPR32:$v, addr:$a)>;
2668def : MipsPat<(atomic_store_32 addr:$a, GPR32:$v), (SW GPR32:$v, addr:$a)>;
2669
2670//===----------------------------------------------------------------------===//
2671// Floating Point Support
2672//===----------------------------------------------------------------------===//
2673
2674include "MipsInstrFPU.td"
2675include "Mips64InstrInfo.td"
2676include "MipsCondMov.td"
2677
2678include "Mips32r6InstrInfo.td"
2679include "Mips64r6InstrInfo.td"
2680
2681//
2682// Mips16
2683
2684include "Mips16InstrFormats.td"
2685include "Mips16InstrInfo.td"
2686
2687// DSP
2688include "MipsDSPInstrFormats.td"
2689include "MipsDSPInstrInfo.td"
2690
2691// MSA
2692include "MipsMSAInstrFormats.td"
2693include "MipsMSAInstrInfo.td"
2694
2695// EVA
2696include "MipsEVAInstrFormats.td"
2697include "MipsEVAInstrInfo.td"
2698
2699// Micromips
2700include "MicroMipsInstrFormats.td"
2701include "MicroMipsInstrInfo.td"
2702include "MicroMipsInstrFPU.td"
2703
2704// Micromips r6
2705include "MicroMips32r6InstrFormats.td"
2706include "MicroMips32r6InstrInfo.td"
2707
2708// Micromips64 r6
2709include "MicroMips64r6InstrFormats.td"
2710include "MicroMips64r6InstrInfo.td"
2711
2712// Micromips DSP
2713include "MicroMipsDSPInstrFormats.td"
2714include "MicroMipsDSPInstrInfo.td"
2715