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>, SDTCisVT<1, 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)
63 // Hi is the odd node out, on MIPS64 it can expand to either daddiu when
64 // using static relocations with 64 bit symbols, or lui when using 32 bit
66 def MipsHigher : SDNode<"MipsISD::Higher", SDTIntUnaryOp>;
67 def MipsHighest : SDNode<"MipsISD::Highest", SDTIntUnaryOp>;
68 def MipsHi : SDNode<"MipsISD::Hi", SDTIntUnaryOp>;
69 def MipsLo : SDNode<"MipsISD::Lo", SDTIntUnaryOp>;
71 def MipsGPRel : SDNode<"MipsISD::GPRel", SDTIntUnaryOp>;
73 // Hi node for accessing the GOT.
74 def MipsGotHi : SDNode<"MipsISD::GotHi", SDTIntUnaryOp>;
76 // TlsGd node is used to handle General Dynamic TLS
77 def MipsTlsGd : SDNode<"MipsISD::TlsGd", SDTIntUnaryOp>;
79 // TprelHi and TprelLo nodes are used to handle Local Exec TLS
80 def MipsTprelHi : SDNode<"MipsISD::TprelHi", SDTIntUnaryOp>;
81 def MipsTprelLo : SDNode<"MipsISD::TprelLo", SDTIntUnaryOp>;
84 def MipsThreadPointer: SDNode<"MipsISD::ThreadPointer", SDT_MipsThreadPointer>;
87 def MipsRet : SDNode<"MipsISD::Ret", SDTNone,
88 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
90 def MipsERet : SDNode<"MipsISD::ERet", SDTNone,
91 [SDNPHasChain, SDNPOptInGlue, SDNPSideEffect]>;
93 // These are target-independent nodes, but have target-specific formats.
94 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MipsCallSeqStart,
95 [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>;
96 def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeqEnd,
97 [SDNPHasChain, SDNPSideEffect,
98 SDNPOptInGlue, SDNPOutGlue]>;
100 // Nodes used to extract LO/HI registers.
101 def MipsMFHI : SDNode<"MipsISD::MFHI", SDT_MFLOHI>;
102 def MipsMFLO : SDNode<"MipsISD::MFLO", SDT_MFLOHI>;
104 // Node used to insert 32-bit integers to LOHI register pair.
105 def MipsMTLOHI : SDNode<"MipsISD::MTLOHI", SDT_MTLOHI>;
108 def MipsMult : SDNode<"MipsISD::Mult", SDT_MipsMultDiv>;
109 def MipsMultu : SDNode<"MipsISD::Multu", SDT_MipsMultDiv>;
112 def MipsMAdd : SDNode<"MipsISD::MAdd", SDT_MipsMAddMSub>;
113 def MipsMAddu : SDNode<"MipsISD::MAddu", SDT_MipsMAddMSub>;
114 def MipsMSub : SDNode<"MipsISD::MSub", SDT_MipsMAddMSub>;
115 def MipsMSubu : SDNode<"MipsISD::MSubu", SDT_MipsMAddMSub>;
118 def MipsDivRem : SDNode<"MipsISD::DivRem", SDT_MipsMultDiv>;
119 def MipsDivRemU : SDNode<"MipsISD::DivRemU", SDT_MipsMultDiv>;
120 def MipsDivRem16 : SDNode<"MipsISD::DivRem16", SDT_MipsDivRem16,
122 def MipsDivRemU16 : SDNode<"MipsISD::DivRemU16", SDT_MipsDivRem16,
125 // Target constant nodes that are not part of any isel patterns and remain
126 // unchanged can cause instructions with illegal operands to be emitted.
127 // Wrapper node patterns give the instruction selector a chance to replace
128 // target constant nodes that would otherwise remain unchanged with ADDiu
129 // nodes. Without these wrapper node patterns, the following conditional move
130 // instruction is emitted when function cmov2 in test/CodeGen/Mips/cmov.ll is
132 // movn %got(d)($gp), %got(c)($gp), $4
133 // This instruction is illegal since movn can take only register operands.
135 def MipsWrapper : SDNode<"MipsISD::Wrapper", SDTIntBinOp>;
137 def MipsSync : SDNode<"MipsISD::Sync", SDT_Sync, [SDNPHasChain,SDNPSideEffect]>;
139 def MipsExt : SDNode<"MipsISD::Ext", SDT_Ext>;
140 def MipsIns : SDNode<"MipsISD::Ins", SDT_Ins>;
141 def MipsCIns : SDNode<"MipsISD::CIns", SDT_Ext>;
143 def MipsLWL : SDNode<"MipsISD::LWL", SDTMipsLoadLR,
144 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
145 def MipsLWR : SDNode<"MipsISD::LWR", SDTMipsLoadLR,
146 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
147 def MipsSWL : SDNode<"MipsISD::SWL", SDTStore,
148 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
149 def MipsSWR : SDNode<"MipsISD::SWR", SDTStore,
150 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
151 def MipsLDL : SDNode<"MipsISD::LDL", SDTMipsLoadLR,
152 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
153 def MipsLDR : SDNode<"MipsISD::LDR", SDTMipsLoadLR,
154 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
155 def MipsSDL : SDNode<"MipsISD::SDL", SDTStore,
156 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
157 def MipsSDR : SDNode<"MipsISD::SDR", SDTStore,
158 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
160 //===----------------------------------------------------------------------===//
161 // Mips Instruction Predicate Definitions.
162 //===----------------------------------------------------------------------===//
163 def HasMips2 : Predicate<"Subtarget->hasMips2()">,
164 AssemblerPredicate<"FeatureMips2">;
165 def HasMips3_32 : Predicate<"Subtarget->hasMips3_32()">,
166 AssemblerPredicate<"FeatureMips3_32">;
167 def HasMips3_32r2 : Predicate<"Subtarget->hasMips3_32r2()">,
168 AssemblerPredicate<"FeatureMips3_32r2">;
169 def HasMips3 : Predicate<"Subtarget->hasMips3()">,
170 AssemblerPredicate<"FeatureMips3">;
171 def NotMips3 : Predicate<"!Subtarget->hasMips3()">,
172 AssemblerPredicate<"!FeatureMips3">;
173 def HasMips4_32 : Predicate<"Subtarget->hasMips4_32()">,
174 AssemblerPredicate<"FeatureMips4_32">;
175 def NotMips4_32 : Predicate<"!Subtarget->hasMips4_32()">,
176 AssemblerPredicate<"!FeatureMips4_32">;
177 def HasMips4_32r2 : Predicate<"Subtarget->hasMips4_32r2()">,
178 AssemblerPredicate<"FeatureMips4_32r2">;
179 def HasMips5_32r2 : Predicate<"Subtarget->hasMips5_32r2()">,
180 AssemblerPredicate<"FeatureMips5_32r2">;
181 def HasMips32 : Predicate<"Subtarget->hasMips32()">,
182 AssemblerPredicate<"FeatureMips32">;
183 def HasMips32r2 : Predicate<"Subtarget->hasMips32r2()">,
184 AssemblerPredicate<"FeatureMips32r2">;
185 def HasMips32r5 : Predicate<"Subtarget->hasMips32r5()">,
186 AssemblerPredicate<"FeatureMips32r5">;
187 def HasMips32r6 : Predicate<"Subtarget->hasMips32r6()">,
188 AssemblerPredicate<"FeatureMips32r6">;
189 def NotMips32r6 : Predicate<"!Subtarget->hasMips32r6()">,
190 AssemblerPredicate<"!FeatureMips32r6">;
191 def IsGP64bit : Predicate<"Subtarget->isGP64bit()">,
192 AssemblerPredicate<"FeatureGP64Bit">;
193 def IsGP32bit : Predicate<"!Subtarget->isGP64bit()">,
194 AssemblerPredicate<"!FeatureGP64Bit">;
195 def IsPTR64bit : Predicate<"Subtarget->isABI_N64()">,
196 AssemblerPredicate<"FeaturePTR64Bit">;
197 def IsPTR32bit : Predicate<"!Subtarget->isABI_N64()">,
198 AssemblerPredicate<"!FeaturePTR64Bit">;
199 def HasMips64 : Predicate<"Subtarget->hasMips64()">,
200 AssemblerPredicate<"FeatureMips64">;
201 def NotMips64 : Predicate<"!Subtarget->hasMips64()">,
202 AssemblerPredicate<"!FeatureMips64">;
203 def HasMips64r2 : Predicate<"Subtarget->hasMips64r2()">,
204 AssemblerPredicate<"FeatureMips64r2">;
205 def HasMips64r6 : Predicate<"Subtarget->hasMips64r6()">,
206 AssemblerPredicate<"FeatureMips64r6">;
207 def NotMips64r6 : Predicate<"!Subtarget->hasMips64r6()">,
208 AssemblerPredicate<"!FeatureMips64r6">;
209 def HasMicroMips32r6 : Predicate<"Subtarget->inMicroMips32r6Mode()">,
210 AssemblerPredicate<"FeatureMicroMips,FeatureMips32r6">;
211 def HasMicroMips64r6 : Predicate<"Subtarget->inMicroMips64r6Mode()">,
212 AssemblerPredicate<"FeatureMicroMips,FeatureMips64r6">;
213 def InMips16Mode : Predicate<"Subtarget->inMips16Mode()">,
214 AssemblerPredicate<"FeatureMips16">;
215 def HasCnMips : Predicate<"Subtarget->hasCnMips()">,
216 AssemblerPredicate<"FeatureCnMips">;
217 def NotCnMips : Predicate<"!Subtarget->hasCnMips()">,
218 AssemblerPredicate<"!FeatureCnMips">;
219 def IsSym32 : Predicate<"Subtarget->HasSym32()">,
220 AssemblerPredicate<"FeatureSym32">;
221 def IsSym64 : Predicate<"!Subtarget->HasSym32()">,
222 AssemblerPredicate<"!FeatureSym32">;
223 def RelocNotPIC : Predicate<"!TM.isPositionIndependent()">;
224 def RelocPIC : Predicate<"TM.isPositionIndependent()">;
225 def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">;
226 def HasStdEnc : Predicate<"Subtarget->hasStandardEncoding()">,
227 AssemblerPredicate<"!FeatureMips16">;
228 def NotDSP : Predicate<"!Subtarget->hasDSP()">;
229 def InMicroMips : Predicate<"Subtarget->inMicroMipsMode()">,
230 AssemblerPredicate<"FeatureMicroMips">;
231 def NotInMicroMips : Predicate<"!Subtarget->inMicroMipsMode()">,
232 AssemblerPredicate<"!FeatureMicroMips">;
233 def IsLE : Predicate<"Subtarget->isLittle()">;
234 def IsBE : Predicate<"!Subtarget->isLittle()">;
235 def IsNotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
236 def UseTCCInDIV : AssemblerPredicate<"FeatureUseTCCInDIV">;
237 def HasEVA : Predicate<"Subtarget->hasEVA()">,
238 AssemblerPredicate<"FeatureEVA,FeatureMips32r2">;
239 def HasMSA : Predicate<"Subtarget->hasMSA()">,
240 AssemblerPredicate<"FeatureMSA">;
241 def HasMadd4 : Predicate<"!Subtarget->disableMadd4()">,
242 AssemblerPredicate<"!FeatureMadd4">;
243 def HasMT : Predicate<"Subtarget->hasMT()">,
244 AssemblerPredicate<"FeatureMT">;
246 //===----------------------------------------------------------------------===//
247 // Mips GPR size adjectives.
248 // They are mutually exclusive.
249 //===----------------------------------------------------------------------===//
251 class GPR_32 { list<Predicate> GPRPredicates = [IsGP32bit]; }
252 class GPR_64 { list<Predicate> GPRPredicates = [IsGP64bit]; }
254 class PTR_32 { list<Predicate> PTRPredicates = [IsPTR32bit]; }
255 class PTR_64 { list<Predicate> PTRPredicates = [IsPTR64bit]; }
257 //===----------------------------------------------------------------------===//
258 // Mips Symbol size adjectives.
259 // They are mutally exculsive.
260 //===----------------------------------------------------------------------===//
262 class SYM_32 { list<Predicate> SYMPredicates = [IsSym32]; }
263 class SYM_64 { list<Predicate> SYMPredicates = [IsSym64]; }
265 //===----------------------------------------------------------------------===//
266 // Mips ISA/ASE membership and instruction group membership adjectives.
267 // They are mutually exclusive.
268 //===----------------------------------------------------------------------===//
270 // FIXME: I'd prefer to use additive predicates to build the instruction sets
271 // but we are short on assembler feature bits at the moment. Using a
272 // subtractive predicate will hopefully keep us under the 32 predicate
273 // limit long enough to develop an alternative way to handle P1||P2
275 class ISA_MIPS1_NOT_MIPS3 {
276 list<Predicate> InsnPredicates = [NotMips3];
278 class ISA_MIPS1_NOT_4_32 {
279 list<Predicate> InsnPredicates = [NotMips4_32];
281 class ISA_MIPS1_NOT_32R6_64R6 {
282 list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6];
284 class ISA_MIPS2 { list<Predicate> InsnPredicates = [HasMips2]; }
285 class ISA_MIPS2_NOT_32R6_64R6 {
286 list<Predicate> InsnPredicates = [HasMips2, NotMips32r6, NotMips64r6];
288 class ISA_MIPS3 { list<Predicate> InsnPredicates = [HasMips3]; }
289 class ISA_MIPS3_NOT_32R6_64R6 {
290 list<Predicate> InsnPredicates = [HasMips3, NotMips32r6, NotMips64r6];
292 class ISA_MIPS32 { list<Predicate> InsnPredicates = [HasMips32]; }
293 class ISA_MIPS32_NOT_32R6_64R6 {
294 list<Predicate> InsnPredicates = [HasMips32, NotMips32r6, NotMips64r6];
296 class ISA_MIPS32R2 { list<Predicate> InsnPredicates = [HasMips32r2]; }
297 class ISA_MIPS32R2_NOT_32R6_64R6 {
298 list<Predicate> InsnPredicates = [HasMips32r2, NotMips32r6, NotMips64r6];
300 class ISA_MIPS32R5 { list<Predicate> InsnPredicates = [HasMips32r5]; }
301 class ISA_MIPS64 { list<Predicate> InsnPredicates = [HasMips64]; }
302 class ISA_MIPS64_NOT_64R6 {
303 list<Predicate> InsnPredicates = [HasMips64, NotMips64r6];
305 class ISA_MIPS64R2 { list<Predicate> InsnPredicates = [HasMips64r2]; }
306 class ISA_MIPS32R6 { list<Predicate> InsnPredicates = [HasMips32r6]; }
307 class ISA_MIPS64R6 { list<Predicate> InsnPredicates = [HasMips64r6]; }
308 class ISA_MICROMIPS { list<Predicate> InsnPredicates = [InMicroMips]; }
309 class ISA_MICROMIPS32R6 {
310 list<Predicate> InsnPredicates = [HasMicroMips32r6];
312 class ISA_MICROMIPS64R6 {
313 list<Predicate> InsnPredicates = [HasMicroMips64r6];
315 class ISA_MICROMIPS32_NOT_MIPS32R6 {
316 list<Predicate> InsnPredicates = [InMicroMips, NotMips32r6];
319 class INSN_EVA { list<Predicate> InsnPredicates = [HasEVA]; }
320 class INSN_EVA_NOT_32R6_64R6 {
321 list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6, HasEVA];
324 // The portions of MIPS-III that were also added to MIPS32
325 class INSN_MIPS3_32 { list<Predicate> InsnPredicates = [HasMips3_32]; }
327 // The portions of MIPS-III that were also added to MIPS32 but were removed in
328 // MIPS32r6 and MIPS64r6.
329 class INSN_MIPS3_32_NOT_32R6_64R6 {
330 list<Predicate> InsnPredicates = [HasMips3_32, NotMips32r6, NotMips64r6];
333 // The portions of MIPS-III that were also added to MIPS32
334 class INSN_MIPS3_32R2 { list<Predicate> InsnPredicates = [HasMips3_32r2]; }
336 // The portions of MIPS-IV that were also added to MIPS32.
337 class INSN_MIPS4_32 { list <Predicate> InsnPredicates = [HasMips4_32]; }
339 // The portions of MIPS-IV that were also added to MIPS32 but were removed in
340 // MIPS32r6 and MIPS64r6.
341 class INSN_MIPS4_32_NOT_32R6_64R6 {
342 list<Predicate> InsnPredicates = [HasMips4_32, NotMips32r6, NotMips64r6];
345 // The portions of MIPS-IV that were also added to MIPS32r2 but were removed in
346 // MIPS32r6 and MIPS64r6.
347 class INSN_MIPS4_32R2_NOT_32R6_64R6 {
348 list<Predicate> InsnPredicates = [HasMips4_32r2, NotMips32r6, NotMips64r6];
351 // The portions of MIPS-IV that were also added to MIPS32r2.
352 class INSN_MIPS4_32R2 {
353 list<Predicate> InsnPredicates = [HasMips4_32r2];
356 // The portions of MIPS-V that were also added to MIPS32r2 but were removed in
357 // MIPS32r6 and MIPS64r6.
358 class INSN_MIPS5_32R2_NOT_32R6_64R6 {
359 list<Predicate> InsnPredicates = [HasMips5_32r2, NotMips32r6, NotMips64r6];
363 list<Predicate> InsnPredicates = [HasCnMips];
366 class NOT_ASE_CNMIPS {
367 list<Predicate> InsnPredicates = [NotCnMips];
370 class ASE_MIPS64_CNMIPS {
371 list<Predicate> InsnPredicates = [HasMips64, HasCnMips];
375 list<Predicate> InsnPredicates = [HasMSA];
378 class ASE_MSA_NOT_MSA64 {
379 list<Predicate> InsnPredicates = [HasMSA, NotMips64];
383 list<Predicate> InsnPredicates = [HasMSA, HasMips64];
387 list <Predicate> InsnPredicates = [HasMT];
390 // Class used for separating microMIPSr6 and microMIPS (r3) instruction.
391 // It can be used only on instructions that doesn't inherit PredicateControl.
392 class ISA_MICROMIPS_NOT_32R6_64R6 : PredicateControl {
393 let InsnPredicates = [InMicroMips, NotMips32r6, NotMips64r6];
397 list<Predicate> InsnPredicates = [NotDSP];
401 list<Predicate> AdditionalPredicates = [HasMadd4];
404 //===----------------------------------------------------------------------===//
406 class MipsPat<dag pattern, dag result> : Pat<pattern, result>, PredicateControl {
407 let EncodingPredicates = [HasStdEnc];
410 class MipsInstAlias<string Asm, dag Result, bit Emit = 0b1> :
411 InstAlias<Asm, Result, Emit>, PredicateControl;
414 bit isCommutable = 1;
434 bit isTerminator = 1;
437 bit hasExtraSrcRegAllocReq = 1;
438 bit isCodeGenOnly = 1;
442 class IsAsCheapAsAMove {
443 bit isAsCheapAsAMove = 1;
446 class NeverHasSideEffects {
447 bit hasSideEffects = 0;
450 //===----------------------------------------------------------------------===//
451 // Instruction format superclass
452 //===----------------------------------------------------------------------===//
454 include "MipsInstrFormats.td"
456 //===----------------------------------------------------------------------===//
457 // Mips Operand, Complex Patterns and Transformations Definitions.
458 //===----------------------------------------------------------------------===//
460 class ConstantSImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
461 int Offset = 0> : AsmOperandClass {
462 let Name = "ConstantSImm" # Bits # "_" # Offset;
463 let RenderMethod = "addConstantSImmOperands<" # Bits # ", " # Offset # ">";
464 let PredicateMethod = "isConstantSImm<" # Bits # ", " # Offset # ">";
465 let SuperClasses = Supers;
466 let DiagnosticType = "SImm" # Bits # "_" # Offset;
469 class SimmLslAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
470 int Shift = 0> : AsmOperandClass {
471 let Name = "Simm" # Bits # "_Lsl" # Shift;
472 let RenderMethod = "addImmOperands";
473 let PredicateMethod = "isScaledSImm<" # Bits # ", " # Shift # ">";
474 let SuperClasses = Supers;
475 let DiagnosticType = "SImm" # Bits # "_Lsl" # Shift;
478 class ConstantUImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
479 int Offset = 0> : AsmOperandClass {
480 let Name = "ConstantUImm" # Bits # "_" # Offset;
481 let RenderMethod = "addConstantUImmOperands<" # Bits # ", " # Offset # ">";
482 let PredicateMethod = "isConstantUImm<" # Bits # ", " # Offset # ">";
483 let SuperClasses = Supers;
484 let DiagnosticType = "UImm" # Bits # "_" # Offset;
487 class ConstantUImmRangeAsmOperandClass<int Bottom, int Top,
488 list<AsmOperandClass> Supers = []>
490 let Name = "ConstantUImmRange" # Bottom # "_" # Top;
491 let RenderMethod = "addImmOperands";
492 let PredicateMethod = "isConstantUImmRange<" # Bottom # ", " # Top # ">";
493 let SuperClasses = Supers;
494 let DiagnosticType = "UImmRange" # Bottom # "_" # Top;
497 class SImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
499 let Name = "SImm" # Bits;
500 let RenderMethod = "addSImmOperands<" # Bits # ">";
501 let PredicateMethod = "isSImm<" # Bits # ">";
502 let SuperClasses = Supers;
503 let DiagnosticType = "SImm" # Bits;
506 class UImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
508 let Name = "UImm" # Bits;
509 let RenderMethod = "addUImmOperands<" # Bits # ">";
510 let PredicateMethod = "isUImm<" # Bits # ">";
511 let SuperClasses = Supers;
512 let DiagnosticType = "UImm" # Bits;
515 // Generic case - only to support certain assembly pseudo instructions.
516 class UImmAnyAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
519 let RenderMethod = "addConstantUImmOperands<32>";
520 let PredicateMethod = "isSImm<" # Bits # ">";
521 let SuperClasses = Supers;
522 let DiagnosticType = "ImmAny";
525 // AsmOperandClasses require a strict ordering which is difficult to manage
526 // as a hierarchy. Instead, we use a linear ordering and impose an order that
527 // is in some places arbitrary.
529 // Here the rules that are in use:
530 // * Wider immediates are a superset of narrower immediates:
531 // uimm4 < uimm5 < uimm6
532 // * For the same bit-width, unsigned immediates are a superset of signed
534 // simm4 < uimm4 < simm5 < uimm5
535 // * For the same upper-bound, signed immediates are a superset of unsigned
537 // uimm3 < simm4 < uimm4 < simm4
538 // * Modified immediates are a superset of ordinary immediates:
539 // uimm5 < uimm5_plus1 (1..32) < uimm5_plus32 (32..63) < uimm6
540 // The term 'superset' starts to break down here since the uimm5_plus* classes
541 // are not true supersets of uimm5 (but they are still subsets of uimm6).
542 // * 'Relaxed' immediates are supersets of the corresponding unsigned immediate.
543 // uimm16 < uimm16_relaxed
544 // * The codeGen pattern type is arbitrarily ordered.
545 // uimm5 < uimm5_64, and uimm5 < vsplat_uimm5
546 // This is entirely arbitrary. We need an ordering and what we pick is
547 // unimportant since only one is possible for a given mnemonic.
549 def UImm32CoercedAsmOperandClass : UImmAnyAsmOperandClass<33, []> {
550 let Name = "UImm32_Coerced";
551 let DiagnosticType = "UImm32_Coerced";
553 def SImm32RelaxedAsmOperandClass
554 : SImmAsmOperandClass<32, [UImm32CoercedAsmOperandClass]> {
555 let Name = "SImm32_Relaxed";
556 let PredicateMethod = "isAnyImm<33>";
557 let DiagnosticType = "SImm32_Relaxed";
559 def SImm32AsmOperandClass
560 : SImmAsmOperandClass<32, [SImm32RelaxedAsmOperandClass]>;
561 def ConstantUImm26AsmOperandClass
562 : ConstantUImmAsmOperandClass<26, [SImm32AsmOperandClass]>;
563 def ConstantUImm20AsmOperandClass
564 : ConstantUImmAsmOperandClass<20, [ConstantUImm26AsmOperandClass]>;
565 def ConstantSImm19Lsl2AsmOperandClass : AsmOperandClass {
566 let Name = "SImm19Lsl2";
567 let RenderMethod = "addImmOperands";
568 let PredicateMethod = "isScaledSImm<19, 2>";
569 let SuperClasses = [ConstantUImm20AsmOperandClass];
570 let DiagnosticType = "SImm19_Lsl2";
572 def UImm16RelaxedAsmOperandClass
573 : UImmAsmOperandClass<16, [ConstantUImm20AsmOperandClass]> {
574 let Name = "UImm16_Relaxed";
575 let PredicateMethod = "isAnyImm<16>";
576 let DiagnosticType = "UImm16_Relaxed";
578 // Similar to the relaxed classes which take an SImm and render it as
579 // an UImm, this takes a UImm and renders it as an SImm.
580 def UImm16AltRelaxedAsmOperandClass
581 : SImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]> {
582 let Name = "UImm16_AltRelaxed";
583 let PredicateMethod = "isUImm<16>";
584 let DiagnosticType = "UImm16_AltRelaxed";
586 // FIXME: One of these should probably have UImm16AsmOperandClass as the
587 // superclass instead of UImm16RelaxedasmOPerandClass.
588 def UImm16AsmOperandClass
589 : UImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]>;
590 def SImm16RelaxedAsmOperandClass
591 : SImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]> {
592 let Name = "SImm16_Relaxed";
593 let PredicateMethod = "isAnyImm<16>";
594 let DiagnosticType = "SImm16_Relaxed";
596 def SImm16AsmOperandClass
597 : SImmAsmOperandClass<16, [SImm16RelaxedAsmOperandClass]>;
598 def ConstantSImm10Lsl3AsmOperandClass : AsmOperandClass {
599 let Name = "SImm10Lsl3";
600 let RenderMethod = "addImmOperands";
601 let PredicateMethod = "isScaledSImm<10, 3>";
602 let SuperClasses = [SImm16AsmOperandClass];
603 let DiagnosticType = "SImm10_Lsl3";
605 def ConstantSImm10Lsl2AsmOperandClass : AsmOperandClass {
606 let Name = "SImm10Lsl2";
607 let RenderMethod = "addImmOperands";
608 let PredicateMethod = "isScaledSImm<10, 2>";
609 let SuperClasses = [ConstantSImm10Lsl3AsmOperandClass];
610 let DiagnosticType = "SImm10_Lsl2";
612 def ConstantSImm11AsmOperandClass
613 : ConstantSImmAsmOperandClass<11, [ConstantSImm10Lsl2AsmOperandClass]>;
614 def ConstantSImm10Lsl1AsmOperandClass : AsmOperandClass {
615 let Name = "SImm10Lsl1";
616 let RenderMethod = "addImmOperands";
617 let PredicateMethod = "isScaledSImm<10, 1>";
618 let SuperClasses = [ConstantSImm11AsmOperandClass];
619 let DiagnosticType = "SImm10_Lsl1";
621 def ConstantUImm10AsmOperandClass
622 : ConstantUImmAsmOperandClass<10, [ConstantSImm10Lsl1AsmOperandClass]>;
623 def ConstantSImm10AsmOperandClass
624 : ConstantSImmAsmOperandClass<10, [ConstantUImm10AsmOperandClass]>;
625 def ConstantSImm9AsmOperandClass
626 : ConstantSImmAsmOperandClass<9, [ConstantSImm10AsmOperandClass]>;
627 def ConstantSImm7Lsl2AsmOperandClass : AsmOperandClass {
628 let Name = "SImm7Lsl2";
629 let RenderMethod = "addImmOperands";
630 let PredicateMethod = "isScaledSImm<7, 2>";
631 let SuperClasses = [ConstantSImm9AsmOperandClass];
632 let DiagnosticType = "SImm7_Lsl2";
634 def ConstantUImm8AsmOperandClass
635 : ConstantUImmAsmOperandClass<8, [ConstantSImm7Lsl2AsmOperandClass]>;
636 def ConstantUImm7Sub1AsmOperandClass
637 : ConstantUImmAsmOperandClass<7, [ConstantUImm8AsmOperandClass], -1> {
638 // Specify the names since the -1 offset causes invalid identifiers otherwise.
639 let Name = "UImm7_N1";
640 let DiagnosticType = "UImm7_N1";
642 def ConstantUImm7AsmOperandClass
643 : ConstantUImmAsmOperandClass<7, [ConstantUImm7Sub1AsmOperandClass]>;
644 def ConstantUImm6Lsl2AsmOperandClass : AsmOperandClass {
645 let Name = "UImm6Lsl2";
646 let RenderMethod = "addImmOperands";
647 let PredicateMethod = "isScaledUImm<6, 2>";
648 let SuperClasses = [ConstantUImm7AsmOperandClass];
649 let DiagnosticType = "UImm6_Lsl2";
651 def ConstantUImm6AsmOperandClass
652 : ConstantUImmAsmOperandClass<6, [ConstantUImm6Lsl2AsmOperandClass]>;
653 def ConstantSImm6AsmOperandClass
654 : ConstantSImmAsmOperandClass<6, [ConstantUImm6AsmOperandClass]>;
655 def ConstantUImm5Lsl2AsmOperandClass : AsmOperandClass {
656 let Name = "UImm5Lsl2";
657 let RenderMethod = "addImmOperands";
658 let PredicateMethod = "isScaledUImm<5, 2>";
659 let SuperClasses = [ConstantSImm6AsmOperandClass];
660 let DiagnosticType = "UImm5_Lsl2";
662 def ConstantUImm5_Range2_64AsmOperandClass
663 : ConstantUImmRangeAsmOperandClass<2, 64, [ConstantUImm5Lsl2AsmOperandClass]>;
664 def ConstantUImm5Plus33AsmOperandClass
665 : ConstantUImmAsmOperandClass<5, [ConstantUImm5_Range2_64AsmOperandClass],
667 def ConstantUImm5ReportUImm6AsmOperandClass
668 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus33AsmOperandClass]> {
669 let Name = "ConstantUImm5_0_Report_UImm6";
670 let DiagnosticType = "UImm5_0_Report_UImm6";
672 def ConstantUImm5Plus32AsmOperandClass
673 : ConstantUImmAsmOperandClass<
674 5, [ConstantUImm5ReportUImm6AsmOperandClass], 32>;
675 def ConstantUImm5Plus32NormalizeAsmOperandClass
676 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus32AsmOperandClass], 32> {
677 let Name = "ConstantUImm5_32_Norm";
678 // We must also subtract 32 when we render the operand.
679 let RenderMethod = "addConstantUImmOperands<5, 32, -32>";
681 def ConstantUImm5Plus1AsmOperandClass
682 : ConstantUImmAsmOperandClass<
683 5, [ConstantUImm5Plus32NormalizeAsmOperandClass], 1>;
684 def ConstantUImm5AsmOperandClass
685 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus1AsmOperandClass]>;
686 def ConstantSImm5AsmOperandClass
687 : ConstantSImmAsmOperandClass<5, [ConstantUImm5AsmOperandClass]>;
688 def ConstantUImm4AsmOperandClass
689 : ConstantUImmAsmOperandClass<4, [ConstantSImm5AsmOperandClass]>;
690 def ConstantSImm4AsmOperandClass
691 : ConstantSImmAsmOperandClass<4, [ConstantUImm4AsmOperandClass]>;
692 def ConstantUImm3AsmOperandClass
693 : ConstantUImmAsmOperandClass<3, [ConstantSImm4AsmOperandClass]>;
694 def ConstantUImm2Plus1AsmOperandClass
695 : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass], 1>;
696 def ConstantUImm2AsmOperandClass
697 : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass]>;
698 def ConstantUImm1AsmOperandClass
699 : ConstantUImmAsmOperandClass<1, [ConstantUImm2AsmOperandClass]>;
700 def ConstantImmzAsmOperandClass : AsmOperandClass {
701 let Name = "ConstantImmz";
702 let RenderMethod = "addConstantUImmOperands<1>";
703 let PredicateMethod = "isConstantImmz";
704 let SuperClasses = [ConstantUImm1AsmOperandClass];
705 let DiagnosticType = "Immz";
708 def Simm19Lsl2AsmOperand
709 : SimmLslAsmOperandClass<19, [], 2>;
711 def MipsJumpTargetAsmOperand : AsmOperandClass {
712 let Name = "JumpTarget";
713 let ParserMethod = "parseJumpTarget";
714 let PredicateMethod = "isImm";
715 let RenderMethod = "addImmOperands";
718 // Instruction operand types
719 def jmptarget : Operand<OtherVT> {
720 let EncoderMethod = "getJumpTargetOpValue";
721 let ParserMatchClass = MipsJumpTargetAsmOperand;
723 def brtarget : Operand<OtherVT> {
724 let EncoderMethod = "getBranchTargetOpValue";
725 let OperandType = "OPERAND_PCREL";
726 let DecoderMethod = "DecodeBranchTarget";
727 let ParserMatchClass = MipsJumpTargetAsmOperand;
729 def brtarget1SImm16 : Operand<OtherVT> {
730 let EncoderMethod = "getBranchTargetOpValue1SImm16";
731 let OperandType = "OPERAND_PCREL";
732 let DecoderMethod = "DecodeBranchTarget1SImm16";
733 let ParserMatchClass = MipsJumpTargetAsmOperand;
735 def calltarget : Operand<iPTR> {
736 let EncoderMethod = "getJumpTargetOpValue";
737 let ParserMatchClass = MipsJumpTargetAsmOperand;
740 def imm64: Operand<i64>;
742 def simm19_lsl2 : Operand<i32> {
743 let EncoderMethod = "getSimm19Lsl2Encoding";
744 let DecoderMethod = "DecodeSimm19Lsl2";
745 let ParserMatchClass = Simm19Lsl2AsmOperand;
748 def simm18_lsl3 : Operand<i32> {
749 let EncoderMethod = "getSimm18Lsl3Encoding";
750 let DecoderMethod = "DecodeSimm18Lsl3";
751 let ParserMatchClass = MipsJumpTargetAsmOperand;
755 def uimmz : Operand<i32> {
756 let PrintMethod = "printUImm<0>";
757 let ParserMatchClass = ConstantImmzAsmOperandClass;
760 // size operand of ins instruction
761 def uimm_range_2_64 : Operand<i32> {
762 let PrintMethod = "printUImm<6, 2>";
763 let EncoderMethod = "getSizeInsEncoding";
764 let DecoderMethod = "DecodeInsSize";
765 let ParserMatchClass = ConstantUImm5_Range2_64AsmOperandClass;
769 foreach I = {1, 2, 3, 4, 5, 6, 7, 8, 10, 20, 26} in
770 def uimm # I : Operand<i32> {
771 let PrintMethod = "printUImm<" # I # ">";
772 let ParserMatchClass =
773 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
776 def uimm2_plus1 : Operand<i32> {
777 let PrintMethod = "printUImm<2, 1>";
778 let EncoderMethod = "getUImmWithOffsetEncoding<2, 1>";
779 let DecoderMethod = "DecodeUImmWithOffset<2, 1>";
780 let ParserMatchClass = ConstantUImm2Plus1AsmOperandClass;
783 def uimm5_plus1 : Operand<i32> {
784 let PrintMethod = "printUImm<5, 1>";
785 let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
786 let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
787 let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass;
790 def uimm5_plus32 : Operand<i32> {
791 let PrintMethod = "printUImm<5, 32>";
792 let ParserMatchClass = ConstantUImm5Plus32AsmOperandClass;
795 def uimm5_plus33 : Operand<i32> {
796 let PrintMethod = "printUImm<5, 33>";
797 let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
798 let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
799 let ParserMatchClass = ConstantUImm5Plus33AsmOperandClass;
802 def uimm5_inssize_plus1 : Operand<i32> {
803 let PrintMethod = "printUImm<6>";
804 let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass;
805 let EncoderMethod = "getSizeInsEncoding";
806 let DecoderMethod = "DecodeInsSize";
809 def uimm5_plus32_normalize : Operand<i32> {
810 let PrintMethod = "printUImm<5>";
811 let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
814 def uimm5_lsl2 : Operand<OtherVT> {
815 let EncoderMethod = "getUImm5Lsl2Encoding";
816 let DecoderMethod = "DecodeUImmWithOffsetAndScale<5, 0, 4>";
817 let ParserMatchClass = ConstantUImm5Lsl2AsmOperandClass;
820 def uimm5_plus32_normalize_64 : Operand<i64> {
821 let PrintMethod = "printUImm<5>";
822 let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
825 def uimm6_lsl2 : Operand<OtherVT> {
826 let EncoderMethod = "getUImm6Lsl2Encoding";
827 let DecoderMethod = "DecodeUImmWithOffsetAndScale<6, 0, 4>";
828 let ParserMatchClass = ConstantUImm6Lsl2AsmOperandClass;
832 def uimm # I : Operand<i32> {
833 let PrintMethod = "printUImm<" # I # ">";
834 let ParserMatchClass =
835 !cast<AsmOperandClass>("UImm" # I # "AsmOperandClass");
838 // Like uimm16_64 but coerces simm16 to uimm16.
839 def uimm16_relaxed : Operand<i32> {
840 let PrintMethod = "printUImm<16>";
841 let ParserMatchClass =
842 !cast<AsmOperandClass>("UImm16RelaxedAsmOperandClass");
846 def uimm # I # _64 : Operand<i64> {
847 let PrintMethod = "printUImm<" # I # ">";
848 let ParserMatchClass =
849 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
853 def uimm # I # _64 : Operand<i64> {
854 let PrintMethod = "printUImm<" # I # ">";
855 let ParserMatchClass =
856 !cast<AsmOperandClass>("UImm" # I # "AsmOperandClass");
859 // Like uimm16_64 but coerces simm16 to uimm16.
860 def uimm16_64_relaxed : Operand<i64> {
861 let PrintMethod = "printUImm<16>";
862 let ParserMatchClass =
863 !cast<AsmOperandClass>("UImm16RelaxedAsmOperandClass");
866 def uimm16_altrelaxed : Operand<i32> {
867 let PrintMethod = "printUImm<16>";
868 let ParserMatchClass =
869 !cast<AsmOperandClass>("UImm16AltRelaxedAsmOperandClass");
871 // Like uimm5 but reports a less confusing error for 32-63 when
872 // an instruction alias permits that.
873 def uimm5_report_uimm6 : Operand<i32> {
874 let PrintMethod = "printUImm<5>";
875 let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
878 // Like uimm5_64 but reports a less confusing error for 32-63 when
879 // an instruction alias permits that.
880 def uimm5_64_report_uimm6 : Operand<i64> {
881 let PrintMethod = "printUImm<5>";
882 let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
885 foreach I = {1, 2, 3, 4} in
886 def uimm # I # _ptr : Operand<iPTR> {
887 let PrintMethod = "printUImm<" # I # ">";
888 let ParserMatchClass =
889 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
892 foreach I = {1, 2, 3, 4, 5, 6, 8} in
893 def vsplat_uimm # I : Operand<vAny> {
894 let PrintMethod = "printUImm<" # I # ">";
895 let ParserMatchClass =
896 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
900 foreach I = {4, 5, 6, 9, 10, 11} in
901 def simm # I : Operand<i32> {
902 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
903 let ParserMatchClass =
904 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
907 foreach I = {1, 2, 3} in
908 def simm10_lsl # I : Operand<i32> {
909 let DecoderMethod = "DecodeSImmWithOffsetAndScale<10, " # I # ">";
910 let ParserMatchClass =
911 !cast<AsmOperandClass>("ConstantSImm10Lsl" # I # "AsmOperandClass");
915 def simm # I # _64 : Operand<i64> {
916 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
917 let ParserMatchClass =
918 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
921 foreach I = {5, 10} in
922 def vsplat_simm # I : Operand<vAny> {
923 let ParserMatchClass =
924 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
927 def simm7_lsl2 : Operand<OtherVT> {
928 let EncoderMethod = "getSImm7Lsl2Encoding";
929 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ", 0, 4>";
930 let ParserMatchClass = ConstantSImm7Lsl2AsmOperandClass;
933 foreach I = {16, 32} in
934 def simm # I : Operand<i32> {
935 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
936 let ParserMatchClass = !cast<AsmOperandClass>("SImm" # I # "AsmOperandClass");
939 // Like simm16 but coerces uimm16 to simm16.
940 def simm16_relaxed : Operand<i32> {
941 let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
942 let ParserMatchClass = !cast<AsmOperandClass>("SImm16RelaxedAsmOperandClass");
945 def simm16_64 : Operand<i64> {
946 let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
947 let ParserMatchClass = !cast<AsmOperandClass>("SImm16AsmOperandClass");
950 // like simm32 but coerces simm32 to uimm32.
951 def uimm32_coerced : Operand<i32> {
952 let ParserMatchClass = !cast<AsmOperandClass>("UImm32CoercedAsmOperandClass");
954 // Like simm32 but coerces uimm32 to simm32.
955 def simm32_relaxed : Operand<i32> {
956 let DecoderMethod = "DecodeSImmWithOffsetAndScale<32>";
957 let ParserMatchClass = !cast<AsmOperandClass>("SImm32RelaxedAsmOperandClass");
960 // This is almost the same as a uimm7 but 0x7f is interpreted as -1.
961 def li16_imm : Operand<i32> {
962 let DecoderMethod = "DecodeLi16Imm";
963 let ParserMatchClass = ConstantUImm7Sub1AsmOperandClass;
966 def MipsMemAsmOperand : AsmOperandClass {
968 let ParserMethod = "parseMemOperand";
971 def MipsMemSimm9AsmOperand : AsmOperandClass {
972 let Name = "MemOffsetSimm9";
973 let SuperClasses = [MipsMemAsmOperand];
974 let RenderMethod = "addMemOperands";
975 let ParserMethod = "parseMemOperand";
976 let PredicateMethod = "isMemWithSimmOffset<9>";
977 let DiagnosticType = "MemSImm9";
980 def MipsMemSimm10AsmOperand : AsmOperandClass {
981 let Name = "MemOffsetSimm10";
982 let SuperClasses = [MipsMemAsmOperand];
983 let RenderMethod = "addMemOperands";
984 let ParserMethod = "parseMemOperand";
985 let PredicateMethod = "isMemWithSimmOffset<10>";
986 let DiagnosticType = "MemSImm10";
989 def MipsMemSimm12AsmOperand : AsmOperandClass {
990 let Name = "MemOffsetSimm12";
991 let SuperClasses = [MipsMemAsmOperand];
992 let RenderMethod = "addMemOperands";
993 let ParserMethod = "parseMemOperand";
994 let PredicateMethod = "isMemWithSimmOffset<12>";
995 let DiagnosticType = "MemSImm12";
998 foreach I = {1, 2, 3} in
999 def MipsMemSimm10Lsl # I # AsmOperand : AsmOperandClass {
1000 let Name = "MemOffsetSimm10_" # I;
1001 let SuperClasses = [MipsMemAsmOperand];
1002 let RenderMethod = "addMemOperands";
1003 let ParserMethod = "parseMemOperand";
1004 let PredicateMethod = "isMemWithSimmOffset<10, " # I # ">";
1005 let DiagnosticType = "MemSImm10Lsl" # I;
1008 def MipsMemSimm11AsmOperand : AsmOperandClass {
1009 let Name = "MemOffsetSimm11";
1010 let SuperClasses = [MipsMemAsmOperand];
1011 let RenderMethod = "addMemOperands";
1012 let ParserMethod = "parseMemOperand";
1013 let PredicateMethod = "isMemWithSimmOffset<11>";
1014 let DiagnosticType = "MemSImm11";
1017 def MipsMemSimm16AsmOperand : AsmOperandClass {
1018 let Name = "MemOffsetSimm16";
1019 let SuperClasses = [MipsMemAsmOperand];
1020 let RenderMethod = "addMemOperands";
1021 let ParserMethod = "parseMemOperand";
1022 let PredicateMethod = "isMemWithSimmOffset<16>";
1023 let DiagnosticType = "MemSImm16";
1026 def MipsInvertedImmoperand : AsmOperandClass {
1027 let Name = "InvNum";
1028 let RenderMethod = "addImmOperands";
1029 let ParserMethod = "parseInvNum";
1032 def InvertedImOperand : Operand<i32> {
1033 let ParserMatchClass = MipsInvertedImmoperand;
1036 def InvertedImOperand64 : Operand<i64> {
1037 let ParserMatchClass = MipsInvertedImmoperand;
1040 class mem_generic : Operand<iPTR> {
1041 let PrintMethod = "printMemOperand";
1042 let MIOperandInfo = (ops ptr_rc, simm16);
1043 let EncoderMethod = "getMemEncoding";
1044 let ParserMatchClass = MipsMemAsmOperand;
1045 let OperandType = "OPERAND_MEMORY";
1049 def mem : mem_generic;
1051 // MSA specific address operand
1052 def mem_msa : mem_generic {
1053 let MIOperandInfo = (ops ptr_rc, simm10);
1054 let EncoderMethod = "getMSAMemEncoding";
1057 def simm12 : Operand<i32> {
1058 let DecoderMethod = "DecodeSimm12";
1061 def mem_simm9 : mem_generic {
1062 let MIOperandInfo = (ops ptr_rc, simm9);
1063 let EncoderMethod = "getMemEncoding";
1064 let ParserMatchClass = MipsMemSimm9AsmOperand;
1067 def mem_simm10 : mem_generic {
1068 let MIOperandInfo = (ops ptr_rc, simm10);
1069 let EncoderMethod = "getMemEncoding";
1070 let ParserMatchClass = MipsMemSimm10AsmOperand;
1073 foreach I = {1, 2, 3} in
1074 def mem_simm10_lsl # I : mem_generic {
1075 let MIOperandInfo = (ops ptr_rc, !cast<Operand>("simm10_lsl" # I));
1076 let EncoderMethod = "getMemEncoding<" # I # ">";
1077 let ParserMatchClass =
1078 !cast<AsmOperandClass>("MipsMemSimm10Lsl" # I # "AsmOperand");
1081 def mem_simm11 : mem_generic {
1082 let MIOperandInfo = (ops ptr_rc, simm11);
1083 let EncoderMethod = "getMemEncoding";
1084 let ParserMatchClass = MipsMemSimm11AsmOperand;
1087 def mem_simm12 : mem_generic {
1088 let MIOperandInfo = (ops ptr_rc, simm12);
1089 let EncoderMethod = "getMemEncoding";
1090 let ParserMatchClass = MipsMemSimm12AsmOperand;
1093 def mem_simm16 : mem_generic {
1094 let MIOperandInfo = (ops ptr_rc, simm16);
1095 let EncoderMethod = "getMemEncoding";
1096 let ParserMatchClass = MipsMemSimm16AsmOperand;
1099 def mem_ea : Operand<iPTR> {
1100 let PrintMethod = "printMemOperandEA";
1101 let MIOperandInfo = (ops ptr_rc, simm16);
1102 let EncoderMethod = "getMemEncoding";
1103 let OperandType = "OPERAND_MEMORY";
1106 def PtrRC : Operand<iPTR> {
1107 let MIOperandInfo = (ops ptr_rc);
1108 let DecoderMethod = "DecodePtrRegisterClass";
1109 let ParserMatchClass = GPR32AsmOperand;
1112 // size operand of ins instruction
1113 def size_ins : Operand<i32> {
1114 let EncoderMethod = "getSizeInsEncoding";
1115 let DecoderMethod = "DecodeInsSize";
1118 // Transformation Function - get the lower 16 bits.
1119 def LO16 : SDNodeXForm<imm, [{
1120 return getImm(N, N->getZExtValue() & 0xFFFF);
1123 // Transformation Function - get the higher 16 bits.
1124 def HI16 : SDNodeXForm<imm, [{
1125 return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF);
1129 def Plus1 : SDNodeXForm<imm, [{ return getImm(N, N->getSExtValue() + 1); }]>;
1131 // Node immediate is zero (e.g. insve.d)
1132 def immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>;
1134 // Node immediate fits as 16-bit sign extended on target immediate.
1136 def immSExt8 : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;
1138 // Node immediate fits as 16-bit sign extended on target immediate.
1140 def immSExt16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;
1142 // Node immediate fits as 7-bit zero extended on target immediate.
1143 def immZExt7 : PatLeaf<(imm), [{ return isUInt<7>(N->getZExtValue()); }]>;
1145 // Node immediate fits as 16-bit zero extended on target immediate.
1146 // The LO16 param means that only the lower 16 bits of the node
1147 // immediate are caught.
1148 // e.g. addiu, sltiu
1149 def immZExt16 : PatLeaf<(imm), [{
1150 if (N->getValueType(0) == MVT::i32)
1151 return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
1153 return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
1156 // Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared).
1157 def immSExt32Low16Zero : PatLeaf<(imm), [{
1158 int64_t Val = N->getSExtValue();
1159 return isInt<32>(Val) && !(Val & 0xffff);
1162 // Zero-extended 32-bit unsigned int with lower 16-bit cleared.
1163 def immZExt32Low16Zero : PatLeaf<(imm), [{
1164 uint64_t Val = N->getZExtValue();
1165 return isUInt<32>(Val) && !(Val & 0xffff);
1168 // Note immediate fits as a 32 bit signed extended on target immediate.
1169 def immSExt32 : PatLeaf<(imm), [{ return isInt<32>(N->getSExtValue()); }]>;
1171 // Note immediate fits as a 32 bit zero extended on target immediate.
1172 def immZExt32 : PatLeaf<(imm), [{ return isUInt<32>(N->getZExtValue()); }]>;
1174 // shamt field must fit in 5 bits.
1175 def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
1177 def immZExt5Plus1 : PatLeaf<(imm), [{
1178 return isUInt<5>(N->getZExtValue() - 1);
1180 def immZExt5Plus32 : PatLeaf<(imm), [{
1181 return isUInt<5>(N->getZExtValue() - 32);
1183 def immZExt5Plus33 : PatLeaf<(imm), [{
1184 return isUInt<5>(N->getZExtValue() - 33);
1187 def immZExt5To31 : SDNodeXForm<imm, [{
1188 return getImm(N, 31 - N->getZExtValue());
1191 // True if (N + 1) fits in 16-bit field.
1192 def immSExt16Plus1 : PatLeaf<(imm), [{
1193 return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1);
1196 // Mips Address Mode! SDNode frameindex could possibily be a match
1197 // since load and store instructions from stack used it.
1199 ComplexPattern<iPTR, 2, "selectIntAddr", [frameindex]>;
1202 ComplexPattern<iPTR, 2, "selectAddrRegImm", [frameindex]>;
1205 ComplexPattern<iPTR, 2, "selectAddrDefault", [frameindex]>;
1207 def addrimm10 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10", [frameindex]>;
1208 def addrimm10lsl1 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl1",
1210 def addrimm10lsl2 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl2",
1212 def addrimm10lsl3 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl3",
1215 //===----------------------------------------------------------------------===//
1216 // Instructions specific format
1217 //===----------------------------------------------------------------------===//
1219 // Arithmetic and logical instructions with 3 register operands.
1220 class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0,
1221 InstrItinClass Itin = NoItinerary,
1222 SDPatternOperator OpNode = null_frag>:
1223 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
1224 !strconcat(opstr, "\t$rd, $rs, $rt"),
1225 [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> {
1226 let isCommutable = isComm;
1227 let isReMaterializable = 1;
1228 let TwoOperandAliasConstraint = "$rd = $rs";
1231 // Arithmetic and logical instructions with 2 register operands.
1232 class ArithLogicI<string opstr, Operand Od, RegisterOperand RO,
1233 InstrItinClass Itin = NoItinerary,
1234 SDPatternOperator imm_type = null_frag,
1235 SDPatternOperator OpNode = null_frag> :
1236 InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16),
1237 !strconcat(opstr, "\t$rt, $rs, $imm16"),
1238 [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))],
1239 Itin, FrmI, opstr> {
1240 let isReMaterializable = 1;
1241 let TwoOperandAliasConstraint = "$rs = $rt";
1244 // Arithmetic Multiply ADD/SUB
1245 class MArithR<string opstr, InstrItinClass itin, bit isComm = 0> :
1246 InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1247 !strconcat(opstr, "\t$rs, $rt"), [], itin, FrmR, opstr> {
1248 let Defs = [HI0, LO0];
1249 let Uses = [HI0, LO0];
1250 let isCommutable = isComm;
1254 class LogicNOR<string opstr, RegisterOperand RO>:
1255 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
1256 !strconcat(opstr, "\t$rd, $rs, $rt"),
1257 [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], II_NOR, FrmR, opstr> {
1258 let isCommutable = 1;
1262 class shift_rotate_imm<string opstr, Operand ImmOpnd,
1263 RegisterOperand RO, InstrItinClass itin,
1264 SDPatternOperator OpNode = null_frag,
1265 SDPatternOperator PF = null_frag> :
1266 InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt),
1267 !strconcat(opstr, "\t$rd, $rt, $shamt"),
1268 [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], itin, FrmR, opstr> {
1269 let TwoOperandAliasConstraint = "$rt = $rd";
1272 class shift_rotate_reg<string opstr, RegisterOperand RO, InstrItinClass itin,
1273 SDPatternOperator OpNode = null_frag>:
1274 InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs),
1275 !strconcat(opstr, "\t$rd, $rt, $rs"),
1276 [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], itin, FrmR,
1279 // Load Upper Immediate
1280 class LoadUpper<string opstr, RegisterOperand RO, Operand Imm>:
1281 InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"),
1282 [], II_LUI, FrmI, opstr>, IsAsCheapAsAMove {
1283 let hasSideEffects = 0;
1284 let isReMaterializable = 1;
1287 // Memory Load/Store
1288 class LoadMemory<string opstr, DAGOperand RO, DAGOperand MO,
1289 SDPatternOperator OpNode = null_frag,
1290 InstrItinClass Itin = NoItinerary,
1291 ComplexPattern Addr = addr> :
1292 InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1293 [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> {
1294 let DecoderMethod = "DecodeMem";
1295 let canFoldAsLoad = 1;
1299 class Load<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
1300 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
1301 LoadMemory<opstr, RO, mem, OpNode, Itin, Addr>;
1303 class StoreMemory<string opstr, DAGOperand RO, DAGOperand MO,
1304 SDPatternOperator OpNode = null_frag,
1305 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
1306 InstSE<(outs), (ins RO:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1307 [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> {
1308 let DecoderMethod = "DecodeMem";
1312 class Store<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
1313 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr,
1314 DAGOperand MO = mem> :
1315 StoreMemory<opstr, RO, MO, OpNode, Itin, Addr>;
1317 // Load/Store Left/Right
1318 let canFoldAsLoad = 1 in
1319 class LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
1320 InstrItinClass Itin> :
1321 InstSE<(outs RO:$rt), (ins mem:$addr, RO:$src),
1322 !strconcat(opstr, "\t$rt, $addr"),
1323 [(set RO:$rt, (OpNode addr:$addr, RO:$src))], Itin, FrmI> {
1324 let DecoderMethod = "DecodeMem";
1325 string Constraints = "$src = $rt";
1328 class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
1329 InstrItinClass Itin> :
1330 InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1331 [(OpNode RO:$rt, addr:$addr)], Itin, FrmI> {
1332 let DecoderMethod = "DecodeMem";
1336 class LW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
1337 SDPatternOperator OpNode= null_frag> :
1338 InstSE<(outs RC:$rt), (ins mem_simm16:$addr),
1339 !strconcat(opstr, "\t$rt, $addr"),
1340 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
1341 let DecoderMethod = "DecodeFMem2";
1345 class SW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
1346 SDPatternOperator OpNode= null_frag> :
1347 InstSE<(outs), (ins RC:$rt, mem_simm16:$addr),
1348 !strconcat(opstr, "\t$rt, $addr"),
1349 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
1350 let DecoderMethod = "DecodeFMem2";
1355 class LW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
1356 SDPatternOperator OpNode= null_frag> :
1357 InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1358 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
1359 let DecoderMethod = "DecodeFMem3";
1363 class SW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
1364 SDPatternOperator OpNode= null_frag> :
1365 InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1366 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
1367 let DecoderMethod = "DecodeFMem3";
1371 // Conditional Branch
1372 class CBranch<string opstr, DAGOperand opnd, PatFrag cond_op,
1373 RegisterOperand RO, bit DelaySlot = 1> :
1374 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
1375 !strconcat(opstr, "\t$rs, $rt, $offset"),
1376 [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], II_BCC,
1379 let isTerminator = 1;
1380 let hasDelaySlot = DelaySlot;
1385 class CBranchZero<string opstr, DAGOperand opnd, PatFrag cond_op,
1386 RegisterOperand RO, bit DelaySlot = 1> :
1387 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1388 !strconcat(opstr, "\t$rs, $offset"),
1389 [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], II_BCCZ,
1392 let isTerminator = 1;
1393 let hasDelaySlot = DelaySlot;
1399 class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> :
1400 InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt),
1401 !strconcat(opstr, "\t$rd, $rs, $rt"),
1402 [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))],
1403 II_SLT_SLTU, FrmR, opstr>;
1405 class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
1406 RegisterOperand RO>:
1407 InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16),
1408 !strconcat(opstr, "\t$rt, $rs, $imm16"),
1409 [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))],
1410 II_SLTI_SLTIU, FrmI, opstr>;
1413 class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
1414 SDPatternOperator targetoperator, string bopstr> :
1415 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
1416 [(operator targetoperator:$target)], II_J, FrmJ, bopstr> {
1419 let hasDelaySlot = 1;
1420 let DecoderMethod = "DecodeJumpTarget";
1425 // Unconditional branch
1426 class UncondBranch<Instruction BEQInst> :
1427 PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], II_B>,
1428 PseudoInstExpansion<(BEQInst ZERO, ZERO, brtarget:$offset)> {
1430 let isTerminator = 1;
1432 let hasDelaySlot = 1;
1433 let AdditionalPredicates = [RelocPIC];
1438 // Base class for indirect branch and return instruction classes.
1439 let isTerminator=1, isBarrier=1, hasDelaySlot = 1, isCTI = 1 in
1440 class JumpFR<string opstr, RegisterOperand RO,
1441 SDPatternOperator operator = null_frag>:
1442 InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], II_JR,
1446 class IndirectBranch<string opstr, RegisterOperand RO> : JumpFR<opstr, RO> {
1448 let isIndirectBranch = 1;
1451 // Jump and Link (Call)
1452 let isCall=1, hasDelaySlot=1, isCTI=1, Defs = [RA] in {
1453 class JumpLink<string opstr, DAGOperand opnd> :
1454 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
1455 [(MipsJmpLink tglobaladdr:$target)], II_JAL, FrmJ, opstr> {
1456 let DecoderMethod = "DecodeJumpTarget";
1459 class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst,
1460 Register RetReg, RegisterOperand ResRO = RO>:
1461 PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], II_JALR>,
1462 PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)>;
1464 class JumpLinkReg<string opstr, RegisterOperand RO>:
1465 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1466 [], II_JALR, FrmR, opstr>;
1468 class BGEZAL_FT<string opstr, DAGOperand opnd,
1469 RegisterOperand RO, bit DelaySlot = 1> :
1470 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1471 !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZAL, FrmI, opstr> {
1472 let hasDelaySlot = DelaySlot;
1477 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
1478 hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT] in {
1479 class TailCall<Instruction JumpInst, DAGOperand Opnd> :
1480 PseudoSE<(outs), (ins calltarget:$target), [], II_J>,
1481 PseudoInstExpansion<(JumpInst Opnd:$target)>;
1483 class TailCallReg<RegisterOperand RO> :
1484 MipsPseudo<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>;
1487 class BAL_BR_Pseudo<Instruction RealInst> :
1488 PseudoSE<(outs), (ins brtarget:$offset), [], II_BCCZAL>,
1489 PseudoInstExpansion<(RealInst ZERO, brtarget:$offset)> {
1491 let isTerminator = 1;
1493 let hasDelaySlot = 1;
1500 class SYS_FT<string opstr, Operand ImmOp, InstrItinClass itin = NoItinerary> :
1501 InstSE<(outs), (ins ImmOp:$code_),
1502 !strconcat(opstr, "\t$code_"), [], itin, FrmI, opstr>;
1504 class BRK_FT<string opstr> :
1505 InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
1506 !strconcat(opstr, "\t$code_1, $code_2"), [], II_BREAK,
1510 class ER_FT<string opstr, InstrItinClass itin = NoItinerary> :
1511 InstSE<(outs), (ins),
1512 opstr, [], itin, FrmOther, opstr>;
1515 class WAIT_FT<string opstr> :
1516 InstSE<(outs), (ins), opstr, [], II_WAIT, FrmOther, opstr>;
1520 class DEI_FT<string opstr, RegisterOperand RO,
1521 InstrItinClass itin = NoItinerary> :
1522 InstSE<(outs RO:$rt), (ins),
1523 !strconcat(opstr, "\t$rt"), [], itin, FrmOther, opstr>;
1526 let hasSideEffects = 1 in
1527 class SYNC_FT<string opstr> :
1528 InstSE<(outs), (ins uimm5:$stype), "sync $stype",
1529 [(MipsSync immZExt5:$stype)], II_SYNC, FrmOther, opstr>;
1531 class SYNCI_FT<string opstr> :
1532 InstSE<(outs), (ins mem_simm16:$addr), !strconcat(opstr, "\t$addr"), [],
1533 II_SYNCI, FrmOther, opstr> {
1534 let hasSideEffects = 1;
1535 let DecoderMethod = "DecodeSyncI";
1538 let hasSideEffects = 1, isCTI = 1 in {
1539 class TEQ_FT<string opstr, RegisterOperand RO, Operand ImmOp,
1540 InstrItinClass itin = NoItinerary> :
1541 InstSE<(outs), (ins RO:$rs, RO:$rt, ImmOp:$code_),
1542 !strconcat(opstr, "\t$rs, $rt, $code_"), [], itin, FrmI, opstr>;
1544 class TEQI_FT<string opstr, RegisterOperand RO,
1545 InstrItinClass itin = NoItinerary> :
1546 InstSE<(outs), (ins RO:$rs, simm16:$imm16),
1547 !strconcat(opstr, "\t$rs, $imm16"), [], itin, FrmOther, opstr>;
1551 class Mult<string opstr, InstrItinClass itin, RegisterOperand RO,
1552 list<Register> DefRegs> :
1553 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [],
1554 itin, FrmR, opstr> {
1555 let isCommutable = 1;
1557 let hasSideEffects = 0;
1560 // Pseudo multiply/divide instruction with explicit accumulator register
1562 class MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1,
1563 SDPatternOperator OpNode, InstrItinClass Itin,
1564 bit IsComm = 1, bit HasSideEffects = 0,
1565 bit UsesCustomInserter = 0> :
1566 PseudoSE<(outs R0:$ac), (ins R1:$rs, R1:$rt),
1567 [(set R0:$ac, (OpNode R1:$rs, R1:$rt))], Itin>,
1568 PseudoInstExpansion<(RealInst R1:$rs, R1:$rt)> {
1569 let isCommutable = IsComm;
1570 let hasSideEffects = HasSideEffects;
1571 let usesCustomInserter = UsesCustomInserter;
1574 // Pseudo multiply add/sub instruction with explicit accumulator register
1576 class MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode,
1577 InstrItinClass itin>
1578 : PseudoSE<(outs ACC64:$ac),
1579 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin),
1581 (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))],
1583 PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> {
1584 string Constraints = "$acin = $ac";
1587 class Div<string opstr, InstrItinClass itin, RegisterOperand RO,
1588 list<Register> DefRegs> :
1589 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$$zero, $rs, $rt"),
1590 [], itin, FrmR, opstr> {
1595 class PseudoMFLOHI<RegisterClass DstRC, RegisterClass SrcRC, SDNode OpNode>
1596 : PseudoSE<(outs DstRC:$rd), (ins SrcRC:$hilo),
1597 [(set DstRC:$rd, (OpNode SrcRC:$hilo))], II_MFHI_MFLO>;
1599 class MoveFromLOHI<string opstr, RegisterOperand RO, Register UseReg>:
1600 InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO,
1602 let Uses = [UseReg];
1603 let hasSideEffects = 0;
1606 class PseudoMTLOHI<RegisterClass DstRC, RegisterClass SrcRC>
1607 : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi),
1608 [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))],
1611 class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>:
1612 InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO,
1615 let hasSideEffects = 0;
1618 class EffectiveAddress<string opstr, RegisterOperand RO> :
1619 InstSE<(outs RO:$rt), (ins mem_ea:$addr), !strconcat(opstr, "\t$rt, $addr"),
1620 [(set RO:$rt, addr:$addr)], II_ADDIU, FrmI,
1621 !strconcat(opstr, "_lea")> {
1622 let isCodeGenOnly = 1;
1623 let hasNoSchedulingInfo = 1;
1624 let DecoderMethod = "DecodeMem";
1627 // Count Leading Ones/Zeros in Word
1628 class CountLeading0<string opstr, RegisterOperand RO,
1629 InstrItinClass itin = NoItinerary>:
1630 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1631 [(set RO:$rd, (ctlz RO:$rs))], itin, FrmR, opstr>;
1633 class CountLeading1<string opstr, RegisterOperand RO,
1634 InstrItinClass itin = NoItinerary>:
1635 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1636 [(set RO:$rd, (ctlz (not RO:$rs)))], itin, FrmR, opstr>;
1638 // Sign Extend in Register.
1639 class SignExtInReg<string opstr, ValueType vt, RegisterOperand RO,
1640 InstrItinClass itin> :
1641 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"),
1642 [(set RO:$rd, (sext_inreg RO:$rt, vt))], itin, FrmR, opstr>;
1645 class SubwordSwap<string opstr, RegisterOperand RO,
1646 InstrItinClass itin = NoItinerary>:
1647 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [], itin,
1649 let hasSideEffects = 0;
1653 class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> :
1654 InstSE<(outs CPURegOperand:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [],
1655 II_RDHWR, FrmR, "rdhwr">;
1658 class ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1659 Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm,
1660 SDPatternOperator Op = null_frag> :
1661 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size),
1662 !strconcat(opstr, " $rt, $rs, $pos, $size"),
1663 [(set RO:$rt, (Op RO:$rs, PosImm:$pos, SizeImm:$size))], II_EXT,
1664 FrmR, opstr>, ISA_MIPS32R2;
1666 class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1667 Operand SizeOpnd, SDPatternOperator Op = null_frag>:
1668 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size, RO:$src),
1669 !strconcat(opstr, " $rt, $rs, $pos, $size"),
1670 [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size, RO:$src))],
1671 II_INS, FrmR, opstr>, ISA_MIPS32R2 {
1672 let Constraints = "$src = $rt";
1675 // Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*).
1676 class Atomic2Ops<PatFrag Op, RegisterClass DRC> :
1677 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr),
1678 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]>;
1680 // Atomic Compare & Swap.
1681 class AtomicCmpSwap<PatFrag Op, RegisterClass DRC> :
1682 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap),
1683 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]>;
1685 class LLBase<string opstr, RegisterOperand RO, DAGOperand MO = mem> :
1686 InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1687 [], II_LL, FrmI, opstr> {
1688 let DecoderMethod = "DecodeMem";
1692 class SCBase<string opstr, RegisterOperand RO> :
1693 InstSE<(outs RO:$dst), (ins RO:$rt, mem:$addr),
1694 !strconcat(opstr, "\t$rt, $addr"), [], II_SC, FrmI> {
1695 let DecoderMethod = "DecodeMem";
1697 let Constraints = "$rt = $dst";
1700 class MFC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
1701 InstrItinClass itin> :
1702 InstSE<(outs RO:$rt), (ins RD:$rd, uimm3:$sel),
1703 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR>;
1705 class MTC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
1706 InstrItinClass itin> :
1707 InstSE<(outs RO:$rd), (ins RD:$rt, uimm3:$sel),
1708 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR>;
1710 class TrapBase<Instruction RealInst>
1711 : PseudoSE<(outs), (ins), [(trap)], II_TRAP>,
1712 PseudoInstExpansion<(RealInst 0, 0)> {
1714 let isTerminator = 1;
1715 let isCodeGenOnly = 1;
1719 //===----------------------------------------------------------------------===//
1720 // Pseudo instructions
1721 //===----------------------------------------------------------------------===//
1724 let isReturn=1, isTerminator=1, isBarrier=1, hasCtrlDep=1, isCTI=1 in {
1725 let hasDelaySlot=1 in
1726 def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
1728 let hasSideEffects=1 in
1729 def ERet : PseudoSE<(outs), (ins), [(MipsERet)]>;
1732 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
1733 def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1734 [(callseq_start timm:$amt1, timm:$amt2)]>;
1735 def ADJCALLSTACKUP : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1736 [(callseq_end timm:$amt1, timm:$amt2)]>;
1739 let usesCustomInserter = 1 in {
1740 def ATOMIC_LOAD_ADD_I8 : Atomic2Ops<atomic_load_add_8, GPR32>;
1741 def ATOMIC_LOAD_ADD_I16 : Atomic2Ops<atomic_load_add_16, GPR32>;
1742 def ATOMIC_LOAD_ADD_I32 : Atomic2Ops<atomic_load_add_32, GPR32>;
1743 def ATOMIC_LOAD_SUB_I8 : Atomic2Ops<atomic_load_sub_8, GPR32>;
1744 def ATOMIC_LOAD_SUB_I16 : Atomic2Ops<atomic_load_sub_16, GPR32>;
1745 def ATOMIC_LOAD_SUB_I32 : Atomic2Ops<atomic_load_sub_32, GPR32>;
1746 def ATOMIC_LOAD_AND_I8 : Atomic2Ops<atomic_load_and_8, GPR32>;
1747 def ATOMIC_LOAD_AND_I16 : Atomic2Ops<atomic_load_and_16, GPR32>;
1748 def ATOMIC_LOAD_AND_I32 : Atomic2Ops<atomic_load_and_32, GPR32>;
1749 def ATOMIC_LOAD_OR_I8 : Atomic2Ops<atomic_load_or_8, GPR32>;
1750 def ATOMIC_LOAD_OR_I16 : Atomic2Ops<atomic_load_or_16, GPR32>;
1751 def ATOMIC_LOAD_OR_I32 : Atomic2Ops<atomic_load_or_32, GPR32>;
1752 def ATOMIC_LOAD_XOR_I8 : Atomic2Ops<atomic_load_xor_8, GPR32>;
1753 def ATOMIC_LOAD_XOR_I16 : Atomic2Ops<atomic_load_xor_16, GPR32>;
1754 def ATOMIC_LOAD_XOR_I32 : Atomic2Ops<atomic_load_xor_32, GPR32>;
1755 def ATOMIC_LOAD_NAND_I8 : Atomic2Ops<atomic_load_nand_8, GPR32>;
1756 def ATOMIC_LOAD_NAND_I16 : Atomic2Ops<atomic_load_nand_16, GPR32>;
1757 def ATOMIC_LOAD_NAND_I32 : Atomic2Ops<atomic_load_nand_32, GPR32>;
1759 def ATOMIC_SWAP_I8 : Atomic2Ops<atomic_swap_8, GPR32>;
1760 def ATOMIC_SWAP_I16 : Atomic2Ops<atomic_swap_16, GPR32>;
1761 def ATOMIC_SWAP_I32 : Atomic2Ops<atomic_swap_32, GPR32>;
1763 def ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap<atomic_cmp_swap_8, GPR32>;
1764 def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap<atomic_cmp_swap_16, GPR32>;
1765 def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_32, GPR32>;
1768 /// Pseudo instructions for loading and storing accumulator registers.
1769 let isPseudo = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in {
1770 def LOAD_ACC64 : Load<"", ACC64>;
1771 def STORE_ACC64 : Store<"", ACC64>;
1774 // We need these two pseudo instructions to avoid offset calculation for long
1775 // branches. See the comment in file MipsLongBranch.cpp for detailed
1778 // Expands to: lui $dst, %hi($tgt - $baltgt)
1779 def LONG_BRANCH_LUi : PseudoSE<(outs GPR32Opnd:$dst),
1780 (ins brtarget:$tgt, brtarget:$baltgt), []>;
1782 // Expands to: addiu $dst, $src, %lo($tgt - $baltgt)
1783 def LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst),
1784 (ins GPR32Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []>;
1786 //===----------------------------------------------------------------------===//
1787 // Instruction definition
1788 //===----------------------------------------------------------------------===//
1789 //===----------------------------------------------------------------------===//
1790 // MipsI Instructions
1791 //===----------------------------------------------------------------------===//
1793 /// Arithmetic Instructions (ALU Immediate)
1794 let AdditionalPredicates = [NotInMicroMips] in {
1795 def ADDiu : MMRel, StdMMR6Rel, ArithLogicI<"addiu", simm16_relaxed, GPR32Opnd,
1796 II_ADDIU, immSExt16, add>,
1797 ADDI_FM<0x9>, IsAsCheapAsAMove;
1799 def ANDi : MMRel, StdMMR6Rel,
1800 ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16, and>,
1802 def ORi : MMRel, StdMMR6Rel,
1803 ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16, or>,
1805 def XORi : MMRel, StdMMR6Rel,
1806 ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16, xor>,
1809 def ADDi : MMRel, ArithLogicI<"addi", simm16_relaxed, GPR32Opnd, II_ADDI>, ADDI_FM<0x8>,
1810 ISA_MIPS1_NOT_32R6_64R6;
1811 let AdditionalPredicates = [NotInMicroMips] in {
1812 def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
1814 def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
1817 def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16_relaxed>, LUI_FM;
1818 let AdditionalPredicates = [NotInMicroMips] in {
1819 /// Arithmetic Instructions (3-Operand, R-Type)
1820 def ADDu : MMRel, StdMMR6Rel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
1822 def SUBu : MMRel, StdMMR6Rel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
1825 let Defs = [HI0, LO0] in
1826 def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>,
1827 ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6;
1828 def ADD : MMRel, StdMMR6Rel, ArithLogicR<"add", GPR32Opnd, 1, II_ADD>, ADD_FM<0, 0x20>;
1829 def SUB : MMRel, StdMMR6Rel, ArithLogicR<"sub", GPR32Opnd, 0, II_SUB>, ADD_FM<0, 0x22>;
1830 let AdditionalPredicates = [NotInMicroMips] in {
1831 def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>;
1832 def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>;
1833 def AND : MMRel, StdMMR6Rel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
1835 def OR : MMRel, StdMMR6Rel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
1837 def XOR : MMRel, StdMMR6Rel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
1839 def NOR : MMRel, StdMMR6Rel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>;
1842 /// Shift Instructions
1843 let AdditionalPredicates = [NotInMicroMips] in {
1844 def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl,
1845 immZExt5>, SRA_FM<0, 0>;
1846 def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl,
1847 immZExt5>, SRA_FM<2, 0>;
1848 def SRA : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, sra,
1849 immZExt5>, SRA_FM<3, 0>;
1850 def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, shl>,
1852 def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, srl>,
1854 def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, sra>,
1858 // Rotate Instructions
1859 let AdditionalPredicates = [NotInMicroMips] in {
1860 def ROTR : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr,
1862 SRA_FM<2, 1>, ISA_MIPS32R2;
1863 def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>,
1864 SRLV_FM<6, 1>, ISA_MIPS32R2;
1867 /// Load and Store Instructions
1869 def LB : LoadMemory<"lb", GPR32Opnd, mem_simm16, sextloadi8, II_LB>, MMRel,
1871 def LBu : LoadMemory<"lbu", GPR32Opnd, mem_simm16, zextloadi8, II_LBU,
1872 addrDefault>, MMRel, LW_FM<0x24>;
1873 let AdditionalPredicates = [NotInMicroMips] in {
1874 def LH : LoadMemory<"lh", GPR32Opnd, mem_simm16, sextloadi16, II_LH,
1875 addrDefault>, MMRel, LW_FM<0x21>;
1876 def LHu : LoadMemory<"lhu", GPR32Opnd, mem_simm16, zextloadi16, II_LHU>,
1878 def LW : StdMMR6Rel, Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel,
1881 def SB : StdMMR6Rel, Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel,
1883 def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>;
1884 let AdditionalPredicates = [NotInMicroMips] in {
1885 def SW : Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>;
1888 /// load/store left/right
1889 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1890 AdditionalPredicates = [NotInMicroMips] in {
1891 def LWL : LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>,
1892 ISA_MIPS1_NOT_32R6_64R6;
1893 def LWR : LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>,
1894 ISA_MIPS1_NOT_32R6_64R6;
1895 def SWL : StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>,
1896 ISA_MIPS1_NOT_32R6_64R6;
1897 def SWR : StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>,
1898 ISA_MIPS1_NOT_32R6_64R6;
1901 let AdditionalPredicates = [NotInMicroMips] in {
1902 // COP2 Memory Instructions
1903 def LWC2 : StdMMR6Rel, LW_FT2<"lwc2", COP2Opnd, II_LWC2, load>, LW_FM<0x32>,
1904 ISA_MIPS1_NOT_32R6_64R6;
1905 def SWC2 : StdMMR6Rel, SW_FT2<"swc2", COP2Opnd, II_SWC2, store>,
1906 LW_FM<0x3a>, ISA_MIPS1_NOT_32R6_64R6;
1907 def LDC2 : StdMMR6Rel, LW_FT2<"ldc2", COP2Opnd, II_LDC2, load>, LW_FM<0x36>,
1908 ISA_MIPS2_NOT_32R6_64R6;
1909 def SDC2 : StdMMR6Rel, SW_FT2<"sdc2", COP2Opnd, II_SDC2, store>,
1910 LW_FM<0x3e>, ISA_MIPS2_NOT_32R6_64R6;
1912 // COP3 Memory Instructions
1913 let DecoderNamespace = "COP3_" in {
1914 def LWC3 : LW_FT3<"lwc3", COP3Opnd, II_LWC3, load>, LW_FM<0x33>;
1915 def SWC3 : SW_FT3<"swc3", COP3Opnd, II_SWC3, store>, LW_FM<0x3b>;
1916 def LDC3 : LW_FT3<"ldc3", COP3Opnd, II_LDC3, load>, LW_FM<0x37>,
1918 def SDC3 : SW_FT3<"sdc3", COP3Opnd, II_SDC3, store>, LW_FM<0x3f>,
1922 def SYNC : MMRel, StdMMR6Rel, SYNC_FT<"sync">, SYNC_FM, ISA_MIPS2;
1923 def SYNCI : MMRel, StdMMR6Rel, SYNCI_FT<"synci">, SYNCI_FM, ISA_MIPS32R2;
1926 let AdditionalPredicates = [NotInMicroMips] in {
1927 def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd, uimm10, II_TEQ>, TEQ_FM<0x34>, ISA_MIPS2;
1928 def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd, uimm10, II_TGE>, TEQ_FM<0x30>, ISA_MIPS2;
1929 def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd, uimm10, II_TGEU>, TEQ_FM<0x31>, ISA_MIPS2;
1930 def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd, uimm10, II_TLT>, TEQ_FM<0x32>, ISA_MIPS2;
1931 def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd, uimm10, II_TLTU>, TEQ_FM<0x33>, ISA_MIPS2;
1932 def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd, uimm10, II_TNE>, TEQ_FM<0x36>, ISA_MIPS2;
1935 def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd, II_TEQI>, TEQI_FM<0xc>,
1936 ISA_MIPS2_NOT_32R6_64R6;
1937 def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd, II_TGEI>, TEQI_FM<0x8>,
1938 ISA_MIPS2_NOT_32R6_64R6;
1939 def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd, II_TGEIU>, TEQI_FM<0x9>,
1940 ISA_MIPS2_NOT_32R6_64R6;
1941 def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd, II_TLTI>, TEQI_FM<0xa>,
1942 ISA_MIPS2_NOT_32R6_64R6;
1943 def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd, II_TTLTIU>, TEQI_FM<0xb>,
1944 ISA_MIPS2_NOT_32R6_64R6;
1945 def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd, II_TNEI>, TEQI_FM<0xe>,
1946 ISA_MIPS2_NOT_32R6_64R6;
1948 let AdditionalPredicates = [NotInMicroMips] in {
1949 def BREAK : MMRel, StdMMR6Rel, BRK_FT<"break">, BRK_FM<0xd>;
1950 def SYSCALL : MMRel, SYS_FT<"syscall", uimm20, II_SYSCALL>, SYS_FM<0xc>;
1952 def TRAP : TrapBase<BREAK>;
1953 let AdditionalPredicates = [NotInMicroMips] in {
1954 def SDBBP : MMRel, SYS_FT<"sdbbp", uimm20, II_SDBBP>, SDBBP_FM, ISA_MIPS32_NOT_32R6_64R6;
1957 let AdditionalPredicates = [NotInMicroMips] in {
1958 def ERET : MMRel, ER_FT<"eret", II_ERET>, ER_FM<0x18, 0x0>, INSN_MIPS3_32;
1959 def ERETNC : MMRel, ER_FT<"eretnc", II_ERETNC>, ER_FM<0x18, 0x1>, ISA_MIPS32R5;
1960 def DERET : MMRel, ER_FT<"deret", II_DERET>, ER_FM<0x1f, 0x0>, ISA_MIPS32;
1963 let AdditionalPredicates = [NotInMicroMips] in {
1964 def EI : MMRel, StdMMR6Rel, DEI_FT<"ei", GPR32Opnd, II_EI>, EI_FM<1>, ISA_MIPS32R2;
1965 def DI : MMRel, StdMMR6Rel, DEI_FT<"di", GPR32Opnd, II_DI>, EI_FM<0>, ISA_MIPS32R2;
1968 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1969 AdditionalPredicates = [NotInMicroMips] in {
1970 def WAIT : WAIT_FT<"wait">, WAIT_FM;
1973 let AdditionalPredicates = [NotInMicroMips] in {
1974 /// Load-linked, Store-conditional
1975 def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
1976 def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
1979 /// Jump and Branch Instructions
1980 def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
1981 AdditionalRequires<[RelocNotPIC]>, IsBranch;
1982 def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>, ISA_MIPS1_NOT_32R6_64R6;
1983 def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>;
1984 def BEQL : MMRel, CBranch<"beql", brtarget, seteq, GPR32Opnd, 0>,
1985 BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6;
1986 def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>;
1987 def BNEL : MMRel, CBranch<"bnel", brtarget, setne, GPR32Opnd, 0>,
1988 BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6;
1989 def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
1991 def BGEZL : MMRel, CBranchZero<"bgezl", brtarget, setge, GPR32Opnd, 0>,
1992 BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6;
1993 def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
1995 def BGTZL : MMRel, CBranchZero<"bgtzl", brtarget, setgt, GPR32Opnd, 0>,
1996 BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6;
1997 def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
1999 def BLEZL : MMRel, CBranchZero<"blezl", brtarget, setle, GPR32Opnd, 0>,
2000 BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6;
2001 def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
2003 def BLTZL : MMRel, CBranchZero<"bltzl", brtarget, setlt, GPR32Opnd, 0>,
2004 BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6;
2005 def B : UncondBranch<BEQ>;
2007 def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>;
2008 let AdditionalPredicates = [NotInMicroMips] in {
2009 def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM;
2010 def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>;
2013 def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>,
2014 ISA_MIPS32_NOT_32R6_64R6;
2015 def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>,
2016 ISA_MIPS1_NOT_32R6_64R6;
2017 def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd, 0>,
2018 BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6;
2019 def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>,
2020 ISA_MIPS1_NOT_32R6_64R6;
2021 def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd, 0>,
2022 BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6;
2023 def BAL_BR : BAL_BR_Pseudo<BGEZAL>;
2025 let Predicates = [NotInMicroMips] in {
2026 def TAILCALL : TailCall<J, jmptarget>;
2029 def TAILCALLREG : TailCallReg<GPR32Opnd>;
2031 // Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64
2032 // then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA.
2033 class PseudoIndirectBranchBase<RegisterOperand RO> :
2034 MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)],
2035 II_IndirectBranchPseudo> {
2038 let hasDelaySlot = 1;
2040 let isIndirectBranch = 1;
2044 def PseudoIndirectBranch : PseudoIndirectBranchBase<GPR32Opnd>;
2046 // Return instructions are matched as a RetRA instruction, then are expanded
2047 // into PseudoReturn/PseudoReturn64 after register allocation. Finally,
2048 // MipsAsmPrinter expands this into JR, JR64, JALR, or JALR64 depending on the
2050 class PseudoReturnBase<RegisterOperand RO> : MipsPseudo<(outs), (ins RO:$rs),
2051 [], II_ReturnPseudo> {
2052 let isTerminator = 1;
2054 let hasDelaySlot = 1;
2056 let isCodeGenOnly = 1;
2058 let hasExtraSrcRegAllocReq = 1;
2062 def PseudoReturn : PseudoReturnBase<GPR32Opnd>;
2064 // Exception handling related node and instructions.
2065 // The conversion sequence is:
2066 // ISD::EH_RETURN -> MipsISD::EH_RETURN ->
2067 // MIPSeh_return -> (stack change + indirect branch)
2069 // MIPSeh_return takes the place of regular return instruction
2070 // but takes two arguments (V1, V0) which are used for storing
2071 // the offset and return address respectively.
2072 def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
2074 def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
2075 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
2077 let Uses = [V0, V1], isTerminator = 1, isReturn = 1, isBarrier = 1, isCTI = 1 in {
2078 def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
2079 [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
2080 def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff,
2082 [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
2085 /// Multiply and Divide Instructions.
2086 def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
2087 MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6;
2088 def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
2089 MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6;
2090 let AdditionalPredicates = [NotInMicroMips] in {
2091 def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
2092 MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6;
2093 def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
2094 MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6;
2096 def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>,
2097 ISA_MIPS1_NOT_32R6_64R6;
2098 def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>,
2099 ISA_MIPS1_NOT_32R6_64R6;
2100 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
2101 AdditionalPredicates = [NotInMicroMips] in {
2102 def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>,
2103 ISA_MIPS1_NOT_32R6_64R6;
2104 def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>,
2105 ISA_MIPS1_NOT_32R6_64R6;
2108 /// Sign Ext In Register Instructions.
2109 def SEB : MMRel, StdMMR6Rel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,
2110 SEB_FM<0x10, 0x20>, ISA_MIPS32R2;
2111 def SEH : MMRel, StdMMR6Rel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
2112 SEB_FM<0x18, 0x20>, ISA_MIPS32R2;
2115 def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd, II_CLZ>, CLO_FM<0x20>,
2116 ISA_MIPS32_NOT_32R6_64R6;
2117 def CLO : MMRel, CountLeading1<"clo", GPR32Opnd, II_CLO>, CLO_FM<0x21>,
2118 ISA_MIPS32_NOT_32R6_64R6;
2120 let AdditionalPredicates = [NotInMicroMips] in {
2121 /// Word Swap Bytes Within Halfwords
2122 def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd, II_WSBH>, SEB_FM<2, 0x20>,
2127 def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>;
2129 // FrameIndexes are legalized when they are operands from load/store
2130 // instructions. The same not happens for stack address copies, so an
2131 // add op with mem ComplexPattern is used and the stack address copy
2132 // can be matched. It's similar to Sparc LEA_ADDRi
2133 def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>;
2136 def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>,
2137 ISA_MIPS32_NOT_32R6_64R6;
2138 def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>,
2139 ISA_MIPS32_NOT_32R6_64R6;
2140 def MSUB : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>,
2141 ISA_MIPS32_NOT_32R6_64R6;
2142 def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>,
2143 ISA_MIPS32_NOT_32R6_64R6;
2145 let AdditionalPredicates = [NotDSP] in {
2146 def PseudoMULT : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>,
2147 ISA_MIPS1_NOT_32R6_64R6;
2148 def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>,
2149 ISA_MIPS1_NOT_32R6_64R6;
2150 def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>, ISA_MIPS1_NOT_32R6_64R6;
2151 def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>, ISA_MIPS1_NOT_32R6_64R6;
2152 def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>, ISA_MIPS1_NOT_32R6_64R6;
2153 def PseudoMADD : MAddSubPseudo<MADD, MipsMAdd, II_MADD>,
2154 ISA_MIPS32_NOT_32R6_64R6;
2155 def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>,
2156 ISA_MIPS32_NOT_32R6_64R6;
2157 def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>,
2158 ISA_MIPS32_NOT_32R6_64R6;
2159 def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>,
2160 ISA_MIPS32_NOT_32R6_64R6;
2163 let AdditionalPredicates = [NotInMicroMips] in {
2164 def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV,
2165 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
2166 def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU,
2167 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
2168 def RDHWR : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM;
2169 // TODO: Add '0 < pos+size <= 32' constraint check to ext instruction
2170 def EXT : MMRel, StdMMR6Rel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1,
2171 immZExt5, immZExt5Plus1, MipsExt>,
2173 def INS : MMRel, StdMMR6Rel, InsBase<"ins", GPR32Opnd, uimm5,
2174 uimm5_inssize_plus1, MipsIns>,
2177 /// Move Control Registers From/To CPU Registers
2178 let AdditionalPredicates = [NotInMicroMips] in {
2179 def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd, II_MTC0>, MFC3OP_FM<0x10, 4>,
2181 def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd, II_MFC0>, MFC3OP_FM<0x10, 0>,
2184 def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd, II_MFC2>, MFC3OP_FM<0x12, 0>;
2185 def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd, II_MTC2>, MFC3OP_FM<0x12, 4>;
2187 class Barrier<string asmstr, InstrItinClass itin = NoItinerary> :
2188 InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2190 def SSNOP : MMRel, StdMMR6Rel, Barrier<"ssnop", II_SSNOP>, BARRIER_FM<1>;
2191 def EHB : MMRel, Barrier<"ehb", II_EHB>, BARRIER_FM<3>;
2194 def PAUSE : MMRel, StdMMR6Rel, Barrier<"pause", II_PAUSE>, BARRIER_FM<5>,
2197 // JR_HB and JALR_HB are defined here using the new style naming
2198 // scheme because some of this code is shared with Mips32r6InstrInfo.td
2199 // and because of that it doesn't follow the naming convention of the
2200 // rest of the file. To avoid a mixture of old vs new style, the new
2201 // style was chosen.
2202 class JR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
2203 dag OutOperandList = (outs);
2204 dag InOperandList = (ins GPROpnd:$rs);
2205 string AsmString = !strconcat(instr_asm, "\t$rs");
2206 list<dag> Pattern = [];
2209 class JALR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
2210 dag OutOperandList = (outs GPROpnd:$rd);
2211 dag InOperandList = (ins GPROpnd:$rs);
2212 string AsmString = !strconcat(instr_asm, "\t$rd, $rs");
2213 list<dag> Pattern = [];
2216 class JR_HB_DESC : InstSE<(outs), (ins), "", [], II_JR_HB, FrmJ>,
2217 JR_HB_DESC_BASE<"jr.hb", GPR32Opnd> {
2219 let isIndirectBranch=1;
2226 class JALR_HB_DESC : InstSE<(outs), (ins), "", [], II_JALR_HB, FrmJ>,
2227 JALR_HB_DESC_BASE<"jalr.hb", GPR32Opnd> {
2228 let isIndirectBranch=1;
2233 class JR_HB_ENC : JR_HB_FM<8>;
2234 class JALR_HB_ENC : JALR_HB_FM<9>;
2236 def JR_HB : JR_HB_DESC, JR_HB_ENC, ISA_MIPS32_NOT_32R6_64R6;
2237 def JALR_HB : JALR_HB_DESC, JALR_HB_ENC, ISA_MIPS32;
2239 class TLB<string asmstr, InstrItinClass itin = NoItinerary> :
2240 InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2241 let AdditionalPredicates = [NotInMicroMips] in {
2242 def TLBP : MMRel, TLB<"tlbp", II_TLBP>, COP0_TLB_FM<0x08>;
2243 def TLBR : MMRel, TLB<"tlbr", II_TLBR>, COP0_TLB_FM<0x01>;
2244 def TLBWI : MMRel, TLB<"tlbwi", II_TLBWI>, COP0_TLB_FM<0x02>;
2245 def TLBWR : MMRel, TLB<"tlbwr", II_TLBWR>, COP0_TLB_FM<0x06>;
2247 class CacheOp<string instr_asm, Operand MemOpnd,
2248 InstrItinClass itin = NoItinerary> :
2249 InstSE<(outs), (ins MemOpnd:$addr, uimm5:$hint),
2250 !strconcat(instr_asm, "\t$hint, $addr"), [], itin, FrmOther,
2252 let DecoderMethod = "DecodeCacheOp";
2255 def CACHE : MMRel, CacheOp<"cache", mem, II_CACHE>, CACHEOP_FM<0b101111>,
2256 INSN_MIPS3_32_NOT_32R6_64R6;
2257 def PREF : MMRel, CacheOp<"pref", mem, II_PREF>, CACHEOP_FM<0b110011>,
2258 INSN_MIPS3_32_NOT_32R6_64R6;
2260 def ROL : MipsAsmPseudoInst<(outs),
2261 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2262 "rol\t$rs, $rt, $rd">;
2263 def ROLImm : MipsAsmPseudoInst<(outs),
2264 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2265 "rol\t$rs, $rt, $imm">;
2266 def : MipsInstAlias<"rol $rd, $rs",
2267 (ROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2268 def : MipsInstAlias<"rol $rd, $imm",
2269 (ROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2271 def ROR : MipsAsmPseudoInst<(outs),
2272 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2273 "ror\t$rs, $rt, $rd">;
2274 def RORImm : MipsAsmPseudoInst<(outs),
2275 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2276 "ror\t$rs, $rt, $imm">;
2277 def : MipsInstAlias<"ror $rd, $rs",
2278 (ROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2279 def : MipsInstAlias<"ror $rd, $imm",
2280 (RORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2282 def DROL : MipsAsmPseudoInst<(outs),
2283 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2284 "drol\t$rs, $rt, $rd">, ISA_MIPS64;
2285 def DROLImm : MipsAsmPseudoInst<(outs),
2286 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2287 "drol\t$rs, $rt, $imm">, ISA_MIPS64;
2288 def : MipsInstAlias<"drol $rd, $rs",
2289 (DROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
2290 def : MipsInstAlias<"drol $rd, $imm",
2291 (DROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
2293 def DROR : MipsAsmPseudoInst<(outs),
2294 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2295 "dror\t$rs, $rt, $rd">, ISA_MIPS64;
2296 def DRORImm : MipsAsmPseudoInst<(outs),
2297 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2298 "dror\t$rs, $rt, $imm">, ISA_MIPS64;
2299 def : MipsInstAlias<"dror $rd, $rs",
2300 (DROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
2301 def : MipsInstAlias<"dror $rd, $imm",
2302 (DRORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
2304 def ABSMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2307 def SEQMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2308 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2309 "seq $rd, $rs, $rt">, NOT_ASE_CNMIPS;
2311 def : MipsInstAlias<"seq $rd, $rs",
2312 (SEQMacro GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>,
2315 def SEQIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2316 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
2317 "seq $rd, $rs, $imm">, NOT_ASE_CNMIPS;
2319 def : MipsInstAlias<"seq $rd, $imm",
2320 (SEQIMacro GPR32Opnd:$rd, GPR32Opnd:$rd, simm32:$imm), 0>,
2323 def MULImmMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2324 simm32_relaxed:$imm),
2325 "mul\t$rd, $rs, $imm">,
2326 ISA_MIPS1_NOT_32R6_64R6;
2327 def MULOMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2329 "mulo\t$rd, $rs, $rt">,
2330 ISA_MIPS1_NOT_32R6_64R6;
2331 def MULOUMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2333 "mulou\t$rd, $rs, $rt">,
2334 ISA_MIPS1_NOT_32R6_64R6;
2336 //===----------------------------------------------------------------------===//
2337 // Instruction aliases
2338 //===----------------------------------------------------------------------===//
2340 multiclass OneOrTwoOperandMacroImmediateAlias<string Memnomic,
2342 RegisterOperand RO = GPR32Opnd,
2343 Operand Imm = simm32_relaxed> {
2344 def : MipsInstAlias<!strconcat(Memnomic, " $rs, $rt, $imm"),
2348 def : MipsInstAlias<!strconcat(Memnomic, " $rs, $imm"),
2354 def : MipsInstAlias<"move $dst, $src",
2355 (OR GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2357 let AdditionalPredicates = [NotInMicroMips];
2359 def : MipsInstAlias<"move $dst, $src",
2360 (ADDu GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2362 let AdditionalPredicates = [NotInMicroMips];
2364 def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>,
2365 ISA_MIPS1_NOT_32R6_64R6;
2367 def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>;
2368 let Predicates = [NotInMicroMips] in {
2369 def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
2371 def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>, ISA_MIPS32;
2372 def : MipsInstAlias<"neg $rt, $rs",
2373 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
2374 def : MipsInstAlias<"neg $rt",
2375 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>;
2376 def : MipsInstAlias<"negu $rt, $rs",
2377 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
2378 def : MipsInstAlias<"negu $rt",
2379 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>;
2380 let AdditionalPredicates = [NotInMicroMips] in {
2381 def : MipsInstAlias<
2382 "sgt $rd, $rs, $rt",
2383 (SLT GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2384 def : MipsInstAlias<
2386 (SLT GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2387 def : MipsInstAlias<
2388 "sgtu $rd, $rs, $rt",
2389 (SLTu GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2390 def : MipsInstAlias<
2392 (SLTu GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2393 def : MipsInstAlias<
2395 (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>;
2396 def : MipsInstAlias<
2398 (NOR GPR32Opnd:$rt, GPR32Opnd:$rt, ZERO), 0>;
2399 def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>;
2401 defm : OneOrTwoOperandMacroImmediateAlias<"add", ADDi>, ISA_MIPS1_NOT_32R6_64R6;
2403 defm : OneOrTwoOperandMacroImmediateAlias<"addu", ADDiu>;
2405 defm : OneOrTwoOperandMacroImmediateAlias<"and", ANDi>, GPR_32;
2407 defm : OneOrTwoOperandMacroImmediateAlias<"or", ORi>, GPR_32;
2409 defm : OneOrTwoOperandMacroImmediateAlias<"xor", XORi>, GPR_32;
2411 defm : OneOrTwoOperandMacroImmediateAlias<"slt", SLTi>, GPR_32;
2413 defm : OneOrTwoOperandMacroImmediateAlias<"sltu", SLTiu>, GPR_32;
2415 def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>;
2416 def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>;
2417 def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, COP2Opnd:$rd, 0), 0>;
2418 def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 COP2Opnd:$rd, GPR32Opnd:$rt, 0), 0>;
2419 let AdditionalPredicates = [NotInMicroMips] in {
2420 def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>;
2422 def : MipsInstAlias<"bnez $rs,$offset",
2423 (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
2424 def : MipsInstAlias<"bnezl $rs,$offset",
2425 (BNEL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
2426 def : MipsInstAlias<"beqz $rs,$offset",
2427 (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
2428 def : MipsInstAlias<"beqzl $rs,$offset",
2429 (BEQL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
2430 let AdditionalPredicates = [NotInMicroMips] in {
2431 def : MipsInstAlias<"syscall", (SYSCALL 0), 1>;
2434 def : MipsInstAlias<"break", (BREAK 0, 0), 1>;
2435 def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>;
2436 let AdditionalPredicates = [NotInMicroMips] in {
2437 def : MipsInstAlias<"ei", (EI ZERO), 1>, ISA_MIPS32R2;
2438 def : MipsInstAlias<"di", (DI ZERO), 1>, ISA_MIPS32R2;
2440 let AdditionalPredicates = [NotInMicroMips] in {
2441 def : MipsInstAlias<"teq $rs, $rt",
2442 (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2443 def : MipsInstAlias<"tge $rs, $rt",
2444 (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2445 def : MipsInstAlias<"tgeu $rs, $rt",
2446 (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2447 def : MipsInstAlias<"tlt $rs, $rt",
2448 (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2449 def : MipsInstAlias<"tltu $rs, $rt",
2450 (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2451 def : MipsInstAlias<"tne $rs, $rt",
2452 (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2454 def : MipsInstAlias<"sub, $rd, $rs, $imm",
2455 (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs,
2456 InvertedImOperand:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6;
2457 def : MipsInstAlias<"sub $rs, $imm",
2458 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm),
2459 0>, ISA_MIPS1_NOT_32R6_64R6;
2460 def : MipsInstAlias<"subu, $rd, $rs, $imm",
2461 (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs,
2462 InvertedImOperand:$imm), 0>;
2463 def : MipsInstAlias<"subu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs,
2464 InvertedImOperand:$imm), 0>;
2465 let AdditionalPredicates = [NotInMicroMips] in {
2466 def : MipsInstAlias<"sll $rd, $rt, $rs",
2467 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2468 def : MipsInstAlias<"sra $rd, $rt, $rs",
2469 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2470 def : MipsInstAlias<"srl $rd, $rt, $rs",
2471 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2472 def : MipsInstAlias<"sll $rd, $rt",
2473 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2474 def : MipsInstAlias<"sra $rd, $rt",
2475 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2476 def : MipsInstAlias<"srl $rd, $rt",
2477 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2478 def : MipsInstAlias<"seh $rd", (SEH GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
2480 def : MipsInstAlias<"seb $rd", (SEB GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
2483 def : MipsInstAlias<"sdbbp", (SDBBP 0)>, ISA_MIPS32_NOT_32R6_64R6;
2484 def : MipsInstAlias<"sync",
2485 (SYNC 0), 1>, ISA_MIPS2;
2487 def : MipsInstAlias<"mulo $rs, $rt",
2488 (MULOMacro GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2489 ISA_MIPS1_NOT_32R6_64R6;
2490 def : MipsInstAlias<"mulou $rs, $rt",
2491 (MULOUMacro GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2492 ISA_MIPS1_NOT_32R6_64R6;
2494 //===----------------------------------------------------------------------===//
2495 // Assembler Pseudo Instructions
2496 //===----------------------------------------------------------------------===//
2498 // We use uimm32_coerced to accept a 33 bit signed number that is rendered into
2500 class LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> :
2501 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2502 !strconcat(instr_asm, "\t$rt, $imm32")> ;
2503 def LoadImm32 : LoadImmediate32<"li", uimm32_coerced, GPR32Opnd>;
2505 class LoadAddressFromReg32<string instr_asm, Operand MemOpnd,
2506 RegisterOperand RO> :
2507 MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
2508 !strconcat(instr_asm, "\t$rt, $addr")> ;
2509 def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>;
2511 class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> :
2512 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2513 !strconcat(instr_asm, "\t$rt, $imm32")> ;
2514 def LoadAddrImm32 : LoadAddressFromImm32<"la", i32imm, GPR32Opnd>;
2516 def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2518 def JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs),
2521 class NORIMM_DESC_BASE<RegisterOperand RO, DAGOperand Imm> :
2522 MipsAsmPseudoInst<(outs RO:$rs), (ins RO:$rt, Imm:$imm),
2523 "nor\t$rs, $rt, $imm">;
2524 def NORImm : NORIMM_DESC_BASE<GPR32Opnd, simm32_relaxed>, GPR_32;
2525 def : MipsInstAlias<"nor\t$rs, $imm", (NORImm GPR32Opnd:$rs, GPR32Opnd:$rs,
2526 simm32_relaxed:$imm)>, GPR_32;
2528 let hasDelaySlot = 1, isCTI = 1 in {
2529 def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2530 (ins imm64:$imm64, brtarget:$offset),
2531 "bne\t$rt, $imm64, $offset">;
2532 def BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2533 (ins imm64:$imm64, brtarget:$offset),
2534 "beq\t$rt, $imm64, $offset">;
2536 class CondBranchPseudo<string instr_asm> :
2537 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt,
2539 !strconcat(instr_asm, "\t$rs, $rt, $offset")>;
2542 def BLT : CondBranchPseudo<"blt">;
2543 def BLE : CondBranchPseudo<"ble">;
2544 def BGE : CondBranchPseudo<"bge">;
2545 def BGT : CondBranchPseudo<"bgt">;
2546 def BLTU : CondBranchPseudo<"bltu">;
2547 def BLEU : CondBranchPseudo<"bleu">;
2548 def BGEU : CondBranchPseudo<"bgeu">;
2549 def BGTU : CondBranchPseudo<"bgtu">;
2550 def BLTL : CondBranchPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2551 def BLEL : CondBranchPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2552 def BGEL : CondBranchPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2553 def BGTL : CondBranchPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2554 def BLTUL: CondBranchPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2555 def BLEUL: CondBranchPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2556 def BGEUL: CondBranchPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2557 def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
2560 class CondBranchImmPseudo<string instr_asm> :
2561 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, imm64:$imm, brtarget:$offset),
2562 !strconcat(instr_asm, "\t$rs, $imm, $offset")>;
2564 def BEQLImmMacro : CondBranchImmPseudo<"beql">, ISA_MIPS2_NOT_32R6_64R6;
2565 def BNELImmMacro : CondBranchImmPseudo<"bnel">, ISA_MIPS2_NOT_32R6_64R6;
2567 def BLTImmMacro : CondBranchImmPseudo<"blt">;
2568 def BLEImmMacro : CondBranchImmPseudo<"ble">;
2569 def BGEImmMacro : CondBranchImmPseudo<"bge">;
2570 def BGTImmMacro : CondBranchImmPseudo<"bgt">;
2571 def BLTUImmMacro : CondBranchImmPseudo<"bltu">;
2572 def BLEUImmMacro : CondBranchImmPseudo<"bleu">;
2573 def BGEUImmMacro : CondBranchImmPseudo<"bgeu">;
2574 def BGTUImmMacro : CondBranchImmPseudo<"bgtu">;
2575 def BLTLImmMacro : CondBranchImmPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2576 def BLELImmMacro : CondBranchImmPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2577 def BGELImmMacro : CondBranchImmPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2578 def BGTLImmMacro : CondBranchImmPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2579 def BLTULImmMacro : CondBranchImmPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2580 def BLEULImmMacro : CondBranchImmPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2581 def BGEULImmMacro : CondBranchImmPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2582 def BGTULImmMacro : CondBranchImmPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
2584 // FIXME: Predicates are removed because instructions are matched regardless of
2585 // predicates, because PredicateControl was not in the hierarchy. This was
2586 // done to emit more precise error message from expansion function.
2587 // Once the tablegen-erated errors are made better, this needs to be fixed and
2588 // predicates needs to be restored.
2590 def SDivMacro : MipsAsmPseudoInst<(outs GPR32NonZeroOpnd:$rd),
2591 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2592 "div\t$rd, $rs, $rt">,
2593 ISA_MIPS1_NOT_32R6_64R6;
2594 def SDivIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2595 (ins GPR32Opnd:$rs, simm32:$imm),
2596 "div\t$rd, $rs, $imm">,
2597 ISA_MIPS1_NOT_32R6_64R6;
2598 def UDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2599 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2600 "divu\t$rd, $rs, $rt">,
2601 ISA_MIPS1_NOT_32R6_64R6;
2602 def UDivIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2603 (ins GPR32Opnd:$rs, simm32:$imm),
2604 "divu\t$rd, $rs, $imm">,
2605 ISA_MIPS1_NOT_32R6_64R6;
2608 def : MipsInstAlias<"div $rs, $rt", (SDIV GPR32ZeroOpnd:$rs,
2610 ISA_MIPS1_NOT_32R6_64R6;
2611 def : MipsInstAlias<"div $rs, $rt", (SDivMacro GPR32NonZeroOpnd:$rs,
2612 GPR32NonZeroOpnd:$rs,
2614 ISA_MIPS1_NOT_32R6_64R6;
2615 def : MipsInstAlias<"div $rd, $imm", (SDivIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
2617 ISA_MIPS1_NOT_32R6_64R6;
2619 def : MipsInstAlias<"divu $rt, $rs", (UDIV GPR32ZeroOpnd:$rt,
2621 ISA_MIPS1_NOT_32R6_64R6;
2622 def : MipsInstAlias<"divu $rt, $rs", (UDivMacro GPR32NonZeroOpnd:$rt,
2623 GPR32NonZeroOpnd:$rt,
2625 ISA_MIPS1_NOT_32R6_64R6;
2627 def : MipsInstAlias<"divu $rd, $imm", (UDivIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
2629 ISA_MIPS1_NOT_32R6_64R6;
2631 def Ulh : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2632 "ulh\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2634 def Ulhu : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2635 "ulhu\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2637 def Ulw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2638 "ulw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2640 def Ush : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2641 "ush\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2643 def Usw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2644 "usw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2646 def LDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2647 (ins mem_simm16:$addr), "ld $rt, $addr">,
2648 ISA_MIPS1_NOT_MIPS3;
2649 def SDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2650 (ins mem_simm16:$addr), "sd $rt, $addr">,
2651 ISA_MIPS1_NOT_MIPS3;
2652 //===----------------------------------------------------------------------===//
2653 // Arbitrary patterns that map to one or more instructions
2654 //===----------------------------------------------------------------------===//
2656 // Load/store pattern templates.
2657 class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
2658 MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
2660 class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
2661 MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
2663 // Materialize constants.
2664 multiclass MaterializeImms<ValueType VT, Register ZEROReg,
2665 Instruction ADDiuOp, Instruction LUiOp,
2666 Instruction ORiOp> {
2669 def : MipsPat<(VT immSExt16:$imm), (ADDiuOp ZEROReg, imm:$imm)>;
2670 def : MipsPat<(VT immZExt16:$imm), (ORiOp ZEROReg, imm:$imm)>;
2672 // Bits 32-16 set, sign/zero extended.
2673 def : MipsPat<(VT immSExt32Low16Zero:$imm), (LUiOp (HI16 imm:$imm))>;
2675 // Arbitrary immediates
2676 def : MipsPat<(VT immSExt32:$imm), (ORiOp (LUiOp (HI16 imm:$imm)), (LO16 imm:$imm))>;
2679 let AdditionalPredicates = [NotInMicroMips] in
2680 defm : MaterializeImms<i32, ZERO, ADDiu, LUi, ORi>;
2682 // Carry MipsPatterns
2683 let AdditionalPredicates = [NotInMicroMips] in {
2684 def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
2685 (SUBu GPR32:$lhs, GPR32:$rhs)>;
2687 def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
2688 (ADDu GPR32:$lhs, GPR32:$rhs)>, ASE_NOT_DSP;
2689 def : MipsPat<(addc GPR32:$src, immSExt16:$imm),
2690 (ADDiu GPR32:$src, imm:$imm)>, ASE_NOT_DSP;
2692 // Support multiplication for pre-Mips32 targets that don't have
2693 // the MUL instruction.
2694 def : MipsPat<(mul GPR32:$lhs, GPR32:$rhs),
2695 (PseudoMFLO (PseudoMULT GPR32:$lhs, GPR32:$rhs))>,
2696 ISA_MIPS1_NOT_32R6_64R6;
2699 def : MipsPat<(MipsSync (i32 immz)),
2700 (SYNC 0)>, ISA_MIPS2;
2703 def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
2704 (JAL texternalsym:$dst)>;
2705 //def : MipsPat<(MipsJmpLink GPR32:$dst),
2706 // (JALR GPR32:$dst)>;
2709 def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
2710 (TAILCALL tglobaladdr:$dst)>;
2711 def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
2712 (TAILCALL texternalsym:$dst)>;
2714 multiclass MipsHiLoRelocs<Instruction Lui, Instruction Addiu,
2715 Register ZeroReg, RegisterOperand GPROpnd> {
2716 def : MipsPat<(MipsHi tglobaladdr:$in), (Lui tglobaladdr:$in)>;
2717 def : MipsPat<(MipsHi tblockaddress:$in), (Lui tblockaddress:$in)>;
2718 def : MipsPat<(MipsHi tjumptable:$in), (Lui tjumptable:$in)>;
2719 def : MipsPat<(MipsHi tconstpool:$in), (Lui tconstpool:$in)>;
2720 def : MipsPat<(MipsHi tglobaltlsaddr:$in), (Lui tglobaltlsaddr:$in)>;
2721 def : MipsPat<(MipsHi texternalsym:$in), (Lui texternalsym:$in)>;
2723 def : MipsPat<(MipsLo tglobaladdr:$in), (Addiu ZeroReg, tglobaladdr:$in)>;
2724 def : MipsPat<(MipsLo tblockaddress:$in),
2725 (Addiu ZeroReg, tblockaddress:$in)>;
2726 def : MipsPat<(MipsLo tjumptable:$in), (Addiu ZeroReg, tjumptable:$in)>;
2727 def : MipsPat<(MipsLo tconstpool:$in), (Addiu ZeroReg, tconstpool:$in)>;
2728 def : MipsPat<(MipsLo tglobaltlsaddr:$in),
2729 (Addiu ZeroReg, tglobaltlsaddr:$in)>;
2730 def : MipsPat<(MipsLo texternalsym:$in), (Addiu ZeroReg, texternalsym:$in)>;
2732 def : MipsPat<(add GPROpnd:$hi, (MipsLo tglobaladdr:$lo)),
2733 (Addiu GPROpnd:$hi, tglobaladdr:$lo)>;
2734 def : MipsPat<(add GPROpnd:$hi, (MipsLo tblockaddress:$lo)),
2735 (Addiu GPROpnd:$hi, tblockaddress:$lo)>;
2736 def : MipsPat<(add GPROpnd:$hi, (MipsLo tjumptable:$lo)),
2737 (Addiu GPROpnd:$hi, tjumptable:$lo)>;
2738 def : MipsPat<(add GPROpnd:$hi, (MipsLo tconstpool:$lo)),
2739 (Addiu GPROpnd:$hi, tconstpool:$lo)>;
2740 def : MipsPat<(add GPROpnd:$hi, (MipsLo tglobaltlsaddr:$lo)),
2741 (Addiu GPROpnd:$hi, tglobaltlsaddr:$lo)>;
2744 defm : MipsHiLoRelocs<LUi, ADDiu, ZERO, GPR32Opnd>;
2746 def : MipsPat<(MipsGotHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
2747 def : MipsPat<(MipsGotHi texternalsym:$in), (LUi texternalsym:$in)>;
2750 def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
2751 (ADDiu GPR32:$gp, tglobaladdr:$in)>;
2752 def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
2753 (ADDiu GPR32:$gp, tconstpool:$in)>;
2756 class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
2757 MipsPat<(MipsWrapper RC:$gp, node:$in),
2758 (ADDiuOp RC:$gp, node:$in)>;
2760 def : WrapperPat<tglobaladdr, ADDiu, GPR32>;
2761 def : WrapperPat<tconstpool, ADDiu, GPR32>;
2762 def : WrapperPat<texternalsym, ADDiu, GPR32>;
2763 def : WrapperPat<tblockaddress, ADDiu, GPR32>;
2764 def : WrapperPat<tjumptable, ADDiu, GPR32>;
2765 def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>;
2767 let AdditionalPredicates = [NotInMicroMips] in {
2768 // Mips does not have "not", so we expand our way
2769 def : MipsPat<(not GPR32:$in),
2770 (NOR GPR32Opnd:$in, ZERO)>;
2774 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>;
2775 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>;
2776 let AdditionalPredicates = [NotInMicroMips] in {
2777 def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
2781 def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>;
2784 multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BEQOp1,
2785 Instruction BNEOp, Instruction SLTOp, Instruction SLTuOp,
2786 Instruction SLTiOp, Instruction SLTiuOp,
2788 def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
2789 (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
2790 def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
2791 (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
2793 def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
2794 (BEQOp1 (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
2795 def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
2796 (BEQOp1 (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
2797 def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
2798 (BEQOp1 (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
2799 def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
2800 (BEQOp1 (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
2801 def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
2802 (BEQOp1 (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
2803 def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
2804 (BEQOp1 (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
2806 def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
2807 (BEQOp1 (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
2808 def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
2809 (BEQOp1 (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
2811 def : MipsPat<(brcond RC:$cond, bb:$dst),
2812 (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
2814 let AdditionalPredicates = [NotInMicroMips] in {
2815 defm : BrcondPats<GPR32, BEQ, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>;
2817 def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
2818 (BLEZ i32:$lhs, bb:$dst)>;
2819 def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
2820 (BGEZ i32:$lhs, bb:$dst)>;
2823 multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp,
2824 Instruction SLTuOp, Register ZEROReg> {
2825 def : MipsPat<(seteq RC:$lhs, 0),
2826 (SLTiuOp RC:$lhs, 1)>;
2827 def : MipsPat<(setne RC:$lhs, 0),
2828 (SLTuOp ZEROReg, RC:$lhs)>;
2829 def : MipsPat<(seteq RC:$lhs, RC:$rhs),
2830 (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>;
2831 def : MipsPat<(setne RC:$lhs, RC:$rhs),
2832 (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
2835 multiclass SetlePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp,
2836 Instruction SLTuOp> {
2837 def : MipsPat<(setle RC:$lhs, RC:$rhs),
2838 (XORiOp (SLTOp RC:$rhs, RC:$lhs), 1)>;
2839 def : MipsPat<(setule RC:$lhs, RC:$rhs),
2840 (XORiOp (SLTuOp RC:$rhs, RC:$lhs), 1)>;
2843 multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
2844 def : MipsPat<(setgt RC:$lhs, RC:$rhs),
2845 (SLTOp RC:$rhs, RC:$lhs)>;
2846 def : MipsPat<(setugt RC:$lhs, RC:$rhs),
2847 (SLTuOp RC:$rhs, RC:$lhs)>;
2850 multiclass SetgePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp,
2851 Instruction SLTuOp> {
2852 def : MipsPat<(setge RC:$lhs, RC:$rhs),
2853 (XORiOp (SLTOp RC:$lhs, RC:$rhs), 1)>;
2854 def : MipsPat<(setuge RC:$lhs, RC:$rhs),
2855 (XORiOp (SLTuOp RC:$lhs, RC:$rhs), 1)>;
2858 multiclass SetgeImmPats<RegisterClass RC, Instruction XORiOp,
2859 Instruction SLTiOp, Instruction SLTiuOp> {
2860 def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
2861 (XORiOp (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
2862 def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
2863 (XORiOp (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
2866 let AdditionalPredicates = [NotInMicroMips] in {
2867 defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>;
2868 defm : SetlePats<GPR32, XORi, SLT, SLTu>;
2869 defm : SetgtPats<GPR32, SLT, SLTu>;
2870 defm : SetgePats<GPR32, XORi, SLT, SLTu>;
2871 defm : SetgeImmPats<GPR32, XORi, SLTi, SLTiu>;
2875 def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>;
2877 // Load halfword/word patterns.
2878 let AddedComplexity = 40 in {
2879 def : LoadRegImmPat<LBu, i32, zextloadi8>;
2880 let AdditionalPredicates = [NotInMicroMips] in {
2881 def : LoadRegImmPat<LH, i32, sextloadi16>;
2882 def : LoadRegImmPat<LW, i32, load>;
2886 // Atomic load patterns.
2887 def : MipsPat<(atomic_load_8 addr:$a), (LB addr:$a)>;
2888 let AdditionalPredicates = [NotInMicroMips] in {
2889 def : MipsPat<(atomic_load_16 addr:$a), (LH addr:$a)>;
2891 def : MipsPat<(atomic_load_32 addr:$a), (LW addr:$a)>;
2893 // Atomic store patterns.
2894 def : MipsPat<(atomic_store_8 addr:$a, GPR32:$v), (SB GPR32:$v, addr:$a)>;
2895 def : MipsPat<(atomic_store_16 addr:$a, GPR32:$v), (SH GPR32:$v, addr:$a)>;
2896 def : MipsPat<(atomic_store_32 addr:$a, GPR32:$v), (SW GPR32:$v, addr:$a)>;
2898 //===----------------------------------------------------------------------===//
2899 // Floating Point Support
2900 //===----------------------------------------------------------------------===//
2902 include "MipsInstrFPU.td"
2903 include "Mips64InstrInfo.td"
2904 include "MipsCondMov.td"
2906 include "Mips32r6InstrInfo.td"
2907 include "Mips64r6InstrInfo.td"
2912 include "Mips16InstrFormats.td"
2913 include "Mips16InstrInfo.td"
2916 include "MipsDSPInstrFormats.td"
2917 include "MipsDSPInstrInfo.td"
2920 include "MipsMSAInstrFormats.td"
2921 include "MipsMSAInstrInfo.td"
2924 include "MipsEVAInstrFormats.td"
2925 include "MipsEVAInstrInfo.td"
2928 include "MipsMTInstrFormats.td"
2929 include "MipsMTInstrInfo.td"
2932 include "MicroMipsInstrFormats.td"
2933 include "MicroMipsInstrInfo.td"
2934 include "MicroMipsInstrFPU.td"
2937 include "MicroMips32r6InstrFormats.td"
2938 include "MicroMips32r6InstrInfo.td"
2941 include "MicroMips64r6InstrFormats.td"
2942 include "MicroMips64r6InstrInfo.td"
2945 include "MicroMipsDSPInstrFormats.td"
2946 include "MicroMipsDSPInstrInfo.td"