1 //===- MipsInstrInfo.td - Target Description for Mips Target -*- tablegen -*-=//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the Mips implementation of the TargetInstrInfo class.
12 //===----------------------------------------------------------------------===//
15 //===----------------------------------------------------------------------===//
16 // Mips profiles and nodes
17 //===----------------------------------------------------------------------===//
19 def SDT_MipsJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
20 def SDT_MipsCMov : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>,
24 def SDT_MipsCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>;
25 def SDT_MipsCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
26 def SDT_MFLOHI : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisVT<1, untyped>]>;
27 def SDT_MTLOHI : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>,
28 SDTCisInt<1>, SDTCisSameAs<1, 2>]>;
29 def SDT_MipsMultDiv : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>, SDTCisInt<1>,
31 def SDT_MipsMAddMSub : SDTypeProfile<1, 3,
32 [SDTCisVT<0, untyped>, SDTCisSameAs<0, 3>,
33 SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>;
34 def SDT_MipsDivRem16 : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>]>;
36 def SDT_MipsThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
38 def SDT_Sync : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
40 def SDT_Ext : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
41 SDTCisVT<2, i32>, SDTCisSameAs<2, 3>]>;
42 def SDT_Ins : SDTypeProfile<1, 4, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
43 SDTCisVT<2, i32>, SDTCisSameAs<2, 3>,
46 def SDTMipsLoadLR : SDTypeProfile<1, 2,
47 [SDTCisInt<0>, SDTCisPtrTy<1>,
51 def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink,
52 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,
56 def MipsTailCall : SDNode<"MipsISD::TailCall", SDT_MipsJmpLink,
57 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
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)
62 def MipsHi : SDNode<"MipsISD::Hi", SDTIntUnaryOp>;
63 def MipsLo : SDNode<"MipsISD::Lo", SDTIntUnaryOp>;
64 def MipsGPRel : SDNode<"MipsISD::GPRel", SDTIntUnaryOp>;
66 // TlsGd node is used to handle General Dynamic TLS
67 def MipsTlsGd : SDNode<"MipsISD::TlsGd", SDTIntUnaryOp>;
69 // TprelHi and TprelLo nodes are used to handle Local Exec TLS
70 def MipsTprelHi : SDNode<"MipsISD::TprelHi", SDTIntUnaryOp>;
71 def MipsTprelLo : SDNode<"MipsISD::TprelLo", SDTIntUnaryOp>;
74 def MipsThreadPointer: SDNode<"MipsISD::ThreadPointer", SDT_MipsThreadPointer>;
77 def MipsRet : SDNode<"MipsISD::Ret", SDTNone,
78 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
80 def MipsERet : SDNode<"MipsISD::ERet", SDTNone,
81 [SDNPHasChain, SDNPOptInGlue, SDNPSideEffect]>;
83 // These are target-independent nodes, but have target-specific formats.
84 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MipsCallSeqStart,
85 [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>;
86 def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeqEnd,
87 [SDNPHasChain, SDNPSideEffect,
88 SDNPOptInGlue, SDNPOutGlue]>;
90 // Nodes used to extract LO/HI registers.
91 def MipsMFHI : SDNode<"MipsISD::MFHI", SDT_MFLOHI>;
92 def MipsMFLO : SDNode<"MipsISD::MFLO", SDT_MFLOHI>;
94 // Node used to insert 32-bit integers to LOHI register pair.
95 def MipsMTLOHI : SDNode<"MipsISD::MTLOHI", SDT_MTLOHI>;
98 def MipsMult : SDNode<"MipsISD::Mult", SDT_MipsMultDiv>;
99 def MipsMultu : SDNode<"MipsISD::Multu", SDT_MipsMultDiv>;
102 def MipsMAdd : SDNode<"MipsISD::MAdd", SDT_MipsMAddMSub>;
103 def MipsMAddu : SDNode<"MipsISD::MAddu", SDT_MipsMAddMSub>;
104 def MipsMSub : SDNode<"MipsISD::MSub", SDT_MipsMAddMSub>;
105 def MipsMSubu : SDNode<"MipsISD::MSubu", SDT_MipsMAddMSub>;
108 def MipsDivRem : SDNode<"MipsISD::DivRem", SDT_MipsMultDiv>;
109 def MipsDivRemU : SDNode<"MipsISD::DivRemU", SDT_MipsMultDiv>;
110 def MipsDivRem16 : SDNode<"MipsISD::DivRem16", SDT_MipsDivRem16,
112 def MipsDivRemU16 : SDNode<"MipsISD::DivRemU16", SDT_MipsDivRem16,
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
122 // movn %got(d)($gp), %got(c)($gp), $4
123 // This instruction is illegal since movn can take only register operands.
125 def MipsWrapper : SDNode<"MipsISD::Wrapper", SDTIntBinOp>;
127 def MipsSync : SDNode<"MipsISD::Sync", SDT_Sync, [SDNPHasChain,SDNPSideEffect]>;
129 def MipsExt : SDNode<"MipsISD::Ext", SDT_Ext>;
130 def MipsIns : SDNode<"MipsISD::Ins", SDT_Ins>;
132 def MipsLWL : SDNode<"MipsISD::LWL", SDTMipsLoadLR,
133 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
134 def MipsLWR : SDNode<"MipsISD::LWR", SDTMipsLoadLR,
135 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
136 def MipsSWL : SDNode<"MipsISD::SWL", SDTStore,
137 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
138 def MipsSWR : SDNode<"MipsISD::SWR", SDTStore,
139 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
140 def MipsLDL : SDNode<"MipsISD::LDL", SDTMipsLoadLR,
141 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
142 def MipsLDR : SDNode<"MipsISD::LDR", SDTMipsLoadLR,
143 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
144 def MipsSDL : SDNode<"MipsISD::SDL", SDTStore,
145 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
146 def MipsSDR : SDNode<"MipsISD::SDR", SDTStore,
147 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
149 //===----------------------------------------------------------------------===//
150 // Mips Instruction Predicate Definitions.
151 //===----------------------------------------------------------------------===//
152 def HasMips2 : Predicate<"Subtarget->hasMips2()">,
153 AssemblerPredicate<"FeatureMips2">;
154 def HasMips3_32 : Predicate<"Subtarget->hasMips3_32()">,
155 AssemblerPredicate<"FeatureMips3_32">;
156 def HasMips3_32r2 : Predicate<"Subtarget->hasMips3_32r2()">,
157 AssemblerPredicate<"FeatureMips3_32r2">;
158 def HasMips3 : Predicate<"Subtarget->hasMips3()">,
159 AssemblerPredicate<"FeatureMips3">;
160 def HasMips4_32 : Predicate<"Subtarget->hasMips4_32()">,
161 AssemblerPredicate<"FeatureMips4_32">;
162 def NotMips4_32 : Predicate<"!Subtarget->hasMips4_32()">,
163 AssemblerPredicate<"!FeatureMips4_32">;
164 def HasMips4_32r2 : Predicate<"Subtarget->hasMips4_32r2()">,
165 AssemblerPredicate<"FeatureMips4_32r2">;
166 def HasMips5_32r2 : Predicate<"Subtarget->hasMips5_32r2()">,
167 AssemblerPredicate<"FeatureMips5_32r2">;
168 def HasMips32 : Predicate<"Subtarget->hasMips32()">,
169 AssemblerPredicate<"FeatureMips32">;
170 def HasMips32r2 : Predicate<"Subtarget->hasMips32r2()">,
171 AssemblerPredicate<"FeatureMips32r2">;
172 def HasMips32r5 : Predicate<"Subtarget->hasMips32r5()">,
173 AssemblerPredicate<"FeatureMips32r5">;
174 def HasMips32r6 : Predicate<"Subtarget->hasMips32r6()">,
175 AssemblerPredicate<"FeatureMips32r6">;
176 def NotMips32r6 : Predicate<"!Subtarget->hasMips32r6()">,
177 AssemblerPredicate<"!FeatureMips32r6">;
178 def IsGP64bit : Predicate<"Subtarget->isGP64bit()">,
179 AssemblerPredicate<"FeatureGP64Bit">;
180 def IsGP32bit : Predicate<"!Subtarget->isGP64bit()">,
181 AssemblerPredicate<"!FeatureGP64Bit">;
182 def IsPTR64bit : Predicate<"Subtarget->isABI_N64()">,
183 AssemblerPredicate<"FeaturePTR64Bit">;
184 def IsPTR32bit : Predicate<"!Subtarget->isABI_N64()">,
185 AssemblerPredicate<"!FeaturePTR64Bit">;
186 def HasMips64 : Predicate<"Subtarget->hasMips64()">,
187 AssemblerPredicate<"FeatureMips64">;
188 def NotMips64 : Predicate<"!Subtarget->hasMips64()">,
189 AssemblerPredicate<"!FeatureMips64">;
190 def HasMips64r2 : Predicate<"Subtarget->hasMips64r2()">,
191 AssemblerPredicate<"FeatureMips64r2">;
192 def HasMips64r6 : Predicate<"Subtarget->hasMips64r6()">,
193 AssemblerPredicate<"FeatureMips64r6">;
194 def NotMips64r6 : Predicate<"!Subtarget->hasMips64r6()">,
195 AssemblerPredicate<"!FeatureMips64r6">;
196 def HasMicroMips32r6 : Predicate<"Subtarget->inMicroMips32r6Mode()">,
197 AssemblerPredicate<"FeatureMicroMips,FeatureMips32r6">;
198 def HasMicroMips64r6 : Predicate<"Subtarget->inMicroMips64r6Mode()">,
199 AssemblerPredicate<"FeatureMicroMips,FeatureMips64r6">;
200 def InMips16Mode : Predicate<"Subtarget->inMips16Mode()">,
201 AssemblerPredicate<"FeatureMips16">;
202 def HasCnMips : Predicate<"Subtarget->hasCnMips()">,
203 AssemblerPredicate<"FeatureCnMips">;
204 def RelocNotPIC : Predicate<"!TM.isPositionIndependent()">;
205 def RelocPIC : Predicate<"TM.isPositionIndependent()">;
206 def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">;
207 def HasStdEnc : Predicate<"Subtarget->hasStandardEncoding()">,
208 AssemblerPredicate<"!FeatureMips16">;
209 def NotDSP : Predicate<"!Subtarget->hasDSP()">;
210 def InMicroMips : Predicate<"Subtarget->inMicroMipsMode()">,
211 AssemblerPredicate<"FeatureMicroMips">;
212 def NotInMicroMips : Predicate<"!Subtarget->inMicroMipsMode()">,
213 AssemblerPredicate<"!FeatureMicroMips">;
214 def IsLE : Predicate<"Subtarget->isLittle()">;
215 def IsBE : Predicate<"!Subtarget->isLittle()">;
216 def IsNotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
217 def UseTCCInDIV : AssemblerPredicate<"FeatureUseTCCInDIV">;
218 def HasEVA : Predicate<"Subtarget->hasEVA()">,
219 AssemblerPredicate<"FeatureEVA,FeatureMips32r2">;
220 def HasMSA : Predicate<"Subtarget->hasMSA()">,
221 AssemblerPredicate<"FeatureMSA">;
224 //===----------------------------------------------------------------------===//
225 // Mips GPR size adjectives.
226 // They are mutually exclusive.
227 //===----------------------------------------------------------------------===//
229 class GPR_32 { list<Predicate> GPRPredicates = [IsGP32bit]; }
230 class GPR_64 { list<Predicate> GPRPredicates = [IsGP64bit]; }
232 class PTR_32 { list<Predicate> PTRPredicates = [IsPTR32bit]; }
233 class PTR_64 { list<Predicate> PTRPredicates = [IsPTR64bit]; }
235 //===----------------------------------------------------------------------===//
236 // Mips ISA/ASE membership and instruction group membership adjectives.
237 // They are mutually exclusive.
238 //===----------------------------------------------------------------------===//
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
245 class ISA_MIPS1_NOT_4_32 {
246 list<Predicate> InsnPredicates = [NotMips4_32];
248 class ISA_MIPS1_NOT_32R6_64R6 {
249 list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6];
251 class ISA_MIPS2 { list<Predicate> InsnPredicates = [HasMips2]; }
252 class ISA_MIPS2_NOT_32R6_64R6 {
253 list<Predicate> InsnPredicates = [HasMips2, NotMips32r6, NotMips64r6];
255 class ISA_MIPS3 { list<Predicate> InsnPredicates = [HasMips3]; }
256 class ISA_MIPS3_NOT_32R6_64R6 {
257 list<Predicate> InsnPredicates = [HasMips3, NotMips32r6, NotMips64r6];
259 class ISA_MIPS32 { list<Predicate> InsnPredicates = [HasMips32]; }
260 class ISA_MIPS32_NOT_32R6_64R6 {
261 list<Predicate> InsnPredicates = [HasMips32, NotMips32r6, NotMips64r6];
263 class ISA_MIPS32R2 { list<Predicate> InsnPredicates = [HasMips32r2]; }
264 class ISA_MIPS32R2_NOT_32R6_64R6 {
265 list<Predicate> InsnPredicates = [HasMips32r2, NotMips32r6, NotMips64r6];
267 class ISA_MIPS32R5 { list<Predicate> InsnPredicates = [HasMips32r5]; }
268 class ISA_MIPS64 { list<Predicate> InsnPredicates = [HasMips64]; }
269 class ISA_MIPS64_NOT_64R6 {
270 list<Predicate> InsnPredicates = [HasMips64, NotMips64r6];
272 class ISA_MIPS64R2 { list<Predicate> InsnPredicates = [HasMips64r2]; }
273 class ISA_MIPS32R6 { list<Predicate> InsnPredicates = [HasMips32r6]; }
274 class ISA_MIPS64R6 { list<Predicate> InsnPredicates = [HasMips64r6]; }
275 class ISA_MICROMIPS { list<Predicate> InsnPredicates = [InMicroMips]; }
276 class ISA_MICROMIPS32R6 {
277 list<Predicate> InsnPredicates = [HasMicroMips32r6];
279 class ISA_MICROMIPS64R6 {
280 list<Predicate> InsnPredicates = [HasMicroMips64r6];
282 class ISA_MICROMIPS32_NOT_MIPS32R6 {
283 list<Predicate> InsnPredicates = [InMicroMips, NotMips32r6];
286 class INSN_EVA { list<Predicate> InsnPredicates = [HasEVA]; }
287 class INSN_EVA_NOT_32R6_64R6 {
288 list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6, HasEVA];
291 // The portions of MIPS-III that were also added to MIPS32
292 class INSN_MIPS3_32 { list<Predicate> InsnPredicates = [HasMips3_32]; }
294 // The portions of MIPS-III that were also added to MIPS32 but were removed in
295 // MIPS32r6 and MIPS64r6.
296 class INSN_MIPS3_32_NOT_32R6_64R6 {
297 list<Predicate> InsnPredicates = [HasMips3_32, NotMips32r6, NotMips64r6];
300 // The portions of MIPS-III that were also added to MIPS32
301 class INSN_MIPS3_32R2 { list<Predicate> InsnPredicates = [HasMips3_32r2]; }
303 // The portions of MIPS-IV that were also added to MIPS32 but were removed in
304 // MIPS32r6 and MIPS64r6.
305 class INSN_MIPS4_32_NOT_32R6_64R6 {
306 list<Predicate> InsnPredicates = [HasMips4_32, NotMips32r6, NotMips64r6];
309 // The portions of MIPS-IV that were also added to MIPS32r2 but were removed in
310 // MIPS32r6 and MIPS64r6.
311 class INSN_MIPS4_32R2_NOT_32R6_64R6 {
312 list<Predicate> InsnPredicates = [HasMips4_32r2, NotMips32r6, NotMips64r6];
315 // The portions of MIPS-V that were also added to MIPS32r2 but were removed in
316 // MIPS32r6 and MIPS64r6.
317 class INSN_MIPS5_32R2_NOT_32R6_64R6 {
318 list<Predicate> InsnPredicates = [HasMips5_32r2, NotMips32r6, NotMips64r6];
322 list<Predicate> InsnPredicates = [HasCnMips];
325 class ASE_MIPS64_CNMIPS {
326 list<Predicate> InsnPredicates = [HasMips64, HasCnMips];
330 list<Predicate> InsnPredicates = [HasMSA];
333 class ASE_MSA_NOT_MSA64 {
334 list<Predicate> InsnPredicates = [HasMSA, NotMips64];
338 list<Predicate> InsnPredicates = [HasMSA, HasMips64];
341 // Class used for separating microMIPSr6 and microMIPS (r3) instruction.
342 // It can be used only on instructions that doesn't inherit PredicateControl.
343 class ISA_MICROMIPS_NOT_32R6_64R6 : PredicateControl {
344 let InsnPredicates = [InMicroMips, NotMips32r6, NotMips64r6];
348 list<Predicate> InsnPredicates = [NotDSP];
351 //===----------------------------------------------------------------------===//
353 class MipsPat<dag pattern, dag result> : Pat<pattern, result>, PredicateControl {
354 let EncodingPredicates = [HasStdEnc];
357 class MipsInstAlias<string Asm, dag Result, bit Emit = 0b1> :
358 InstAlias<Asm, Result, Emit>, PredicateControl;
361 bit isCommutable = 1;
381 bit isTerminator = 1;
384 bit hasExtraSrcRegAllocReq = 1;
385 bit isCodeGenOnly = 1;
389 class IsAsCheapAsAMove {
390 bit isAsCheapAsAMove = 1;
393 class NeverHasSideEffects {
394 bit hasSideEffects = 0;
397 //===----------------------------------------------------------------------===//
398 // Instruction format superclass
399 //===----------------------------------------------------------------------===//
401 include "MipsInstrFormats.td"
403 //===----------------------------------------------------------------------===//
404 // Mips Operand, Complex Patterns and Transformations Definitions.
405 //===----------------------------------------------------------------------===//
407 class 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;
416 class 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;
425 class ConstantUImmRangeAsmOperandClass<int Bottom, int Top,
426 list<AsmOperandClass> Supers = []>
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;
435 class SImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
437 let Name = "SImm" # Bits;
438 let RenderMethod = "addSImmOperands<" # Bits # ">";
439 let PredicateMethod = "isSImm<" # Bits # ">";
440 let SuperClasses = Supers;
441 let DiagnosticType = "SImm" # Bits;
444 class UImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
446 let Name = "UImm" # Bits;
447 let RenderMethod = "addUImmOperands<" # Bits # ">";
448 let PredicateMethod = "isUImm<" # Bits # ">";
449 let SuperClasses = Supers;
450 let DiagnosticType = "UImm" # Bits;
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.
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
462 // simm4 < uimm4 < simm5 < uimm5
463 // * For the same upper-bound, signed immediates are a superset of unsigned
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.
476 def SImm32RelaxedAsmOperandClass
477 : SImmAsmOperandClass<32, []> {
478 let Name = "SImm32_Relaxed";
479 let PredicateMethod = "isAnyImm<32>";
480 let DiagnosticType = "SImm32_Relaxed";
482 def SImm32AsmOperandClass
483 : SImmAsmOperandClass<32, [SImm32RelaxedAsmOperandClass]>;
484 def ConstantUImm26AsmOperandClass
485 : ConstantUImmAsmOperandClass<26, [SImm32AsmOperandClass]>;
486 def ConstantUImm20AsmOperandClass
487 : ConstantUImmAsmOperandClass<20, [ConstantUImm26AsmOperandClass]>;
488 def UImm16RelaxedAsmOperandClass
489 : UImmAsmOperandClass<16, [ConstantUImm20AsmOperandClass]> {
490 let Name = "UImm16_Relaxed";
491 let PredicateMethod = "isAnyImm<16>";
492 let DiagnosticType = "UImm16_Relaxed";
494 def UImm16AsmOperandClass
495 : UImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]>;
496 def SImm16RelaxedAsmOperandClass
497 : SImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]> {
498 let Name = "SImm16_Relaxed";
499 let PredicateMethod = "isAnyImm<16>";
500 let DiagnosticType = "SImm16_Relaxed";
502 def SImm16AsmOperandClass
503 : SImmAsmOperandClass<16, [SImm16RelaxedAsmOperandClass]>;
504 def 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";
511 def 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";
518 def ConstantSImm11AsmOperandClass
519 : ConstantSImmAsmOperandClass<11, [ConstantSImm10Lsl2AsmOperandClass]>;
520 def 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";
527 def ConstantUImm10AsmOperandClass
528 : ConstantUImmAsmOperandClass<10, [ConstantSImm10Lsl1AsmOperandClass]>;
529 def ConstantSImm10AsmOperandClass
530 : ConstantSImmAsmOperandClass<10, [ConstantUImm10AsmOperandClass]>;
531 def ConstantSImm9AsmOperandClass
532 : ConstantSImmAsmOperandClass<9, [ConstantSImm10AsmOperandClass]>;
533 def 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";
540 def ConstantUImm8AsmOperandClass
541 : ConstantUImmAsmOperandClass<8, [ConstantSImm7Lsl2AsmOperandClass]>;
542 def 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";
548 def ConstantUImm7AsmOperandClass
549 : ConstantUImmAsmOperandClass<7, [ConstantUImm7Sub1AsmOperandClass]>;
550 def 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";
557 def ConstantUImm6AsmOperandClass
558 : ConstantUImmAsmOperandClass<6, [ConstantUImm6Lsl2AsmOperandClass]>;
559 def ConstantSImm6AsmOperandClass
560 : ConstantSImmAsmOperandClass<6, [ConstantUImm6AsmOperandClass]>;
561 def 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";
568 def ConstantUImm5_Range2_64AsmOperandClass
569 : ConstantUImmRangeAsmOperandClass<2, 64, [ConstantUImm5Lsl2AsmOperandClass]>;
570 def ConstantUImm5Plus33AsmOperandClass
571 : ConstantUImmAsmOperandClass<5, [ConstantUImm5_Range2_64AsmOperandClass],
573 def ConstantUImm5ReportUImm6AsmOperandClass
574 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus33AsmOperandClass]> {
575 let Name = "ConstantUImm5_0_Report_UImm6";
576 let DiagnosticType = "UImm5_0_Report_UImm6";
578 def ConstantUImm5Plus32AsmOperandClass
579 : ConstantUImmAsmOperandClass<
580 5, [ConstantUImm5ReportUImm6AsmOperandClass], 32>;
581 def 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>";
587 def ConstantUImm5Plus1AsmOperandClass
588 : ConstantUImmAsmOperandClass<
589 5, [ConstantUImm5Plus32NormalizeAsmOperandClass], 1>;
590 def ConstantUImm5AsmOperandClass
591 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus1AsmOperandClass]>;
592 def ConstantSImm5AsmOperandClass
593 : ConstantSImmAsmOperandClass<5, [ConstantUImm5AsmOperandClass]>;
594 def ConstantUImm4AsmOperandClass
595 : ConstantUImmAsmOperandClass<4, [ConstantSImm5AsmOperandClass]>;
596 def ConstantSImm4AsmOperandClass
597 : ConstantSImmAsmOperandClass<4, [ConstantUImm4AsmOperandClass]>;
598 def ConstantUImm3AsmOperandClass
599 : ConstantUImmAsmOperandClass<3, [ConstantSImm4AsmOperandClass]>;
600 def ConstantUImm2Plus1AsmOperandClass
601 : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass], 1>;
602 def ConstantUImm2AsmOperandClass
603 : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass]>;
604 def ConstantUImm1AsmOperandClass
605 : ConstantUImmAsmOperandClass<1, [ConstantUImm2AsmOperandClass]>;
606 def ConstantImmzAsmOperandClass : AsmOperandClass {
607 let Name = "ConstantImmz";
608 let RenderMethod = "addConstantUImmOperands<1>";
609 let PredicateMethod = "isConstantImmz";
610 let SuperClasses = [ConstantUImm1AsmOperandClass];
611 let DiagnosticType = "Immz";
614 def MipsJumpTargetAsmOperand : AsmOperandClass {
615 let Name = "JumpTarget";
616 let ParserMethod = "parseJumpTarget";
617 let PredicateMethod = "isImm";
618 let RenderMethod = "addImmOperands";
621 // Instruction operand types
622 def jmptarget : Operand<OtherVT> {
623 let EncoderMethod = "getJumpTargetOpValue";
624 let ParserMatchClass = MipsJumpTargetAsmOperand;
626 def brtarget : Operand<OtherVT> {
627 let EncoderMethod = "getBranchTargetOpValue";
628 let OperandType = "OPERAND_PCREL";
629 let DecoderMethod = "DecodeBranchTarget";
630 let ParserMatchClass = MipsJumpTargetAsmOperand;
632 def brtarget1SImm16 : Operand<OtherVT> {
633 let EncoderMethod = "getBranchTargetOpValue1SImm16";
634 let OperandType = "OPERAND_PCREL";
635 let DecoderMethod = "DecodeBranchTarget1SImm16";
636 let ParserMatchClass = MipsJumpTargetAsmOperand;
638 def calltarget : Operand<iPTR> {
639 let EncoderMethod = "getJumpTargetOpValue";
640 let ParserMatchClass = MipsJumpTargetAsmOperand;
643 def imm64: Operand<i64>;
645 def simm19_lsl2 : Operand<i32> {
646 let EncoderMethod = "getSimm19Lsl2Encoding";
647 let DecoderMethod = "DecodeSimm19Lsl2";
648 let ParserMatchClass = MipsJumpTargetAsmOperand;
651 def simm18_lsl3 : Operand<i32> {
652 let EncoderMethod = "getSimm18Lsl3Encoding";
653 let DecoderMethod = "DecodeSimm18Lsl3";
654 let ParserMatchClass = MipsJumpTargetAsmOperand;
658 def uimmz : Operand<i32> {
659 let PrintMethod = "printUImm<0>";
660 let ParserMatchClass = ConstantImmzAsmOperandClass;
663 // size operand of ins instruction
664 def 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;
672 foreach 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");
679 def 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;
686 def 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;
693 def uimm5_plus32 : Operand<i32> {
694 let PrintMethod = "printUImm<5, 32>";
695 let ParserMatchClass = ConstantUImm5Plus32AsmOperandClass;
698 def 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;
705 def uimm5_inssize_plus1 : Operand<i32> {
706 let PrintMethod = "printUImm<6>";
707 let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass;
708 let EncoderMethod = "getSizeInsEncoding";
709 let DecoderMethod = "DecodeInsSize";
712 def uimm5_plus32_normalize : Operand<i32> {
713 let PrintMethod = "printUImm<5>";
714 let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
717 def uimm5_lsl2 : Operand<OtherVT> {
718 let EncoderMethod = "getUImm5Lsl2Encoding";
719 let DecoderMethod = "DecodeUImmWithOffsetAndScale<5, 0, 4>";
720 let ParserMatchClass = ConstantUImm5Lsl2AsmOperandClass;
723 def uimm5_plus32_normalize_64 : Operand<i64> {
724 let PrintMethod = "printUImm<5>";
725 let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
728 def uimm6_lsl2 : Operand<OtherVT> {
729 let EncoderMethod = "getUImm6Lsl2Encoding";
730 let DecoderMethod = "DecodeUImmWithOffsetAndScale<6, 0, 4>";
731 let ParserMatchClass = ConstantUImm6Lsl2AsmOperandClass;
735 def uimm # I : Operand<i32> {
736 let PrintMethod = "printUImm<" # I # ">";
737 let ParserMatchClass =
738 !cast<AsmOperandClass>("UImm" # I # "AsmOperandClass");
741 // Like uimm16_64 but coerces simm16 to uimm16.
742 def uimm16_relaxed : Operand<i32> {
743 let PrintMethod = "printUImm<16>";
744 let ParserMatchClass =
745 !cast<AsmOperandClass>("UImm16RelaxedAsmOperandClass");
749 def uimm # I # _64 : Operand<i64> {
750 let PrintMethod = "printUImm<" # I # ">";
751 let ParserMatchClass =
752 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
756 def uimm # I # _64 : Operand<i64> {
757 let PrintMethod = "printUImm<" # I # ">";
758 let ParserMatchClass =
759 !cast<AsmOperandClass>("UImm" # I # "AsmOperandClass");
762 // Like uimm16_64 but coerces simm16 to uimm16.
763 def uimm16_64_relaxed : Operand<i64> {
764 let PrintMethod = "printUImm<16>";
765 let ParserMatchClass =
766 !cast<AsmOperandClass>("UImm16RelaxedAsmOperandClass");
769 // Like uimm5 but reports a less confusing error for 32-63 when
770 // an instruction alias permits that.
771 def uimm5_report_uimm6 : Operand<i32> {
772 let PrintMethod = "printUImm<5>";
773 let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
776 // Like uimm5_64 but reports a less confusing error for 32-63 when
777 // an instruction alias permits that.
778 def uimm5_64_report_uimm6 : Operand<i64> {
779 let PrintMethod = "printUImm<5>";
780 let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
783 foreach 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");
790 foreach 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");
798 foreach 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");
805 foreach 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");
813 def simm # I # _64 : Operand<i64> {
814 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
815 let ParserMatchClass =
816 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
819 foreach I = {5, 10} in
820 def vsplat_simm # I : Operand<vAny> {
821 let ParserMatchClass =
822 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
825 def simm7_lsl2 : Operand<OtherVT> {
826 let EncoderMethod = "getSImm7Lsl2Encoding";
827 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ", 0, 4>";
828 let ParserMatchClass = ConstantSImm7Lsl2AsmOperandClass;
831 foreach I = {16, 32} in
832 def simm # I : Operand<i32> {
833 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
834 let ParserMatchClass = !cast<AsmOperandClass>("SImm" # I # "AsmOperandClass");
837 // Like simm16 but coerces uimm16 to simm16.
838 def simm16_relaxed : Operand<i32> {
839 let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
840 let ParserMatchClass = !cast<AsmOperandClass>("SImm16RelaxedAsmOperandClass");
843 def simm16_64 : Operand<i64> {
844 let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
845 let ParserMatchClass = !cast<AsmOperandClass>("SImm16AsmOperandClass");
848 // Like simm32 but coerces uimm32 to simm32.
849 def simm32_relaxed : Operand<i32> {
850 let DecoderMethod = "DecodeSImmWithOffsetAndScale<32>";
851 let ParserMatchClass = !cast<AsmOperandClass>("SImm32RelaxedAsmOperandClass");
854 // This is almost the same as a uimm7 but 0x7f is interpreted as -1.
855 def li16_imm : Operand<i32> {
856 let DecoderMethod = "DecodeLi16Imm";
857 let ParserMatchClass = ConstantUImm7Sub1AsmOperandClass;
860 def MipsMemAsmOperand : AsmOperandClass {
862 let ParserMethod = "parseMemOperand";
865 def 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";
874 def 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";
883 def 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";
892 foreach 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;
902 def 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";
911 def 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";
920 def MipsInvertedImmoperand : AsmOperandClass {
922 let RenderMethod = "addImmOperands";
923 let ParserMethod = "parseInvNum";
926 def InvertedImOperand : Operand<i32> {
927 let ParserMatchClass = MipsInvertedImmoperand;
930 def InvertedImOperand64 : Operand<i64> {
931 let ParserMatchClass = MipsInvertedImmoperand;
934 class 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";
943 def mem : mem_generic;
945 // MSA specific address operand
946 def mem_msa : mem_generic {
947 let MIOperandInfo = (ops ptr_rc, simm10);
948 let EncoderMethod = "getMSAMemEncoding";
951 def simm12 : Operand<i32> {
952 let DecoderMethod = "DecodeSimm12";
955 def mem_simm9 : mem_generic {
956 let MIOperandInfo = (ops ptr_rc, simm9);
957 let EncoderMethod = "getMemEncoding";
958 let ParserMatchClass = MipsMemSimm9AsmOperand;
961 def mem_simm10 : mem_generic {
962 let MIOperandInfo = (ops ptr_rc, simm10);
963 let EncoderMethod = "getMemEncoding";
964 let ParserMatchClass = MipsMemSimm10AsmOperand;
967 foreach 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");
975 def mem_simm11 : mem_generic {
976 let MIOperandInfo = (ops ptr_rc, simm11);
977 let EncoderMethod = "getMemEncoding";
978 let ParserMatchClass = MipsMemSimm11AsmOperand;
981 def mem_simm12 : mem_generic {
982 let MIOperandInfo = (ops ptr_rc, simm12);
983 let EncoderMethod = "getMemEncoding";
984 let ParserMatchClass = MipsMemSimm12AsmOperand;
987 def mem_simm16 : mem_generic {
988 let MIOperandInfo = (ops ptr_rc, simm16);
989 let EncoderMethod = "getMemEncoding";
990 let ParserMatchClass = MipsMemSimm16AsmOperand;
993 def mem_ea : Operand<iPTR> {
994 let PrintMethod = "printMemOperandEA";
995 let MIOperandInfo = (ops ptr_rc, simm16);
996 let EncoderMethod = "getMemEncoding";
997 let OperandType = "OPERAND_MEMORY";
1000 def PtrRC : Operand<iPTR> {
1001 let MIOperandInfo = (ops ptr_rc);
1002 let DecoderMethod = "DecodePtrRegisterClass";
1003 let ParserMatchClass = GPR32AsmOperand;
1006 // size operand of ins instruction
1007 def size_ins : Operand<i32> {
1008 let EncoderMethod = "getSizeInsEncoding";
1009 let DecoderMethod = "DecodeInsSize";
1012 // Transformation Function - get the lower 16 bits.
1013 def LO16 : SDNodeXForm<imm, [{
1014 return getImm(N, N->getZExtValue() & 0xFFFF);
1017 // Transformation Function - get the higher 16 bits.
1018 def HI16 : SDNodeXForm<imm, [{
1019 return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF);
1023 def Plus1 : SDNodeXForm<imm, [{ return getImm(N, N->getSExtValue() + 1); }]>;
1025 // Node immediate is zero (e.g. insve.d)
1026 def immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>;
1028 // Node immediate fits as 16-bit sign extended on target immediate.
1030 def immSExt8 : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;
1032 // Node immediate fits as 16-bit sign extended on target immediate.
1034 def immSExt16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;
1036 // Node immediate fits as 15-bit sign extended on target immediate.
1038 def immSExt15 : PatLeaf<(imm), [{ return isInt<15>(N->getSExtValue()); }]>;
1040 // Node immediate fits as 7-bit zero extended on target immediate.
1041 def immZExt7 : PatLeaf<(imm), [{ return isUInt<7>(N->getZExtValue()); }]>;
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
1047 def immZExt16 : PatLeaf<(imm), [{
1048 if (N->getValueType(0) == MVT::i32)
1049 return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
1051 return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
1054 // Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared).
1055 def immLow16Zero : PatLeaf<(imm), [{
1056 int64_t Val = N->getSExtValue();
1057 return isInt<32>(Val) && !(Val & 0xffff);
1060 // shamt field must fit in 5 bits.
1061 def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
1063 def immZExt5Plus1 : PatLeaf<(imm), [{
1064 return isUInt<5>(N->getZExtValue() - 1);
1066 def immZExt5Plus32 : PatLeaf<(imm), [{
1067 return isUInt<5>(N->getZExtValue() - 32);
1069 def immZExt5Plus33 : PatLeaf<(imm), [{
1070 return isUInt<5>(N->getZExtValue() - 33);
1073 // True if (N + 1) fits in 16-bit field.
1074 def immSExt16Plus1 : PatLeaf<(imm), [{
1075 return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1);
1078 // Mips Address Mode! SDNode frameindex could possibily be a match
1079 // since load and store instructions from stack used it.
1081 ComplexPattern<iPTR, 2, "selectIntAddr", [frameindex]>;
1084 ComplexPattern<iPTR, 2, "selectAddrRegImm", [frameindex]>;
1087 ComplexPattern<iPTR, 2, "selectAddrDefault", [frameindex]>;
1089 def addrimm10 : ComplexPattern<iPTR, 2, "selectIntAddrMSA", [frameindex]>;
1091 //===----------------------------------------------------------------------===//
1092 // Instructions specific format
1093 //===----------------------------------------------------------------------===//
1095 // Arithmetic and logical instructions with 3 register operands.
1096 class 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";
1107 // Arithmetic and logical instructions with 2 register operands.
1108 class 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";
1120 // Arithmetic Multiply ADD/SUB
1121 class 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;
1130 class 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;
1138 class 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";
1148 class 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,
1155 // Load Upper Immediate
1156 class 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;
1163 // Memory Load/Store
1164 class 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;
1175 class Load<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
1176 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
1177 LoadMemory<opstr, RO, mem, OpNode, Itin, Addr>;
1179 class 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";
1188 class 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>;
1193 // Load/Store Left/Right
1194 let canFoldAsLoad = 1 in
1195 class 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";
1204 class 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";
1212 class 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";
1221 class 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";
1231 class 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";
1239 class 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";
1247 // Conditional Branch
1248 class 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,
1255 let isTerminator = 1;
1256 let hasDelaySlot = DelaySlot;
1261 class 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,
1268 let isTerminator = 1;
1269 let hasDelaySlot = DelaySlot;
1275 class 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>;
1281 class 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>;
1289 class 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> {
1295 let hasDelaySlot = 1;
1296 let DecoderMethod = "DecodeJumpTarget";
1301 // Unconditional branch
1302 class UncondBranch<Instruction BEQInst> :
1303 PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], II_B>,
1304 PseudoInstExpansion<(BEQInst ZERO, ZERO, brtarget:$offset)> {
1306 let isTerminator = 1;
1308 let hasDelaySlot = 1;
1309 let AdditionalPredicates = [RelocPIC];
1314 // Base class for indirect branch and return instruction classes.
1315 let isTerminator=1, isBarrier=1, hasDelaySlot = 1, isCTI = 1 in
1316 class JumpFR<string opstr, RegisterOperand RO,
1317 SDPatternOperator operator = null_frag>:
1318 InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], II_JR,
1322 class IndirectBranch<string opstr, RegisterOperand RO> : JumpFR<opstr, RO> {
1324 let isIndirectBranch = 1;
1327 // Jump and Link (Call)
1328 let 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";
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)>;
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>;
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;
1353 let 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)>;
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)>;
1365 class BAL_BR_Pseudo<Instruction RealInst> :
1366 PseudoSE<(outs), (ins brtarget:$offset), [], II_BCCZAL>,
1367 PseudoInstExpansion<(RealInst ZERO, brtarget:$offset)> {
1369 let isTerminator = 1;
1371 let hasDelaySlot = 1;
1378 class SYS_FT<string opstr, Operand ImmOp, InstrItinClass itin = NoItinerary> :
1379 InstSE<(outs), (ins ImmOp:$code_),
1380 !strconcat(opstr, "\t$code_"), [], itin, FrmI, opstr>;
1382 class BRK_FT<string opstr> :
1383 InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
1384 !strconcat(opstr, "\t$code_1, $code_2"), [], II_BREAK,
1388 class ER_FT<string opstr, InstrItinClass itin = NoItinerary> :
1389 InstSE<(outs), (ins),
1390 opstr, [], itin, FrmOther, opstr>;
1393 class WAIT_FT<string opstr> :
1394 InstSE<(outs), (ins), opstr, [], II_WAIT, FrmOther, opstr>;
1398 class DEI_FT<string opstr, RegisterOperand RO,
1399 InstrItinClass itin = NoItinerary> :
1400 InstSE<(outs RO:$rt), (ins),
1401 !strconcat(opstr, "\t$rt"), [], itin, FrmOther, opstr>;
1404 let hasSideEffects = 1 in
1405 class SYNC_FT<string opstr> :
1406 InstSE<(outs), (ins uimm5:$stype), "sync $stype",
1407 [(MipsSync immZExt5:$stype)], II_SYNC, FrmOther, opstr>;
1409 class 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";
1416 let hasSideEffects = 1, isCTI = 1 in {
1417 class 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>;
1422 class 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>;
1429 class 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;
1435 let hasSideEffects = 0;
1438 // Pseudo multiply/divide instruction with explicit accumulator register
1440 class 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;
1452 // Pseudo multiply add/sub instruction with explicit accumulator register
1454 class MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode,
1455 InstrItinClass itin>
1456 : PseudoSE<(outs ACC64:$ac),
1457 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin),
1459 (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))],
1461 PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> {
1462 string Constraints = "$acin = $ac";
1465 class 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> {
1473 class 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>;
1477 class MoveFromLOHI<string opstr, RegisterOperand RO, Register UseReg>:
1478 InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO,
1480 let Uses = [UseReg];
1481 let hasSideEffects = 0;
1484 class PseudoMTLOHI<RegisterClass DstRC, RegisterClass SrcRC>
1485 : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi),
1486 [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))],
1489 class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>:
1490 InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO,
1493 let hasSideEffects = 0;
1496 class 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";
1505 // Count Leading Ones/Zeros in Word
1506 class 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>;
1511 class 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>;
1516 // Sign Extend in Register.
1517 class 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>;
1523 class SubwordSwap<string opstr, RegisterOperand RO,
1524 InstrItinClass itin = NoItinerary>:
1525 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [], itin,
1527 let hasSideEffects = 0;
1531 class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> :
1532 InstSE<(outs CPURegOperand:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [],
1533 II_RDHWR, FrmR, "rdhwr">;
1536 class 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;
1544 class 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";
1553 // Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*).
1554 class Atomic2Ops<PatFrag Op, RegisterClass DRC> :
1555 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr),
1556 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]>;
1558 // Atomic Compare & Swap.
1559 class 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))]>;
1563 class 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";
1570 class 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";
1575 let Constraints = "$rt = $dst";
1578 class 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>;
1583 class 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>;
1588 class TrapBase<Instruction RealInst>
1589 : PseudoSE<(outs), (ins), [(trap)], II_TRAP>,
1590 PseudoInstExpansion<(RealInst 0, 0)> {
1592 let isTerminator = 1;
1593 let isCodeGenOnly = 1;
1597 //===----------------------------------------------------------------------===//
1598 // Pseudo instructions
1599 //===----------------------------------------------------------------------===//
1602 let isReturn=1, isTerminator=1, isBarrier=1, hasCtrlDep=1, isCTI=1 in {
1603 let hasDelaySlot=1 in
1604 def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
1606 let hasSideEffects=1 in
1607 def ERet : PseudoSE<(outs), (ins), [(MipsERet)]>;
1610 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
1611 def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt),
1612 [(callseq_start timm:$amt)]>;
1613 def ADJCALLSTACKUP : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1614 [(callseq_end timm:$amt1, timm:$amt2)]>;
1617 let 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>;
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>;
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>;
1646 /// Pseudo instructions for loading and storing accumulator registers.
1647 let isPseudo = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in {
1648 def LOAD_ACC64 : Load<"", ACC64>;
1649 def STORE_ACC64 : Store<"", ACC64>;
1652 // We need these two pseudo instructions to avoid offset calculation for long
1653 // branches. See the comment in file MipsLongBranch.cpp for detailed
1656 // Expands to: lui $dst, %hi($tgt - $baltgt)
1657 def LONG_BRANCH_LUi : PseudoSE<(outs GPR32Opnd:$dst),
1658 (ins brtarget:$tgt, brtarget:$baltgt), []>;
1660 // Expands to: addiu $dst, $src, %lo($tgt - $baltgt)
1661 def LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst),
1662 (ins GPR32Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []>;
1664 //===----------------------------------------------------------------------===//
1665 // Instruction definition
1666 //===----------------------------------------------------------------------===//
1667 //===----------------------------------------------------------------------===//
1668 // MipsI Instructions
1669 //===----------------------------------------------------------------------===//
1671 /// Arithmetic Instructions (ALU Immediate)
1672 let AdditionalPredicates = [NotInMicroMips] in {
1673 def ADDiu : MMRel, StdMMR6Rel, ArithLogicI<"addiu", simm16_relaxed, GPR32Opnd,
1674 II_ADDIU, immSExt16, add>,
1675 ADDI_FM<0x9>, IsAsCheapAsAMove;
1677 def ANDi : MMRel, StdMMR6Rel,
1678 ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16, and>,
1680 def ORi : MMRel, StdMMR6Rel,
1681 ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16, or>,
1683 def XORi : MMRel, StdMMR6Rel,
1684 ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16, xor>,
1687 def ADDi : MMRel, ArithLogicI<"addi", simm16_relaxed, GPR32Opnd, II_ADDI>, ADDI_FM<0x8>,
1688 ISA_MIPS1_NOT_32R6_64R6;
1689 def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
1691 def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
1693 def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16_relaxed>, LUI_FM;
1694 let AdditionalPredicates = [NotInMicroMips] in {
1695 /// Arithmetic Instructions (3-Operand, R-Type)
1696 def ADDu : MMRel, StdMMR6Rel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
1698 def SUBu : MMRel, StdMMR6Rel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
1701 let Defs = [HI0, LO0] in
1702 def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>,
1703 ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6;
1704 def ADD : MMRel, StdMMR6Rel, ArithLogicR<"add", GPR32Opnd, 1, II_ADD>, ADD_FM<0, 0x20>;
1705 def SUB : MMRel, StdMMR6Rel, ArithLogicR<"sub", GPR32Opnd, 0, II_SUB>, ADD_FM<0, 0x22>;
1706 def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>;
1707 def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>;
1708 let AdditionalPredicates = [NotInMicroMips] in {
1709 def AND : MMRel, StdMMR6Rel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
1711 def OR : MMRel, StdMMR6Rel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
1713 def XOR : MMRel, StdMMR6Rel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
1715 def NOR : MMRel, StdMMR6Rel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>;
1718 /// Shift Instructions
1719 let AdditionalPredicates = [NotInMicroMips] in {
1720 def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl,
1721 immZExt5>, SRA_FM<0, 0>;
1722 def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl,
1723 immZExt5>, SRA_FM<2, 0>;
1724 def SRA : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, sra,
1725 immZExt5>, SRA_FM<3, 0>;
1726 def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, shl>,
1728 def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, srl>,
1730 def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, sra>,
1734 // Rotate Instructions
1735 let AdditionalPredicates = [NotInMicroMips] in {
1736 def ROTR : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr,
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;
1743 /// Load and Store Instructions
1745 def LB : LoadMemory<"lb", GPR32Opnd, mem_simm16, sextloadi8, II_LB>, MMRel,
1747 def LBu : LoadMemory<"lbu", GPR32Opnd, mem_simm16, zextloadi8, II_LBU,
1748 addrDefault>, MMRel, LW_FM<0x24>;
1749 let 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>,
1754 def LW : StdMMR6Rel, Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel,
1757 def SB : StdMMR6Rel, Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel,
1759 def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>;
1760 let AdditionalPredicates = [NotInMicroMips] in {
1761 def SW : Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>;
1764 /// load/store left/right
1765 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1766 AdditionalPredicates = [NotInMicroMips] in {
1767 def LWL : LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>,
1768 ISA_MIPS1_NOT_32R6_64R6;
1769 def LWR : LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>,
1770 ISA_MIPS1_NOT_32R6_64R6;
1771 def SWL : StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>,
1772 ISA_MIPS1_NOT_32R6_64R6;
1773 def SWR : StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>,
1774 ISA_MIPS1_NOT_32R6_64R6;
1777 let AdditionalPredicates = [NotInMicroMips] in {
1778 // COP2 Memory Instructions
1779 def LWC2 : StdMMR6Rel, LW_FT2<"lwc2", COP2Opnd, II_LWC2, load>, LW_FM<0x32>,
1780 ISA_MIPS1_NOT_32R6_64R6;
1781 def SWC2 : StdMMR6Rel, SW_FT2<"swc2", COP2Opnd, II_SWC2, store>,
1782 LW_FM<0x3a>, ISA_MIPS1_NOT_32R6_64R6;
1783 def LDC2 : StdMMR6Rel, LW_FT2<"ldc2", COP2Opnd, II_LDC2, load>, LW_FM<0x36>,
1784 ISA_MIPS2_NOT_32R6_64R6;
1785 def SDC2 : StdMMR6Rel, SW_FT2<"sdc2", COP2Opnd, II_SDC2, store>,
1786 LW_FM<0x3e>, ISA_MIPS2_NOT_32R6_64R6;
1788 // COP3 Memory Instructions
1789 let 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>,
1794 def SDC3 : SW_FT3<"sdc3", COP3Opnd, II_SDC3, store>, LW_FM<0x3f>,
1799 def SYNC : MMRel, StdMMR6Rel, SYNC_FT<"sync">, SYNC_FM,
1801 def SYNCI : MMRel, StdMMR6Rel, SYNCI_FT<"synci">, SYNCI_FM, ISA_MIPS32R2;
1803 let 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;
1812 def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd, II_TEQI>, TEQI_FM<0xc>,
1813 ISA_MIPS2_NOT_32R6_64R6;
1814 def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd, II_TGEI>, TEQI_FM<0x8>,
1815 ISA_MIPS2_NOT_32R6_64R6;
1816 def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd, II_TGEIU>, TEQI_FM<0x9>,
1817 ISA_MIPS2_NOT_32R6_64R6;
1818 def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd, II_TLTI>, TEQI_FM<0xa>,
1819 ISA_MIPS2_NOT_32R6_64R6;
1820 def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd, II_TTLTIU>, TEQI_FM<0xb>,
1821 ISA_MIPS2_NOT_32R6_64R6;
1822 def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd, II_TNEI>, TEQI_FM<0xe>,
1823 ISA_MIPS2_NOT_32R6_64R6;
1825 let AdditionalPredicates = [NotInMicroMips] in {
1826 def BREAK : MMRel, StdMMR6Rel, BRK_FT<"break">, BRK_FM<0xd>;
1827 def SYSCALL : MMRel, SYS_FT<"syscall", uimm20, II_SYSCALL>, SYS_FM<0xc>;
1829 def TRAP : TrapBase<BREAK>;
1830 let AdditionalPredicates = [NotInMicroMips] in {
1831 def SDBBP : MMRel, SYS_FT<"sdbbp", uimm20, II_SDBBP>, SDBBP_FM, ISA_MIPS32_NOT_32R6_64R6;
1834 let 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;
1840 let 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;
1845 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1846 AdditionalPredicates = [NotInMicroMips] in {
1847 def WAIT : WAIT_FT<"wait">, WAIT_FM;
1850 let AdditionalPredicates = [NotInMicroMips] in {
1851 /// Load-linked, Store-conditional
1852 def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
1853 def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
1856 /// Jump and Branch Instructions
1857 def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
1858 AdditionalRequires<[RelocNotPIC]>, IsBranch;
1859 def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>, ISA_MIPS1_NOT_32R6_64R6;
1860 def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>;
1861 def BEQL : MMRel, CBranch<"beql", brtarget, seteq, GPR32Opnd, 0>,
1862 BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6;
1863 def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>;
1864 def BNEL : MMRel, CBranch<"bnel", brtarget, setne, GPR32Opnd, 0>,
1865 BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6;
1866 def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
1868 def BGEZL : MMRel, CBranchZero<"bgezl", brtarget, setge, GPR32Opnd, 0>,
1869 BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6;
1870 def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
1872 def BGTZL : MMRel, CBranchZero<"bgtzl", brtarget, setgt, GPR32Opnd, 0>,
1873 BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6;
1874 def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
1876 def BLEZL : MMRel, CBranchZero<"blezl", brtarget, setle, GPR32Opnd, 0>,
1877 BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6;
1878 def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
1880 def BLTZL : MMRel, CBranchZero<"bltzl", brtarget, setlt, GPR32Opnd, 0>,
1881 BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6;
1882 def B : UncondBranch<BEQ>;
1884 def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>;
1885 let AdditionalPredicates = [NotInMicroMips] in {
1886 def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM;
1887 def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>;
1890 def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>,
1891 ISA_MIPS32_NOT_32R6_64R6;
1892 def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>,
1893 ISA_MIPS1_NOT_32R6_64R6;
1894 def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd, 0>,
1895 BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6;
1896 def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>,
1897 ISA_MIPS1_NOT_32R6_64R6;
1898 def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd, 0>,
1899 BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6;
1900 def BAL_BR : BAL_BR_Pseudo<BGEZAL>;
1901 def TAILCALL : TailCall<J>;
1902 def TAILCALL_R : TailCallReg<GPR32Opnd, JR>;
1904 // Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64
1905 // then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA.
1906 class PseudoIndirectBranchBase<RegisterOperand RO> :
1907 MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)],
1908 II_IndirectBranchPseudo> {
1911 let hasDelaySlot = 1;
1913 let isIndirectBranch = 1;
1917 def PseudoIndirectBranch : PseudoIndirectBranchBase<GPR32Opnd>;
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
1923 class PseudoReturnBase<RegisterOperand RO> : MipsPseudo<(outs), (ins RO:$rs),
1924 [], II_ReturnPseudo> {
1925 let isTerminator = 1;
1927 let hasDelaySlot = 1;
1929 let isCodeGenOnly = 1;
1931 let hasExtraSrcRegAllocReq = 1;
1935 def PseudoReturn : PseudoReturnBase<GPR32Opnd>;
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)
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.
1945 def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
1947 def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
1948 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
1950 let 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,
1955 [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
1958 /// Multiply and Divide Instructions.
1959 def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
1960 MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6;
1961 def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
1962 MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6;
1963 let 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;
1969 def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>,
1970 ISA_MIPS1_NOT_32R6_64R6;
1971 def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>,
1972 ISA_MIPS1_NOT_32R6_64R6;
1973 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1974 AdditionalPredicates = [NotInMicroMips] in {
1975 def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>,
1976 ISA_MIPS1_NOT_32R6_64R6;
1977 def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>,
1978 ISA_MIPS1_NOT_32R6_64R6;
1981 /// Sign Ext In Register Instructions.
1982 def SEB : MMRel, StdMMR6Rel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,
1983 SEB_FM<0x10, 0x20>, ISA_MIPS32R2;
1984 def SEH : MMRel, StdMMR6Rel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
1985 SEB_FM<0x18, 0x20>, ISA_MIPS32R2;
1988 def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd, II_CLZ>, CLO_FM<0x20>,
1989 ISA_MIPS32_NOT_32R6_64R6;
1990 def CLO : MMRel, CountLeading1<"clo", GPR32Opnd, II_CLO>, CLO_FM<0x21>,
1991 ISA_MIPS32_NOT_32R6_64R6;
1993 let AdditionalPredicates = [NotInMicroMips] in {
1994 /// Word Swap Bytes Within Halfwords
1995 def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd, II_WSBH>, SEB_FM<2, 0x20>,
2000 def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>;
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
2006 def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>;
2009 def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>,
2010 ISA_MIPS32_NOT_32R6_64R6;
2011 def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>,
2012 ISA_MIPS32_NOT_32R6_64R6;
2013 def MSUB : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>,
2014 ISA_MIPS32_NOT_32R6_64R6;
2015 def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>,
2016 ISA_MIPS32_NOT_32R6_64R6;
2018 let AdditionalPredicates = [NotDSP] in {
2019 def PseudoMULT : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>,
2020 ISA_MIPS1_NOT_32R6_64R6;
2021 def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>,
2022 ISA_MIPS1_NOT_32R6_64R6;
2023 def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>, ISA_MIPS1_NOT_32R6_64R6;
2024 def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>, ISA_MIPS1_NOT_32R6_64R6;
2025 def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>, ISA_MIPS1_NOT_32R6_64R6;
2026 def PseudoMADD : MAddSubPseudo<MADD, MipsMAdd, II_MADD>,
2027 ISA_MIPS32_NOT_32R6_64R6;
2028 def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>,
2029 ISA_MIPS32_NOT_32R6_64R6;
2030 def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>,
2031 ISA_MIPS32_NOT_32R6_64R6;
2032 def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>,
2033 ISA_MIPS32_NOT_32R6_64R6;
2036 let 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>,
2046 def INS : MMRel, StdMMR6Rel, InsBase<"ins", GPR32Opnd, uimm5,
2047 uimm5_inssize_plus1, MipsIns>,
2050 /// Move Control Registers From/To CPU Registers
2051 let AdditionalPredicates = [NotInMicroMips] in {
2052 def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd, II_MTC0>, MFC3OP_FM<0x10, 4>,
2054 def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd, II_MFC0>, MFC3OP_FM<0x10, 0>,
2057 def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd, II_MFC2>, MFC3OP_FM<0x12, 0>;
2058 def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd, II_MTC2>, MFC3OP_FM<0x12, 4>;
2060 class Barrier<string asmstr, InstrItinClass itin = NoItinerary> :
2061 InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2063 def SSNOP : MMRel, StdMMR6Rel, Barrier<"ssnop", II_SSNOP>, BARRIER_FM<1>;
2064 def EHB : MMRel, Barrier<"ehb", II_EHB>, BARRIER_FM<3>;
2067 def PAUSE : MMRel, StdMMR6Rel, Barrier<"pause", II_PAUSE>, BARRIER_FM<5>,
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.
2075 class 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 = [];
2082 class 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 = [];
2089 class JR_HB_DESC : InstSE<(outs), (ins), "", [], II_JR_HB, FrmJ>,
2090 JR_HB_DESC_BASE<"jr.hb", GPR32Opnd> {
2092 let isIndirectBranch=1;
2099 class JALR_HB_DESC : InstSE<(outs), (ins), "", [], II_JALR_HB, FrmJ>,
2100 JALR_HB_DESC_BASE<"jalr.hb", GPR32Opnd> {
2101 let isIndirectBranch=1;
2106 class JR_HB_ENC : JR_HB_FM<8>;
2107 class JALR_HB_ENC : JALR_HB_FM<9>;
2109 def JR_HB : JR_HB_DESC, JR_HB_ENC, ISA_MIPS32_NOT_32R6_64R6;
2110 def JALR_HB : JALR_HB_DESC, JALR_HB_ENC, ISA_MIPS32;
2112 class TLB<string asmstr, InstrItinClass itin = NoItinerary> :
2113 InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2114 let AdditionalPredicates = [NotInMicroMips] in {
2115 def TLBP : MMRel, TLB<"tlbp", II_TLBP>, COP0_TLB_FM<0x08>;
2116 def TLBR : MMRel, TLB<"tlbr", II_TLBR>, COP0_TLB_FM<0x01>;
2117 def TLBWI : MMRel, TLB<"tlbwi", II_TLBWI>, COP0_TLB_FM<0x02>;
2118 def TLBWR : MMRel, TLB<"tlbwr", II_TLBWR>, COP0_TLB_FM<0x06>;
2120 class 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,
2125 let DecoderMethod = "DecodeCacheOp";
2128 def CACHE : MMRel, CacheOp<"cache", mem, II_CACHE>, CACHEOP_FM<0b101111>,
2129 INSN_MIPS3_32_NOT_32R6_64R6;
2130 def PREF : MMRel, CacheOp<"pref", mem, II_PREF>, CACHEOP_FM<0b110011>,
2131 INSN_MIPS3_32_NOT_32R6_64R6;
2133 def ROL : MipsAsmPseudoInst<(outs),
2134 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2135 "rol\t$rs, $rt, $rd">;
2136 def ROLImm : MipsAsmPseudoInst<(outs),
2137 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2138 "rol\t$rs, $rt, $imm">;
2139 def : MipsInstAlias<"rol $rd, $rs",
2140 (ROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2141 def : MipsInstAlias<"rol $rd, $imm",
2142 (ROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2144 def ROR : MipsAsmPseudoInst<(outs),
2145 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2146 "ror\t$rs, $rt, $rd">;
2147 def RORImm : MipsAsmPseudoInst<(outs),
2148 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2149 "ror\t$rs, $rt, $imm">;
2150 def : MipsInstAlias<"ror $rd, $rs",
2151 (ROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2152 def : MipsInstAlias<"ror $rd, $imm",
2153 (RORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2155 def DROL : MipsAsmPseudoInst<(outs),
2156 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2157 "drol\t$rs, $rt, $rd">, ISA_MIPS64;
2158 def DROLImm : MipsAsmPseudoInst<(outs),
2159 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2160 "drol\t$rs, $rt, $imm">, ISA_MIPS64;
2161 def : MipsInstAlias<"drol $rd, $rs",
2162 (DROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
2163 def : MipsInstAlias<"drol $rd, $imm",
2164 (DROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
2166 def DROR : MipsAsmPseudoInst<(outs),
2167 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2168 "dror\t$rs, $rt, $rd">, ISA_MIPS64;
2169 def DRORImm : MipsAsmPseudoInst<(outs),
2170 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2171 "dror\t$rs, $rt, $imm">, ISA_MIPS64;
2172 def : MipsInstAlias<"dror $rd, $rs",
2173 (DROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
2174 def : MipsInstAlias<"dror $rd, $imm",
2175 (DRORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
2177 def ABSMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2180 //===----------------------------------------------------------------------===//
2181 // Instruction aliases
2182 //===----------------------------------------------------------------------===//
2183 def : MipsInstAlias<"move $dst, $src",
2184 (OR GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2186 let AdditionalPredicates = [NotInMicroMips];
2188 def : MipsInstAlias<"move $dst, $src",
2189 (ADDu GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2191 let AdditionalPredicates = [NotInMicroMips];
2193 def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>,
2194 ISA_MIPS1_NOT_32R6_64R6;
2195 def : MipsInstAlias<
2196 "addu $rs, $rt, $imm",
2197 (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>;
2198 def : MipsInstAlias<
2200 (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>;
2201 def : MipsInstAlias<
2202 "add $rs, $rt, $imm",
2203 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>,
2204 ISA_MIPS1_NOT_32R6_64R6;
2205 def : MipsInstAlias<
2207 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>,
2208 ISA_MIPS1_NOT_32R6_64R6;
2209 def : MipsInstAlias<
2210 "and $rs, $rt, $imm",
2211 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>;
2212 def : MipsInstAlias<
2214 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>;
2215 def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>;
2216 let Predicates = [NotInMicroMips] in {
2217 def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
2219 def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>, ISA_MIPS32;
2220 def : MipsInstAlias<"neg $rt, $rs",
2221 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
2222 def : MipsInstAlias<"negu $rt",
2223 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 0>;
2224 def : MipsInstAlias<"negu $rt, $rs",
2225 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
2226 def : MipsInstAlias<
2227 "slt $rs, $rt, $imm",
2228 (SLTi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>;
2229 def : MipsInstAlias<
2230 "sltu $rt, $rs, $imm",
2231 (SLTiu GPR32Opnd:$rt, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>;
2232 let AdditionalPredicates = [NotInMicroMips] in {
2233 def : MipsInstAlias<
2234 "and $rs, $rt, $imm",
2235 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>;
2236 def : MipsInstAlias<
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<
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<
2250 (ORi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>;
2251 def : MipsInstAlias<
2253 (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>;
2254 def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>;
2256 def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>;
2257 def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>;
2258 def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, COP2Opnd:$rd, 0), 0>;
2259 def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 COP2Opnd:$rd, GPR32Opnd:$rt, 0), 0>;
2260 let AdditionalPredicates = [NotInMicroMips] in {
2261 def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>;
2263 def : MipsInstAlias<"bnez $rs,$offset",
2264 (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
2265 def : MipsInstAlias<"bnezl $rs,$offset",
2266 (BNEL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
2267 def : MipsInstAlias<"beqz $rs,$offset",
2268 (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
2269 def : MipsInstAlias<"beqzl $rs,$offset",
2270 (BEQL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
2271 let AdditionalPredicates = [NotInMicroMips] in {
2272 def : MipsInstAlias<"syscall", (SYSCALL 0), 1>;
2275 def : MipsInstAlias<"break", (BREAK 0, 0), 1>;
2276 def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>;
2277 let AdditionalPredicates = [NotInMicroMips] in {
2278 def : MipsInstAlias<"ei", (EI ZERO), 1>, ISA_MIPS32R2;
2279 def : MipsInstAlias<"di", (DI ZERO), 1>, ISA_MIPS32R2;
2281 let 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;
2295 def : MipsInstAlias<"sub, $rd, $rs, $imm",
2296 (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs,
2297 InvertedImOperand:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6;
2298 def : MipsInstAlias<"sub $rs, $imm",
2299 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm),
2300 0>, ISA_MIPS1_NOT_32R6_64R6;
2301 def : MipsInstAlias<"subu, $rd, $rs, $imm",
2302 (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs,
2303 InvertedImOperand:$imm), 0>;
2304 def : MipsInstAlias<"subu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs,
2305 InvertedImOperand:$imm), 0>;
2306 let 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>;
2314 def : MipsInstAlias<"sdbbp", (SDBBP 0)>, ISA_MIPS32_NOT_32R6_64R6;
2315 def : MipsInstAlias<"sync",
2316 (SYNC 0), 1>, ISA_MIPS2;
2317 //===----------------------------------------------------------------------===//
2318 // Assembler Pseudo Instructions
2319 //===----------------------------------------------------------------------===//
2321 // We use i32imm on li/la to defer range checking to the assembler.
2322 class LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> :
2323 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2324 !strconcat(instr_asm, "\t$rt, $imm32")> ;
2325 def LoadImm32 : LoadImmediate32<"li", i32imm, GPR32Opnd>;
2327 class LoadAddressFromReg32<string instr_asm, Operand MemOpnd,
2328 RegisterOperand RO> :
2329 MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
2330 !strconcat(instr_asm, "\t$rt, $addr")> ;
2331 def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>;
2333 class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> :
2334 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2335 !strconcat(instr_asm, "\t$rt, $imm32")> ;
2336 def LoadAddrImm32 : LoadAddressFromImm32<"la", i32imm, GPR32Opnd>;
2338 def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2340 def JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs),
2343 def NORImm : MipsAsmPseudoInst<
2344 (outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm32:$imm),
2345 "nor\t$rs, $rt, $imm"> ;
2347 let hasDelaySlot = 1, isCTI = 1 in {
2348 def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2349 (ins imm64:$imm64, brtarget:$offset),
2350 "bne\t$rt, $imm64, $offset">;
2351 def BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2352 (ins imm64:$imm64, brtarget:$offset),
2353 "beq\t$rt, $imm64, $offset">;
2355 class CondBranchPseudo<string instr_asm> :
2356 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt,
2358 !strconcat(instr_asm, "\t$rs, $rt, $offset")>;
2361 def BLT : CondBranchPseudo<"blt">;
2362 def BLE : CondBranchPseudo<"ble">;
2363 def BGE : CondBranchPseudo<"bge">;
2364 def BGT : CondBranchPseudo<"bgt">;
2365 def BLTU : CondBranchPseudo<"bltu">;
2366 def BLEU : CondBranchPseudo<"bleu">;
2367 def BGEU : CondBranchPseudo<"bgeu">;
2368 def BGTU : CondBranchPseudo<"bgtu">;
2369 def BLTL : CondBranchPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2370 def BLEL : CondBranchPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2371 def BGEL : CondBranchPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2372 def BGTL : CondBranchPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2373 def BLTUL: CondBranchPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2374 def BLEUL: CondBranchPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2375 def BGEUL: CondBranchPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2376 def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
2379 class CondBranchImmPseudo<string instr_asm> :
2380 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, imm64:$imm, brtarget:$offset),
2381 !strconcat(instr_asm, "\t$rs, $imm, $offset")>;
2383 def BLTImmMacro : CondBranchImmPseudo<"blt">;
2384 def BLEImmMacro : CondBranchImmPseudo<"ble">;
2385 def BGEImmMacro : CondBranchImmPseudo<"bge">;
2386 def BGTImmMacro : CondBranchImmPseudo<"bgt">;
2387 def BLTUImmMacro : CondBranchImmPseudo<"bltu">;
2388 def BLEUImmMacro : CondBranchImmPseudo<"bleu">;
2389 def BGEUImmMacro : CondBranchImmPseudo<"bgeu">;
2390 def BGTUImmMacro : CondBranchImmPseudo<"bgtu">;
2391 def BLTLImmMacro : CondBranchImmPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2392 def BLELImmMacro : CondBranchImmPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2393 def BGELImmMacro : CondBranchImmPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2394 def BGTLImmMacro : CondBranchImmPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2395 def BLTULImmMacro : CondBranchImmPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2396 def BLEULImmMacro : CondBranchImmPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2397 def BGEULImmMacro : CondBranchImmPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2398 def BGTULImmMacro : CondBranchImmPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
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.
2406 def SDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2407 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2408 "div\t$rd, $rs, $rt">,
2409 ISA_MIPS1_NOT_32R6_64R6;
2410 def UDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2411 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2412 "divu\t$rd, $rs, $rt">,
2413 ISA_MIPS1_NOT_32R6_64R6;
2414 def : MipsInstAlias<"div $rt, $rs", (SDivMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
2416 ISA_MIPS1_NOT_32R6_64R6;
2417 def : MipsInstAlias<"divu $rt, $rs", (UDivMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
2419 ISA_MIPS1_NOT_32R6_64R6;
2420 def DSDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2421 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2422 "ddiv\t$rd, $rs, $rt">,
2423 ISA_MIPS64_NOT_64R6;
2424 def DUDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2425 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2426 "ddivu\t$rd, $rs, $rt">,
2427 ISA_MIPS64_NOT_64R6;
2428 def : MipsInstAlias<"ddiv $rt, $rs", (DSDivMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
2430 ISA_MIPS64_NOT_64R6;
2431 def : MipsInstAlias<"ddivu $rt, $rs", (DUDivMacro GPR32Opnd:$rt, GPR32Opnd:$rt,
2433 ISA_MIPS64_NOT_64R6;
2435 def Ulh : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2436 "ulh\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2438 def Ulhu : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2439 "ulhu\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2441 def Ulw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2442 "ulw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2444 //===----------------------------------------------------------------------===//
2445 // Arbitrary patterns that map to one or more instructions
2446 //===----------------------------------------------------------------------===//
2448 // Load/store pattern templates.
2449 class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
2450 MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
2452 class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
2453 MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
2456 let AdditionalPredicates = [NotInMicroMips] in {
2457 def : MipsPat<(i32 immSExt16:$in),
2458 (ADDiu ZERO, imm:$in)>;
2459 def : MipsPat<(i32 immZExt16:$in),
2460 (ORi ZERO, imm:$in)>;
2462 def : MipsPat<(i32 immLow16Zero:$in),
2463 (LUi (HI16 imm:$in))>;
2465 // Arbitrary immediates
2466 def : MipsPat<(i32 imm:$imm),
2467 (ORi (LUi (HI16 imm:$imm)), (LO16 imm:$imm))>;
2469 // Carry MipsPatterns
2470 let AdditionalPredicates = [NotInMicroMips] in {
2471 def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
2472 (SUBu GPR32:$lhs, GPR32:$rhs)>;
2474 def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
2475 (ADDu GPR32:$lhs, GPR32:$rhs)>, ASE_NOT_DSP;
2476 def : MipsPat<(addc GPR32:$src, immSExt16:$imm),
2477 (ADDiu GPR32:$src, imm:$imm)>, ASE_NOT_DSP;
2479 // Support multiplication for pre-Mips32 targets that don't have
2480 // the MUL instruction.
2481 def : MipsPat<(mul GPR32:$lhs, GPR32:$rhs),
2482 (PseudoMFLO (PseudoMULT GPR32:$lhs, GPR32:$rhs))>,
2483 ISA_MIPS1_NOT_32R6_64R6;
2486 def : MipsPat<(MipsSync (i32 immz)),
2487 (SYNC 0)>, ISA_MIPS2;
2490 def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
2491 (JAL texternalsym:$dst)>;
2492 //def : MipsPat<(MipsJmpLink GPR32:$dst),
2493 // (JALR GPR32:$dst)>;
2496 def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
2497 (TAILCALL tglobaladdr:$dst)>;
2498 def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
2499 (TAILCALL texternalsym:$dst)>;
2501 def : MipsPat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
2502 def : MipsPat<(MipsHi tblockaddress:$in), (LUi tblockaddress:$in)>;
2503 def : MipsPat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>;
2504 def : MipsPat<(MipsHi tconstpool:$in), (LUi tconstpool:$in)>;
2505 def : MipsPat<(MipsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>;
2506 def : MipsPat<(MipsHi texternalsym:$in), (LUi texternalsym:$in)>;
2508 def : MipsPat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
2509 def : MipsPat<(MipsLo tblockaddress:$in), (ADDiu ZERO, tblockaddress:$in)>;
2510 def : MipsPat<(MipsLo tjumptable:$in), (ADDiu ZERO, tjumptable:$in)>;
2511 def : MipsPat<(MipsLo tconstpool:$in), (ADDiu ZERO, tconstpool:$in)>;
2512 def : MipsPat<(MipsLo tglobaltlsaddr:$in), (ADDiu ZERO, tglobaltlsaddr:$in)>;
2513 def : MipsPat<(MipsLo texternalsym:$in), (ADDiu ZERO, texternalsym:$in)>;
2515 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaladdr:$lo)),
2516 (ADDiu GPR32:$hi, tglobaladdr:$lo)>;
2517 def : MipsPat<(add GPR32:$hi, (MipsLo tblockaddress:$lo)),
2518 (ADDiu GPR32:$hi, tblockaddress:$lo)>;
2519 def : MipsPat<(add GPR32:$hi, (MipsLo tjumptable:$lo)),
2520 (ADDiu GPR32:$hi, tjumptable:$lo)>;
2521 def : MipsPat<(add GPR32:$hi, (MipsLo tconstpool:$lo)),
2522 (ADDiu GPR32:$hi, tconstpool:$lo)>;
2523 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaltlsaddr:$lo)),
2524 (ADDiu GPR32:$hi, tglobaltlsaddr:$lo)>;
2527 def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
2528 (ADDiu GPR32:$gp, tglobaladdr:$in)>;
2529 def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
2530 (ADDiu GPR32:$gp, tconstpool:$in)>;
2533 class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
2534 MipsPat<(MipsWrapper RC:$gp, node:$in),
2535 (ADDiuOp RC:$gp, node:$in)>;
2537 def : WrapperPat<tglobaladdr, ADDiu, GPR32>;
2538 def : WrapperPat<tconstpool, ADDiu, GPR32>;
2539 def : WrapperPat<texternalsym, ADDiu, GPR32>;
2540 def : WrapperPat<tblockaddress, ADDiu, GPR32>;
2541 def : WrapperPat<tjumptable, ADDiu, GPR32>;
2542 def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>;
2544 let AdditionalPredicates = [NotInMicroMips] in {
2545 // Mips does not have "not", so we expand our way
2546 def : MipsPat<(not GPR32:$in),
2547 (NOR GPR32Opnd:$in, ZERO)>;
2551 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>;
2552 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>;
2553 let AdditionalPredicates = [NotInMicroMips] in {
2554 def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
2558 def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>;
2561 multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BNEOp,
2562 Instruction SLTOp, Instruction SLTuOp, Instruction SLTiOp,
2563 Instruction SLTiuOp, Register ZEROReg> {
2564 def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
2565 (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
2566 def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
2567 (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
2569 def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
2570 (BEQ (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
2571 def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
2572 (BEQ (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
2573 def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
2574 (BEQ (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
2575 def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
2576 (BEQ (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
2577 def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
2578 (BEQ (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
2579 def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
2580 (BEQ (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
2582 def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
2583 (BEQ (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
2584 def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
2585 (BEQ (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
2587 def : MipsPat<(brcond RC:$cond, bb:$dst),
2588 (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
2591 defm : BrcondPats<GPR32, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>;
2593 def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
2594 (BLEZ i32:$lhs, bb:$dst)>;
2595 def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
2596 (BGEZ i32:$lhs, bb:$dst)>;
2599 multiclass 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))>;
2611 multiclass 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)>;
2618 multiclass 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)>;
2625 multiclass 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)>;
2632 multiclass 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)>;
2640 defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>;
2641 defm : SetlePats<GPR32, SLT, SLTu>;
2642 defm : SetgtPats<GPR32, SLT, SLTu>;
2643 defm : SetgePats<GPR32, SLT, SLTu>;
2644 defm : SetgeImmPats<GPR32, SLTi, SLTiu>;
2647 def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>;
2649 // Load halfword/word patterns.
2650 let 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>;
2658 // Atomic load patterns.
2659 def : MipsPat<(atomic_load_8 addr:$a), (LB addr:$a)>;
2660 let AdditionalPredicates = [NotInMicroMips] in {
2661 def : MipsPat<(atomic_load_16 addr:$a), (LH addr:$a)>;
2663 def : MipsPat<(atomic_load_32 addr:$a), (LW addr:$a)>;
2665 // Atomic store patterns.
2666 def : MipsPat<(atomic_store_8 addr:$a, GPR32:$v), (SB GPR32:$v, addr:$a)>;
2667 def : MipsPat<(atomic_store_16 addr:$a, GPR32:$v), (SH GPR32:$v, addr:$a)>;
2668 def : MipsPat<(atomic_store_32 addr:$a, GPR32:$v), (SW GPR32:$v, addr:$a)>;
2670 //===----------------------------------------------------------------------===//
2671 // Floating Point Support
2672 //===----------------------------------------------------------------------===//
2674 include "MipsInstrFPU.td"
2675 include "Mips64InstrInfo.td"
2676 include "MipsCondMov.td"
2678 include "Mips32r6InstrInfo.td"
2679 include "Mips64r6InstrInfo.td"
2684 include "Mips16InstrFormats.td"
2685 include "Mips16InstrInfo.td"
2688 include "MipsDSPInstrFormats.td"
2689 include "MipsDSPInstrInfo.td"
2692 include "MipsMSAInstrFormats.td"
2693 include "MipsMSAInstrInfo.td"
2696 include "MipsEVAInstrFormats.td"
2697 include "MipsEVAInstrInfo.td"
2700 include "MicroMipsInstrFormats.td"
2701 include "MicroMipsInstrInfo.td"
2702 include "MicroMipsInstrFPU.td"
2705 include "MicroMips32r6InstrFormats.td"
2706 include "MicroMips32r6InstrInfo.td"
2709 include "MicroMips64r6InstrFormats.td"
2710 include "MicroMips64r6InstrInfo.td"
2713 include "MicroMipsDSPInstrFormats.td"
2714 include "MicroMipsDSPInstrInfo.td"