1 //===- MipsInstrInfo.td - Target Description for Mips Target -*- tablegen -*-=//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the Mips implementation of the TargetInstrInfo class.
12 //===----------------------------------------------------------------------===//
15 //===----------------------------------------------------------------------===//
16 // Mips profiles and nodes
17 //===----------------------------------------------------------------------===//
19 def SDT_MipsJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
20 def SDT_MipsCMov : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>,
24 def SDT_MipsCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>;
25 def SDT_MipsCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
26 def SDT_MFLOHI : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisVT<1, untyped>]>;
27 def SDT_MTLOHI : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>,
28 SDTCisInt<1>, SDTCisSameAs<1, 2>]>;
29 def SDT_MipsMultDiv : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>, SDTCisInt<1>,
31 def SDT_MipsMAddMSub : SDTypeProfile<1, 3,
32 [SDTCisVT<0, untyped>, SDTCisSameAs<0, 3>,
33 SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>;
34 def SDT_MipsDivRem16 : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>]>;
36 def SDT_MipsThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
38 def SDT_Sync : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
40 def SDT_Ext : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
41 SDTCisVT<2, i32>, SDTCisSameAs<2, 3>]>;
42 def SDT_Ins : SDTypeProfile<1, 4, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
43 SDTCisVT<2, i32>, SDTCisSameAs<2, 3>,
46 def SDTMipsLoadLR : SDTypeProfile<1, 2,
47 [SDTCisInt<0>, SDTCisPtrTy<1>,
51 def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink,
52 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,
56 def MipsTailCall : SDNode<"MipsISD::TailCall", SDT_MipsJmpLink,
57 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
59 // Hi and Lo nodes are used to handle global addresses. Used on
60 // MipsISelLowering to lower stuff like GlobalAddress, ExternalSymbol
61 // static model. (nothing to do with Mips Registers Hi and Lo)
62 def MipsHi : SDNode<"MipsISD::Hi", SDTIntUnaryOp>;
63 def MipsLo : SDNode<"MipsISD::Lo", SDTIntUnaryOp>;
64 def MipsGPRel : SDNode<"MipsISD::GPRel", SDTIntUnaryOp>;
66 // TlsGd node is used to handle General Dynamic TLS
67 def MipsTlsGd : SDNode<"MipsISD::TlsGd", SDTIntUnaryOp>;
69 // TprelHi and TprelLo nodes are used to handle Local Exec TLS
70 def MipsTprelHi : SDNode<"MipsISD::TprelHi", SDTIntUnaryOp>;
71 def MipsTprelLo : SDNode<"MipsISD::TprelLo", SDTIntUnaryOp>;
74 def MipsThreadPointer: SDNode<"MipsISD::ThreadPointer", SDT_MipsThreadPointer>;
77 def MipsRet : SDNode<"MipsISD::Ret", SDTNone,
78 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
80 def MipsERet : SDNode<"MipsISD::ERet", SDTNone,
81 [SDNPHasChain, SDNPOptInGlue, SDNPSideEffect]>;
83 // These are target-independent nodes, but have target-specific formats.
84 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MipsCallSeqStart,
85 [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>;
86 def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeqEnd,
87 [SDNPHasChain, SDNPSideEffect,
88 SDNPOptInGlue, SDNPOutGlue]>;
90 // Nodes used to extract LO/HI registers.
91 def MipsMFHI : SDNode<"MipsISD::MFHI", SDT_MFLOHI>;
92 def MipsMFLO : SDNode<"MipsISD::MFLO", SDT_MFLOHI>;
94 // Node used to insert 32-bit integers to LOHI register pair.
95 def MipsMTLOHI : SDNode<"MipsISD::MTLOHI", SDT_MTLOHI>;
98 def MipsMult : SDNode<"MipsISD::Mult", SDT_MipsMultDiv>;
99 def MipsMultu : SDNode<"MipsISD::Multu", SDT_MipsMultDiv>;
102 def MipsMAdd : SDNode<"MipsISD::MAdd", SDT_MipsMAddMSub>;
103 def MipsMAddu : SDNode<"MipsISD::MAddu", SDT_MipsMAddMSub>;
104 def MipsMSub : SDNode<"MipsISD::MSub", SDT_MipsMAddMSub>;
105 def MipsMSubu : SDNode<"MipsISD::MSubu", SDT_MipsMAddMSub>;
108 def MipsDivRem : SDNode<"MipsISD::DivRem", SDT_MipsMultDiv>;
109 def MipsDivRemU : SDNode<"MipsISD::DivRemU", SDT_MipsMultDiv>;
110 def MipsDivRem16 : SDNode<"MipsISD::DivRem16", SDT_MipsDivRem16,
112 def MipsDivRemU16 : SDNode<"MipsISD::DivRemU16", SDT_MipsDivRem16,
115 // Target constant nodes that are not part of any isel patterns and remain
116 // unchanged can cause instructions with illegal operands to be emitted.
117 // Wrapper node patterns give the instruction selector a chance to replace
118 // target constant nodes that would otherwise remain unchanged with ADDiu
119 // nodes. Without these wrapper node patterns, the following conditional move
120 // instruction is emitted when function cmov2 in test/CodeGen/Mips/cmov.ll is
122 // movn %got(d)($gp), %got(c)($gp), $4
123 // This instruction is illegal since movn can take only register operands.
125 def MipsWrapper : SDNode<"MipsISD::Wrapper", SDTIntBinOp>;
127 def MipsSync : SDNode<"MipsISD::Sync", SDT_Sync, [SDNPHasChain,SDNPSideEffect]>;
129 def MipsExt : SDNode<"MipsISD::Ext", SDT_Ext>;
130 def MipsIns : SDNode<"MipsISD::Ins", SDT_Ins>;
132 def MipsLWL : SDNode<"MipsISD::LWL", SDTMipsLoadLR,
133 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
134 def MipsLWR : SDNode<"MipsISD::LWR", SDTMipsLoadLR,
135 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
136 def MipsSWL : SDNode<"MipsISD::SWL", SDTStore,
137 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
138 def MipsSWR : SDNode<"MipsISD::SWR", SDTStore,
139 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
140 def MipsLDL : SDNode<"MipsISD::LDL", SDTMipsLoadLR,
141 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
142 def MipsLDR : SDNode<"MipsISD::LDR", SDTMipsLoadLR,
143 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
144 def MipsSDL : SDNode<"MipsISD::SDL", SDTStore,
145 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
146 def MipsSDR : SDNode<"MipsISD::SDR", SDTStore,
147 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
149 //===----------------------------------------------------------------------===//
150 // Mips Instruction Predicate Definitions.
151 //===----------------------------------------------------------------------===//
152 def HasMips2 : Predicate<"Subtarget->hasMips2()">,
153 AssemblerPredicate<"FeatureMips2">;
154 def HasMips3_32 : Predicate<"Subtarget->hasMips3_32()">,
155 AssemblerPredicate<"FeatureMips3_32">;
156 def HasMips3_32r2 : Predicate<"Subtarget->hasMips3_32r2()">,
157 AssemblerPredicate<"FeatureMips3_32r2">;
158 def HasMips3 : Predicate<"Subtarget->hasMips3()">,
159 AssemblerPredicate<"FeatureMips3">;
160 def HasMips4_32 : Predicate<"Subtarget->hasMips4_32()">,
161 AssemblerPredicate<"FeatureMips4_32">;
162 def NotMips4_32 : Predicate<"!Subtarget->hasMips4_32()">,
163 AssemblerPredicate<"!FeatureMips4_32">;
164 def HasMips4_32r2 : Predicate<"Subtarget->hasMips4_32r2()">,
165 AssemblerPredicate<"FeatureMips4_32r2">;
166 def HasMips5_32r2 : Predicate<"Subtarget->hasMips5_32r2()">,
167 AssemblerPredicate<"FeatureMips5_32r2">;
168 def HasMips32 : Predicate<"Subtarget->hasMips32()">,
169 AssemblerPredicate<"FeatureMips32">;
170 def HasMips32r2 : Predicate<"Subtarget->hasMips32r2()">,
171 AssemblerPredicate<"FeatureMips32r2">;
172 def HasMips32r5 : Predicate<"Subtarget->hasMips32r5()">,
173 AssemblerPredicate<"FeatureMips32r5">;
174 def HasMips32r6 : Predicate<"Subtarget->hasMips32r6()">,
175 AssemblerPredicate<"FeatureMips32r6">;
176 def NotMips32r6 : Predicate<"!Subtarget->hasMips32r6()">,
177 AssemblerPredicate<"!FeatureMips32r6">;
178 def IsGP64bit : Predicate<"Subtarget->isGP64bit()">,
179 AssemblerPredicate<"FeatureGP64Bit">;
180 def IsGP32bit : Predicate<"!Subtarget->isGP64bit()">,
181 AssemblerPredicate<"!FeatureGP64Bit">;
182 def HasMips64 : Predicate<"Subtarget->hasMips64()">,
183 AssemblerPredicate<"FeatureMips64">;
184 def NotMips64 : Predicate<"!Subtarget->hasMips64()">,
185 AssemblerPredicate<"!FeatureMips64">;
186 def HasMips64r2 : Predicate<"Subtarget->hasMips64r2()">,
187 AssemblerPredicate<"FeatureMips64r2">;
188 def HasMips64r6 : Predicate<"Subtarget->hasMips64r6()">,
189 AssemblerPredicate<"FeatureMips64r6">;
190 def NotMips64r6 : Predicate<"!Subtarget->hasMips64r6()">,
191 AssemblerPredicate<"!FeatureMips64r6">;
192 def HasMicroMips32r6 : Predicate<"Subtarget->inMicroMips32r6Mode()">,
193 AssemblerPredicate<"FeatureMicroMips,FeatureMips32r6">;
194 def HasMicroMips64r6 : Predicate<"Subtarget->inMicroMips64r6Mode()">,
195 AssemblerPredicate<"FeatureMicroMips,FeatureMips64r6">;
196 def InMips16Mode : Predicate<"Subtarget->inMips16Mode()">,
197 AssemblerPredicate<"FeatureMips16">;
198 def HasCnMips : Predicate<"Subtarget->hasCnMips()">,
199 AssemblerPredicate<"FeatureCnMips">;
200 def RelocStatic : Predicate<"TM.getRelocationModel() == Reloc::Static">;
201 def RelocPIC : Predicate<"TM.getRelocationModel() == Reloc::PIC_">;
202 def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">;
203 def HasStdEnc : Predicate<"Subtarget->hasStandardEncoding()">,
204 AssemblerPredicate<"!FeatureMips16">;
205 def NotDSP : Predicate<"!Subtarget->hasDSP()">;
206 def InMicroMips : Predicate<"Subtarget->inMicroMipsMode()">,
207 AssemblerPredicate<"FeatureMicroMips">;
208 def NotInMicroMips : Predicate<"!Subtarget->inMicroMipsMode()">,
209 AssemblerPredicate<"!FeatureMicroMips">;
210 def IsLE : Predicate<"Subtarget->isLittle()">;
211 def IsBE : Predicate<"!Subtarget->isLittle()">;
212 def IsNotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
213 def UseTCCInDIV : AssemblerPredicate<"FeatureUseTCCInDIV">;
214 def HasEVA : Predicate<"Subtarget->hasEVA()">,
215 AssemblerPredicate<"FeatureEVA,FeatureMips32r2">;
216 def HasMSA : Predicate<"Subtarget->hasMSA()">,
217 AssemblerPredicate<"FeatureMSA">;
220 //===----------------------------------------------------------------------===//
221 // Mips GPR size adjectives.
222 // They are mutually exclusive.
223 //===----------------------------------------------------------------------===//
225 class GPR_32 { list<Predicate> GPRPredicates = [IsGP32bit]; }
226 class GPR_64 { list<Predicate> GPRPredicates = [IsGP64bit]; }
228 //===----------------------------------------------------------------------===//
229 // Mips ISA/ASE membership and instruction group membership adjectives.
230 // They are mutually exclusive.
231 //===----------------------------------------------------------------------===//
233 // FIXME: I'd prefer to use additive predicates to build the instruction sets
234 // but we are short on assembler feature bits at the moment. Using a
235 // subtractive predicate will hopefully keep us under the 32 predicate
236 // limit long enough to develop an alternative way to handle P1||P2
238 class ISA_MIPS1_NOT_4_32 {
239 list<Predicate> InsnPredicates = [NotMips4_32];
241 class ISA_MIPS1_NOT_32R6_64R6 {
242 list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6];
244 class ISA_MIPS2 { list<Predicate> InsnPredicates = [HasMips2]; }
245 class ISA_MIPS2_NOT_32R6_64R6 {
246 list<Predicate> InsnPredicates = [HasMips2, NotMips32r6, NotMips64r6];
248 class ISA_MIPS3 { list<Predicate> InsnPredicates = [HasMips3]; }
249 class ISA_MIPS3_NOT_32R6_64R6 {
250 list<Predicate> InsnPredicates = [HasMips3, NotMips32r6, NotMips64r6];
252 class ISA_MIPS32 { list<Predicate> InsnPredicates = [HasMips32]; }
253 class ISA_MIPS32_NOT_32R6_64R6 {
254 list<Predicate> InsnPredicates = [HasMips32, NotMips32r6, NotMips64r6];
256 class ISA_MIPS32R2 { list<Predicate> InsnPredicates = [HasMips32r2]; }
257 class ISA_MIPS32R2_NOT_32R6_64R6 {
258 list<Predicate> InsnPredicates = [HasMips32r2, NotMips32r6, NotMips64r6];
260 class ISA_MIPS32R5 { list<Predicate> InsnPredicates = [HasMips32r5]; }
261 class ISA_MIPS64 { list<Predicate> InsnPredicates = [HasMips64]; }
262 class ISA_MIPS64_NOT_64R6 {
263 list<Predicate> InsnPredicates = [HasMips64, NotMips64r6];
265 class ISA_MIPS64R2 { list<Predicate> InsnPredicates = [HasMips64r2]; }
266 class ISA_MIPS32R6 { list<Predicate> InsnPredicates = [HasMips32r6]; }
267 class ISA_MIPS64R6 { list<Predicate> InsnPredicates = [HasMips64r6]; }
268 class ISA_MICROMIPS { list<Predicate> InsnPredicates = [InMicroMips]; }
269 class ISA_MICROMIPS32R6 {
270 list<Predicate> InsnPredicates = [HasMicroMips32r6];
272 class ISA_MICROMIPS64R6 {
273 list<Predicate> InsnPredicates = [HasMicroMips64r6];
275 class ISA_MICROMIPS32_NOT_MIPS32R6 {
276 list<Predicate> InsnPredicates = [InMicroMips, NotMips32r6];
279 class INSN_EVA { list<Predicate> InsnPredicates = [HasEVA]; }
280 class INSN_EVA_NOT_32R6_64R6 {
281 list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6, HasEVA];
284 // The portions of MIPS-III that were also added to MIPS32
285 class INSN_MIPS3_32 { list<Predicate> InsnPredicates = [HasMips3_32]; }
287 // The portions of MIPS-III that were also added to MIPS32 but were removed in
288 // MIPS32r6 and MIPS64r6.
289 class INSN_MIPS3_32_NOT_32R6_64R6 {
290 list<Predicate> InsnPredicates = [HasMips3_32, NotMips32r6, NotMips64r6];
293 // The portions of MIPS-III that were also added to MIPS32
294 class INSN_MIPS3_32R2 { list<Predicate> InsnPredicates = [HasMips3_32r2]; }
296 // The portions of MIPS-IV that were also added to MIPS32 but were removed in
297 // MIPS32r6 and MIPS64r6.
298 class INSN_MIPS4_32_NOT_32R6_64R6 {
299 list<Predicate> InsnPredicates = [HasMips4_32, NotMips32r6, NotMips64r6];
302 // The portions of MIPS-IV that were also added to MIPS32r2 but were removed in
303 // MIPS32r6 and MIPS64r6.
304 class INSN_MIPS4_32R2_NOT_32R6_64R6 {
305 list<Predicate> InsnPredicates = [HasMips4_32r2, NotMips32r6, NotMips64r6];
308 // The portions of MIPS-V that were also added to MIPS32r2 but were removed in
309 // MIPS32r6 and MIPS64r6.
310 class INSN_MIPS5_32R2_NOT_32R6_64R6 {
311 list<Predicate> InsnPredicates = [HasMips5_32r2, NotMips32r6, NotMips64r6];
315 list<Predicate> InsnPredicates = [HasCnMips];
319 list<Predicate> InsnPredicates = [HasMSA];
322 class ASE_MSA_NOT_MSA64 {
323 list<Predicate> InsnPredicates = [HasMSA, NotMips64];
327 list<Predicate> InsnPredicates = [HasMSA, HasMips64];
330 // Class used for separating microMIPSr6 and microMIPS (r3) instruction.
331 // It can be used only on instructions that doesn't inherit PredicateControl.
332 class ISA_MICROMIPS_NOT_32R6_64R6 : PredicateControl {
333 let InsnPredicates = [InMicroMips, NotMips32r6, NotMips64r6];
336 //===----------------------------------------------------------------------===//
338 class MipsPat<dag pattern, dag result> : Pat<pattern, result>, PredicateControl {
339 let EncodingPredicates = [HasStdEnc];
342 class MipsInstAlias<string Asm, dag Result, bit Emit = 0b1> :
343 InstAlias<Asm, Result, Emit>, PredicateControl;
346 bit isCommutable = 1;
363 bit isTerminator = 1;
366 bit hasExtraSrcRegAllocReq = 1;
367 bit isCodeGenOnly = 1;
370 class IsAsCheapAsAMove {
371 bit isAsCheapAsAMove = 1;
374 class NeverHasSideEffects {
375 bit hasSideEffects = 0;
378 //===----------------------------------------------------------------------===//
379 // Instruction format superclass
380 //===----------------------------------------------------------------------===//
382 include "MipsInstrFormats.td"
384 //===----------------------------------------------------------------------===//
385 // Mips Operand, Complex Patterns and Transformations Definitions.
386 //===----------------------------------------------------------------------===//
388 class ConstantSImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
390 let Name = "ConstantSImm" # Bits;
391 let RenderMethod = "addImmOperands";
392 let PredicateMethod = "isConstantSImm<" # Bits # ">";
393 let SuperClasses = Supers;
394 let DiagnosticType = "SImm" # Bits;
397 class ConstantUImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
398 int Offset = 0> : AsmOperandClass {
399 let Name = "ConstantUImm" # Bits # "_" # Offset;
400 let RenderMethod = "addConstantUImmOperands<" # Bits # ", " # Offset # ">";
401 let PredicateMethod = "isConstantUImm<" # Bits # ", " # Offset # ">";
402 let SuperClasses = Supers;
403 let DiagnosticType = "UImm" # Bits # "_" # Offset;
406 def ConstantUImm10AsmOperandClass
407 : ConstantUImmAsmOperandClass<10, []>;
408 def ConstantUImm8AsmOperandClass
409 : ConstantUImmAsmOperandClass<8, [ConstantUImm10AsmOperandClass]>;
410 def ConstantUImm7AsmOperandClass
411 : ConstantUImmAsmOperandClass<7, [ConstantUImm8AsmOperandClass]>;
412 def ConstantUImm6AsmOperandClass
413 : ConstantUImmAsmOperandClass<6, [ConstantUImm7AsmOperandClass]>;
414 def ConstantSImm6AsmOperandClass
415 : ConstantSImmAsmOperandClass<6, [ConstantUImm7AsmOperandClass]>;
416 def ConstantUImm5Plus1AsmOperandClass
417 : ConstantUImmAsmOperandClass<5, [ConstantUImm6AsmOperandClass], 1>;
418 def ConstantUImm5Plus32AsmOperandClass
419 : ConstantUImmAsmOperandClass<5, [ConstantUImm6AsmOperandClass], 32>;
420 def ConstantUImm5Plus33AsmOperandClass
421 : ConstantUImmAsmOperandClass<5, [ConstantUImm6AsmOperandClass], 33>;
422 def ConstantUImm5Plus32NormalizeAsmOperandClass
423 : ConstantUImmAsmOperandClass<5, [ConstantUImm6AsmOperandClass], 32> {
424 let Name = "ConstantUImm5_32_Norm";
425 // We must also subtract 32 when we render the operand.
426 let RenderMethod = "addConstantUImmOperands<5, 32, -32>";
428 def ConstantUImm5Lsl2AsmOperandClass : AsmOperandClass {
429 let Name = "UImm5Lsl2";
430 let RenderMethod = "addImmOperands";
431 let PredicateMethod = "isScaledUImm<5, 2>";
432 let SuperClasses = [ConstantUImm6AsmOperandClass];
433 let DiagnosticType = "UImm5_Lsl2";
435 def ConstantUImm5ReportUImm6AsmOperandClass
436 : ConstantUImmAsmOperandClass<5, [ConstantUImm6AsmOperandClass]> {
437 let Name = "ConstantUImm5_0_Report_UImm6";
438 let DiagnosticType = "UImm5_0_Report_UImm6";
440 def ConstantUImm5AsmOperandClass
441 : ConstantUImmAsmOperandClass<5, [ConstantUImm6AsmOperandClass]>;
442 def ConstantUImm4AsmOperandClass
443 : ConstantUImmAsmOperandClass<
444 4, [ConstantUImm5AsmOperandClass,
445 ConstantUImm5Plus32AsmOperandClass,
446 ConstantUImm5Plus32NormalizeAsmOperandClass]>;
447 def ConstantUImm3AsmOperandClass
448 : ConstantUImmAsmOperandClass<3, [ConstantUImm4AsmOperandClass]>;
449 def ConstantUImm2Plus1AsmOperandClass
450 : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass], 1>;
451 def ConstantUImm2AsmOperandClass
452 : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass]>;
453 def ConstantUImm1AsmOperandClass
454 : ConstantUImmAsmOperandClass<1, [ConstantUImm2AsmOperandClass]>;
455 def ConstantImmzAsmOperandClass : AsmOperandClass {
456 let Name = "ConstantImmz";
457 let RenderMethod = "addConstantUImmOperands<1>";
458 let PredicateMethod = "isConstantImmz";
459 let SuperClasses = [ConstantUImm1AsmOperandClass];
460 let DiagnosticType = "Immz";
463 def MipsJumpTargetAsmOperand : AsmOperandClass {
464 let Name = "JumpTarget";
465 let ParserMethod = "parseJumpTarget";
466 let PredicateMethod = "isImm";
467 let RenderMethod = "addImmOperands";
470 // Instruction operand types
471 def jmptarget : Operand<OtherVT> {
472 let EncoderMethod = "getJumpTargetOpValue";
473 let ParserMatchClass = MipsJumpTargetAsmOperand;
475 def brtarget : Operand<OtherVT> {
476 let EncoderMethod = "getBranchTargetOpValue";
477 let OperandType = "OPERAND_PCREL";
478 let DecoderMethod = "DecodeBranchTarget";
479 let ParserMatchClass = MipsJumpTargetAsmOperand;
481 def calltarget : Operand<iPTR> {
482 let EncoderMethod = "getJumpTargetOpValue";
483 let ParserMatchClass = MipsJumpTargetAsmOperand;
486 def imm64: Operand<i64>;
488 def simm6 : Operand<i32> {
489 let ParserMatchClass = ConstantSImm6AsmOperandClass;
490 let OperandType = "OPERAND_IMMEDIATE";
492 def simm9 : Operand<i32>;
493 def simm10 : Operand<i32>;
494 def simm11 : Operand<i32>;
496 def simm16 : Operand<i32> {
497 let DecoderMethod= "DecodeSimm16";
500 def simm19_lsl2 : Operand<i32> {
501 let EncoderMethod = "getSimm19Lsl2Encoding";
502 let DecoderMethod = "DecodeSimm19Lsl2";
503 let ParserMatchClass = MipsJumpTargetAsmOperand;
506 def simm18_lsl3 : Operand<i32> {
507 let EncoderMethod = "getSimm18Lsl3Encoding";
508 let DecoderMethod = "DecodeSimm18Lsl3";
509 let ParserMatchClass = MipsJumpTargetAsmOperand;
512 def simm20 : Operand<i32>;
513 def simm32 : Operand<i32>;
515 def uimm20 : Operand<i32> {
518 def simm16_64 : Operand<i64> {
519 let DecoderMethod = "DecodeSimm16";
523 def uimmz : Operand<i32> {
524 let PrintMethod = "printUnsignedImm";
525 let ParserMatchClass = ConstantImmzAsmOperandClass;
529 foreach I = {1, 2, 3, 4, 5, 6, 7, 8, 10} in
530 def uimm # I : Operand<i32> {
531 let PrintMethod = "printUnsignedImm";
532 let ParserMatchClass =
533 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
536 def uimm2_plus1 : Operand<i32> {
537 let PrintMethod = "printUnsignedImm";
538 let EncoderMethod = "getUImmWithOffsetEncoding<2, 1>";
539 let DecoderMethod = "DecodeUImmWithOffset<2, 1>";
540 let ParserMatchClass = ConstantUImm2Plus1AsmOperandClass;
543 def uimm5_plus1 : Operand<i32> {
544 let PrintMethod = "printUnsignedImm";
545 let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
546 let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
547 let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass;
550 def uimm5_plus32 : Operand<i32> {
551 let PrintMethod = "printUnsignedImm";
552 let ParserMatchClass = ConstantUImm5Plus32AsmOperandClass;
555 def uimm5_plus33 : Operand<i32> {
556 let PrintMethod = "printUnsignedImm";
557 let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>";
558 let DecoderMethod = "DecodeUImmWithOffset<5, 1>";
559 let ParserMatchClass = ConstantUImm5Plus33AsmOperandClass;
562 def uimm5_plus32_normalize : Operand<i32> {
563 let PrintMethod = "printUnsignedImm";
564 let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
567 def uimm5_lsl2 : Operand<OtherVT> {
568 let EncoderMethod = "getUImm5Lsl2Encoding";
569 let DecoderMethod = "DecodeUImm5lsl2";
570 let ParserMatchClass = ConstantUImm5Lsl2AsmOperandClass;
573 def uimm5_plus32_normalize_64 : Operand<i64> {
574 let PrintMethod = "printUnsignedImm";
575 let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
579 def uimm # I # _64 : Operand<i64> {
580 let PrintMethod = "printUnsignedImm";
581 let ParserMatchClass =
582 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
585 // Like uimm5_64 but reports a less confusing error for 32-63 when
586 // an instruction alias permits that.
587 def uimm5_64_report_uimm6 : Operand<i64> {
588 let PrintMethod = "printUnsignedImm";
589 let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
592 def uimm16 : Operand<i32> {
593 let PrintMethod = "printUnsignedImm";
596 def pcrel16 : Operand<i32> {
599 def MipsMemAsmOperand : AsmOperandClass {
601 let ParserMethod = "parseMemOperand";
604 def MipsMemSimm9AsmOperand : AsmOperandClass {
605 let Name = "MemOffsetSimm9";
606 let SuperClasses = [MipsMemAsmOperand];
607 let RenderMethod = "addMemOperands";
608 let ParserMethod = "parseMemOperand";
609 let PredicateMethod = "isMemWithSimmOffset<9>";
612 def MipsMemSimm9GPRAsmOperand : AsmOperandClass {
613 let Name = "MemOffsetSimm9GPR";
614 let SuperClasses = [MipsMemAsmOperand];
615 let RenderMethod = "addMemOperands";
616 let ParserMethod = "parseMemOperand";
617 let PredicateMethod = "isMemWithSimmOffsetGPR<9>";
620 def MipsMemSimm11AsmOperand : AsmOperandClass {
621 let Name = "MemOffsetSimm11";
622 let SuperClasses = [MipsMemAsmOperand];
623 let RenderMethod = "addMemOperands";
624 let ParserMethod = "parseMemOperand";
625 let PredicateMethod = "isMemWithSimmOffset<11>";
628 def MipsMemSimm16AsmOperand : AsmOperandClass {
629 let Name = "MemOffsetSimm16";
630 let SuperClasses = [MipsMemAsmOperand];
631 let RenderMethod = "addMemOperands";
632 let ParserMethod = "parseMemOperand";
633 let PredicateMethod = "isMemWithSimmOffset<16>";
636 def MipsInvertedImmoperand : AsmOperandClass {
638 let RenderMethod = "addImmOperands";
639 let ParserMethod = "parseInvNum";
642 def InvertedImOperand : Operand<i32> {
643 let ParserMatchClass = MipsInvertedImmoperand;
646 def InvertedImOperand64 : Operand<i64> {
647 let ParserMatchClass = MipsInvertedImmoperand;
650 class mem_generic : Operand<iPTR> {
651 let PrintMethod = "printMemOperand";
652 let MIOperandInfo = (ops ptr_rc, simm16);
653 let EncoderMethod = "getMemEncoding";
654 let ParserMatchClass = MipsMemAsmOperand;
655 let OperandType = "OPERAND_MEMORY";
659 def mem : mem_generic;
661 // MSA specific address operand
662 def mem_msa : mem_generic {
663 let MIOperandInfo = (ops ptr_rc, simm10);
664 let EncoderMethod = "getMSAMemEncoding";
667 def mem_simm9 : mem_generic {
668 let MIOperandInfo = (ops ptr_rc, simm9);
669 let EncoderMethod = "getMemEncoding";
670 let ParserMatchClass = MipsMemSimm9AsmOperand;
673 def mem_simm9gpr : mem_generic {
674 let MIOperandInfo = (ops ptr_rc, simm9);
675 let EncoderMethod = "getMemEncoding";
676 let ParserMatchClass = MipsMemSimm9GPRAsmOperand;
679 def mem_simm11 : mem_generic {
680 let MIOperandInfo = (ops ptr_rc, simm11);
681 let EncoderMethod = "getMemEncoding";
682 let ParserMatchClass = MipsMemSimm11AsmOperand;
685 def mem_simm16 : mem_generic {
686 let MIOperandInfo = (ops ptr_rc, simm16);
687 let EncoderMethod = "getMemEncoding";
688 let ParserMatchClass = MipsMemSimm16AsmOperand;
691 def mem_ea : Operand<iPTR> {
692 let PrintMethod = "printMemOperandEA";
693 let MIOperandInfo = (ops ptr_rc, simm16);
694 let EncoderMethod = "getMemEncoding";
695 let OperandType = "OPERAND_MEMORY";
698 def PtrRC : Operand<iPTR> {
699 let MIOperandInfo = (ops ptr_rc);
700 let DecoderMethod = "DecodePtrRegisterClass";
701 let ParserMatchClass = GPR32AsmOperand;
704 // size operand of ins instruction
705 def size_ins : Operand<i32> {
706 let EncoderMethod = "getSizeInsEncoding";
707 let DecoderMethod = "DecodeInsSize";
710 // Transformation Function - get the lower 16 bits.
711 def LO16 : SDNodeXForm<imm, [{
712 return getImm(N, N->getZExtValue() & 0xFFFF);
715 // Transformation Function - get the higher 16 bits.
716 def HI16 : SDNodeXForm<imm, [{
717 return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF);
721 def Plus1 : SDNodeXForm<imm, [{ return getImm(N, N->getSExtValue() + 1); }]>;
723 // Node immediate is zero (e.g. insve.d)
724 def immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>;
726 // Node immediate fits as 16-bit sign extended on target immediate.
728 def immSExt8 : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;
730 // Node immediate fits as 16-bit sign extended on target immediate.
732 def immSExt16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;
734 // Node immediate fits as 15-bit sign extended on target immediate.
736 def immSExt15 : PatLeaf<(imm), [{ return isInt<15>(N->getSExtValue()); }]>;
738 // Node immediate fits as 16-bit zero extended on target immediate.
739 // The LO16 param means that only the lower 16 bits of the node
740 // immediate are caught.
742 def immZExt16 : PatLeaf<(imm), [{
743 if (N->getValueType(0) == MVT::i32)
744 return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
746 return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
749 // Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared).
750 def immLow16Zero : PatLeaf<(imm), [{
751 int64_t Val = N->getSExtValue();
752 return isInt<32>(Val) && !(Val & 0xffff);
755 // shamt field must fit in 5 bits.
756 def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
758 // True if (N + 1) fits in 16-bit field.
759 def immSExt16Plus1 : PatLeaf<(imm), [{
760 return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1);
763 // Mips Address Mode! SDNode frameindex could possibily be a match
764 // since load and store instructions from stack used it.
766 ComplexPattern<iPTR, 2, "selectIntAddr", [frameindex]>;
769 ComplexPattern<iPTR, 2, "selectAddrRegImm", [frameindex]>;
772 ComplexPattern<iPTR, 2, "selectAddrRegReg", [frameindex]>;
775 ComplexPattern<iPTR, 2, "selectAddrDefault", [frameindex]>;
777 def addrimm10 : ComplexPattern<iPTR, 2, "selectIntAddrMSA", [frameindex]>;
779 //===----------------------------------------------------------------------===//
780 // Instructions specific format
781 //===----------------------------------------------------------------------===//
783 // Arithmetic and logical instructions with 3 register operands.
784 class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0,
785 InstrItinClass Itin = NoItinerary,
786 SDPatternOperator OpNode = null_frag>:
787 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
788 !strconcat(opstr, "\t$rd, $rs, $rt"),
789 [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> {
790 let isCommutable = isComm;
791 let isReMaterializable = 1;
792 let TwoOperandAliasConstraint = "$rd = $rs";
795 // Arithmetic and logical instructions with 2 register operands.
796 class ArithLogicI<string opstr, Operand Od, RegisterOperand RO,
797 InstrItinClass Itin = NoItinerary,
798 SDPatternOperator imm_type = null_frag,
799 SDPatternOperator OpNode = null_frag> :
800 InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16),
801 !strconcat(opstr, "\t$rt, $rs, $imm16"),
802 [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))],
804 let isReMaterializable = 1;
805 let TwoOperandAliasConstraint = "$rs = $rt";
808 // Arithmetic Multiply ADD/SUB
809 class MArithR<string opstr, InstrItinClass itin, bit isComm = 0> :
810 InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
811 !strconcat(opstr, "\t$rs, $rt"), [], itin, FrmR, opstr> {
812 let Defs = [HI0, LO0];
813 let Uses = [HI0, LO0];
814 let isCommutable = isComm;
818 class LogicNOR<string opstr, RegisterOperand RO>:
819 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
820 !strconcat(opstr, "\t$rd, $rs, $rt"),
821 [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], II_NOR, FrmR, opstr> {
822 let isCommutable = 1;
826 class shift_rotate_imm<string opstr, Operand ImmOpnd,
827 RegisterOperand RO, InstrItinClass itin,
828 SDPatternOperator OpNode = null_frag,
829 SDPatternOperator PF = null_frag> :
830 InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt),
831 !strconcat(opstr, "\t$rd, $rt, $shamt"),
832 [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], itin, FrmR, opstr> {
833 let TwoOperandAliasConstraint = "$rt = $rd";
836 class shift_rotate_reg<string opstr, RegisterOperand RO, InstrItinClass itin,
837 SDPatternOperator OpNode = null_frag>:
838 InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs),
839 !strconcat(opstr, "\t$rd, $rt, $rs"),
840 [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], itin, FrmR,
843 // Load Upper Immediate
844 class LoadUpper<string opstr, RegisterOperand RO, Operand Imm>:
845 InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"),
846 [], II_LUI, FrmI, opstr>, IsAsCheapAsAMove {
847 let hasSideEffects = 0;
848 let isReMaterializable = 1;
852 class Load<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
853 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
854 InstSE<(outs RO:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
855 [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> {
856 let DecoderMethod = "DecodeMem";
857 let canFoldAsLoad = 1;
861 class StoreMemory<string opstr, DAGOperand RO, DAGOperand MO,
862 SDPatternOperator OpNode = null_frag,
863 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
864 InstSE<(outs), (ins RO:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
865 [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> {
866 let DecoderMethod = "DecodeMem";
870 class Store<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
871 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
872 StoreMemory<opstr, RO, mem, OpNode, Itin, Addr>;
874 // Load/Store Left/Right
875 let canFoldAsLoad = 1 in
876 class LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
877 InstrItinClass Itin> :
878 InstSE<(outs RO:$rt), (ins mem:$addr, RO:$src),
879 !strconcat(opstr, "\t$rt, $addr"),
880 [(set RO:$rt, (OpNode addr:$addr, RO:$src))], Itin, FrmI> {
881 let DecoderMethod = "DecodeMem";
882 string Constraints = "$src = $rt";
885 class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
886 InstrItinClass Itin> :
887 InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
888 [(OpNode RO:$rt, addr:$addr)], Itin, FrmI> {
889 let DecoderMethod = "DecodeMem";
893 class LW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
894 SDPatternOperator OpNode= null_frag> :
895 InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
896 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
897 let DecoderMethod = "DecodeFMem2";
901 class SW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
902 SDPatternOperator OpNode= null_frag> :
903 InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
904 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
905 let DecoderMethod = "DecodeFMem2";
910 class LW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
911 SDPatternOperator OpNode= null_frag> :
912 InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
913 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
914 let DecoderMethod = "DecodeFMem3";
918 class SW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
919 SDPatternOperator OpNode= null_frag> :
920 InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
921 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
922 let DecoderMethod = "DecodeFMem3";
926 // Conditional Branch
927 class CBranch<string opstr, DAGOperand opnd, PatFrag cond_op,
928 RegisterOperand RO, bit DelaySlot = 1> :
929 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
930 !strconcat(opstr, "\t$rs, $rt, $offset"),
931 [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], II_BCC,
934 let isTerminator = 1;
935 let hasDelaySlot = DelaySlot;
939 class CBranchZero<string opstr, DAGOperand opnd, PatFrag cond_op,
940 RegisterOperand RO, bit DelaySlot = 1> :
941 InstSE<(outs), (ins RO:$rs, opnd:$offset),
942 !strconcat(opstr, "\t$rs, $offset"),
943 [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], II_BCCZ,
946 let isTerminator = 1;
947 let hasDelaySlot = DelaySlot;
952 class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> :
953 InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt),
954 !strconcat(opstr, "\t$rd, $rs, $rt"),
955 [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))],
956 II_SLT_SLTU, FrmR, opstr>;
958 class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
960 InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16),
961 !strconcat(opstr, "\t$rt, $rs, $imm16"),
962 [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))],
963 II_SLTI_SLTIU, FrmI, opstr>;
966 class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
967 SDPatternOperator targetoperator, string bopstr> :
968 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
969 [(operator targetoperator:$target)], II_J, FrmJ, bopstr> {
972 let hasDelaySlot = 1;
973 let DecoderMethod = "DecodeJumpTarget";
977 // Unconditional branch
978 class UncondBranch<Instruction BEQInst> :
979 PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], II_B>,
980 PseudoInstExpansion<(BEQInst ZERO, ZERO, brtarget:$offset)> {
982 let isTerminator = 1;
984 let hasDelaySlot = 1;
985 let AdditionalPredicates = [RelocPIC];
989 // Base class for indirect branch and return instruction classes.
990 let isTerminator=1, isBarrier=1, hasDelaySlot = 1 in
991 class JumpFR<string opstr, RegisterOperand RO,
992 SDPatternOperator operator = null_frag>:
993 InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], II_JR,
997 class IndirectBranch<string opstr, RegisterOperand RO> : JumpFR<opstr, RO> {
999 let isIndirectBranch = 1;
1002 // Jump and Link (Call)
1003 let isCall=1, hasDelaySlot=1, Defs = [RA] in {
1004 class JumpLink<string opstr, DAGOperand opnd> :
1005 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
1006 [(MipsJmpLink tglobaladdr:$target)], II_JAL, FrmJ, opstr> {
1007 let DecoderMethod = "DecodeJumpTarget";
1010 class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst,
1011 Register RetReg, RegisterOperand ResRO = RO>:
1012 PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], II_JALR>,
1013 PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)>;
1015 class JumpLinkReg<string opstr, RegisterOperand RO>:
1016 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1017 [], II_JALR, FrmR, opstr>;
1019 class BGEZAL_FT<string opstr, DAGOperand opnd,
1020 RegisterOperand RO, bit DelaySlot = 1> :
1021 InstSE<(outs), (ins RO:$rs, opnd:$offset),
1022 !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZAL, FrmI, opstr> {
1023 let hasDelaySlot = DelaySlot;
1028 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
1029 hasExtraSrcRegAllocReq = 1, Defs = [AT] in {
1030 class TailCall<Instruction JumpInst> :
1031 PseudoSE<(outs), (ins calltarget:$target), [], II_J>,
1032 PseudoInstExpansion<(JumpInst jmptarget:$target)>;
1034 class TailCallReg<RegisterOperand RO, Instruction JRInst,
1035 RegisterOperand ResRO = RO> :
1036 PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>,
1037 PseudoInstExpansion<(JRInst ResRO:$rs)>;
1040 class BAL_BR_Pseudo<Instruction RealInst> :
1041 PseudoSE<(outs), (ins brtarget:$offset), [], II_BCCZAL>,
1042 PseudoInstExpansion<(RealInst ZERO, brtarget:$offset)> {
1044 let isTerminator = 1;
1046 let hasDelaySlot = 1;
1051 class SYS_FT<string opstr> :
1052 InstSE<(outs), (ins uimm20:$code_),
1053 !strconcat(opstr, "\t$code_"), [], NoItinerary, FrmI, opstr>;
1055 class BRK_FT<string opstr> :
1056 InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
1057 !strconcat(opstr, "\t$code_1, $code_2"), [], NoItinerary,
1061 class ER_FT<string opstr> :
1062 InstSE<(outs), (ins),
1063 opstr, [], NoItinerary, FrmOther, opstr>;
1066 class DEI_FT<string opstr, RegisterOperand RO> :
1067 InstSE<(outs RO:$rt), (ins),
1068 !strconcat(opstr, "\t$rt"), [], NoItinerary, FrmOther, opstr>;
1071 class WAIT_FT<string opstr> :
1072 InstSE<(outs), (ins), opstr, [], NoItinerary, FrmOther, opstr>;
1075 let hasSideEffects = 1 in
1076 class SYNC_FT<string opstr> :
1077 InstSE<(outs), (ins i32imm:$stype), "sync $stype", [(MipsSync imm:$stype)],
1078 NoItinerary, FrmOther, opstr>;
1080 class SYNCI_FT<string opstr> :
1081 InstSE<(outs), (ins mem_simm16:$addr), !strconcat(opstr, "\t$addr"), [],
1082 NoItinerary, FrmOther, opstr> {
1083 let hasSideEffects = 1;
1084 let DecoderMethod = "DecodeSyncI";
1087 let hasSideEffects = 1 in
1088 class TEQ_FT<string opstr, RegisterOperand RO> :
1089 InstSE<(outs), (ins RO:$rs, RO:$rt, uimm16:$code_),
1090 !strconcat(opstr, "\t$rs, $rt, $code_"), [], NoItinerary,
1093 class TEQI_FT<string opstr, RegisterOperand RO> :
1094 InstSE<(outs), (ins RO:$rs, uimm16:$imm16),
1095 !strconcat(opstr, "\t$rs, $imm16"), [], NoItinerary, FrmOther, opstr>;
1097 class Mult<string opstr, InstrItinClass itin, RegisterOperand RO,
1098 list<Register> DefRegs> :
1099 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [],
1100 itin, FrmR, opstr> {
1101 let isCommutable = 1;
1103 let hasSideEffects = 0;
1106 // Pseudo multiply/divide instruction with explicit accumulator register
1108 class MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1,
1109 SDPatternOperator OpNode, InstrItinClass Itin,
1110 bit IsComm = 1, bit HasSideEffects = 0,
1111 bit UsesCustomInserter = 0> :
1112 PseudoSE<(outs R0:$ac), (ins R1:$rs, R1:$rt),
1113 [(set R0:$ac, (OpNode R1:$rs, R1:$rt))], Itin>,
1114 PseudoInstExpansion<(RealInst R1:$rs, R1:$rt)> {
1115 let isCommutable = IsComm;
1116 let hasSideEffects = HasSideEffects;
1117 let usesCustomInserter = UsesCustomInserter;
1120 // Pseudo multiply add/sub instruction with explicit accumulator register
1122 class MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode,
1123 InstrItinClass itin>
1124 : PseudoSE<(outs ACC64:$ac),
1125 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin),
1127 (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))],
1129 PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> {
1130 string Constraints = "$acin = $ac";
1133 class Div<string opstr, InstrItinClass itin, RegisterOperand RO,
1134 list<Register> DefRegs> :
1135 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$$zero, $rs, $rt"),
1136 [], itin, FrmR, opstr> {
1141 class PseudoMFLOHI<RegisterClass DstRC, RegisterClass SrcRC, SDNode OpNode>
1142 : PseudoSE<(outs DstRC:$rd), (ins SrcRC:$hilo),
1143 [(set DstRC:$rd, (OpNode SrcRC:$hilo))], II_MFHI_MFLO>;
1145 class MoveFromLOHI<string opstr, RegisterOperand RO, Register UseReg>:
1146 InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO,
1148 let Uses = [UseReg];
1149 let hasSideEffects = 0;
1152 class PseudoMTLOHI<RegisterClass DstRC, RegisterClass SrcRC>
1153 : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi),
1154 [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))],
1157 class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>:
1158 InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO,
1161 let hasSideEffects = 0;
1164 class EffectiveAddress<string opstr, RegisterOperand RO> :
1165 InstSE<(outs RO:$rt), (ins mem_ea:$addr), !strconcat(opstr, "\t$rt, $addr"),
1166 [(set RO:$rt, addr:$addr)], NoItinerary, FrmI,
1167 !strconcat(opstr, "_lea")> {
1168 let isCodeGenOnly = 1;
1169 let DecoderMethod = "DecodeMem";
1172 // Count Leading Ones/Zeros in Word
1173 class CountLeading0<string opstr, RegisterOperand RO>:
1174 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1175 [(set RO:$rd, (ctlz RO:$rs))], II_CLZ, FrmR, opstr>;
1177 class CountLeading1<string opstr, RegisterOperand RO>:
1178 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1179 [(set RO:$rd, (ctlz (not RO:$rs)))], II_CLO, FrmR, opstr>;
1181 // Sign Extend in Register.
1182 class SignExtInReg<string opstr, ValueType vt, RegisterOperand RO,
1183 InstrItinClass itin> :
1184 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"),
1185 [(set RO:$rd, (sext_inreg RO:$rt, vt))], itin, FrmR, opstr>;
1188 class SubwordSwap<string opstr, RegisterOperand RO,
1189 InstrItinClass itin = NoItinerary>:
1190 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [], itin,
1192 let hasSideEffects = 0;
1196 class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> :
1197 InstSE<(outs CPURegOperand:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [],
1198 II_RDHWR, FrmR, "rdhwr">;
1201 class ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1202 Operand SizeOpnd, SDPatternOperator Op = null_frag> :
1203 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size),
1204 !strconcat(opstr, " $rt, $rs, $pos, $size"),
1205 [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size))], II_EXT,
1206 FrmR, opstr>, ISA_MIPS32R2;
1208 class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1209 SDPatternOperator Op = null_frag>:
1210 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, size_ins:$size, RO:$src),
1211 !strconcat(opstr, " $rt, $rs, $pos, $size"),
1212 [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size, RO:$src))],
1213 II_INS, FrmR, opstr>, ISA_MIPS32R2 {
1214 let Constraints = "$src = $rt";
1217 // Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*).
1218 class Atomic2Ops<PatFrag Op, RegisterClass DRC> :
1219 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr),
1220 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]>;
1222 // Atomic Compare & Swap.
1223 class AtomicCmpSwap<PatFrag Op, RegisterClass DRC> :
1224 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap),
1225 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]>;
1227 class LLBase<string opstr, RegisterOperand RO> :
1228 InstSE<(outs RO:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1229 [], NoItinerary, FrmI> {
1230 let DecoderMethod = "DecodeMem";
1234 class SCBase<string opstr, RegisterOperand RO> :
1235 InstSE<(outs RO:$dst), (ins RO:$rt, mem:$addr),
1236 !strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> {
1237 let DecoderMethod = "DecodeMem";
1239 let Constraints = "$rt = $dst";
1242 class MFC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD> :
1243 InstSE<(outs RO:$rt), (ins RD:$rd, uimm16:$sel),
1244 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], NoItinerary, FrmFR>;
1246 class MTC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD> :
1247 InstSE<(outs RO:$rd), (ins RD:$rt, uimm16:$sel),
1248 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], NoItinerary, FrmFR>;
1250 class TrapBase<Instruction RealInst>
1251 : PseudoSE<(outs), (ins), [(trap)], NoItinerary>,
1252 PseudoInstExpansion<(RealInst 0, 0)> {
1254 let isTerminator = 1;
1255 let isCodeGenOnly = 1;
1258 //===----------------------------------------------------------------------===//
1259 // Pseudo instructions
1260 //===----------------------------------------------------------------------===//
1263 let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1 in
1264 def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
1266 let isReturn=1, isTerminator=1, isBarrier=1, hasCtrlDep=1, hasSideEffects=1 in
1267 def ERet : PseudoSE<(outs), (ins), [(MipsERet)]>;
1269 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
1270 def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt),
1271 [(callseq_start timm:$amt)]>;
1272 def ADJCALLSTACKUP : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1273 [(callseq_end timm:$amt1, timm:$amt2)]>;
1276 let usesCustomInserter = 1 in {
1277 def ATOMIC_LOAD_ADD_I8 : Atomic2Ops<atomic_load_add_8, GPR32>;
1278 def ATOMIC_LOAD_ADD_I16 : Atomic2Ops<atomic_load_add_16, GPR32>;
1279 def ATOMIC_LOAD_ADD_I32 : Atomic2Ops<atomic_load_add_32, GPR32>;
1280 def ATOMIC_LOAD_SUB_I8 : Atomic2Ops<atomic_load_sub_8, GPR32>;
1281 def ATOMIC_LOAD_SUB_I16 : Atomic2Ops<atomic_load_sub_16, GPR32>;
1282 def ATOMIC_LOAD_SUB_I32 : Atomic2Ops<atomic_load_sub_32, GPR32>;
1283 def ATOMIC_LOAD_AND_I8 : Atomic2Ops<atomic_load_and_8, GPR32>;
1284 def ATOMIC_LOAD_AND_I16 : Atomic2Ops<atomic_load_and_16, GPR32>;
1285 def ATOMIC_LOAD_AND_I32 : Atomic2Ops<atomic_load_and_32, GPR32>;
1286 def ATOMIC_LOAD_OR_I8 : Atomic2Ops<atomic_load_or_8, GPR32>;
1287 def ATOMIC_LOAD_OR_I16 : Atomic2Ops<atomic_load_or_16, GPR32>;
1288 def ATOMIC_LOAD_OR_I32 : Atomic2Ops<atomic_load_or_32, GPR32>;
1289 def ATOMIC_LOAD_XOR_I8 : Atomic2Ops<atomic_load_xor_8, GPR32>;
1290 def ATOMIC_LOAD_XOR_I16 : Atomic2Ops<atomic_load_xor_16, GPR32>;
1291 def ATOMIC_LOAD_XOR_I32 : Atomic2Ops<atomic_load_xor_32, GPR32>;
1292 def ATOMIC_LOAD_NAND_I8 : Atomic2Ops<atomic_load_nand_8, GPR32>;
1293 def ATOMIC_LOAD_NAND_I16 : Atomic2Ops<atomic_load_nand_16, GPR32>;
1294 def ATOMIC_LOAD_NAND_I32 : Atomic2Ops<atomic_load_nand_32, GPR32>;
1296 def ATOMIC_SWAP_I8 : Atomic2Ops<atomic_swap_8, GPR32>;
1297 def ATOMIC_SWAP_I16 : Atomic2Ops<atomic_swap_16, GPR32>;
1298 def ATOMIC_SWAP_I32 : Atomic2Ops<atomic_swap_32, GPR32>;
1300 def ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap<atomic_cmp_swap_8, GPR32>;
1301 def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap<atomic_cmp_swap_16, GPR32>;
1302 def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_32, GPR32>;
1305 /// Pseudo instructions for loading and storing accumulator registers.
1306 let isPseudo = 1, isCodeGenOnly = 1 in {
1307 def LOAD_ACC64 : Load<"", ACC64>;
1308 def STORE_ACC64 : Store<"", ACC64>;
1311 // We need these two pseudo instructions to avoid offset calculation for long
1312 // branches. See the comment in file MipsLongBranch.cpp for detailed
1315 // Expands to: lui $dst, %hi($tgt - $baltgt)
1316 def LONG_BRANCH_LUi : PseudoSE<(outs GPR32Opnd:$dst),
1317 (ins brtarget:$tgt, brtarget:$baltgt), []>;
1319 // Expands to: addiu $dst, $src, %lo($tgt - $baltgt)
1320 def LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst),
1321 (ins GPR32Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []>;
1323 //===----------------------------------------------------------------------===//
1324 // Instruction definition
1325 //===----------------------------------------------------------------------===//
1326 //===----------------------------------------------------------------------===//
1327 // MipsI Instructions
1328 //===----------------------------------------------------------------------===//
1330 /// Arithmetic Instructions (ALU Immediate)
1331 let AdditionalPredicates = [NotInMicroMips] in {
1332 def ADDiu : MMRel, StdMMR6Rel, ArithLogicI<"addiu", simm16, GPR32Opnd,
1333 II_ADDIU, immSExt16, add>,
1334 ADDI_FM<0x9>, IsAsCheapAsAMove;
1336 def ADDi : MMRel, ArithLogicI<"addi", simm16, GPR32Opnd>, ADDI_FM<0x8>,
1337 ISA_MIPS1_NOT_32R6_64R6;
1338 def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
1340 def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
1342 let AdditionalPredicates = [NotInMicroMips] in {
1343 def ANDi : MMRel, StdMMR6Rel,
1344 ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16, and>,
1347 def ORi : MMRel, StdMMR6Rel,
1348 ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16, or>,
1350 def XORi : MMRel, StdMMR6Rel,
1351 ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16, xor>,
1353 def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16>, LUI_FM;
1354 let AdditionalPredicates = [NotInMicroMips] in {
1355 /// Arithmetic Instructions (3-Operand, R-Type)
1356 def ADDu : MMRel, StdMMR6Rel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
1358 def SUBu : MMRel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
1361 let Defs = [HI0, LO0] in
1362 def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>,
1363 ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6;
1364 def ADD : MMRel, StdMMR6Rel, ArithLogicR<"add", GPR32Opnd>, ADD_FM<0, 0x20>;
1365 def SUB : MMRel, ArithLogicR<"sub", GPR32Opnd>, ADD_FM<0, 0x22>;
1366 def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>;
1367 def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>;
1368 let AdditionalPredicates = [NotInMicroMips] in {
1369 def AND : MMRel, StdMMR6Rel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
1371 def OR : MMRel, StdMMR6Rel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
1373 def XOR : MMRel, StdMMR6Rel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
1376 def NOR : MMRel, StdMMR6Rel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>;
1378 /// Shift Instructions
1379 let AdditionalPredicates = [NotInMicroMips] in {
1380 def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl,
1381 immZExt5>, SRA_FM<0, 0>;
1382 def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl,
1383 immZExt5>, SRA_FM<2, 0>;
1385 def SRA : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, sra,
1386 immZExt5>, SRA_FM<3, 0>;
1387 def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, shl>,
1389 def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, srl>,
1391 def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, sra>,
1394 // Rotate Instructions
1395 def ROTR : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr,
1397 SRA_FM<2, 1>, ISA_MIPS32R2;
1398 def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>,
1399 SRLV_FM<6, 1>, ISA_MIPS32R2;
1401 /// Load and Store Instructions
1403 def LB : Load<"lb", GPR32Opnd, sextloadi8, II_LB>, MMRel, LW_FM<0x20>;
1404 def LBu : Load<"lbu", GPR32Opnd, zextloadi8, II_LBU, addrDefault>, MMRel,
1406 def LH : Load<"lh", GPR32Opnd, sextloadi16, II_LH, addrDefault>, MMRel,
1408 def LHu : Load<"lhu", GPR32Opnd, zextloadi16, II_LHU>, MMRel, LW_FM<0x25>;
1409 let AdditionalPredicates = [NotInMicroMips] in {
1410 def LW : StdMMR6Rel, Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel,
1413 def SB : StdMMR6Rel, Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel,
1415 def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>;
1416 let AdditionalPredicates = [NotInMicroMips] in {
1417 def SW : Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>;
1420 /// load/store left/right
1421 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1422 AdditionalPredicates = [NotInMicroMips] in {
1423 def LWL : LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>,
1424 ISA_MIPS1_NOT_32R6_64R6;
1425 def LWR : LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>,
1426 ISA_MIPS1_NOT_32R6_64R6;
1427 def SWL : StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>,
1428 ISA_MIPS1_NOT_32R6_64R6;
1429 def SWR : StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>,
1430 ISA_MIPS1_NOT_32R6_64R6;
1433 let AdditionalPredicates = [NotInMicroMips] in {
1434 // COP2 Memory Instructions
1435 def LWC2 : LW_FT2<"lwc2", COP2Opnd, NoItinerary, load>, LW_FM<0x32>,
1436 ISA_MIPS1_NOT_32R6_64R6;
1437 def SWC2 : SW_FT2<"swc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3a>,
1438 ISA_MIPS1_NOT_32R6_64R6;
1439 def LDC2 : LW_FT2<"ldc2", COP2Opnd, NoItinerary, load>, LW_FM<0x36>,
1440 ISA_MIPS2_NOT_32R6_64R6;
1441 def SDC2 : SW_FT2<"sdc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3e>,
1442 ISA_MIPS2_NOT_32R6_64R6;
1444 // COP3 Memory Instructions
1445 let DecoderNamespace = "COP3_" in {
1446 def LWC3 : LW_FT3<"lwc3", COP3Opnd, NoItinerary, load>, LW_FM<0x33>;
1447 def SWC3 : SW_FT3<"swc3", COP3Opnd, NoItinerary, store>, LW_FM<0x3b>;
1448 def LDC3 : LW_FT3<"ldc3", COP3Opnd, NoItinerary, load>, LW_FM<0x37>,
1450 def SDC3 : SW_FT3<"sdc3", COP3Opnd, NoItinerary, store>, LW_FM<0x3f>,
1455 def SYNC : MMRel, StdMMR6Rel, SYNC_FT<"sync">, SYNC_FM, ISA_MIPS32;
1456 def SYNCI : MMRel, StdMMR6Rel, SYNCI_FT<"synci">, SYNCI_FM, ISA_MIPS32R2;
1458 let AdditionalPredicates = [NotInMicroMips] in {
1459 def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM<0x34>, ISA_MIPS2;
1460 def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM<0x30>, ISA_MIPS2;
1461 def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd>, TEQ_FM<0x31>, ISA_MIPS2;
1462 def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd>, TEQ_FM<0x32>, ISA_MIPS2;
1463 def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd>, TEQ_FM<0x33>, ISA_MIPS2;
1464 def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd>, TEQ_FM<0x36>, ISA_MIPS2;
1467 def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd>, TEQI_FM<0xc>,
1468 ISA_MIPS2_NOT_32R6_64R6;
1469 def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd>, TEQI_FM<0x8>,
1470 ISA_MIPS2_NOT_32R6_64R6;
1471 def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd>, TEQI_FM<0x9>,
1472 ISA_MIPS2_NOT_32R6_64R6;
1473 def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd>, TEQI_FM<0xa>,
1474 ISA_MIPS2_NOT_32R6_64R6;
1475 def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd>, TEQI_FM<0xb>,
1476 ISA_MIPS2_NOT_32R6_64R6;
1477 def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd>, TEQI_FM<0xe>,
1478 ISA_MIPS2_NOT_32R6_64R6;
1480 let AdditionalPredicates = [NotInMicroMips] in {
1481 def BREAK : MMRel, StdMMR6Rel, BRK_FT<"break">, BRK_FM<0xd>;
1483 def SYSCALL : MMRel, SYS_FT<"syscall">, SYS_FM<0xc>;
1484 def TRAP : TrapBase<BREAK>;
1485 def SDBBP : MMRel, SYS_FT<"sdbbp">, SDBBP_FM, ISA_MIPS32_NOT_32R6_64R6;
1487 let AdditionalPredicates = [NotInMicroMips] in {
1488 def ERET : MMRel, ER_FT<"eret">, ER_FM<0x18, 0x0>, INSN_MIPS3_32;
1489 def ERETNC : MMRel, ER_FT<"eretnc">, ER_FM<0x18, 0x1>, ISA_MIPS32R5;
1490 def DERET : MMRel, ER_FT<"deret">, ER_FM<0x1f, 0x0>, ISA_MIPS32;
1493 let AdditionalPredicates = [NotInMicroMips] in {
1494 def EI : MMRel, StdMMR6Rel, DEI_FT<"ei", GPR32Opnd>, EI_FM<1>, ISA_MIPS32R2;
1495 def DI : MMRel, StdMMR6Rel, DEI_FT<"di", GPR32Opnd>, EI_FM<0>, ISA_MIPS32R2;
1498 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1499 AdditionalPredicates = [NotInMicroMips] in {
1500 def WAIT : WAIT_FT<"wait">, WAIT_FM;
1502 /// Load-linked, Store-conditional
1503 def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, ISA_MIPS2_NOT_32R6_64R6;
1504 def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, ISA_MIPS2_NOT_32R6_64R6;
1507 /// Jump and Branch Instructions
1508 def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
1509 AdditionalRequires<[RelocStatic]>, IsBranch;
1510 def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>;
1511 def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>;
1512 def BEQL : MMRel, CBranch<"beql", brtarget, seteq, GPR32Opnd, 0>,
1513 BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6;
1514 def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>;
1515 def BNEL : MMRel, CBranch<"bnel", brtarget, setne, GPR32Opnd, 0>,
1516 BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6;
1517 def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
1519 def BGEZL : MMRel, CBranchZero<"bgezl", brtarget, setge, GPR32Opnd, 0>,
1520 BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6;
1521 def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
1523 def BGTZL : MMRel, CBranchZero<"bgtzl", brtarget, setgt, GPR32Opnd, 0>,
1524 BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6;
1525 def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
1527 def BLEZL : MMRel, CBranchZero<"blezl", brtarget, setle, GPR32Opnd, 0>,
1528 BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6;
1529 def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
1531 def BLTZL : MMRel, CBranchZero<"bltzl", brtarget, setlt, GPR32Opnd, 0>,
1532 BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6;
1533 def B : UncondBranch<BEQ>;
1535 def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>;
1536 let AdditionalPredicates = [NotInMicroMips] in {
1537 def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM;
1538 def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>;
1541 def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>,
1542 ISA_MIPS32_NOT_32R6_64R6;
1543 def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>,
1544 ISA_MIPS1_NOT_32R6_64R6;
1545 def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd, 0>,
1546 BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6;
1547 def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>,
1548 ISA_MIPS1_NOT_32R6_64R6;
1549 def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd, 0>,
1550 BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6;
1551 def BAL_BR : BAL_BR_Pseudo<BGEZAL>;
1552 def TAILCALL : TailCall<J>;
1553 def TAILCALL_R : TailCallReg<GPR32Opnd, JR>;
1555 // Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64
1556 // then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA.
1557 class PseudoIndirectBranchBase<RegisterOperand RO> :
1558 MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)],
1559 II_IndirectBranchPseudo> {
1562 let hasDelaySlot = 1;
1564 let isIndirectBranch = 1;
1567 def PseudoIndirectBranch : PseudoIndirectBranchBase<GPR32Opnd>;
1569 // Return instructions are matched as a RetRA instruction, then are expanded
1570 // into PseudoReturn/PseudoReturn64 after register allocation. Finally,
1571 // MipsAsmPrinter expands this into JR, JR64, JALR, or JALR64 depending on the
1573 class PseudoReturnBase<RegisterOperand RO> : MipsPseudo<(outs), (ins RO:$rs),
1574 [], II_ReturnPseudo> {
1575 let isTerminator = 1;
1577 let hasDelaySlot = 1;
1579 let isCodeGenOnly = 1;
1581 let hasExtraSrcRegAllocReq = 1;
1584 def PseudoReturn : PseudoReturnBase<GPR32Opnd>;
1586 // Exception handling related node and instructions.
1587 // The conversion sequence is:
1588 // ISD::EH_RETURN -> MipsISD::EH_RETURN ->
1589 // MIPSeh_return -> (stack change + indirect branch)
1591 // MIPSeh_return takes the place of regular return instruction
1592 // but takes two arguments (V1, V0) which are used for storing
1593 // the offset and return address respectively.
1594 def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
1596 def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
1597 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
1599 let Uses = [V0, V1], isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1600 def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
1601 [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
1602 def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff,
1604 [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
1607 /// Multiply and Divide Instructions.
1608 def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
1609 MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6;
1610 def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
1611 MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6;
1612 def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
1613 MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6;
1614 def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
1615 MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6;
1617 def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>,
1618 ISA_MIPS1_NOT_32R6_64R6;
1619 def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>,
1620 ISA_MIPS1_NOT_32R6_64R6;
1621 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1622 AdditionalPredicates = [NotInMicroMips] in {
1623 def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>,
1624 ISA_MIPS1_NOT_32R6_64R6;
1625 def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>,
1626 ISA_MIPS1_NOT_32R6_64R6;
1629 /// Sign Ext In Register Instructions.
1630 def SEB : MMRel, StdMMR6Rel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,
1631 SEB_FM<0x10, 0x20>, ISA_MIPS32R2;
1632 def SEH : MMRel, StdMMR6Rel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
1633 SEB_FM<0x18, 0x20>, ISA_MIPS32R2;
1636 def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd>, CLO_FM<0x20>,
1637 ISA_MIPS32_NOT_32R6_64R6;
1638 def CLO : MMRel, CountLeading1<"clo", GPR32Opnd>, CLO_FM<0x21>,
1639 ISA_MIPS32_NOT_32R6_64R6;
1641 let AdditionalPredicates = [NotInMicroMips] in {
1642 /// Word Swap Bytes Within Halfwords
1643 def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd, II_WSBH>, SEB_FM<2, 0x20>,
1648 def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>;
1650 // FrameIndexes are legalized when they are operands from load/store
1651 // instructions. The same not happens for stack address copies, so an
1652 // add op with mem ComplexPattern is used and the stack address copy
1653 // can be matched. It's similar to Sparc LEA_ADDRi
1654 def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>;
1657 def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>,
1658 ISA_MIPS32_NOT_32R6_64R6;
1659 def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>,
1660 ISA_MIPS32_NOT_32R6_64R6;
1661 def MSUB : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>,
1662 ISA_MIPS32_NOT_32R6_64R6;
1663 def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>,
1664 ISA_MIPS32_NOT_32R6_64R6;
1666 let AdditionalPredicates = [NotDSP] in {
1667 def PseudoMULT : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>,
1668 ISA_MIPS1_NOT_32R6_64R6;
1669 def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>,
1670 ISA_MIPS1_NOT_32R6_64R6;
1671 def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>, ISA_MIPS1_NOT_32R6_64R6;
1672 def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>, ISA_MIPS1_NOT_32R6_64R6;
1673 def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>, ISA_MIPS1_NOT_32R6_64R6;
1674 def PseudoMADD : MAddSubPseudo<MADD, MipsMAdd, II_MADD>,
1675 ISA_MIPS32_NOT_32R6_64R6;
1676 def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>,
1677 ISA_MIPS32_NOT_32R6_64R6;
1678 def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>,
1679 ISA_MIPS32_NOT_32R6_64R6;
1680 def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>,
1681 ISA_MIPS32_NOT_32R6_64R6;
1684 def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV,
1685 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
1686 def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU,
1687 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
1688 let AdditionalPredicates = [NotInMicroMips] in {
1689 def RDHWR : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM;
1691 // TODO: Add '0 < pos+size <= 32' constraint check to ext instruction
1692 def EXT : MMRel, ExtBase<"ext", GPR32Opnd, uimm5, uimm5_plus1, MipsExt>,
1694 def INS : MMRel, InsBase<"ins", GPR32Opnd, uimm5, MipsIns>, EXT_FM<4>;
1696 /// Move Control Registers From/To CPU Registers
1697 def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd>, MFC3OP_FM<0x10, 0>, ISA_MIPS32;
1698 def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd>, MFC3OP_FM<0x10, 4>, ISA_MIPS32;
1699 def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd>, MFC3OP_FM<0x12, 0>;
1700 def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd>, MFC3OP_FM<0x12, 4>;
1702 class Barrier<string asmstr> : InstSE<(outs), (ins), asmstr, [], NoItinerary,
1704 def SSNOP : MMRel, StdMMR6Rel, Barrier<"ssnop">, BARRIER_FM<1>;
1705 def EHB : MMRel, Barrier<"ehb">, BARRIER_FM<3>;
1706 def PAUSE : MMRel, StdMMR6Rel, Barrier<"pause">, BARRIER_FM<5>, ISA_MIPS32R2;
1708 // JR_HB and JALR_HB are defined here using the new style naming
1709 // scheme because some of this code is shared with Mips32r6InstrInfo.td
1710 // and because of that it doesn't follow the naming convention of the
1711 // rest of the file. To avoid a mixture of old vs new style, the new
1712 // style was chosen.
1713 class JR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
1714 dag OutOperandList = (outs);
1715 dag InOperandList = (ins GPROpnd:$rs);
1716 string AsmString = !strconcat(instr_asm, "\t$rs");
1717 list<dag> Pattern = [];
1720 class JALR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
1721 dag OutOperandList = (outs GPROpnd:$rd);
1722 dag InOperandList = (ins GPROpnd:$rs);
1723 string AsmString = !strconcat(instr_asm, "\t$rd, $rs");
1724 list<dag> Pattern = [];
1727 class JR_HB_DESC : InstSE<(outs), (ins), "", [], NoItinerary, FrmJ>,
1728 JR_HB_DESC_BASE<"jr.hb", GPR32Opnd> {
1730 let isIndirectBranch=1;
1736 class JALR_HB_DESC : InstSE<(outs), (ins), "", [], NoItinerary, FrmJ>,
1737 JALR_HB_DESC_BASE<"jalr.hb", GPR32Opnd> {
1738 let isIndirectBranch=1;
1742 class JR_HB_ENC : JR_HB_FM<8>;
1743 class JALR_HB_ENC : JALR_HB_FM<9>;
1745 def JR_HB : JR_HB_DESC, JR_HB_ENC, ISA_MIPS32_NOT_32R6_64R6;
1746 def JALR_HB : JALR_HB_DESC, JALR_HB_ENC, ISA_MIPS32;
1748 class TLB<string asmstr> : InstSE<(outs), (ins), asmstr, [], NoItinerary,
1750 def TLBP : MMRel, TLB<"tlbp">, COP0_TLB_FM<0x08>;
1751 def TLBR : MMRel, TLB<"tlbr">, COP0_TLB_FM<0x01>;
1752 def TLBWI : MMRel, TLB<"tlbwi">, COP0_TLB_FM<0x02>;
1753 def TLBWR : MMRel, TLB<"tlbwr">, COP0_TLB_FM<0x06>;
1755 class CacheOp<string instr_asm, Operand MemOpnd> :
1756 InstSE<(outs), (ins MemOpnd:$addr, uimm5:$hint),
1757 !strconcat(instr_asm, "\t$hint, $addr"), [], NoItinerary, FrmOther,
1759 let DecoderMethod = "DecodeCacheOp";
1762 def CACHE : MMRel, CacheOp<"cache", mem>, CACHEOP_FM<0b101111>,
1763 INSN_MIPS3_32_NOT_32R6_64R6;
1764 def PREF : MMRel, CacheOp<"pref", mem>, CACHEOP_FM<0b110011>,
1765 INSN_MIPS3_32_NOT_32R6_64R6;
1767 def ROL : MipsAsmPseudoInst<(outs),
1768 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
1769 "rol\t$rs, $rt, $rd">;
1770 def ROLImm : MipsAsmPseudoInst<(outs),
1771 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
1772 "rol\t$rs, $rt, $imm">;
1773 def : MipsInstAlias<"rol $rd, $rs",
1774 (ROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
1775 def : MipsInstAlias<"rol $rd, $imm",
1776 (ROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
1778 def ROR : MipsAsmPseudoInst<(outs),
1779 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
1780 "ror\t$rs, $rt, $rd">;
1781 def RORImm : MipsAsmPseudoInst<(outs),
1782 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
1783 "ror\t$rs, $rt, $imm">;
1784 def : MipsInstAlias<"ror $rd, $rs",
1785 (ROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
1786 def : MipsInstAlias<"ror $rd, $imm",
1787 (RORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
1789 def DROL : MipsAsmPseudoInst<(outs),
1790 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
1791 "drol\t$rs, $rt, $rd">, ISA_MIPS64;
1792 def DROLImm : MipsAsmPseudoInst<(outs),
1793 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
1794 "drol\t$rs, $rt, $imm">, ISA_MIPS64;
1795 def : MipsInstAlias<"drol $rd, $rs",
1796 (DROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
1797 def : MipsInstAlias<"drol $rd, $imm",
1798 (DROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
1800 def DROR : MipsAsmPseudoInst<(outs),
1801 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
1802 "dror\t$rs, $rt, $rd">, ISA_MIPS64;
1803 def DRORImm : MipsAsmPseudoInst<(outs),
1804 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
1805 "dror\t$rs, $rt, $imm">, ISA_MIPS64;
1806 def : MipsInstAlias<"dror $rd, $rs",
1807 (DROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
1808 def : MipsInstAlias<"dror $rd, $imm",
1809 (DRORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
1811 //===----------------------------------------------------------------------===//
1812 // Instruction aliases
1813 //===----------------------------------------------------------------------===//
1814 def : MipsInstAlias<"move $dst, $src",
1815 (OR GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
1817 let AdditionalPredicates = [NotInMicroMips];
1819 def : MipsInstAlias<"move $dst, $src",
1820 (ADDu GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
1822 let AdditionalPredicates = [NotInMicroMips];
1824 def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>,
1825 ISA_MIPS1_NOT_32R6_64R6;
1826 def : MipsInstAlias<"addu $rs, $rt, $imm",
1827 (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1828 def : MipsInstAlias<"addu $rs, $imm",
1829 (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>;
1830 def : MipsInstAlias<"add $rs, $rt, $imm",
1831 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>,
1832 ISA_MIPS1_NOT_32R6_64R6;
1833 def : MipsInstAlias<"add $rs, $imm",
1834 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>,
1835 ISA_MIPS1_NOT_32R6_64R6;
1836 def : MipsInstAlias<"and $rs, $rt, $imm",
1837 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1838 def : MipsInstAlias<"and $rs, $imm",
1839 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>;
1840 def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>;
1841 let Predicates = [NotInMicroMips] in {
1842 def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
1844 def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>, ISA_MIPS32;
1845 def : MipsInstAlias<"not $rt, $rs",
1846 (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>;
1847 def : MipsInstAlias<"neg $rt, $rs",
1848 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
1849 def : MipsInstAlias<"negu $rt",
1850 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 0>;
1851 def : MipsInstAlias<"negu $rt, $rs",
1852 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
1853 def : MipsInstAlias<"slt $rs, $rt, $imm",
1854 (SLTi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1855 def : MipsInstAlias<"sltu $rt, $rs, $imm",
1856 (SLTiu GPR32Opnd:$rt, GPR32Opnd:$rs, simm16:$imm), 0>;
1857 def : MipsInstAlias<"xor $rs, $rt, $imm",
1858 (XORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
1859 def : MipsInstAlias<"xor $rs, $imm",
1860 (XORi GPR32Opnd:$rs, GPR32Opnd:$rs, uimm16:$imm), 0>;
1861 def : MipsInstAlias<"or $rs, $rt, $imm",
1862 (ORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
1863 def : MipsInstAlias<"or $rs, $imm",
1864 (ORi GPR32Opnd:$rs, GPR32Opnd:$rs, uimm16:$imm), 0>;
1865 let AdditionalPredicates = [NotInMicroMips] in {
1866 def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>;
1868 def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>;
1869 def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>;
1870 def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, COP2Opnd:$rd, 0), 0>;
1871 def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 COP2Opnd:$rd, GPR32Opnd:$rt, 0), 0>;
1872 let AdditionalPredicates = [NotInMicroMips] in {
1873 def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>;
1875 def : MipsInstAlias<"bnez $rs,$offset",
1876 (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1877 def : MipsInstAlias<"bnezl $rs,$offset",
1878 (BNEL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1879 def : MipsInstAlias<"beqz $rs,$offset",
1880 (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1881 def : MipsInstAlias<"beqzl $rs,$offset",
1882 (BEQL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1883 def : MipsInstAlias<"syscall", (SYSCALL 0), 1>;
1885 def : MipsInstAlias<"break", (BREAK 0, 0), 1>;
1886 def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>;
1887 let AdditionalPredicates = [NotInMicroMips] in {
1888 def : MipsInstAlias<"ei", (EI ZERO), 1>, ISA_MIPS32R2;
1889 def : MipsInstAlias<"di", (DI ZERO), 1>, ISA_MIPS32R2;
1891 let AdditionalPredicates = [NotInMicroMips] in {
1892 def : MipsInstAlias<"teq $rs, $rt",
1893 (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1894 def : MipsInstAlias<"tge $rs, $rt",
1895 (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1896 def : MipsInstAlias<"tgeu $rs, $rt",
1897 (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1898 def : MipsInstAlias<"tlt $rs, $rt",
1899 (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1900 def : MipsInstAlias<"tltu $rs, $rt",
1901 (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1902 def : MipsInstAlias<"tne $rs, $rt",
1903 (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1905 def : MipsInstAlias<"sll $rd, $rt, $rs",
1906 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1907 def : MipsInstAlias<"sub, $rd, $rs, $imm",
1908 (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs,
1909 InvertedImOperand:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6;
1910 def : MipsInstAlias<"sub $rs, $imm",
1911 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm),
1912 0>, ISA_MIPS1_NOT_32R6_64R6;
1913 def : MipsInstAlias<"subu, $rd, $rs, $imm",
1914 (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs,
1915 InvertedImOperand:$imm), 0>;
1916 def : MipsInstAlias<"subu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs,
1917 InvertedImOperand:$imm), 0>;
1918 def : MipsInstAlias<"sra $rd, $rt, $rs",
1919 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1920 def : MipsInstAlias<"srl $rd, $rt, $rs",
1921 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1922 def : MipsInstAlias<"sdbbp", (SDBBP 0)>, ISA_MIPS32_NOT_32R6_64R6;
1923 def : MipsInstAlias<"sync",
1924 (SYNC 0), 1>, ISA_MIPS2;
1925 //===----------------------------------------------------------------------===//
1926 // Assembler Pseudo Instructions
1927 //===----------------------------------------------------------------------===//
1929 class LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> :
1930 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
1931 !strconcat(instr_asm, "\t$rt, $imm32")> ;
1932 def LoadImm32 : LoadImmediate32<"li", simm32, GPR32Opnd>;
1934 class LoadAddressFromReg32<string instr_asm, Operand MemOpnd,
1935 RegisterOperand RO> :
1936 MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
1937 !strconcat(instr_asm, "\t$rt, $addr")> ;
1938 def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>;
1940 class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> :
1941 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
1942 !strconcat(instr_asm, "\t$rt, $imm32")> ;
1943 def LoadAddrImm32 : LoadAddressFromImm32<"la", simm32, GPR32Opnd>;
1945 def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
1947 def JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs),
1950 def NORImm : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
1951 "nor\t$rs, $rt, $imm"> ;
1953 let hasDelaySlot = 1 in {
1954 def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
1955 (ins imm64:$imm64, brtarget:$offset),
1956 "bne\t$rt, $imm64, $offset">;
1957 def BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
1958 (ins imm64:$imm64, brtarget:$offset),
1959 "beq\t$rt, $imm64, $offset">;
1961 class CondBranchPseudo<string instr_asm> :
1962 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt,
1964 !strconcat(instr_asm, "\t$rs, $rt, $offset")>;
1967 def BLT : CondBranchPseudo<"blt">;
1968 def BLE : CondBranchPseudo<"ble">;
1969 def BGE : CondBranchPseudo<"bge">;
1970 def BGT : CondBranchPseudo<"bgt">;
1971 def BLTU : CondBranchPseudo<"bltu">;
1972 def BLEU : CondBranchPseudo<"bleu">;
1973 def BGEU : CondBranchPseudo<"bgeu">;
1974 def BGTU : CondBranchPseudo<"bgtu">;
1975 def BLTL : CondBranchPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
1976 def BLEL : CondBranchPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
1977 def BGEL : CondBranchPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
1978 def BGTL : CondBranchPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
1979 def BLTUL: CondBranchPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
1980 def BLEUL: CondBranchPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
1981 def BGEUL: CondBranchPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
1982 def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
1984 class CondBranchImmPseudo<string instr_asm> :
1985 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, imm64:$imm, brtarget:$offset),
1986 !strconcat(instr_asm, "\t$rs, $imm, $offset")>;
1988 def BLTImmMacro : CondBranchImmPseudo<"blt">;
1989 def BLEImmMacro : CondBranchImmPseudo<"ble">;
1990 def BGEImmMacro : CondBranchImmPseudo<"bge">;
1991 def BGTImmMacro : CondBranchImmPseudo<"bgt">;
1992 def BLTUImmMacro : CondBranchImmPseudo<"bltu">;
1993 def BLEUImmMacro : CondBranchImmPseudo<"bleu">;
1994 def BGEUImmMacro : CondBranchImmPseudo<"bgeu">;
1995 def BGTUImmMacro : CondBranchImmPseudo<"bgtu">;
1996 def BLTLImmMacro : CondBranchImmPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
1997 def BLELImmMacro : CondBranchImmPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
1998 def BGELImmMacro : CondBranchImmPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
1999 def BGTLImmMacro : CondBranchImmPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
2000 def BLTULImmMacro : CondBranchImmPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
2001 def BLEULImmMacro : CondBranchImmPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
2002 def BGEULImmMacro : CondBranchImmPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
2003 def BGTULImmMacro : CondBranchImmPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
2005 // FIXME: Predicates are removed because instructions are matched regardless of
2006 // predicates, because PredicateControl was not in the hierarchy. This was
2007 // done to emit more precise error message from expansion function.
2008 // Once the tablegen-erated errors are made better, this needs to be fixed and
2009 // predicates needs to be restored.
2011 def SDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2012 "div\t$rs, $rt">; //, ISA_MIPS1_NOT_32R6_64R6;
2014 def UDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2015 "divu\t$rs, $rt">; //, ISA_MIPS1_NOT_32R6_64R6;
2017 def DSDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2018 "ddiv\t$rs, $rt">; //, ISA_MIPS64_NOT_64R6;
2020 def DUDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
2021 "ddivu\t$rs, $rt">; //, ISA_MIPS64_NOT_64R6;
2023 def Ulh : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2024 "ulh\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2026 def Ulhu : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2027 "ulhu\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2029 def Ulw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
2030 "ulw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2032 //===----------------------------------------------------------------------===//
2033 // Arbitrary patterns that map to one or more instructions
2034 //===----------------------------------------------------------------------===//
2036 // Load/store pattern templates.
2037 class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
2038 MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
2040 class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
2041 MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
2044 let AdditionalPredicates = [NotInMicroMips] in {
2045 def : MipsPat<(i32 immSExt16:$in),
2046 (ADDiu ZERO, imm:$in)>;
2047 def : MipsPat<(i32 immZExt16:$in),
2048 (ORi ZERO, imm:$in)>;
2050 def : MipsPat<(i32 immLow16Zero:$in),
2051 (LUi (HI16 imm:$in))>;
2053 // Arbitrary immediates
2054 def : MipsPat<(i32 imm:$imm),
2055 (ORi (LUi (HI16 imm:$imm)), (LO16 imm:$imm))>;
2057 // Carry MipsPatterns
2058 def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
2059 (SUBu GPR32:$lhs, GPR32:$rhs)>;
2060 let AdditionalPredicates = [NotDSP] in {
2061 def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
2062 (ADDu GPR32:$lhs, GPR32:$rhs)>;
2063 def : MipsPat<(addc GPR32:$src, immSExt16:$imm),
2064 (ADDiu GPR32:$src, imm:$imm)>;
2067 // Support multiplication for pre-Mips32 targets that don't have
2068 // the MUL instruction.
2069 def : MipsPat<(mul GPR32:$lhs, GPR32:$rhs),
2070 (PseudoMFLO (PseudoMULT GPR32:$lhs, GPR32:$rhs))>,
2071 ISA_MIPS1_NOT_32R6_64R6;
2074 def : MipsPat<(MipsSync (i32 immz)),
2075 (SYNC 0)>, ISA_MIPS2;
2078 def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
2079 (JAL texternalsym:$dst)>;
2080 //def : MipsPat<(MipsJmpLink GPR32:$dst),
2081 // (JALR GPR32:$dst)>;
2084 def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
2085 (TAILCALL tglobaladdr:$dst)>;
2086 def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
2087 (TAILCALL texternalsym:$dst)>;
2089 def : MipsPat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
2090 def : MipsPat<(MipsHi tblockaddress:$in), (LUi tblockaddress:$in)>;
2091 def : MipsPat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>;
2092 def : MipsPat<(MipsHi tconstpool:$in), (LUi tconstpool:$in)>;
2093 def : MipsPat<(MipsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>;
2094 def : MipsPat<(MipsHi texternalsym:$in), (LUi texternalsym:$in)>;
2096 def : MipsPat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
2097 def : MipsPat<(MipsLo tblockaddress:$in), (ADDiu ZERO, tblockaddress:$in)>;
2098 def : MipsPat<(MipsLo tjumptable:$in), (ADDiu ZERO, tjumptable:$in)>;
2099 def : MipsPat<(MipsLo tconstpool:$in), (ADDiu ZERO, tconstpool:$in)>;
2100 def : MipsPat<(MipsLo tglobaltlsaddr:$in), (ADDiu ZERO, tglobaltlsaddr:$in)>;
2101 def : MipsPat<(MipsLo texternalsym:$in), (ADDiu ZERO, texternalsym:$in)>;
2103 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaladdr:$lo)),
2104 (ADDiu GPR32:$hi, tglobaladdr:$lo)>;
2105 def : MipsPat<(add GPR32:$hi, (MipsLo tblockaddress:$lo)),
2106 (ADDiu GPR32:$hi, tblockaddress:$lo)>;
2107 def : MipsPat<(add GPR32:$hi, (MipsLo tjumptable:$lo)),
2108 (ADDiu GPR32:$hi, tjumptable:$lo)>;
2109 def : MipsPat<(add GPR32:$hi, (MipsLo tconstpool:$lo)),
2110 (ADDiu GPR32:$hi, tconstpool:$lo)>;
2111 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaltlsaddr:$lo)),
2112 (ADDiu GPR32:$hi, tglobaltlsaddr:$lo)>;
2115 def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
2116 (ADDiu GPR32:$gp, tglobaladdr:$in)>;
2117 def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
2118 (ADDiu GPR32:$gp, tconstpool:$in)>;
2121 class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
2122 MipsPat<(MipsWrapper RC:$gp, node:$in),
2123 (ADDiuOp RC:$gp, node:$in)>;
2125 def : WrapperPat<tglobaladdr, ADDiu, GPR32>;
2126 def : WrapperPat<tconstpool, ADDiu, GPR32>;
2127 def : WrapperPat<texternalsym, ADDiu, GPR32>;
2128 def : WrapperPat<tblockaddress, ADDiu, GPR32>;
2129 def : WrapperPat<tjumptable, ADDiu, GPR32>;
2130 def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>;
2132 let AdditionalPredicates = [NotInMicroMips] in {
2133 // Mips does not have "not", so we expand our way
2134 def : MipsPat<(not GPR32:$in),
2135 (NOR GPR32Opnd:$in, ZERO)>;
2139 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>;
2140 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>;
2141 def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
2144 def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>;
2147 multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BNEOp,
2148 Instruction SLTOp, Instruction SLTuOp, Instruction SLTiOp,
2149 Instruction SLTiuOp, Register ZEROReg> {
2150 def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
2151 (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
2152 def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
2153 (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
2155 def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
2156 (BEQ (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
2157 def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
2158 (BEQ (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
2159 def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
2160 (BEQ (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
2161 def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
2162 (BEQ (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
2163 def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
2164 (BEQ (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
2165 def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
2166 (BEQ (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
2168 def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
2169 (BEQ (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
2170 def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
2171 (BEQ (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
2173 def : MipsPat<(brcond RC:$cond, bb:$dst),
2174 (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
2177 defm : BrcondPats<GPR32, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>;
2179 def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
2180 (BLEZ i32:$lhs, bb:$dst)>;
2181 def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
2182 (BGEZ i32:$lhs, bb:$dst)>;
2185 multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp,
2186 Instruction SLTuOp, Register ZEROReg> {
2187 def : MipsPat<(seteq RC:$lhs, 0),
2188 (SLTiuOp RC:$lhs, 1)>;
2189 def : MipsPat<(setne RC:$lhs, 0),
2190 (SLTuOp ZEROReg, RC:$lhs)>;
2191 def : MipsPat<(seteq RC:$lhs, RC:$rhs),
2192 (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>;
2193 def : MipsPat<(setne RC:$lhs, RC:$rhs),
2194 (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
2197 multiclass SetlePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
2198 def : MipsPat<(setle RC:$lhs, RC:$rhs),
2199 (XORi (SLTOp RC:$rhs, RC:$lhs), 1)>;
2200 def : MipsPat<(setule RC:$lhs, RC:$rhs),
2201 (XORi (SLTuOp RC:$rhs, RC:$lhs), 1)>;
2204 multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
2205 def : MipsPat<(setgt RC:$lhs, RC:$rhs),
2206 (SLTOp RC:$rhs, RC:$lhs)>;
2207 def : MipsPat<(setugt RC:$lhs, RC:$rhs),
2208 (SLTuOp RC:$rhs, RC:$lhs)>;
2211 multiclass SetgePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
2212 def : MipsPat<(setge RC:$lhs, RC:$rhs),
2213 (XORi (SLTOp RC:$lhs, RC:$rhs), 1)>;
2214 def : MipsPat<(setuge RC:$lhs, RC:$rhs),
2215 (XORi (SLTuOp RC:$lhs, RC:$rhs), 1)>;
2218 multiclass SetgeImmPats<RegisterClass RC, Instruction SLTiOp,
2219 Instruction SLTiuOp> {
2220 def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
2221 (XORi (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
2222 def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
2223 (XORi (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
2226 defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>;
2227 defm : SetlePats<GPR32, SLT, SLTu>;
2228 defm : SetgtPats<GPR32, SLT, SLTu>;
2229 defm : SetgePats<GPR32, SLT, SLTu>;
2230 defm : SetgeImmPats<GPR32, SLTi, SLTiu>;
2233 def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>;
2235 // Load halfword/word patterns.
2236 let AddedComplexity = 40 in {
2237 def : LoadRegImmPat<LBu, i32, zextloadi8>;
2238 def : LoadRegImmPat<LH, i32, sextloadi16>;
2239 let AdditionalPredicates = [NotInMicroMips] in {
2240 def : LoadRegImmPat<LW, i32, load>;
2244 // Atomic load patterns.
2245 def : MipsPat<(atomic_load_8 addr:$a), (LB addr:$a)>;
2246 def : MipsPat<(atomic_load_16 addr:$a), (LH addr:$a)>;
2247 def : MipsPat<(atomic_load_32 addr:$a), (LW addr:$a)>;
2249 // Atomic store patterns.
2250 def : MipsPat<(atomic_store_8 addr:$a, GPR32:$v), (SB GPR32:$v, addr:$a)>;
2251 def : MipsPat<(atomic_store_16 addr:$a, GPR32:$v), (SH GPR32:$v, addr:$a)>;
2252 def : MipsPat<(atomic_store_32 addr:$a, GPR32:$v), (SW GPR32:$v, addr:$a)>;
2254 //===----------------------------------------------------------------------===//
2255 // Floating Point Support
2256 //===----------------------------------------------------------------------===//
2258 include "MipsInstrFPU.td"
2259 include "Mips64InstrInfo.td"
2260 include "MipsCondMov.td"
2262 include "Mips32r6InstrInfo.td"
2263 include "Mips64r6InstrInfo.td"
2268 include "Mips16InstrFormats.td"
2269 include "Mips16InstrInfo.td"
2272 include "MipsDSPInstrFormats.td"
2273 include "MipsDSPInstrInfo.td"
2276 include "MipsMSAInstrFormats.td"
2277 include "MipsMSAInstrInfo.td"
2280 include "MipsEVAInstrFormats.td"
2281 include "MipsEVAInstrInfo.td"
2284 include "MicroMipsInstrFormats.td"
2285 include "MicroMipsInstrInfo.td"
2286 include "MicroMipsInstrFPU.td"
2289 include "MicroMips32r6InstrFormats.td"
2290 include "MicroMips32r6InstrInfo.td"
2293 include "MicroMips64r6InstrFormats.td"
2294 include "MicroMips64r6InstrInfo.td"
2297 include "MicroMipsDSPInstrFormats.td"
2298 include "MicroMipsDSPInstrInfo.td"