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 InMips16Mode : Predicate<"Subtarget->inMips16Mode()">,
212 AssemblerPredicate<"FeatureMips16">;
213 def NotInMips16Mode : 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 IsN64 : Predicate<"Subtarget->isABI_N64()">;
224 def IsNotN64 : Predicate<"!Subtarget->isABI_N64()">;
225 def RelocNotPIC : Predicate<"!TM.isPositionIndependent()">;
226 def RelocPIC : Predicate<"TM.isPositionIndependent()">;
227 def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">;
228 def HasStdEnc : Predicate<"Subtarget->hasStandardEncoding()">,
229 AssemblerPredicate<"!FeatureMips16">;
230 def NotDSP : Predicate<"!Subtarget->hasDSP()">;
231 def InMicroMips : Predicate<"Subtarget->inMicroMipsMode()">,
232 AssemblerPredicate<"FeatureMicroMips">;
233 def NotInMicroMips : Predicate<"!Subtarget->inMicroMipsMode()">,
234 AssemblerPredicate<"!FeatureMicroMips">;
235 def IsLE : Predicate<"Subtarget->isLittle()">;
236 def IsBE : Predicate<"!Subtarget->isLittle()">;
237 def IsNotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
238 def UseTCCInDIV : AssemblerPredicate<"FeatureUseTCCInDIV">;
239 def HasEVA : Predicate<"Subtarget->hasEVA()">,
240 AssemblerPredicate<"FeatureEVA,FeatureMips32r2">;
241 def HasMSA : Predicate<"Subtarget->hasMSA()">,
242 AssemblerPredicate<"FeatureMSA">;
243 def HasMadd4 : Predicate<"!Subtarget->disableMadd4()">,
244 AssemblerPredicate<"!FeatureMadd4">;
245 def HasMT : Predicate<"Subtarget->hasMT()">,
246 AssemblerPredicate<"FeatureMT">;
248 //===----------------------------------------------------------------------===//
249 // Mips GPR size adjectives.
250 // They are mutually exclusive.
251 //===----------------------------------------------------------------------===//
253 class GPR_32 { list<Predicate> GPRPredicates = [IsGP32bit]; }
254 class GPR_64 { list<Predicate> GPRPredicates = [IsGP64bit]; }
256 class PTR_32 { list<Predicate> PTRPredicates = [IsPTR32bit]; }
257 class PTR_64 { list<Predicate> PTRPredicates = [IsPTR64bit]; }
259 //===----------------------------------------------------------------------===//
260 // Mips Symbol size adjectives.
261 // They are mutally exculsive.
262 //===----------------------------------------------------------------------===//
264 class SYM_32 { list<Predicate> SYMPredicates = [IsSym32]; }
265 class SYM_64 { list<Predicate> SYMPredicates = [IsSym64]; }
267 //===----------------------------------------------------------------------===//
268 // Mips ISA/ASE membership and instruction group membership adjectives.
269 // They are mutually exclusive.
270 //===----------------------------------------------------------------------===//
272 // FIXME: I'd prefer to use additive predicates to build the instruction sets
273 // but we are short on assembler feature bits at the moment. Using a
274 // subtractive predicate will hopefully keep us under the 32 predicate
275 // limit long enough to develop an alternative way to handle P1||P2
277 class ISA_MIPS1_NOT_MIPS3 {
278 list<Predicate> InsnPredicates = [NotMips3];
280 class ISA_MIPS1_NOT_4_32 {
281 list<Predicate> InsnPredicates = [NotMips4_32];
283 class ISA_MIPS1_NOT_32R6_64R6 {
284 list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6];
286 class ISA_MIPS2 { list<Predicate> InsnPredicates = [HasMips2]; }
287 class ISA_MIPS2_NOT_32R6_64R6 {
288 list<Predicate> InsnPredicates = [HasMips2, NotMips32r6, NotMips64r6];
290 class ISA_MIPS3 { list<Predicate> InsnPredicates = [HasMips3]; }
291 class ISA_MIPS3_NOT_32R6_64R6 {
292 list<Predicate> InsnPredicates = [HasMips3, NotMips32r6, NotMips64r6];
294 class ISA_MIPS32 { list<Predicate> InsnPredicates = [HasMips32]; }
295 class ISA_MIPS32_NOT_32R6_64R6 {
296 list<Predicate> InsnPredicates = [HasMips32, NotMips32r6, NotMips64r6];
298 class ISA_MIPS32R2 { list<Predicate> InsnPredicates = [HasMips32r2]; }
299 class ISA_MIPS32R2_NOT_32R6_64R6 {
300 list<Predicate> InsnPredicates = [HasMips32r2, NotMips32r6, NotMips64r6];
302 class ISA_MIPS32R5 { list<Predicate> InsnPredicates = [HasMips32r5]; }
303 class ISA_MIPS64 { list<Predicate> InsnPredicates = [HasMips64]; }
304 class ISA_MIPS64_NOT_64R6 {
305 list<Predicate> InsnPredicates = [HasMips64, NotMips64r6];
307 class ISA_MIPS64R2 { list<Predicate> InsnPredicates = [HasMips64r2]; }
308 class ISA_MIPS32R6 { list<Predicate> InsnPredicates = [HasMips32r6]; }
309 class ISA_MIPS64R6 { list<Predicate> InsnPredicates = [HasMips64r6]; }
310 class ISA_MICROMIPS { list<Predicate> InsnPredicates = [InMicroMips]; }
311 class ISA_MICROMIPS32R6 {
312 list<Predicate> InsnPredicates = [HasMicroMips32r6];
314 class ISA_MICROMIPS32_NOT_MIPS32R6 {
315 list<Predicate> InsnPredicates = [InMicroMips, NotMips32r6];
318 class INSN_EVA { list<Predicate> InsnPredicates = [HasEVA]; }
319 class INSN_EVA_NOT_32R6_64R6 {
320 list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6, HasEVA];
323 // The portions of MIPS-III that were also added to MIPS32
324 class INSN_MIPS3_32 { list<Predicate> InsnPredicates = [HasMips3_32]; }
326 // The portions of MIPS-III that were also added to MIPS32 but were removed in
327 // MIPS32r6 and MIPS64r6.
328 class INSN_MIPS3_32_NOT_32R6_64R6 {
329 list<Predicate> InsnPredicates = [HasMips3_32, NotMips32r6, NotMips64r6];
332 // The portions of MIPS-III that were also added to MIPS32
333 class INSN_MIPS3_32R2 { list<Predicate> InsnPredicates = [HasMips3_32r2]; }
335 // The portions of MIPS-IV that were also added to MIPS32.
336 class INSN_MIPS4_32 { list <Predicate> InsnPredicates = [HasMips4_32]; }
338 // The portions of MIPS-IV that were also added to MIPS32 but were removed in
339 // MIPS32r6 and MIPS64r6.
340 class INSN_MIPS4_32_NOT_32R6_64R6 {
341 list<Predicate> InsnPredicates = [HasMips4_32, NotMips32r6, NotMips64r6];
344 // The portions of MIPS-IV that were also added to MIPS32r2 but were removed in
345 // MIPS32r6 and MIPS64r6.
346 class INSN_MIPS4_32R2_NOT_32R6_64R6 {
347 list<Predicate> InsnPredicates = [HasMips4_32r2, NotMips32r6, NotMips64r6];
350 // The portions of MIPS-IV that were also added to MIPS32r2.
351 class INSN_MIPS4_32R2 {
352 list<Predicate> InsnPredicates = [HasMips4_32r2];
355 // The portions of MIPS-V that were also added to MIPS32r2 but were removed in
356 // MIPS32r6 and MIPS64r6.
357 class INSN_MIPS5_32R2_NOT_32R6_64R6 {
358 list<Predicate> InsnPredicates = [HasMips5_32r2, NotMips32r6, NotMips64r6];
362 list<Predicate> InsnPredicates = [HasCnMips];
365 class NOT_ASE_CNMIPS {
366 list<Predicate> InsnPredicates = [NotCnMips];
369 class ASE_MIPS64_CNMIPS {
370 list<Predicate> InsnPredicates = [HasMips64, HasCnMips];
374 list<Predicate> InsnPredicates = [HasMSA];
377 class ASE_MSA_NOT_MSA64 {
378 list<Predicate> InsnPredicates = [HasMSA, NotMips64];
382 list<Predicate> InsnPredicates = [HasMSA, HasMips64];
386 list <Predicate> InsnPredicates = [HasMT];
389 // Class used for separating microMIPSr6 and microMIPS (r3) instruction.
390 // It can be used only on instructions that doesn't inherit PredicateControl.
391 class ISA_MICROMIPS_NOT_32R6 : PredicateControl {
392 let InsnPredicates = [InMicroMips, NotMips32r6];
396 list<Predicate> InsnPredicates = [NotDSP];
400 list<Predicate> AdditionalPredicates = [HasMadd4];
403 // Classses used for separating expansions that differ based on the ABI in
406 list<Predicate> AdditionalPredicates = [IsN64];
410 list<Predicate> AdditionalPredicates = [IsNotN64];
413 //===----------------------------------------------------------------------===//
415 class MipsPat<dag pattern, dag result> : Pat<pattern, result>, PredicateControl {
416 let EncodingPredicates = [HasStdEnc];
419 class MipsInstAlias<string Asm, dag Result, bit Emit = 0b1> :
420 InstAlias<Asm, Result, Emit>, PredicateControl;
423 bit isCommutable = 1;
443 bit isTerminator = 1;
446 bit hasExtraSrcRegAllocReq = 1;
447 bit isCodeGenOnly = 1;
451 class IsAsCheapAsAMove {
452 bit isAsCheapAsAMove = 1;
455 class NeverHasSideEffects {
456 bit hasSideEffects = 0;
459 //===----------------------------------------------------------------------===//
460 // Instruction format superclass
461 //===----------------------------------------------------------------------===//
463 include "MipsInstrFormats.td"
465 //===----------------------------------------------------------------------===//
466 // Mips Operand, Complex Patterns and Transformations Definitions.
467 //===----------------------------------------------------------------------===//
469 class ConstantSImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
470 int Offset = 0> : AsmOperandClass {
471 let Name = "ConstantSImm" # Bits # "_" # Offset;
472 let RenderMethod = "addConstantSImmOperands<" # Bits # ", " # Offset # ">";
473 let PredicateMethod = "isConstantSImm<" # Bits # ", " # Offset # ">";
474 let SuperClasses = Supers;
475 let DiagnosticType = "SImm" # Bits # "_" # Offset;
478 class SimmLslAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
479 int Shift = 0> : AsmOperandClass {
480 let Name = "Simm" # Bits # "_Lsl" # Shift;
481 let RenderMethod = "addImmOperands";
482 let PredicateMethod = "isScaledSImm<" # Bits # ", " # Shift # ">";
483 let SuperClasses = Supers;
484 let DiagnosticType = "SImm" # Bits # "_Lsl" # Shift;
487 class ConstantUImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
488 int Offset = 0> : AsmOperandClass {
489 let Name = "ConstantUImm" # Bits # "_" # Offset;
490 let RenderMethod = "addConstantUImmOperands<" # Bits # ", " # Offset # ">";
491 let PredicateMethod = "isConstantUImm<" # Bits # ", " # Offset # ">";
492 let SuperClasses = Supers;
493 let DiagnosticType = "UImm" # Bits # "_" # Offset;
496 class ConstantUImmRangeAsmOperandClass<int Bottom, int Top,
497 list<AsmOperandClass> Supers = []>
499 let Name = "ConstantUImmRange" # Bottom # "_" # Top;
500 let RenderMethod = "addImmOperands";
501 let PredicateMethod = "isConstantUImmRange<" # Bottom # ", " # Top # ">";
502 let SuperClasses = Supers;
503 let DiagnosticType = "UImmRange" # Bottom # "_" # Top;
506 class SImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
508 let Name = "SImm" # Bits;
509 let RenderMethod = "addSImmOperands<" # Bits # ">";
510 let PredicateMethod = "isSImm<" # Bits # ">";
511 let SuperClasses = Supers;
512 let DiagnosticType = "SImm" # Bits;
515 class UImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
517 let Name = "UImm" # Bits;
518 let RenderMethod = "addUImmOperands<" # Bits # ">";
519 let PredicateMethod = "isUImm<" # Bits # ">";
520 let SuperClasses = Supers;
521 let DiagnosticType = "UImm" # Bits;
524 // Generic case - only to support certain assembly pseudo instructions.
525 class UImmAnyAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
528 let RenderMethod = "addConstantUImmOperands<32>";
529 let PredicateMethod = "isSImm<" # Bits # ">";
530 let SuperClasses = Supers;
531 let DiagnosticType = "ImmAny";
534 // AsmOperandClasses require a strict ordering which is difficult to manage
535 // as a hierarchy. Instead, we use a linear ordering and impose an order that
536 // is in some places arbitrary.
538 // Here the rules that are in use:
539 // * Wider immediates are a superset of narrower immediates:
540 // uimm4 < uimm5 < uimm6
541 // * For the same bit-width, unsigned immediates are a superset of signed
543 // simm4 < uimm4 < simm5 < uimm5
544 // * For the same upper-bound, signed immediates are a superset of unsigned
546 // uimm3 < simm4 < uimm4 < simm4
547 // * Modified immediates are a superset of ordinary immediates:
548 // uimm5 < uimm5_plus1 (1..32) < uimm5_plus32 (32..63) < uimm6
549 // The term 'superset' starts to break down here since the uimm5_plus* classes
550 // are not true supersets of uimm5 (but they are still subsets of uimm6).
551 // * 'Relaxed' immediates are supersets of the corresponding unsigned immediate.
552 // uimm16 < uimm16_relaxed
553 // * The codeGen pattern type is arbitrarily ordered.
554 // uimm5 < uimm5_64, and uimm5 < vsplat_uimm5
555 // This is entirely arbitrary. We need an ordering and what we pick is
556 // unimportant since only one is possible for a given mnemonic.
558 def UImm32CoercedAsmOperandClass : UImmAnyAsmOperandClass<33, []> {
559 let Name = "UImm32_Coerced";
560 let DiagnosticType = "UImm32_Coerced";
562 def SImm32RelaxedAsmOperandClass
563 : SImmAsmOperandClass<32, [UImm32CoercedAsmOperandClass]> {
564 let Name = "SImm32_Relaxed";
565 let PredicateMethod = "isAnyImm<33>";
566 let DiagnosticType = "SImm32_Relaxed";
568 def SImm32AsmOperandClass
569 : SImmAsmOperandClass<32, [SImm32RelaxedAsmOperandClass]>;
570 def ConstantUImm26AsmOperandClass
571 : ConstantUImmAsmOperandClass<26, [SImm32AsmOperandClass]>;
572 def ConstantUImm20AsmOperandClass
573 : ConstantUImmAsmOperandClass<20, [ConstantUImm26AsmOperandClass]>;
574 def ConstantSImm19Lsl2AsmOperandClass : AsmOperandClass {
575 let Name = "SImm19Lsl2";
576 let RenderMethod = "addImmOperands";
577 let PredicateMethod = "isScaledSImm<19, 2>";
578 let SuperClasses = [ConstantUImm20AsmOperandClass];
579 let DiagnosticType = "SImm19_Lsl2";
581 def UImm16RelaxedAsmOperandClass
582 : UImmAsmOperandClass<16, [ConstantUImm20AsmOperandClass]> {
583 let Name = "UImm16_Relaxed";
584 let PredicateMethod = "isAnyImm<16>";
585 let DiagnosticType = "UImm16_Relaxed";
587 // Similar to the relaxed classes which take an SImm and render it as
588 // an UImm, this takes a UImm and renders it as an SImm.
589 def UImm16AltRelaxedAsmOperandClass
590 : SImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]> {
591 let Name = "UImm16_AltRelaxed";
592 let PredicateMethod = "isUImm<16>";
593 let DiagnosticType = "UImm16_AltRelaxed";
595 // FIXME: One of these should probably have UImm16AsmOperandClass as the
596 // superclass instead of UImm16RelaxedasmOPerandClass.
597 def UImm16AsmOperandClass
598 : UImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]>;
599 def SImm16RelaxedAsmOperandClass
600 : SImmAsmOperandClass<16, [UImm16RelaxedAsmOperandClass]> {
601 let Name = "SImm16_Relaxed";
602 let PredicateMethod = "isAnyImm<16>";
603 let DiagnosticType = "SImm16_Relaxed";
605 def SImm16AsmOperandClass
606 : SImmAsmOperandClass<16, [SImm16RelaxedAsmOperandClass]>;
607 def ConstantSImm10Lsl3AsmOperandClass : AsmOperandClass {
608 let Name = "SImm10Lsl3";
609 let RenderMethod = "addImmOperands";
610 let PredicateMethod = "isScaledSImm<10, 3>";
611 let SuperClasses = [SImm16AsmOperandClass];
612 let DiagnosticType = "SImm10_Lsl3";
614 def ConstantSImm10Lsl2AsmOperandClass : AsmOperandClass {
615 let Name = "SImm10Lsl2";
616 let RenderMethod = "addImmOperands";
617 let PredicateMethod = "isScaledSImm<10, 2>";
618 let SuperClasses = [ConstantSImm10Lsl3AsmOperandClass];
619 let DiagnosticType = "SImm10_Lsl2";
621 def ConstantSImm11AsmOperandClass
622 : ConstantSImmAsmOperandClass<11, [ConstantSImm10Lsl2AsmOperandClass]>;
623 def ConstantSImm10Lsl1AsmOperandClass : AsmOperandClass {
624 let Name = "SImm10Lsl1";
625 let RenderMethod = "addImmOperands";
626 let PredicateMethod = "isScaledSImm<10, 1>";
627 let SuperClasses = [ConstantSImm11AsmOperandClass];
628 let DiagnosticType = "SImm10_Lsl1";
630 def ConstantUImm10AsmOperandClass
631 : ConstantUImmAsmOperandClass<10, [ConstantSImm10Lsl1AsmOperandClass]>;
632 def ConstantSImm10AsmOperandClass
633 : ConstantSImmAsmOperandClass<10, [ConstantUImm10AsmOperandClass]>;
634 def ConstantSImm9AsmOperandClass
635 : ConstantSImmAsmOperandClass<9, [ConstantSImm10AsmOperandClass]>;
636 def ConstantSImm7Lsl2AsmOperandClass : AsmOperandClass {
637 let Name = "SImm7Lsl2";
638 let RenderMethod = "addImmOperands";
639 let PredicateMethod = "isScaledSImm<7, 2>";
640 let SuperClasses = [ConstantSImm9AsmOperandClass];
641 let DiagnosticType = "SImm7_Lsl2";
643 def ConstantUImm8AsmOperandClass
644 : ConstantUImmAsmOperandClass<8, [ConstantSImm7Lsl2AsmOperandClass]>;
645 def ConstantUImm7Sub1AsmOperandClass
646 : ConstantUImmAsmOperandClass<7, [ConstantUImm8AsmOperandClass], -1> {
647 // Specify the names since the -1 offset causes invalid identifiers otherwise.
648 let Name = "UImm7_N1";
649 let DiagnosticType = "UImm7_N1";
651 def ConstantUImm7AsmOperandClass
652 : ConstantUImmAsmOperandClass<7, [ConstantUImm7Sub1AsmOperandClass]>;
653 def ConstantUImm6Lsl2AsmOperandClass : AsmOperandClass {
654 let Name = "UImm6Lsl2";
655 let RenderMethod = "addImmOperands";
656 let PredicateMethod = "isScaledUImm<6, 2>";
657 let SuperClasses = [ConstantUImm7AsmOperandClass];
658 let DiagnosticType = "UImm6_Lsl2";
660 def ConstantUImm6AsmOperandClass
661 : ConstantUImmAsmOperandClass<6, [ConstantUImm6Lsl2AsmOperandClass]>;
662 def ConstantSImm6AsmOperandClass
663 : ConstantSImmAsmOperandClass<6, [ConstantUImm6AsmOperandClass]>;
664 def ConstantUImm5Lsl2AsmOperandClass : AsmOperandClass {
665 let Name = "UImm5Lsl2";
666 let RenderMethod = "addImmOperands";
667 let PredicateMethod = "isScaledUImm<5, 2>";
668 let SuperClasses = [ConstantSImm6AsmOperandClass];
669 let DiagnosticType = "UImm5_Lsl2";
671 def ConstantUImm5_Range2_64AsmOperandClass
672 : ConstantUImmRangeAsmOperandClass<2, 64, [ConstantUImm5Lsl2AsmOperandClass]>;
673 def ConstantUImm5Plus33AsmOperandClass
674 : ConstantUImmAsmOperandClass<5, [ConstantUImm5_Range2_64AsmOperandClass],
676 def ConstantUImm5ReportUImm6AsmOperandClass
677 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus33AsmOperandClass]> {
678 let Name = "ConstantUImm5_0_Report_UImm6";
679 let DiagnosticType = "UImm5_0_Report_UImm6";
681 def ConstantUImm5Plus32AsmOperandClass
682 : ConstantUImmAsmOperandClass<
683 5, [ConstantUImm5ReportUImm6AsmOperandClass], 32>;
684 def ConstantUImm5Plus32NormalizeAsmOperandClass
685 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus32AsmOperandClass], 32> {
686 let Name = "ConstantUImm5_32_Norm";
687 // We must also subtract 32 when we render the operand.
688 let RenderMethod = "addConstantUImmOperands<5, 32, -32>";
690 def ConstantUImm5Plus1ReportUImm6AsmOperandClass
691 : ConstantUImmAsmOperandClass<
692 5, [ConstantUImm5Plus32NormalizeAsmOperandClass], 1>{
693 let Name = "ConstantUImm5_Plus1_Report_UImm6";
695 def ConstantUImm5Plus1AsmOperandClass
696 : ConstantUImmAsmOperandClass<
697 5, [ConstantUImm5Plus1ReportUImm6AsmOperandClass], 1>;
698 def ConstantUImm5AsmOperandClass
699 : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus1AsmOperandClass]>;
700 def ConstantSImm5AsmOperandClass
701 : ConstantSImmAsmOperandClass<5, [ConstantUImm5AsmOperandClass]>;
702 def ConstantUImm4AsmOperandClass
703 : ConstantUImmAsmOperandClass<4, [ConstantSImm5AsmOperandClass]>;
704 def ConstantSImm4AsmOperandClass
705 : ConstantSImmAsmOperandClass<4, [ConstantUImm4AsmOperandClass]>;
706 def ConstantUImm3AsmOperandClass
707 : ConstantUImmAsmOperandClass<3, [ConstantSImm4AsmOperandClass]>;
708 def ConstantUImm2Plus1AsmOperandClass
709 : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass], 1>;
710 def ConstantUImm2AsmOperandClass
711 : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass]>;
712 def ConstantUImm1AsmOperandClass
713 : ConstantUImmAsmOperandClass<1, [ConstantUImm2AsmOperandClass]>;
714 def ConstantImmzAsmOperandClass : AsmOperandClass {
715 let Name = "ConstantImmz";
716 let RenderMethod = "addConstantUImmOperands<1>";
717 let PredicateMethod = "isConstantImmz";
718 let SuperClasses = [ConstantUImm1AsmOperandClass];
719 let DiagnosticType = "Immz";
722 def Simm19Lsl2AsmOperand
723 : SimmLslAsmOperandClass<19, [], 2>;
725 def MipsJumpTargetAsmOperand : AsmOperandClass {
726 let Name = "JumpTarget";
727 let ParserMethod = "parseJumpTarget";
728 let PredicateMethod = "isImm";
729 let RenderMethod = "addImmOperands";
732 // Instruction operand types
733 def jmptarget : Operand<OtherVT> {
734 let EncoderMethod = "getJumpTargetOpValue";
735 let ParserMatchClass = MipsJumpTargetAsmOperand;
737 def brtarget : Operand<OtherVT> {
738 let EncoderMethod = "getBranchTargetOpValue";
739 let OperandType = "OPERAND_PCREL";
740 let DecoderMethod = "DecodeBranchTarget";
741 let ParserMatchClass = MipsJumpTargetAsmOperand;
743 def brtarget1SImm16 : Operand<OtherVT> {
744 let EncoderMethod = "getBranchTargetOpValue1SImm16";
745 let OperandType = "OPERAND_PCREL";
746 let DecoderMethod = "DecodeBranchTarget1SImm16";
747 let ParserMatchClass = MipsJumpTargetAsmOperand;
749 def calltarget : Operand<iPTR> {
750 let EncoderMethod = "getJumpTargetOpValue";
751 let ParserMatchClass = MipsJumpTargetAsmOperand;
754 def imm64: Operand<i64>;
756 def simm19_lsl2 : Operand<i32> {
757 let EncoderMethod = "getSimm19Lsl2Encoding";
758 let DecoderMethod = "DecodeSimm19Lsl2";
759 let ParserMatchClass = Simm19Lsl2AsmOperand;
762 def simm18_lsl3 : Operand<i32> {
763 let EncoderMethod = "getSimm18Lsl3Encoding";
764 let DecoderMethod = "DecodeSimm18Lsl3";
765 let ParserMatchClass = MipsJumpTargetAsmOperand;
769 def uimmz : Operand<i32> {
770 let PrintMethod = "printUImm<0>";
771 let ParserMatchClass = ConstantImmzAsmOperandClass;
774 // size operand of ins instruction
775 def uimm_range_2_64 : Operand<i32> {
776 let PrintMethod = "printUImm<6, 2>";
777 let EncoderMethod = "getSizeInsEncoding";
778 let DecoderMethod = "DecodeInsSize";
779 let ParserMatchClass = ConstantUImm5_Range2_64AsmOperandClass;
783 foreach I = {1, 2, 3, 4, 5, 6, 7, 8, 10, 20, 26} in
784 def uimm # I : Operand<i32> {
785 let PrintMethod = "printUImm<" # I # ">";
786 let ParserMatchClass =
787 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
790 def uimm2_plus1 : Operand<i32> {
791 let PrintMethod = "printUImm<2, 1>";
792 let EncoderMethod = "getUImmWithOffsetEncoding<2, 1>";
793 let DecoderMethod = "DecodeUImmWithOffset<2, 1>";
794 let ParserMatchClass = ConstantUImm2Plus1AsmOperandClass;
797 def uimm5_plus1 : Operand<i32> {
798 let PrintMethod = "printUImm<5, 1>";
799 let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
800 let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
801 let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass;
804 def uimm5_plus1_report_uimm6 : Operand<i32> {
805 let PrintMethod = "printUImm<6, 1>";
806 let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
807 let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
808 let ParserMatchClass = ConstantUImm5Plus1ReportUImm6AsmOperandClass;
811 def uimm5_plus32 : Operand<i32> {
812 let PrintMethod = "printUImm<5, 32>";
813 let ParserMatchClass = ConstantUImm5Plus32AsmOperandClass;
816 def uimm5_plus33 : Operand<i32> {
817 let PrintMethod = "printUImm<5, 33>";
818 let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
819 let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
820 let ParserMatchClass = ConstantUImm5Plus33AsmOperandClass;
823 def uimm5_inssize_plus1 : Operand<i32> {
824 let PrintMethod = "printUImm<6>";
825 let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass;
826 let EncoderMethod = "getSizeInsEncoding";
827 let DecoderMethod = "DecodeInsSize";
830 def uimm5_plus32_normalize : Operand<i32> {
831 let PrintMethod = "printUImm<5>";
832 let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
835 def uimm5_lsl2 : Operand<OtherVT> {
836 let EncoderMethod = "getUImm5Lsl2Encoding";
837 let DecoderMethod = "DecodeUImmWithOffsetAndScale<5, 0, 4>";
838 let ParserMatchClass = ConstantUImm5Lsl2AsmOperandClass;
841 def uimm5_plus32_normalize_64 : Operand<i64> {
842 let PrintMethod = "printUImm<5>";
843 let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
846 def uimm6_lsl2 : Operand<OtherVT> {
847 let EncoderMethod = "getUImm6Lsl2Encoding";
848 let DecoderMethod = "DecodeUImmWithOffsetAndScale<6, 0, 4>";
849 let ParserMatchClass = ConstantUImm6Lsl2AsmOperandClass;
853 def uimm # I : Operand<i32> {
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_relaxed : Operand<i32> {
861 let PrintMethod = "printUImm<16>";
862 let ParserMatchClass =
863 !cast<AsmOperandClass>("UImm16RelaxedAsmOperandClass");
867 def uimm # I # _64 : Operand<i64> {
868 let PrintMethod = "printUImm<" # I # ">";
869 let ParserMatchClass =
870 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
874 def uimm # I # _64 : Operand<i64> {
875 let PrintMethod = "printUImm<" # I # ">";
876 let ParserMatchClass =
877 !cast<AsmOperandClass>("UImm" # I # "AsmOperandClass");
880 // Like uimm16_64 but coerces simm16 to uimm16.
881 def uimm16_64_relaxed : Operand<i64> {
882 let PrintMethod = "printUImm<16>";
883 let ParserMatchClass =
884 !cast<AsmOperandClass>("UImm16RelaxedAsmOperandClass");
887 def uimm16_altrelaxed : Operand<i32> {
888 let PrintMethod = "printUImm<16>";
889 let ParserMatchClass =
890 !cast<AsmOperandClass>("UImm16AltRelaxedAsmOperandClass");
892 // Like uimm5 but reports a less confusing error for 32-63 when
893 // an instruction alias permits that.
894 def uimm5_report_uimm6 : Operand<i32> {
895 let PrintMethod = "printUImm<6>";
896 let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
899 // Like uimm5_64 but reports a less confusing error for 32-63 when
900 // an instruction alias permits that.
901 def uimm5_64_report_uimm6 : Operand<i64> {
902 let PrintMethod = "printUImm<5>";
903 let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
906 foreach I = {1, 2, 3, 4} in
907 def uimm # I # _ptr : Operand<iPTR> {
908 let PrintMethod = "printUImm<" # I # ">";
909 let ParserMatchClass =
910 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
913 foreach I = {1, 2, 3, 4, 5, 6, 8} in
914 def vsplat_uimm # I : Operand<vAny> {
915 let PrintMethod = "printUImm<" # I # ">";
916 let ParserMatchClass =
917 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
921 foreach I = {4, 5, 6, 9, 10, 11} in
922 def simm # I : Operand<i32> {
923 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
924 let ParserMatchClass =
925 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
928 foreach I = {1, 2, 3} in
929 def simm10_lsl # I : Operand<i32> {
930 let DecoderMethod = "DecodeSImmWithOffsetAndScale<10, " # I # ">";
931 let ParserMatchClass =
932 !cast<AsmOperandClass>("ConstantSImm10Lsl" # I # "AsmOperandClass");
936 def simm # I # _64 : Operand<i64> {
937 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
938 let ParserMatchClass =
939 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
942 foreach I = {5, 10} in
943 def vsplat_simm # I : Operand<vAny> {
944 let ParserMatchClass =
945 !cast<AsmOperandClass>("ConstantSImm" # I # "AsmOperandClass");
948 def simm7_lsl2 : Operand<OtherVT> {
949 let EncoderMethod = "getSImm7Lsl2Encoding";
950 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ", 0, 4>";
951 let ParserMatchClass = ConstantSImm7Lsl2AsmOperandClass;
954 foreach I = {16, 32} in
955 def simm # I : Operand<i32> {
956 let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
957 let ParserMatchClass = !cast<AsmOperandClass>("SImm" # I # "AsmOperandClass");
960 // Like simm16 but coerces uimm16 to simm16.
961 def simm16_relaxed : Operand<i32> {
962 let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
963 let ParserMatchClass = !cast<AsmOperandClass>("SImm16RelaxedAsmOperandClass");
966 def simm16_64 : Operand<i64> {
967 let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>";
968 let ParserMatchClass = !cast<AsmOperandClass>("SImm16AsmOperandClass");
971 // like simm32 but coerces simm32 to uimm32.
972 def uimm32_coerced : Operand<i32> {
973 let ParserMatchClass = !cast<AsmOperandClass>("UImm32CoercedAsmOperandClass");
975 // Like simm32 but coerces uimm32 to simm32.
976 def simm32_relaxed : Operand<i32> {
977 let DecoderMethod = "DecodeSImmWithOffsetAndScale<32>";
978 let ParserMatchClass = !cast<AsmOperandClass>("SImm32RelaxedAsmOperandClass");
981 // This is almost the same as a uimm7 but 0x7f is interpreted as -1.
982 def li16_imm : Operand<i32> {
983 let DecoderMethod = "DecodeLi16Imm";
984 let ParserMatchClass = ConstantUImm7Sub1AsmOperandClass;
987 def MipsMemAsmOperand : AsmOperandClass {
989 let ParserMethod = "parseMemOperand";
992 def MipsMemSimm9AsmOperand : AsmOperandClass {
993 let Name = "MemOffsetSimm9";
994 let SuperClasses = [MipsMemAsmOperand];
995 let RenderMethod = "addMemOperands";
996 let ParserMethod = "parseMemOperand";
997 let PredicateMethod = "isMemWithSimmOffset<9>";
998 let DiagnosticType = "MemSImm9";
1001 def MipsMemSimm10AsmOperand : AsmOperandClass {
1002 let Name = "MemOffsetSimm10";
1003 let SuperClasses = [MipsMemAsmOperand];
1004 let RenderMethod = "addMemOperands";
1005 let ParserMethod = "parseMemOperand";
1006 let PredicateMethod = "isMemWithSimmOffset<10>";
1007 let DiagnosticType = "MemSImm10";
1010 def MipsMemSimm12AsmOperand : AsmOperandClass {
1011 let Name = "MemOffsetSimm12";
1012 let SuperClasses = [MipsMemAsmOperand];
1013 let RenderMethod = "addMemOperands";
1014 let ParserMethod = "parseMemOperand";
1015 let PredicateMethod = "isMemWithSimmOffset<12>";
1016 let DiagnosticType = "MemSImm12";
1019 foreach I = {1, 2, 3} in
1020 def MipsMemSimm10Lsl # I # AsmOperand : AsmOperandClass {
1021 let Name = "MemOffsetSimm10_" # I;
1022 let SuperClasses = [MipsMemAsmOperand];
1023 let RenderMethod = "addMemOperands";
1024 let ParserMethod = "parseMemOperand";
1025 let PredicateMethod = "isMemWithSimmOffset<10, " # I # ">";
1026 let DiagnosticType = "MemSImm10Lsl" # I;
1029 def MipsMemSimm11AsmOperand : AsmOperandClass {
1030 let Name = "MemOffsetSimm11";
1031 let SuperClasses = [MipsMemAsmOperand];
1032 let RenderMethod = "addMemOperands";
1033 let ParserMethod = "parseMemOperand";
1034 let PredicateMethod = "isMemWithSimmOffset<11>";
1035 let DiagnosticType = "MemSImm11";
1038 def MipsMemSimm16AsmOperand : AsmOperandClass {
1039 let Name = "MemOffsetSimm16";
1040 let SuperClasses = [MipsMemAsmOperand];
1041 let RenderMethod = "addMemOperands";
1042 let ParserMethod = "parseMemOperand";
1043 let PredicateMethod = "isMemWithSimmOffset<16>";
1044 let DiagnosticType = "MemSImm16";
1047 def MipsInvertedImmoperand : AsmOperandClass {
1048 let Name = "InvNum";
1049 let RenderMethod = "addImmOperands";
1050 let ParserMethod = "parseInvNum";
1053 def InvertedImOperand : Operand<i32> {
1054 let ParserMatchClass = MipsInvertedImmoperand;
1057 def InvertedImOperand64 : Operand<i64> {
1058 let ParserMatchClass = MipsInvertedImmoperand;
1061 class mem_generic : Operand<iPTR> {
1062 let PrintMethod = "printMemOperand";
1063 let MIOperandInfo = (ops ptr_rc, simm16);
1064 let EncoderMethod = "getMemEncoding";
1065 let ParserMatchClass = MipsMemAsmOperand;
1066 let OperandType = "OPERAND_MEMORY";
1070 def mem : mem_generic;
1072 // MSA specific address operand
1073 def mem_msa : mem_generic {
1074 let MIOperandInfo = (ops ptr_rc, simm10);
1075 let EncoderMethod = "getMSAMemEncoding";
1078 def simm12 : Operand<i32> {
1079 let DecoderMethod = "DecodeSimm12";
1082 def mem_simm9 : mem_generic {
1083 let MIOperandInfo = (ops ptr_rc, simm9);
1084 let EncoderMethod = "getMemEncoding";
1085 let ParserMatchClass = MipsMemSimm9AsmOperand;
1088 def mem_simm10 : mem_generic {
1089 let MIOperandInfo = (ops ptr_rc, simm10);
1090 let EncoderMethod = "getMemEncoding";
1091 let ParserMatchClass = MipsMemSimm10AsmOperand;
1094 foreach I = {1, 2, 3} in
1095 def mem_simm10_lsl # I : mem_generic {
1096 let MIOperandInfo = (ops ptr_rc, !cast<Operand>("simm10_lsl" # I));
1097 let EncoderMethod = "getMemEncoding<" # I # ">";
1098 let ParserMatchClass =
1099 !cast<AsmOperandClass>("MipsMemSimm10Lsl" # I # "AsmOperand");
1102 def mem_simm11 : mem_generic {
1103 let MIOperandInfo = (ops ptr_rc, simm11);
1104 let EncoderMethod = "getMemEncoding";
1105 let ParserMatchClass = MipsMemSimm11AsmOperand;
1108 def mem_simm12 : mem_generic {
1109 let MIOperandInfo = (ops ptr_rc, simm12);
1110 let EncoderMethod = "getMemEncoding";
1111 let ParserMatchClass = MipsMemSimm12AsmOperand;
1114 def mem_simm16 : mem_generic {
1115 let MIOperandInfo = (ops ptr_rc, simm16);
1116 let EncoderMethod = "getMemEncoding";
1117 let ParserMatchClass = MipsMemSimm16AsmOperand;
1120 def mem_ea : Operand<iPTR> {
1121 let PrintMethod = "printMemOperandEA";
1122 let MIOperandInfo = (ops ptr_rc, simm16);
1123 let EncoderMethod = "getMemEncoding";
1124 let OperandType = "OPERAND_MEMORY";
1127 def PtrRC : Operand<iPTR> {
1128 let MIOperandInfo = (ops ptr_rc);
1129 let DecoderMethod = "DecodePtrRegisterClass";
1130 let ParserMatchClass = GPR32AsmOperand;
1133 // size operand of ins instruction
1134 def size_ins : Operand<i32> {
1135 let EncoderMethod = "getSizeInsEncoding";
1136 let DecoderMethod = "DecodeInsSize";
1139 // Transformation Function - get the lower 16 bits.
1140 def LO16 : SDNodeXForm<imm, [{
1141 return getImm(N, N->getZExtValue() & 0xFFFF);
1144 // Transformation Function - get the higher 16 bits.
1145 def HI16 : SDNodeXForm<imm, [{
1146 return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF);
1150 def Plus1 : SDNodeXForm<imm, [{ return getImm(N, N->getSExtValue() + 1); }]>;
1152 // Node immediate is zero (e.g. insve.d)
1153 def immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>;
1155 // Node immediate fits as 16-bit sign extended on target immediate.
1157 def immSExt8 : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;
1159 // Node immediate fits as 16-bit sign extended on target immediate.
1161 def immSExt16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;
1163 // Node immediate fits as 7-bit zero extended on target immediate.
1164 def immZExt7 : PatLeaf<(imm), [{ return isUInt<7>(N->getZExtValue()); }]>;
1166 // Node immediate fits as 16-bit zero extended on target immediate.
1167 // The LO16 param means that only the lower 16 bits of the node
1168 // immediate are caught.
1169 // e.g. addiu, sltiu
1170 def immZExt16 : PatLeaf<(imm), [{
1171 if (N->getValueType(0) == MVT::i32)
1172 return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
1174 return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
1177 // Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared).
1178 def immSExt32Low16Zero : PatLeaf<(imm), [{
1179 int64_t Val = N->getSExtValue();
1180 return isInt<32>(Val) && !(Val & 0xffff);
1183 // Zero-extended 32-bit unsigned int with lower 16-bit cleared.
1184 def immZExt32Low16Zero : PatLeaf<(imm), [{
1185 uint64_t Val = N->getZExtValue();
1186 return isUInt<32>(Val) && !(Val & 0xffff);
1189 // Note immediate fits as a 32 bit signed extended on target immediate.
1190 def immSExt32 : PatLeaf<(imm), [{ return isInt<32>(N->getSExtValue()); }]>;
1192 // Note immediate fits as a 32 bit zero extended on target immediate.
1193 def immZExt32 : PatLeaf<(imm), [{ return isUInt<32>(N->getZExtValue()); }]>;
1195 // shamt field must fit in 5 bits.
1196 def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
1198 def immZExt5Plus1 : PatLeaf<(imm), [{
1199 return isUInt<5>(N->getZExtValue() - 1);
1201 def immZExt5Plus32 : PatLeaf<(imm), [{
1202 return isUInt<5>(N->getZExtValue() - 32);
1204 def immZExt5Plus33 : PatLeaf<(imm), [{
1205 return isUInt<5>(N->getZExtValue() - 33);
1208 def immZExt5To31 : SDNodeXForm<imm, [{
1209 return getImm(N, 31 - N->getZExtValue());
1212 // True if (N + 1) fits in 16-bit field.
1213 def immSExt16Plus1 : PatLeaf<(imm), [{
1214 return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1);
1217 def immZExtRange2To64 : PatLeaf<(imm), [{
1218 return isUInt<7>(N->getZExtValue()) && (N->getZExtValue() >= 2) &&
1219 (N->getZExtValue() <= 64);
1222 def ORiPred : PatLeaf<(imm), [{
1223 return isUInt<16>(N->getZExtValue()) && !isInt<16>(N->getSExtValue());
1226 def LUiPred : PatLeaf<(imm), [{
1227 int64_t Val = N->getSExtValue();
1228 return !isInt<16>(Val) && isInt<32>(Val) && !(Val & 0xffff);
1231 def LUiORiPred : PatLeaf<(imm), [{
1232 int64_t SVal = N->getSExtValue();
1233 return isInt<32>(SVal) && (SVal & 0xffff);
1236 // Mips Address Mode! SDNode frameindex could possibily be a match
1237 // since load and store instructions from stack used it.
1239 ComplexPattern<iPTR, 2, "selectIntAddr", [frameindex]>;
1242 ComplexPattern<iPTR, 2, "selectAddrRegImm", [frameindex]>;
1245 ComplexPattern<iPTR, 2, "selectAddrDefault", [frameindex]>;
1247 def addrimm10 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10", [frameindex]>;
1248 def addrimm10lsl1 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl1",
1250 def addrimm10lsl2 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl2",
1252 def addrimm10lsl3 : ComplexPattern<iPTR, 2, "selectIntAddrSImm10Lsl3",
1255 //===----------------------------------------------------------------------===//
1256 // Instructions specific format
1257 //===----------------------------------------------------------------------===//
1259 // Arithmetic and logical instructions with 3 register operands.
1260 class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0,
1261 InstrItinClass Itin = NoItinerary,
1262 SDPatternOperator OpNode = null_frag>:
1263 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
1264 !strconcat(opstr, "\t$rd, $rs, $rt"),
1265 [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> {
1266 let isCommutable = isComm;
1267 let isReMaterializable = 1;
1268 let TwoOperandAliasConstraint = "$rd = $rs";
1271 // Arithmetic and logical instructions with 2 register operands.
1272 class ArithLogicI<string opstr, Operand Od, RegisterOperand RO,
1273 InstrItinClass Itin = NoItinerary,
1274 SDPatternOperator imm_type = null_frag,
1275 SDPatternOperator OpNode = null_frag> :
1276 InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16),
1277 !strconcat(opstr, "\t$rt, $rs, $imm16"),
1278 [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))],
1279 Itin, FrmI, opstr> {
1280 let isReMaterializable = 1;
1281 let TwoOperandAliasConstraint = "$rs = $rt";
1284 // Arithmetic Multiply ADD/SUB
1285 class MArithR<string opstr, InstrItinClass itin, bit isComm = 0> :
1286 InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1287 !strconcat(opstr, "\t$rs, $rt"), [], itin, FrmR, opstr> {
1288 let Defs = [HI0, LO0];
1289 let Uses = [HI0, LO0];
1290 let isCommutable = isComm;
1294 class LogicNOR<string opstr, RegisterOperand RO>:
1295 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
1296 !strconcat(opstr, "\t$rd, $rs, $rt"),
1297 [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], II_NOR, FrmR, opstr> {
1298 let isCommutable = 1;
1302 class shift_rotate_imm<string opstr, Operand ImmOpnd,
1303 RegisterOperand RO, InstrItinClass itin,
1304 SDPatternOperator OpNode = null_frag,
1305 SDPatternOperator PF = null_frag> :
1306 InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt),
1307 !strconcat(opstr, "\t$rd, $rt, $shamt"),
1308 [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], itin, FrmR, opstr> {
1309 let TwoOperandAliasConstraint = "$rt = $rd";
1312 class shift_rotate_reg<string opstr, RegisterOperand RO, InstrItinClass itin,
1313 SDPatternOperator OpNode = null_frag>:
1314 InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs),
1315 !strconcat(opstr, "\t$rd, $rt, $rs"),
1316 [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], itin, FrmR,
1319 // Load Upper Immediate
1320 class LoadUpper<string opstr, RegisterOperand RO, Operand Imm>:
1321 InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"),
1322 [], II_LUI, FrmI, opstr>, IsAsCheapAsAMove {
1323 let hasSideEffects = 0;
1324 let isReMaterializable = 1;
1327 // Memory Load/Store
1328 class LoadMemory<string opstr, DAGOperand RO, DAGOperand MO,
1329 SDPatternOperator OpNode = null_frag,
1330 InstrItinClass Itin = NoItinerary,
1331 ComplexPattern Addr = addr> :
1332 InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1333 [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> {
1334 let DecoderMethod = "DecodeMem";
1335 let canFoldAsLoad = 1;
1339 class Load<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
1340 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
1341 LoadMemory<opstr, RO, mem, OpNode, Itin, Addr>;
1343 class StoreMemory<string opstr, DAGOperand RO, DAGOperand MO,
1344 SDPatternOperator OpNode = null_frag,
1345 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
1346 InstSE<(outs), (ins RO:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1347 [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> {
1348 let DecoderMethod = "DecodeMem";
1352 class Store<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
1353 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr,
1354 DAGOperand MO = mem> :
1355 StoreMemory<opstr, RO, MO, OpNode, Itin, Addr>;
1357 // Load/Store Left/Right
1358 let canFoldAsLoad = 1 in
1359 class LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
1360 InstrItinClass Itin> :
1361 InstSE<(outs RO:$rt), (ins mem:$addr, RO:$src),
1362 !strconcat(opstr, "\t$rt, $addr"),
1363 [(set RO:$rt, (OpNode addr:$addr, RO:$src))], Itin, FrmI> {
1364 let DecoderMethod = "DecodeMem";
1365 string Constraints = "$src = $rt";
1368 class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
1369 InstrItinClass Itin> :
1370 InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1371 [(OpNode RO:$rt, addr:$addr)], Itin, FrmI> {
1372 let DecoderMethod = "DecodeMem";
1376 class LW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
1377 SDPatternOperator OpNode= null_frag> :
1378 InstSE<(outs RC:$rt), (ins mem_simm16:$addr),
1379 !strconcat(opstr, "\t$rt, $addr"),
1380 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
1381 let DecoderMethod = "DecodeFMem2";
1385 class SW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
1386 SDPatternOperator OpNode= null_frag> :
1387 InstSE<(outs), (ins RC:$rt, mem_simm16:$addr),
1388 !strconcat(opstr, "\t$rt, $addr"),
1389 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
1390 let DecoderMethod = "DecodeFMem2";
1395 class LW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
1396 SDPatternOperator OpNode= null_frag> :
1397 InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1398 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
1399 let DecoderMethod = "DecodeFMem3";
1403 class SW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
1404 SDPatternOperator OpNode= null_frag> :
1405 InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1406 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
1407 let DecoderMethod = "DecodeFMem3";
1411 // Conditional Branch
1412 class CBranch<string opstr, DAGOperand opnd, PatFrag cond_op,
1413 RegisterOperand RO> :
1414 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
1415 !strconcat(opstr, "\t$rs, $rt, $offset"),
1416 [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], II_BCC,
1419 let isTerminator = 1;
1420 let hasDelaySlot = 1;
1425 class CBranchLikely<string opstr, DAGOperand opnd, RegisterOperand RO> :
1426 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
1427 !strconcat(opstr, "\t$rs, $rt, $offset"), [], II_BCC, FrmI, opstr> {
1429 let isTerminator = 1;
1430 let hasDelaySlot = 1;
1435 class CBranchZero<string opstr, DAGOperand opnd, PatFrag cond_op,
1436 RegisterOperand RO> :
1437 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1438 !strconcat(opstr, "\t$rs, $offset"),
1439 [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], II_BCCZ,
1442 let isTerminator = 1;
1443 let hasDelaySlot = 1;
1448 class CBranchZeroLikely<string opstr, DAGOperand opnd, RegisterOperand RO> :
1449 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1450 !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZ, FrmI, opstr> {
1452 let isTerminator = 1;
1453 let hasDelaySlot = 1;
1459 class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> :
1460 InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt),
1461 !strconcat(opstr, "\t$rd, $rs, $rt"),
1462 [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))],
1463 II_SLT_SLTU, FrmR, opstr>;
1465 class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
1466 RegisterOperand RO>:
1467 InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16),
1468 !strconcat(opstr, "\t$rt, $rs, $imm16"),
1469 [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))],
1470 II_SLTI_SLTIU, FrmI, opstr>;
1473 class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
1474 SDPatternOperator targetoperator, string bopstr> :
1475 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
1476 [(operator targetoperator:$target)], II_J, FrmJ, bopstr> {
1479 let hasDelaySlot = 1;
1480 let DecoderMethod = "DecodeJumpTarget";
1485 // Unconditional branch
1486 class UncondBranch<Instruction BEQInst, DAGOperand opnd> :
1487 PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], II_B>,
1488 PseudoInstExpansion<(BEQInst ZERO, ZERO, opnd:$offset)> {
1490 let isTerminator = 1;
1492 let hasDelaySlot = 1;
1493 let AdditionalPredicates = [RelocPIC];
1498 // Base class for indirect branch and return instruction classes.
1499 let isTerminator=1, isBarrier=1, hasDelaySlot = 1, isCTI = 1 in
1500 class JumpFR<string opstr, RegisterOperand RO,
1501 SDPatternOperator operator = null_frag>:
1502 InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], II_JR,
1506 class IndirectBranch<string opstr, RegisterOperand RO> : JumpFR<opstr, RO> {
1508 let isIndirectBranch = 1;
1511 // Jump and Link (Call)
1512 let isCall=1, hasDelaySlot=1, isCTI=1, Defs = [RA] in {
1513 class JumpLink<string opstr, DAGOperand opnd> :
1514 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
1515 [(MipsJmpLink tglobaladdr:$target)], II_JAL, FrmJ, opstr> {
1516 let DecoderMethod = "DecodeJumpTarget";
1519 class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst,
1520 Register RetReg, RegisterOperand ResRO = RO>:
1521 PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], II_JALR>,
1522 PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)>;
1524 class JumpLinkReg<string opstr, RegisterOperand RO>:
1525 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1526 [], II_JALR, FrmR, opstr>;
1528 class BGEZAL_FT<string opstr, DAGOperand opnd,
1529 RegisterOperand RO> :
1530 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1531 !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZAL, FrmI, opstr> {
1532 let hasDelaySlot = 1;
1537 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
1538 hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT] in {
1539 class TailCall<Instruction JumpInst, DAGOperand Opnd> :
1540 PseudoSE<(outs), (ins calltarget:$target), [], II_J>,
1541 PseudoInstExpansion<(JumpInst Opnd:$target)>;
1543 class TailCallReg<RegisterOperand RO> :
1544 PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>;
1547 class BAL_BR_Pseudo<Instruction RealInst> :
1548 PseudoSE<(outs), (ins brtarget:$offset), [], II_BCCZAL>,
1549 PseudoInstExpansion<(RealInst ZERO, brtarget:$offset)> {
1551 let isTerminator = 1;
1553 let hasDelaySlot = 1;
1560 class SYS_FT<string opstr, Operand ImmOp, InstrItinClass itin = NoItinerary> :
1561 InstSE<(outs), (ins ImmOp:$code_),
1562 !strconcat(opstr, "\t$code_"), [], itin, FrmI, opstr>;
1564 class BRK_FT<string opstr> :
1565 InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
1566 !strconcat(opstr, "\t$code_1, $code_2"), [], II_BREAK,
1570 class ER_FT<string opstr, InstrItinClass itin = NoItinerary> :
1571 InstSE<(outs), (ins),
1572 opstr, [], itin, FrmOther, opstr>;
1575 class WAIT_FT<string opstr> :
1576 InstSE<(outs), (ins), opstr, [], II_WAIT, FrmOther, opstr>;
1580 class DEI_FT<string opstr, RegisterOperand RO,
1581 InstrItinClass itin = NoItinerary> :
1582 InstSE<(outs RO:$rt), (ins),
1583 !strconcat(opstr, "\t$rt"), [], itin, FrmOther, opstr>;
1586 let hasSideEffects = 1 in
1587 class SYNC_FT<string opstr> :
1588 InstSE<(outs), (ins uimm5:$stype), "sync $stype",
1589 [(MipsSync immZExt5:$stype)], II_SYNC, FrmOther, opstr>;
1591 class SYNCI_FT<string opstr> :
1592 InstSE<(outs), (ins mem_simm16:$addr), !strconcat(opstr, "\t$addr"), [],
1593 II_SYNCI, FrmOther, opstr> {
1594 let hasSideEffects = 1;
1595 let DecoderMethod = "DecodeSyncI";
1598 let hasSideEffects = 1, isCTI = 1 in {
1599 class TEQ_FT<string opstr, RegisterOperand RO, Operand ImmOp,
1600 InstrItinClass itin = NoItinerary> :
1601 InstSE<(outs), (ins RO:$rs, RO:$rt, ImmOp:$code_),
1602 !strconcat(opstr, "\t$rs, $rt, $code_"), [], itin, FrmI, opstr>;
1604 class TEQI_FT<string opstr, RegisterOperand RO,
1605 InstrItinClass itin = NoItinerary> :
1606 InstSE<(outs), (ins RO:$rs, simm16:$imm16),
1607 !strconcat(opstr, "\t$rs, $imm16"), [], itin, FrmOther, opstr>;
1611 class Mult<string opstr, InstrItinClass itin, RegisterOperand RO,
1612 list<Register> DefRegs> :
1613 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [],
1614 itin, FrmR, opstr> {
1615 let isCommutable = 1;
1617 let hasSideEffects = 0;
1620 // Pseudo multiply/divide instruction with explicit accumulator register
1622 class MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1,
1623 SDPatternOperator OpNode, InstrItinClass Itin,
1624 bit IsComm = 1, bit HasSideEffects = 0,
1625 bit UsesCustomInserter = 0> :
1626 PseudoSE<(outs R0:$ac), (ins R1:$rs, R1:$rt),
1627 [(set R0:$ac, (OpNode R1:$rs, R1:$rt))], Itin>,
1628 PseudoInstExpansion<(RealInst R1:$rs, R1:$rt)> {
1629 let isCommutable = IsComm;
1630 let hasSideEffects = HasSideEffects;
1631 let usesCustomInserter = UsesCustomInserter;
1634 // Pseudo multiply add/sub instruction with explicit accumulator register
1636 class MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode,
1637 InstrItinClass itin>
1638 : PseudoSE<(outs ACC64:$ac),
1639 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin),
1641 (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))],
1643 PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> {
1644 string Constraints = "$acin = $ac";
1647 class Div<string opstr, InstrItinClass itin, RegisterOperand RO,
1648 list<Register> DefRegs> :
1649 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$$zero, $rs, $rt"),
1650 [], itin, FrmR, opstr> {
1655 class PseudoMFLOHI<RegisterClass DstRC, RegisterClass SrcRC, SDNode OpNode>
1656 : PseudoSE<(outs DstRC:$rd), (ins SrcRC:$hilo),
1657 [(set DstRC:$rd, (OpNode SrcRC:$hilo))], II_MFHI_MFLO>;
1659 class MoveFromLOHI<string opstr, RegisterOperand RO, Register UseReg>:
1660 InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO,
1662 let Uses = [UseReg];
1663 let hasSideEffects = 0;
1666 class PseudoMTLOHI<RegisterClass DstRC, RegisterClass SrcRC>
1667 : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi),
1668 [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))],
1671 class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>:
1672 InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO,
1675 let hasSideEffects = 0;
1678 class EffectiveAddress<string opstr, RegisterOperand RO> :
1679 InstSE<(outs RO:$rt), (ins mem_ea:$addr), !strconcat(opstr, "\t$rt, $addr"),
1680 [(set RO:$rt, addr:$addr)], II_ADDIU, FrmI,
1681 !strconcat(opstr, "_lea")> {
1682 let isCodeGenOnly = 1;
1683 let hasNoSchedulingInfo = 1;
1684 let DecoderMethod = "DecodeMem";
1687 // Count Leading Ones/Zeros in Word
1688 class CountLeading0<string opstr, RegisterOperand RO,
1689 InstrItinClass itin = NoItinerary>:
1690 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1691 [(set RO:$rd, (ctlz RO:$rs))], itin, FrmR, opstr>;
1693 class CountLeading1<string opstr, RegisterOperand RO,
1694 InstrItinClass itin = NoItinerary>:
1695 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1696 [(set RO:$rd, (ctlz (not RO:$rs)))], itin, FrmR, opstr>;
1698 // Sign Extend in Register.
1699 class SignExtInReg<string opstr, ValueType vt, RegisterOperand RO,
1700 InstrItinClass itin> :
1701 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"),
1702 [(set RO:$rd, (sext_inreg RO:$rt, vt))], itin, FrmR, opstr>;
1705 class SubwordSwap<string opstr, RegisterOperand RO,
1706 InstrItinClass itin = NoItinerary>:
1707 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [], itin,
1709 let hasSideEffects = 0;
1713 class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> :
1714 InstSE<(outs CPURegOperand:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [],
1715 II_RDHWR, FrmR, "rdhwr">;
1718 class ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1719 Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm,
1720 SDPatternOperator Op = null_frag> :
1721 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size),
1722 !strconcat(opstr, "\t$rt, $rs, $pos, $size"),
1723 [(set RO:$rt, (Op RO:$rs, PosImm:$pos, SizeImm:$size))], II_EXT,
1724 FrmR, opstr>, ISA_MIPS32R2;
1726 // 'ins' and its' 64 bit variants are matched by C++ code.
1727 class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1728 Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm>:
1729 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size, RO:$src),
1730 !strconcat(opstr, "\t$rt, $rs, $pos, $size"),
1731 [(set RO:$rt, (null_frag RO:$rs, PosImm:$pos, SizeImm:$size,
1733 II_INS, FrmR, opstr>, ISA_MIPS32R2 {
1734 let Constraints = "$src = $rt";
1737 // Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*).
1738 class Atomic2Ops<PatFrag Op, RegisterClass DRC> :
1739 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr),
1740 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]>;
1742 // Atomic Compare & Swap.
1743 class AtomicCmpSwap<PatFrag Op, RegisterClass DRC> :
1744 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap),
1745 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]>;
1747 class LLBase<string opstr, RegisterOperand RO, DAGOperand MO = mem> :
1748 InstSE<(outs RO:$rt), (ins MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
1749 [], II_LL, FrmI, opstr> {
1750 let DecoderMethod = "DecodeMem";
1754 class SCBase<string opstr, RegisterOperand RO> :
1755 InstSE<(outs RO:$dst), (ins RO:$rt, mem:$addr),
1756 !strconcat(opstr, "\t$rt, $addr"), [], II_SC, FrmI> {
1757 let DecoderMethod = "DecodeMem";
1759 let Constraints = "$rt = $dst";
1762 class MFC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
1763 InstrItinClass itin> :
1764 InstSE<(outs RO:$rt), (ins RD:$rd, uimm3:$sel),
1765 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR>;
1767 class MTC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD,
1768 InstrItinClass itin> :
1769 InstSE<(outs RO:$rd), (ins RD:$rt, uimm3:$sel),
1770 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR>;
1772 class TrapBase<Instruction RealInst>
1773 : PseudoSE<(outs), (ins), [(trap)], II_TRAP>,
1774 PseudoInstExpansion<(RealInst 0, 0)> {
1776 let isTerminator = 1;
1777 let isCodeGenOnly = 1;
1781 //===----------------------------------------------------------------------===//
1782 // Pseudo instructions
1783 //===----------------------------------------------------------------------===//
1786 let isReturn=1, isTerminator=1, isBarrier=1, hasCtrlDep=1, isCTI=1 in {
1787 let hasDelaySlot=1 in
1788 def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
1790 let hasSideEffects=1 in
1791 def ERet : PseudoSE<(outs), (ins), [(MipsERet)]>;
1794 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
1795 def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1796 [(callseq_start timm:$amt1, timm:$amt2)]>;
1797 def ADJCALLSTACKUP : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1798 [(callseq_end timm:$amt1, timm:$amt2)]>;
1801 let usesCustomInserter = 1 in {
1802 def ATOMIC_LOAD_ADD_I8 : Atomic2Ops<atomic_load_add_8, GPR32>;
1803 def ATOMIC_LOAD_ADD_I16 : Atomic2Ops<atomic_load_add_16, GPR32>;
1804 def ATOMIC_LOAD_ADD_I32 : Atomic2Ops<atomic_load_add_32, GPR32>;
1805 def ATOMIC_LOAD_SUB_I8 : Atomic2Ops<atomic_load_sub_8, GPR32>;
1806 def ATOMIC_LOAD_SUB_I16 : Atomic2Ops<atomic_load_sub_16, GPR32>;
1807 def ATOMIC_LOAD_SUB_I32 : Atomic2Ops<atomic_load_sub_32, GPR32>;
1808 def ATOMIC_LOAD_AND_I8 : Atomic2Ops<atomic_load_and_8, GPR32>;
1809 def ATOMIC_LOAD_AND_I16 : Atomic2Ops<atomic_load_and_16, GPR32>;
1810 def ATOMIC_LOAD_AND_I32 : Atomic2Ops<atomic_load_and_32, GPR32>;
1811 def ATOMIC_LOAD_OR_I8 : Atomic2Ops<atomic_load_or_8, GPR32>;
1812 def ATOMIC_LOAD_OR_I16 : Atomic2Ops<atomic_load_or_16, GPR32>;
1813 def ATOMIC_LOAD_OR_I32 : Atomic2Ops<atomic_load_or_32, GPR32>;
1814 def ATOMIC_LOAD_XOR_I8 : Atomic2Ops<atomic_load_xor_8, GPR32>;
1815 def ATOMIC_LOAD_XOR_I16 : Atomic2Ops<atomic_load_xor_16, GPR32>;
1816 def ATOMIC_LOAD_XOR_I32 : Atomic2Ops<atomic_load_xor_32, GPR32>;
1817 def ATOMIC_LOAD_NAND_I8 : Atomic2Ops<atomic_load_nand_8, GPR32>;
1818 def ATOMIC_LOAD_NAND_I16 : Atomic2Ops<atomic_load_nand_16, GPR32>;
1819 def ATOMIC_LOAD_NAND_I32 : Atomic2Ops<atomic_load_nand_32, GPR32>;
1821 def ATOMIC_SWAP_I8 : Atomic2Ops<atomic_swap_8, GPR32>;
1822 def ATOMIC_SWAP_I16 : Atomic2Ops<atomic_swap_16, GPR32>;
1823 def ATOMIC_SWAP_I32 : Atomic2Ops<atomic_swap_32, GPR32>;
1825 def ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap<atomic_cmp_swap_8, GPR32>;
1826 def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap<atomic_cmp_swap_16, GPR32>;
1827 def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_32, GPR32>;
1830 /// Pseudo instructions for loading and storing accumulator registers.
1831 let isPseudo = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in {
1832 def LOAD_ACC64 : Load<"", ACC64>;
1833 def STORE_ACC64 : Store<"", ACC64>;
1836 // We need these two pseudo instructions to avoid offset calculation for long
1837 // branches. See the comment in file MipsLongBranch.cpp for detailed
1840 // Expands to: lui $dst, %hi($tgt - $baltgt)
1841 def LONG_BRANCH_LUi : PseudoSE<(outs GPR32Opnd:$dst),
1842 (ins brtarget:$tgt, brtarget:$baltgt), []>;
1844 // Expands to: addiu $dst, $src, %lo($tgt - $baltgt)
1845 def LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst),
1846 (ins GPR32Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []>;
1848 //===----------------------------------------------------------------------===//
1849 // Instruction definition
1850 //===----------------------------------------------------------------------===//
1851 //===----------------------------------------------------------------------===//
1852 // MipsI Instructions
1853 //===----------------------------------------------------------------------===//
1855 /// Arithmetic Instructions (ALU Immediate)
1856 let AdditionalPredicates = [NotInMicroMips] in {
1857 def ADDiu : MMRel, StdMMR6Rel, ArithLogicI<"addiu", simm16_relaxed, GPR32Opnd,
1858 II_ADDIU, immSExt16, add>,
1859 ADDI_FM<0x9>, IsAsCheapAsAMove;
1861 def ANDi : MMRel, StdMMR6Rel,
1862 ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16, and>,
1864 def ORi : MMRel, StdMMR6Rel,
1865 ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16, or>,
1867 def XORi : MMRel, StdMMR6Rel,
1868 ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16, xor>,
1871 def ADDi : MMRel, ArithLogicI<"addi", simm16_relaxed, GPR32Opnd, II_ADDI>, ADDI_FM<0x8>,
1872 ISA_MIPS1_NOT_32R6_64R6;
1873 let AdditionalPredicates = [NotInMicroMips] in {
1874 def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
1876 def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
1879 def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16_relaxed>, LUI_FM;
1880 let AdditionalPredicates = [NotInMicroMips] in {
1881 /// Arithmetic Instructions (3-Operand, R-Type)
1882 def ADDu : MMRel, StdMMR6Rel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
1884 def SUBu : MMRel, StdMMR6Rel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
1887 let Defs = [HI0, LO0] in
1888 def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>,
1889 ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6;
1890 def ADD : MMRel, StdMMR6Rel, ArithLogicR<"add", GPR32Opnd, 1, II_ADD>, ADD_FM<0, 0x20>;
1891 def SUB : MMRel, StdMMR6Rel, ArithLogicR<"sub", GPR32Opnd, 0, II_SUB>, ADD_FM<0, 0x22>;
1892 let AdditionalPredicates = [NotInMicroMips] in {
1893 def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>;
1894 def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>;
1895 def AND : MMRel, StdMMR6Rel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
1897 def OR : MMRel, StdMMR6Rel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
1899 def XOR : MMRel, StdMMR6Rel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
1901 def NOR : MMRel, StdMMR6Rel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>;
1904 /// Shift Instructions
1905 let AdditionalPredicates = [NotInMicroMips] in {
1906 def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl,
1907 immZExt5>, SRA_FM<0, 0>;
1908 def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl,
1909 immZExt5>, SRA_FM<2, 0>;
1910 def SRA : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, sra,
1911 immZExt5>, SRA_FM<3, 0>;
1912 def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, shl>,
1914 def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, srl>,
1916 def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, sra>,
1920 // Rotate Instructions
1921 let AdditionalPredicates = [NotInMicroMips] in {
1922 def ROTR : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr,
1924 SRA_FM<2, 1>, ISA_MIPS32R2;
1925 def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>,
1926 SRLV_FM<6, 1>, ISA_MIPS32R2;
1929 /// Load and Store Instructions
1931 def LB : LoadMemory<"lb", GPR32Opnd, mem_simm16, sextloadi8, II_LB>, MMRel,
1933 def LBu : LoadMemory<"lbu", GPR32Opnd, mem_simm16, zextloadi8, II_LBU,
1934 addrDefault>, MMRel, LW_FM<0x24>;
1935 let AdditionalPredicates = [NotInMicroMips] in {
1936 def LH : LoadMemory<"lh", GPR32Opnd, mem_simm16, sextloadi16, II_LH,
1937 addrDefault>, MMRel, LW_FM<0x21>;
1938 def LHu : LoadMemory<"lhu", GPR32Opnd, mem_simm16, zextloadi16, II_LHU>,
1940 def LW : StdMMR6Rel, Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel,
1943 def SB : StdMMR6Rel, Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel,
1945 def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>;
1946 let AdditionalPredicates = [NotInMicroMips] in {
1947 def SW : Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>;
1950 /// load/store left/right
1951 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1952 AdditionalPredicates = [NotInMicroMips] in {
1953 def LWL : LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>,
1954 ISA_MIPS1_NOT_32R6_64R6;
1955 def LWR : LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>,
1956 ISA_MIPS1_NOT_32R6_64R6;
1957 def SWL : StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>,
1958 ISA_MIPS1_NOT_32R6_64R6;
1959 def SWR : StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>,
1960 ISA_MIPS1_NOT_32R6_64R6;
1963 let AdditionalPredicates = [NotInMicroMips] in {
1964 // COP2 Memory Instructions
1965 def LWC2 : StdMMR6Rel, LW_FT2<"lwc2", COP2Opnd, II_LWC2, load>, LW_FM<0x32>,
1966 ISA_MIPS1_NOT_32R6_64R6;
1967 def SWC2 : StdMMR6Rel, SW_FT2<"swc2", COP2Opnd, II_SWC2, store>,
1968 LW_FM<0x3a>, ISA_MIPS1_NOT_32R6_64R6;
1969 def LDC2 : StdMMR6Rel, LW_FT2<"ldc2", COP2Opnd, II_LDC2, load>, LW_FM<0x36>,
1970 ISA_MIPS2_NOT_32R6_64R6;
1971 def SDC2 : StdMMR6Rel, SW_FT2<"sdc2", COP2Opnd, II_SDC2, store>,
1972 LW_FM<0x3e>, ISA_MIPS2_NOT_32R6_64R6;
1974 // COP3 Memory Instructions
1975 let DecoderNamespace = "COP3_" in {
1976 def LWC3 : LW_FT3<"lwc3", COP3Opnd, II_LWC3, load>, LW_FM<0x33>;
1977 def SWC3 : SW_FT3<"swc3", COP3Opnd, II_SWC3, store>, LW_FM<0x3b>;
1978 def LDC3 : LW_FT3<"ldc3", COP3Opnd, II_LDC3, load>, LW_FM<0x37>,
1980 def SDC3 : SW_FT3<"sdc3", COP3Opnd, II_SDC3, store>, LW_FM<0x3f>,
1984 def SYNC : MMRel, StdMMR6Rel, SYNC_FT<"sync">, SYNC_FM, ISA_MIPS2;
1985 def SYNCI : MMRel, StdMMR6Rel, SYNCI_FT<"synci">, SYNCI_FM, ISA_MIPS32R2;
1988 let AdditionalPredicates = [NotInMicroMips] in {
1989 def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd, uimm10, II_TEQ>, TEQ_FM<0x34>, ISA_MIPS2;
1990 def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd, uimm10, II_TGE>, TEQ_FM<0x30>, ISA_MIPS2;
1991 def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd, uimm10, II_TGEU>, TEQ_FM<0x31>, ISA_MIPS2;
1992 def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd, uimm10, II_TLT>, TEQ_FM<0x32>, ISA_MIPS2;
1993 def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd, uimm10, II_TLTU>, TEQ_FM<0x33>, ISA_MIPS2;
1994 def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd, uimm10, II_TNE>, TEQ_FM<0x36>, ISA_MIPS2;
1997 def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd, II_TEQI>, TEQI_FM<0xc>,
1998 ISA_MIPS2_NOT_32R6_64R6;
1999 def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd, II_TGEI>, TEQI_FM<0x8>,
2000 ISA_MIPS2_NOT_32R6_64R6;
2001 def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd, II_TGEIU>, TEQI_FM<0x9>,
2002 ISA_MIPS2_NOT_32R6_64R6;
2003 def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd, II_TLTI>, TEQI_FM<0xa>,
2004 ISA_MIPS2_NOT_32R6_64R6;
2005 def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd, II_TTLTIU>, TEQI_FM<0xb>,
2006 ISA_MIPS2_NOT_32R6_64R6;
2007 def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd, II_TNEI>, TEQI_FM<0xe>,
2008 ISA_MIPS2_NOT_32R6_64R6;
2010 let AdditionalPredicates = [NotInMicroMips] in {
2011 def BREAK : MMRel, StdMMR6Rel, BRK_FT<"break">, BRK_FM<0xd>;
2012 def SYSCALL : MMRel, SYS_FT<"syscall", uimm20, II_SYSCALL>, SYS_FM<0xc>;
2014 def TRAP : TrapBase<BREAK>;
2015 let AdditionalPredicates = [NotInMicroMips] in {
2016 def SDBBP : MMRel, SYS_FT<"sdbbp", uimm20, II_SDBBP>, SDBBP_FM, ISA_MIPS32_NOT_32R6_64R6;
2019 let AdditionalPredicates = [NotInMicroMips] in {
2020 def ERET : MMRel, ER_FT<"eret", II_ERET>, ER_FM<0x18, 0x0>, INSN_MIPS3_32;
2021 def ERETNC : MMRel, ER_FT<"eretnc", II_ERETNC>, ER_FM<0x18, 0x1>, ISA_MIPS32R5;
2022 def DERET : MMRel, ER_FT<"deret", II_DERET>, ER_FM<0x1f, 0x0>, ISA_MIPS32;
2025 let AdditionalPredicates = [NotInMicroMips] in {
2026 def EI : MMRel, StdMMR6Rel, DEI_FT<"ei", GPR32Opnd, II_EI>, EI_FM<1>, ISA_MIPS32R2;
2027 def DI : MMRel, StdMMR6Rel, DEI_FT<"di", GPR32Opnd, II_DI>, EI_FM<0>, ISA_MIPS32R2;
2030 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
2031 AdditionalPredicates = [NotInMicroMips] in {
2032 def WAIT : WAIT_FT<"wait">, WAIT_FM;
2035 let AdditionalPredicates = [NotInMicroMips] in {
2036 /// Load-linked, Store-conditional
2037 def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
2038 def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, PTR_32, ISA_MIPS2_NOT_32R6_64R6;
2041 /// Jump and Branch Instructions
2042 def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
2043 AdditionalRequires<[RelocNotPIC, NotInMicroMips]>, IsBranch;
2044 def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>, ISA_MIPS1_NOT_32R6_64R6;
2045 def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>;
2046 def BEQL : MMRel, CBranchLikely<"beql", brtarget, GPR32Opnd>,
2047 BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6;
2048 def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>;
2049 def BNEL : MMRel, CBranchLikely<"bnel", brtarget, GPR32Opnd>,
2050 BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6;
2051 def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
2053 def BGEZL : MMRel, CBranchZeroLikely<"bgezl", brtarget, GPR32Opnd>,
2054 BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6;
2055 def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
2057 def BGTZL : MMRel, CBranchZeroLikely<"bgtzl", brtarget, GPR32Opnd>,
2058 BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6;
2059 def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
2061 def BLEZL : MMRel, CBranchZeroLikely<"blezl", brtarget, GPR32Opnd>,
2062 BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6;
2063 def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
2065 def BLTZL : MMRel, CBranchZeroLikely<"bltzl", brtarget, GPR32Opnd>,
2066 BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6;
2067 def B : UncondBranch<BEQ, brtarget>,
2068 AdditionalRequires<[NotInMicroMips]>;
2070 def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>;
2071 let AdditionalPredicates = [NotInMicroMips] in {
2072 def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM;
2073 def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>;
2076 def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>,
2077 ISA_MIPS32_NOT_32R6_64R6;
2078 def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>,
2079 ISA_MIPS1_NOT_32R6_64R6;
2080 def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd>,
2081 BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6;
2082 def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>,
2083 ISA_MIPS1_NOT_32R6_64R6;
2084 def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd>,
2085 BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6;
2086 def BAL_BR : BAL_BR_Pseudo<BGEZAL>;
2088 let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips] in {
2089 def TAILCALL : TailCall<J, jmptarget>;
2092 def TAILCALLREG : TailCallReg<GPR32Opnd>;
2094 // Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64
2095 // then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA.
2096 class PseudoIndirectBranchBase<RegisterOperand RO> :
2097 MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)],
2098 II_IndirectBranchPseudo> {
2101 let hasDelaySlot = 1;
2103 let isIndirectBranch = 1;
2105 let Predicates = [NotInMips16Mode];
2108 def PseudoIndirectBranch : PseudoIndirectBranchBase<GPR32Opnd>;
2110 // Return instructions are matched as a RetRA instruction, then are expanded
2111 // into PseudoReturn/PseudoReturn64 after register allocation. Finally,
2112 // MipsAsmPrinter expands this into JR, JR64, JALR, or JALR64 depending on the
2114 class PseudoReturnBase<RegisterOperand RO> : MipsPseudo<(outs), (ins RO:$rs),
2115 [], II_ReturnPseudo> {
2116 let isTerminator = 1;
2118 let hasDelaySlot = 1;
2120 let isCodeGenOnly = 1;
2122 let hasExtraSrcRegAllocReq = 1;
2126 def PseudoReturn : PseudoReturnBase<GPR32Opnd>;
2128 // Exception handling related node and instructions.
2129 // The conversion sequence is:
2130 // ISD::EH_RETURN -> MipsISD::EH_RETURN ->
2131 // MIPSeh_return -> (stack change + indirect branch)
2133 // MIPSeh_return takes the place of regular return instruction
2134 // but takes two arguments (V1, V0) which are used for storing
2135 // the offset and return address respectively.
2136 def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
2138 def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
2139 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
2141 let Uses = [V0, V1], isTerminator = 1, isReturn = 1, isBarrier = 1, isCTI = 1 in {
2142 def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
2143 [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
2144 def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff,
2146 [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
2149 /// Multiply and Divide Instructions.
2150 def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
2151 MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6;
2152 def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
2153 MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6;
2154 let AdditionalPredicates = [NotInMicroMips] in {
2155 def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
2156 MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6;
2157 def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
2158 MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6;
2160 def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>,
2161 ISA_MIPS1_NOT_32R6_64R6;
2162 def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>,
2163 ISA_MIPS1_NOT_32R6_64R6;
2164 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
2165 AdditionalPredicates = [NotInMicroMips] in {
2166 def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>,
2167 ISA_MIPS1_NOT_32R6_64R6;
2168 def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>,
2169 ISA_MIPS1_NOT_32R6_64R6;
2172 /// Sign Ext In Register Instructions.
2173 def SEB : MMRel, StdMMR6Rel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,
2174 SEB_FM<0x10, 0x20>, ISA_MIPS32R2;
2175 def SEH : MMRel, StdMMR6Rel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
2176 SEB_FM<0x18, 0x20>, ISA_MIPS32R2;
2179 def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd, II_CLZ>, CLO_FM<0x20>,
2180 ISA_MIPS32_NOT_32R6_64R6;
2181 def CLO : MMRel, CountLeading1<"clo", GPR32Opnd, II_CLO>, CLO_FM<0x21>,
2182 ISA_MIPS32_NOT_32R6_64R6;
2184 let AdditionalPredicates = [NotInMicroMips] in {
2185 /// Word Swap Bytes Within Halfwords
2186 def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd, II_WSBH>, SEB_FM<2, 0x20>,
2191 def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>;
2193 // FrameIndexes are legalized when they are operands from load/store
2194 // instructions. The same not happens for stack address copies, so an
2195 // add op with mem ComplexPattern is used and the stack address copy
2196 // can be matched. It's similar to Sparc LEA_ADDRi
2197 def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>;
2200 def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>,
2201 ISA_MIPS32_NOT_32R6_64R6;
2202 def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>,
2203 ISA_MIPS32_NOT_32R6_64R6;
2204 def MSUB : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>,
2205 ISA_MIPS32_NOT_32R6_64R6;
2206 def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>,
2207 ISA_MIPS32_NOT_32R6_64R6;
2209 let AdditionalPredicates = [NotDSP] in {
2210 def PseudoMULT : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>,
2211 ISA_MIPS1_NOT_32R6_64R6;
2212 def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>,
2213 ISA_MIPS1_NOT_32R6_64R6;
2214 def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>, ISA_MIPS1_NOT_32R6_64R6;
2215 def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>, ISA_MIPS1_NOT_32R6_64R6;
2216 def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>, ISA_MIPS1_NOT_32R6_64R6;
2217 def PseudoMADD : MAddSubPseudo<MADD, MipsMAdd, II_MADD>,
2218 ISA_MIPS32_NOT_32R6_64R6;
2219 def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>,
2220 ISA_MIPS32_NOT_32R6_64R6;
2221 def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>,
2222 ISA_MIPS32_NOT_32R6_64R6;
2223 def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>,
2224 ISA_MIPS32_NOT_32R6_64R6;
2227 let AdditionalPredicates = [NotInMicroMips] in {
2228 def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV,
2229 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
2230 def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU,
2231 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
2232 def RDHWR : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM;
2233 // TODO: Add '0 < pos+size <= 32' constraint check to ext instruction
2234 def EXT : MMRel, StdMMR6Rel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1,
2235 immZExt5, immZExt5Plus1, MipsExt>,
2237 def INS : MMRel, StdMMR6Rel, InsBase<"ins", GPR32Opnd, uimm5,
2238 uimm5_inssize_plus1, immZExt5,
2242 /// Move Control Registers From/To CPU Registers
2243 let AdditionalPredicates = [NotInMicroMips] in {
2244 def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd, II_MTC0>, MFC3OP_FM<0x10, 4>,
2246 def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd, II_MFC0>, MFC3OP_FM<0x10, 0>,
2249 def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd, II_MFC2>, MFC3OP_FM<0x12, 0>;
2250 def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd, II_MTC2>, MFC3OP_FM<0x12, 4>;
2252 class Barrier<string asmstr, InstrItinClass itin = NoItinerary> :
2253 InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2255 def SSNOP : MMRel, StdMMR6Rel, Barrier<"ssnop", II_SSNOP>, BARRIER_FM<1>;
2256 def EHB : MMRel, Barrier<"ehb", II_EHB>, BARRIER_FM<3>;
2259 def PAUSE : MMRel, StdMMR6Rel, Barrier<"pause", II_PAUSE>, BARRIER_FM<5>,
2262 // JR_HB and JALR_HB are defined here using the new style naming
2263 // scheme because some of this code is shared with Mips32r6InstrInfo.td
2264 // and because of that it doesn't follow the naming convention of the
2265 // rest of the file. To avoid a mixture of old vs new style, the new
2266 // style was chosen.
2267 class JR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
2268 dag OutOperandList = (outs);
2269 dag InOperandList = (ins GPROpnd:$rs);
2270 string AsmString = !strconcat(instr_asm, "\t$rs");
2271 list<dag> Pattern = [];
2274 class JALR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
2275 dag OutOperandList = (outs GPROpnd:$rd);
2276 dag InOperandList = (ins GPROpnd:$rs);
2277 string AsmString = !strconcat(instr_asm, "\t$rd, $rs");
2278 list<dag> Pattern = [];
2281 class JR_HB_DESC : InstSE<(outs), (ins), "", [], II_JR_HB, FrmJ>,
2282 JR_HB_DESC_BASE<"jr.hb", GPR32Opnd> {
2284 let isIndirectBranch=1;
2291 class JALR_HB_DESC : InstSE<(outs), (ins), "", [], II_JALR_HB, FrmJ>,
2292 JALR_HB_DESC_BASE<"jalr.hb", GPR32Opnd> {
2293 let isIndirectBranch=1;
2298 class JR_HB_ENC : JR_HB_FM<8>;
2299 class JALR_HB_ENC : JALR_HB_FM<9>;
2301 def JR_HB : JR_HB_DESC, JR_HB_ENC, ISA_MIPS32_NOT_32R6_64R6;
2302 def JALR_HB : JALR_HB_DESC, JALR_HB_ENC, ISA_MIPS32;
2304 class TLB<string asmstr, InstrItinClass itin = NoItinerary> :
2305 InstSE<(outs), (ins), asmstr, [], itin, FrmOther, asmstr>;
2306 let AdditionalPredicates = [NotInMicroMips] in {
2307 def TLBP : MMRel, TLB<"tlbp", II_TLBP>, COP0_TLB_FM<0x08>;
2308 def TLBR : MMRel, TLB<"tlbr", II_TLBR>, COP0_TLB_FM<0x01>;
2309 def TLBWI : MMRel, TLB<"tlbwi", II_TLBWI>, COP0_TLB_FM<0x02>;
2310 def TLBWR : MMRel, TLB<"tlbwr", II_TLBWR>, COP0_TLB_FM<0x06>;
2312 class CacheOp<string instr_asm, Operand MemOpnd,
2313 InstrItinClass itin = NoItinerary> :
2314 InstSE<(outs), (ins MemOpnd:$addr, uimm5:$hint),
2315 !strconcat(instr_asm, "\t$hint, $addr"), [], itin, FrmOther,
2317 let DecoderMethod = "DecodeCacheOp";
2320 def CACHE : MMRel, CacheOp<"cache", mem, II_CACHE>, CACHEOP_FM<0b101111>,
2321 INSN_MIPS3_32_NOT_32R6_64R6;
2322 def PREF : MMRel, CacheOp<"pref", mem, II_PREF>, CACHEOP_FM<0b110011>,
2323 INSN_MIPS3_32_NOT_32R6_64R6;
2325 def ROL : MipsAsmPseudoInst<(outs),
2326 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2327 "rol\t$rs, $rt, $rd">;
2328 def ROLImm : MipsAsmPseudoInst<(outs),
2329 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2330 "rol\t$rs, $rt, $imm">;
2331 def : MipsInstAlias<"rol $rd, $rs",
2332 (ROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2333 def : MipsInstAlias<"rol $rd, $imm",
2334 (ROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2336 def ROR : MipsAsmPseudoInst<(outs),
2337 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2338 "ror\t$rs, $rt, $rd">;
2339 def RORImm : MipsAsmPseudoInst<(outs),
2340 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2341 "ror\t$rs, $rt, $imm">;
2342 def : MipsInstAlias<"ror $rd, $rs",
2343 (ROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
2344 def : MipsInstAlias<"ror $rd, $imm",
2345 (RORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
2347 def DROL : MipsAsmPseudoInst<(outs),
2348 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2349 "drol\t$rs, $rt, $rd">, ISA_MIPS64;
2350 def DROLImm : MipsAsmPseudoInst<(outs),
2351 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2352 "drol\t$rs, $rt, $imm">, ISA_MIPS64;
2353 def : MipsInstAlias<"drol $rd, $rs",
2354 (DROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
2355 def : MipsInstAlias<"drol $rd, $imm",
2356 (DROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
2358 def DROR : MipsAsmPseudoInst<(outs),
2359 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
2360 "dror\t$rs, $rt, $rd">, ISA_MIPS64;
2361 def DRORImm : MipsAsmPseudoInst<(outs),
2362 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
2363 "dror\t$rs, $rt, $imm">, ISA_MIPS64;
2364 def : MipsInstAlias<"dror $rd, $rs",
2365 (DROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
2366 def : MipsInstAlias<"dror $rd, $imm",
2367 (DRORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
2369 def ABSMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2372 def SEQMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2373 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2374 "seq $rd, $rs, $rt">, NOT_ASE_CNMIPS;
2376 def : MipsInstAlias<"seq $rd, $rs",
2377 (SEQMacro GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>,
2380 def SEQIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2381 (ins GPR32Opnd:$rs, simm32_relaxed:$imm),
2382 "seq $rd, $rs, $imm">, NOT_ASE_CNMIPS;
2384 def : MipsInstAlias<"seq $rd, $imm",
2385 (SEQIMacro GPR32Opnd:$rd, GPR32Opnd:$rd, simm32:$imm), 0>,
2388 def MULImmMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2389 simm32_relaxed:$imm),
2390 "mul\t$rd, $rs, $imm">,
2391 ISA_MIPS1_NOT_32R6_64R6;
2392 def MULOMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2394 "mulo\t$rd, $rs, $rt">,
2395 ISA_MIPS1_NOT_32R6_64R6;
2396 def MULOUMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs,
2398 "mulou\t$rd, $rs, $rt">,
2399 ISA_MIPS1_NOT_32R6_64R6;
2401 //===----------------------------------------------------------------------===//
2402 // Instruction aliases
2403 //===----------------------------------------------------------------------===//
2405 multiclass OneOrTwoOperandMacroImmediateAlias<string Memnomic,
2407 RegisterOperand RO = GPR32Opnd,
2408 Operand Imm = simm32_relaxed> {
2409 def : MipsInstAlias<!strconcat(Memnomic, " $rs, $rt, $imm"),
2413 def : MipsInstAlias<!strconcat(Memnomic, " $rs, $imm"),
2419 def : MipsInstAlias<"move $dst, $src",
2420 (OR GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2422 let AdditionalPredicates = [NotInMicroMips];
2424 def : MipsInstAlias<"move $dst, $src",
2425 (ADDu GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
2427 let AdditionalPredicates = [NotInMicroMips];
2429 def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>,
2430 ISA_MIPS1_NOT_32R6_64R6;
2432 def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>;
2433 let Predicates = [NotInMicroMips] in {
2434 def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
2436 def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>, ISA_MIPS32;
2437 def : MipsInstAlias<"neg $rt, $rs",
2438 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
2439 def : MipsInstAlias<"neg $rt",
2440 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>;
2441 def : MipsInstAlias<"negu $rt, $rs",
2442 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
2443 def : MipsInstAlias<"negu $rt",
2444 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 1>;
2445 let AdditionalPredicates = [NotInMicroMips] in {
2446 def : MipsInstAlias<
2447 "sgt $rd, $rs, $rt",
2448 (SLT GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2449 def : MipsInstAlias<
2451 (SLT GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2452 def : MipsInstAlias<
2453 "sgtu $rd, $rs, $rt",
2454 (SLTu GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2455 def : MipsInstAlias<
2457 (SLTu GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2458 def : MipsInstAlias<
2460 (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>;
2461 def : MipsInstAlias<
2463 (NOR GPR32Opnd:$rt, GPR32Opnd:$rt, ZERO), 0>;
2464 def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>;
2466 defm : OneOrTwoOperandMacroImmediateAlias<"add", ADDi>, ISA_MIPS1_NOT_32R6_64R6;
2468 defm : OneOrTwoOperandMacroImmediateAlias<"addu", ADDiu>;
2470 defm : OneOrTwoOperandMacroImmediateAlias<"and", ANDi>, GPR_32;
2472 defm : OneOrTwoOperandMacroImmediateAlias<"or", ORi>, GPR_32;
2474 defm : OneOrTwoOperandMacroImmediateAlias<"xor", XORi>, GPR_32;
2476 defm : OneOrTwoOperandMacroImmediateAlias<"slt", SLTi>, GPR_32;
2478 defm : OneOrTwoOperandMacroImmediateAlias<"sltu", SLTiu>, GPR_32;
2480 def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>;
2481 def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>;
2482 def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, COP2Opnd:$rd, 0), 0>;
2483 def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 COP2Opnd:$rd, GPR32Opnd:$rt, 0), 0>;
2484 let AdditionalPredicates = [NotInMicroMips] in {
2485 def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>;
2487 def : MipsInstAlias<"bnez $rs,$offset",
2488 (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
2489 def : MipsInstAlias<"bnezl $rs,$offset",
2490 (BNEL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
2491 def : MipsInstAlias<"beqz $rs,$offset",
2492 (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
2493 def : MipsInstAlias<"beqzl $rs,$offset",
2494 (BEQL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
2495 let AdditionalPredicates = [NotInMicroMips] in {
2496 def : MipsInstAlias<"syscall", (SYSCALL 0), 1>;
2499 def : MipsInstAlias<"break", (BREAK 0, 0), 1>;
2500 def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>;
2501 let AdditionalPredicates = [NotInMicroMips] in {
2502 def : MipsInstAlias<"ei", (EI ZERO), 1>, ISA_MIPS32R2;
2503 def : MipsInstAlias<"di", (DI ZERO), 1>, ISA_MIPS32R2;
2505 let AdditionalPredicates = [NotInMicroMips] in {
2506 def : MipsInstAlias<"teq $rs, $rt",
2507 (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2508 def : MipsInstAlias<"tge $rs, $rt",
2509 (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2510 def : MipsInstAlias<"tgeu $rs, $rt",
2511 (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2512 def : MipsInstAlias<"tlt $rs, $rt",
2513 (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2514 def : MipsInstAlias<"tltu $rs, $rt",
2515 (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2516 def : MipsInstAlias<"tne $rs, $rt",
2517 (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
2519 def : MipsInstAlias<"sub, $rd, $rs, $imm",
2520 (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs,
2521 InvertedImOperand:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6;
2522 def : MipsInstAlias<"sub $rs, $imm",
2523 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm),
2524 0>, ISA_MIPS1_NOT_32R6_64R6;
2525 def : MipsInstAlias<"subu, $rd, $rs, $imm",
2526 (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs,
2527 InvertedImOperand:$imm), 0>;
2528 def : MipsInstAlias<"subu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs,
2529 InvertedImOperand:$imm), 0>;
2530 let AdditionalPredicates = [NotInMicroMips] in {
2531 def : MipsInstAlias<"sll $rd, $rt, $rs",
2532 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2533 def : MipsInstAlias<"sra $rd, $rt, $rs",
2534 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2535 def : MipsInstAlias<"srl $rd, $rt, $rs",
2536 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
2537 def : MipsInstAlias<"sll $rd, $rt",
2538 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2539 def : MipsInstAlias<"sra $rd, $rt",
2540 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2541 def : MipsInstAlias<"srl $rd, $rt",
2542 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rt), 0>;
2543 def : MipsInstAlias<"seh $rd", (SEH GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
2545 def : MipsInstAlias<"seb $rd", (SEB GPR32Opnd:$rd, GPR32Opnd:$rd), 0>,
2548 def : MipsInstAlias<"sdbbp", (SDBBP 0)>, ISA_MIPS32_NOT_32R6_64R6;
2549 def : MipsInstAlias<"sync",
2550 (SYNC 0), 1>, ISA_MIPS2;
2552 def : MipsInstAlias<"mulo $rs, $rt",
2553 (MULOMacro GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2554 ISA_MIPS1_NOT_32R6_64R6;
2555 def : MipsInstAlias<"mulou $rs, $rt",
2556 (MULOUMacro GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>,
2557 ISA_MIPS1_NOT_32R6_64R6;
2559 //===----------------------------------------------------------------------===//
2560 // Assembler Pseudo Instructions
2561 //===----------------------------------------------------------------------===//
2563 // We use uimm32_coerced to accept a 33 bit signed number that is rendered into
2565 class LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> :
2566 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2567 !strconcat(instr_asm, "\t$rt, $imm32")> ;
2568 def LoadImm32 : LoadImmediate32<"li", uimm32_coerced, GPR32Opnd>;
2570 class LoadAddressFromReg32<string instr_asm, Operand MemOpnd,
2571 RegisterOperand RO> :
2572 MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
2573 !strconcat(instr_asm, "\t$rt, $addr")> ;
2574 def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>;
2576 class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> :
2577 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
2578 !strconcat(instr_asm, "\t$rt, $imm32")> ;
2579 def LoadAddrImm32 : LoadAddressFromImm32<"la", i32imm, GPR32Opnd>;
2581 def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
2583 def JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs),
2586 class NORIMM_DESC_BASE<RegisterOperand RO, DAGOperand Imm> :
2587 MipsAsmPseudoInst<(outs RO:$rs), (ins RO:$rt, Imm:$imm),
2588 "nor\t$rs, $rt, $imm">;
2589 def NORImm : NORIMM_DESC_BASE<GPR32Opnd, simm32_relaxed>, GPR_32;
2590 def : MipsInstAlias<"nor\t$rs, $imm", (NORImm GPR32Opnd:$rs, GPR32Opnd:$rs,
2591 simm32_relaxed:$imm)>, GPR_32;
2593 let hasDelaySlot = 1, isCTI = 1 in {
2594 def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2595 (ins imm64:$imm64, brtarget:$offset),
2596 "bne\t$rt, $imm64, $offset">;
2597 def BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2598 (ins imm64:$imm64, brtarget:$offset),
2599 "beq\t$rt, $imm64, $offset">;
2601 class CondBranchPseudo<string instr_asm> :
2602 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt,
2604 !strconcat(instr_asm, "\t$rs, $rt, $offset")>;
2607 def BLT : CondBranchPseudo<"blt">;
2608 def BLE : CondBranchPseudo<"ble">;
2609 def BGE : CondBranchPseudo<"bge">;
2610 def BGT : CondBranchPseudo<"bgt">;
2611 def BLTU : CondBranchPseudo<"bltu">;
2612 def BLEU : CondBranchPseudo<"bleu">;
2613 def BGEU : CondBranchPseudo<"bgeu">;
2614 def BGTU : CondBranchPseudo<"bgtu">;
2615 def BLTL : CondBranchPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2616 def BLEL : CondBranchPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2617 def BGEL : CondBranchPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2618 def BGTL : CondBranchPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2619 def BLTUL: CondBranchPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2620 def BLEUL: CondBranchPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2621 def BGEUL: CondBranchPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2622 def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
2625 class CondBranchImmPseudo<string instr_asm> :
2626 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, imm64:$imm, brtarget:$offset),
2627 !strconcat(instr_asm, "\t$rs, $imm, $offset")>;
2629 def BEQLImmMacro : CondBranchImmPseudo<"beql">, ISA_MIPS2_NOT_32R6_64R6;
2630 def BNELImmMacro : CondBranchImmPseudo<"bnel">, ISA_MIPS2_NOT_32R6_64R6;
2632 def BLTImmMacro : CondBranchImmPseudo<"blt">;
2633 def BLEImmMacro : CondBranchImmPseudo<"ble">;
2634 def BGEImmMacro : CondBranchImmPseudo<"bge">;
2635 def BGTImmMacro : CondBranchImmPseudo<"bgt">;
2636 def BLTUImmMacro : CondBranchImmPseudo<"bltu">;
2637 def BLEUImmMacro : CondBranchImmPseudo<"bleu">;
2638 def BGEUImmMacro : CondBranchImmPseudo<"bgeu">;
2639 def BGTUImmMacro : CondBranchImmPseudo<"bgtu">;
2640 def BLTLImmMacro : CondBranchImmPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
2641 def BLELImmMacro : CondBranchImmPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
2642 def BGELImmMacro : CondBranchImmPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
2643 def BGTLImmMacro : CondBranchImmPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2644 def BLTULImmMacro : CondBranchImmPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2645 def BLEULImmMacro : CondBranchImmPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2646 def BGEULImmMacro : CondBranchImmPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2647 def BGTULImmMacro : CondBranchImmPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
2649 // FIXME: Predicates are removed because instructions are matched regardless of
2650 // predicates, because PredicateControl was not in the hierarchy. This was
2651 // done to emit more precise error message from expansion function.
2652 // Once the tablegen-erated errors are made better, this needs to be fixed and
2653 // predicates needs to be restored.
2655 def SDivMacro : MipsAsmPseudoInst<(outs GPR32NonZeroOpnd:$rd),
2656 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2657 "div\t$rd, $rs, $rt">,
2658 ISA_MIPS1_NOT_32R6_64R6;
2659 def SDivIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2660 (ins GPR32Opnd:$rs, simm32:$imm),
2661 "div\t$rd, $rs, $imm">,
2662 ISA_MIPS1_NOT_32R6_64R6;
2663 def UDivMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2664 (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2665 "divu\t$rd, $rs, $rt">,
2666 ISA_MIPS1_NOT_32R6_64R6;
2667 def UDivIMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rd),
2668 (ins GPR32Opnd:$rs, simm32:$imm),
2669 "divu\t$rd, $rs, $imm">,
2670 ISA_MIPS1_NOT_32R6_64R6;
2673 def : MipsInstAlias<"div $rs, $rt", (SDIV GPR32ZeroOpnd:$rs,
2675 ISA_MIPS1_NOT_32R6_64R6;
2676 def : MipsInstAlias<"div $rs, $rt", (SDivMacro GPR32NonZeroOpnd:$rs,
2677 GPR32NonZeroOpnd:$rs,
2679 ISA_MIPS1_NOT_32R6_64R6;
2680 def : MipsInstAlias<"div $rd, $imm", (SDivIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
2682 ISA_MIPS1_NOT_32R6_64R6;
2684 def : MipsInstAlias<"divu $rt, $rs", (UDIV GPR32ZeroOpnd:$rt,
2686 ISA_MIPS1_NOT_32R6_64R6;
2687 def : MipsInstAlias<"divu $rt, $rs", (UDivMacro GPR32NonZeroOpnd:$rt,
2688 GPR32NonZeroOpnd:$rt,
2690 ISA_MIPS1_NOT_32R6_64R6;
2692 def : MipsInstAlias<"divu $rd, $imm", (UDivIMacro GPR32Opnd:$rd, GPR32Opnd:$rd,
2694 ISA_MIPS1_NOT_32R6_64R6;
2696 def Ulh : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2697 "ulh\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2699 def Ulhu : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2700 "ulhu\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2702 def Ulw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2703 "ulw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2705 def Ush : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2706 "ush\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2708 def Usw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2709 "usw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2711 def LDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2712 (ins mem_simm16:$addr), "ld $rt, $addr">,
2713 ISA_MIPS1_NOT_MIPS3;
2714 def SDMacro : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
2715 (ins mem_simm16:$addr), "sd $rt, $addr">,
2716 ISA_MIPS1_NOT_MIPS3;
2717 //===----------------------------------------------------------------------===//
2718 // Arbitrary patterns that map to one or more instructions
2719 //===----------------------------------------------------------------------===//
2721 // Load/store pattern templates.
2722 class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
2723 MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
2725 class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
2726 MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
2728 // Materialize constants.
2729 multiclass MaterializeImms<ValueType VT, Register ZEROReg,
2730 Instruction ADDiuOp, Instruction LUiOp,
2731 Instruction ORiOp> {
2733 // Constant synthesis previously relied on the ordering of the patterns below.
2734 // By making the predicates they use non-overlapping, the patterns were
2735 // reordered so that the effect of the newly introduced predicates can be
2738 // Arbitrary immediates
2739 def : MipsPat<(VT LUiORiPred:$imm), (ORiOp (LUiOp (HI16 imm:$imm)), (LO16 imm:$imm))>;
2741 // Bits 32-16 set, sign/zero extended.
2742 def : MipsPat<(VT LUiPred:$imm), (LUiOp (HI16 imm:$imm))>;
2745 def : MipsPat<(VT ORiPred:$imm), (ORiOp ZEROReg, imm:$imm)>;
2746 def : MipsPat<(VT immSExt16:$imm), (ADDiuOp ZEROReg, imm:$imm)>;
2749 let AdditionalPredicates = [NotInMicroMips] in
2750 defm : MaterializeImms<i32, ZERO, ADDiu, LUi, ORi>;
2752 // Carry MipsPatterns
2753 let AdditionalPredicates = [NotInMicroMips] in {
2754 def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
2755 (SUBu GPR32:$lhs, GPR32:$rhs)>;
2757 def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
2758 (ADDu GPR32:$lhs, GPR32:$rhs)>, ASE_NOT_DSP;
2759 def : MipsPat<(addc GPR32:$src, immSExt16:$imm),
2760 (ADDiu GPR32:$src, imm:$imm)>, ASE_NOT_DSP;
2762 // Support multiplication for pre-Mips32 targets that don't have
2763 // the MUL instruction.
2764 def : MipsPat<(mul GPR32:$lhs, GPR32:$rhs),
2765 (PseudoMFLO (PseudoMULT GPR32:$lhs, GPR32:$rhs))>,
2766 ISA_MIPS1_NOT_32R6_64R6;
2769 def : MipsPat<(MipsSync (i32 immz)),
2770 (SYNC 0)>, ISA_MIPS2;
2773 def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
2774 (JAL texternalsym:$dst)>;
2775 //def : MipsPat<(MipsJmpLink GPR32:$dst),
2776 // (JALR GPR32:$dst)>;
2779 let AdditionalPredicates = [NotInMicroMips] in {
2780 def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
2781 (TAILCALL tglobaladdr:$dst)>;
2782 def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
2783 (TAILCALL texternalsym:$dst)>;
2786 multiclass MipsHiLoRelocs<Instruction Lui, Instruction Addiu,
2787 Register ZeroReg, RegisterOperand GPROpnd> {
2788 def : MipsPat<(MipsHi tglobaladdr:$in), (Lui tglobaladdr:$in)>;
2789 def : MipsPat<(MipsHi tblockaddress:$in), (Lui tblockaddress:$in)>;
2790 def : MipsPat<(MipsHi tjumptable:$in), (Lui tjumptable:$in)>;
2791 def : MipsPat<(MipsHi tconstpool:$in), (Lui tconstpool:$in)>;
2792 def : MipsPat<(MipsHi tglobaltlsaddr:$in), (Lui tglobaltlsaddr:$in)>;
2793 def : MipsPat<(MipsHi texternalsym:$in), (Lui texternalsym:$in)>;
2795 def : MipsPat<(MipsLo tglobaladdr:$in), (Addiu ZeroReg, tglobaladdr:$in)>;
2796 def : MipsPat<(MipsLo tblockaddress:$in),
2797 (Addiu ZeroReg, tblockaddress:$in)>;
2798 def : MipsPat<(MipsLo tjumptable:$in), (Addiu ZeroReg, tjumptable:$in)>;
2799 def : MipsPat<(MipsLo tconstpool:$in), (Addiu ZeroReg, tconstpool:$in)>;
2800 def : MipsPat<(MipsLo tglobaltlsaddr:$in),
2801 (Addiu ZeroReg, tglobaltlsaddr:$in)>;
2802 def : MipsPat<(MipsLo texternalsym:$in), (Addiu ZeroReg, texternalsym:$in)>;
2804 def : MipsPat<(add GPROpnd:$hi, (MipsLo tglobaladdr:$lo)),
2805 (Addiu GPROpnd:$hi, tglobaladdr:$lo)>;
2806 def : MipsPat<(add GPROpnd:$hi, (MipsLo tblockaddress:$lo)),
2807 (Addiu GPROpnd:$hi, tblockaddress:$lo)>;
2808 def : MipsPat<(add GPROpnd:$hi, (MipsLo tjumptable:$lo)),
2809 (Addiu GPROpnd:$hi, tjumptable:$lo)>;
2810 def : MipsPat<(add GPROpnd:$hi, (MipsLo tconstpool:$lo)),
2811 (Addiu GPROpnd:$hi, tconstpool:$lo)>;
2812 def : MipsPat<(add GPROpnd:$hi, (MipsLo tglobaltlsaddr:$lo)),
2813 (Addiu GPROpnd:$hi, tglobaltlsaddr:$lo)>;
2816 defm : MipsHiLoRelocs<LUi, ADDiu, ZERO, GPR32Opnd>;
2818 def : MipsPat<(MipsGotHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
2819 def : MipsPat<(MipsGotHi texternalsym:$in), (LUi texternalsym:$in)>;
2822 def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
2823 (ADDiu GPR32:$gp, tglobaladdr:$in)>, ABI_NOT_N64;
2824 def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
2825 (ADDiu GPR32:$gp, tconstpool:$in)>, ABI_NOT_N64;
2828 class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
2829 MipsPat<(MipsWrapper RC:$gp, node:$in),
2830 (ADDiuOp RC:$gp, node:$in)>;
2832 def : WrapperPat<tglobaladdr, ADDiu, GPR32>;
2833 def : WrapperPat<tconstpool, ADDiu, GPR32>;
2834 def : WrapperPat<texternalsym, ADDiu, GPR32>;
2835 def : WrapperPat<tblockaddress, ADDiu, GPR32>;
2836 def : WrapperPat<tjumptable, ADDiu, GPR32>;
2837 def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>;
2839 let AdditionalPredicates = [NotInMicroMips] in {
2840 // Mips does not have "not", so we expand our way
2841 def : MipsPat<(not GPR32:$in),
2842 (NOR GPR32Opnd:$in, ZERO)>;
2846 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>;
2847 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>;
2848 let AdditionalPredicates = [NotInMicroMips] in {
2849 def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
2853 def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>;
2856 multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BEQOp1,
2857 Instruction BNEOp, Instruction SLTOp, Instruction SLTuOp,
2858 Instruction SLTiOp, Instruction SLTiuOp,
2860 def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
2861 (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
2862 def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
2863 (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
2865 def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
2866 (BEQOp1 (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
2867 def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
2868 (BEQOp1 (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
2869 def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
2870 (BEQOp1 (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
2871 def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
2872 (BEQOp1 (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
2873 def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
2874 (BEQOp1 (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
2875 def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
2876 (BEQOp1 (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
2878 def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
2879 (BEQOp1 (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
2880 def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
2881 (BEQOp1 (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
2883 def : MipsPat<(brcond RC:$cond, bb:$dst),
2884 (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
2886 let AdditionalPredicates = [NotInMicroMips] in {
2887 defm : BrcondPats<GPR32, BEQ, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>;
2889 def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
2890 (BLEZ i32:$lhs, bb:$dst)>;
2891 def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
2892 (BGEZ i32:$lhs, bb:$dst)>;
2895 multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp,
2896 Instruction SLTuOp, Register ZEROReg> {
2897 def : MipsPat<(seteq RC:$lhs, 0),
2898 (SLTiuOp RC:$lhs, 1)>;
2899 def : MipsPat<(setne RC:$lhs, 0),
2900 (SLTuOp ZEROReg, RC:$lhs)>;
2901 def : MipsPat<(seteq RC:$lhs, RC:$rhs),
2902 (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>;
2903 def : MipsPat<(setne RC:$lhs, RC:$rhs),
2904 (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
2907 multiclass SetlePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp,
2908 Instruction SLTuOp> {
2909 def : MipsPat<(setle RC:$lhs, RC:$rhs),
2910 (XORiOp (SLTOp RC:$rhs, RC:$lhs), 1)>;
2911 def : MipsPat<(setule RC:$lhs, RC:$rhs),
2912 (XORiOp (SLTuOp RC:$rhs, RC:$lhs), 1)>;
2915 multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
2916 def : MipsPat<(setgt RC:$lhs, RC:$rhs),
2917 (SLTOp RC:$rhs, RC:$lhs)>;
2918 def : MipsPat<(setugt RC:$lhs, RC:$rhs),
2919 (SLTuOp RC:$rhs, RC:$lhs)>;
2922 multiclass SetgePats<RegisterClass RC, Instruction XORiOp, Instruction SLTOp,
2923 Instruction SLTuOp> {
2924 def : MipsPat<(setge RC:$lhs, RC:$rhs),
2925 (XORiOp (SLTOp RC:$lhs, RC:$rhs), 1)>;
2926 def : MipsPat<(setuge RC:$lhs, RC:$rhs),
2927 (XORiOp (SLTuOp RC:$lhs, RC:$rhs), 1)>;
2930 multiclass SetgeImmPats<RegisterClass RC, Instruction XORiOp,
2931 Instruction SLTiOp, Instruction SLTiuOp> {
2932 def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
2933 (XORiOp (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
2934 def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
2935 (XORiOp (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
2938 let AdditionalPredicates = [NotInMicroMips] in {
2939 defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>;
2940 defm : SetlePats<GPR32, XORi, SLT, SLTu>;
2941 defm : SetgtPats<GPR32, SLT, SLTu>;
2942 defm : SetgePats<GPR32, XORi, SLT, SLTu>;
2943 defm : SetgeImmPats<GPR32, XORi, SLTi, SLTiu>;
2947 def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>;
2949 // Load halfword/word patterns.
2950 let AddedComplexity = 40 in {
2951 def : LoadRegImmPat<LBu, i32, zextloadi8>;
2952 let AdditionalPredicates = [NotInMicroMips] in {
2953 def : LoadRegImmPat<LH, i32, sextloadi16>;
2954 def : LoadRegImmPat<LW, i32, load>;
2958 // Atomic load patterns.
2959 def : MipsPat<(atomic_load_8 addr:$a), (LB addr:$a)>;
2960 let AdditionalPredicates = [NotInMicroMips] in {
2961 def : MipsPat<(atomic_load_16 addr:$a), (LH addr:$a)>;
2963 def : MipsPat<(atomic_load_32 addr:$a), (LW addr:$a)>;
2965 // Atomic store patterns.
2966 def : MipsPat<(atomic_store_8 addr:$a, GPR32:$v), (SB GPR32:$v, addr:$a)>;
2967 def : MipsPat<(atomic_store_16 addr:$a, GPR32:$v), (SH GPR32:$v, addr:$a)>;
2968 def : MipsPat<(atomic_store_32 addr:$a, GPR32:$v), (SW GPR32:$v, addr:$a)>;
2970 //===----------------------------------------------------------------------===//
2971 // Floating Point Support
2972 //===----------------------------------------------------------------------===//
2974 include "MipsInstrFPU.td"
2975 include "Mips64InstrInfo.td"
2976 include "MipsCondMov.td"
2978 include "Mips32r6InstrInfo.td"
2979 include "Mips64r6InstrInfo.td"
2984 include "Mips16InstrFormats.td"
2985 include "Mips16InstrInfo.td"
2988 include "MipsDSPInstrFormats.td"
2989 include "MipsDSPInstrInfo.td"
2992 include "MipsMSAInstrFormats.td"
2993 include "MipsMSAInstrInfo.td"
2996 include "MipsEVAInstrFormats.td"
2997 include "MipsEVAInstrInfo.td"
3000 include "MipsMTInstrFormats.td"
3001 include "MipsMTInstrInfo.td"
3004 include "MicroMipsInstrFormats.td"
3005 include "MicroMipsInstrInfo.td"
3006 include "MicroMipsInstrFPU.td"
3009 include "MicroMips32r6InstrFormats.td"
3010 include "MicroMips32r6InstrInfo.td"
3013 include "MicroMipsDSPInstrFormats.td"
3014 include "MicroMipsDSPInstrInfo.td"