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 ConstantUImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
389 int Offset = 0> : AsmOperandClass {
390 let Name = "ConstantUImm" # Bits # "_" # Offset;
391 let RenderMethod = "addConstantUImmOperands<" # Bits # ", " # Offset # ">";
392 let PredicateMethod = "isConstantUImm<" # Bits # ", " # Offset # ">";
393 let SuperClasses = Supers;
394 let DiagnosticType = "UImm" # Bits # "_" # Offset;
397 def ConstantUImm10AsmOperandClass
398 : ConstantUImmAsmOperandClass<10, []>;
399 def ConstantUImm8AsmOperandClass
400 : ConstantUImmAsmOperandClass<8, [ConstantUImm10AsmOperandClass]>;
401 def ConstantUImm6AsmOperandClass
402 : ConstantUImmAsmOperandClass<6, [ConstantUImm8AsmOperandClass]>;
403 def ConstantUImm5Plus32AsmOperandClass
404 : ConstantUImmAsmOperandClass<5, [ConstantUImm6AsmOperandClass], 32>;
405 def ConstantUImm5Plus32NormalizeAsmOperandClass
406 : ConstantUImmAsmOperandClass<5, [ConstantUImm6AsmOperandClass], 32> {
407 let Name = "ConstantUImm5_32_Norm";
408 // We must also subtract 32 when we render the operand.
409 let RenderMethod = "addConstantUImmOperands<5, 32, -32>";
411 def ConstantUImm5Lsl2AsmOperandClass : AsmOperandClass {
412 let Name = "UImm5Lsl2";
413 let RenderMethod = "addImmOperands";
414 let PredicateMethod = "isScaledUImm<5, 2>";
415 let SuperClasses = [ConstantUImm6AsmOperandClass];
416 let DiagnosticType = "UImm5_Lsl2";
418 def ConstantUImm5ReportUImm6AsmOperandClass
419 : ConstantUImmAsmOperandClass<5, [ConstantUImm6AsmOperandClass]> {
420 let Name = "ConstantUImm5_0_Report_UImm6";
421 let DiagnosticType = "UImm5_0_Report_UImm6";
423 def ConstantUImm5AsmOperandClass
424 : ConstantUImmAsmOperandClass<5, [ConstantUImm6AsmOperandClass]>;
425 def ConstantUImm4AsmOperandClass
426 : ConstantUImmAsmOperandClass<
427 4, [ConstantUImm5AsmOperandClass,
428 ConstantUImm5Plus32AsmOperandClass,
429 ConstantUImm5Plus32NormalizeAsmOperandClass]>;
430 def ConstantUImm3AsmOperandClass
431 : ConstantUImmAsmOperandClass<3, [ConstantUImm4AsmOperandClass]>;
432 def ConstantUImm2Plus1AsmOperandClass
433 : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass], 1>;
434 def ConstantUImm2AsmOperandClass
435 : ConstantUImmAsmOperandClass<2, [ConstantUImm3AsmOperandClass]>;
436 def ConstantUImm1AsmOperandClass
437 : ConstantUImmAsmOperandClass<1, [ConstantUImm2AsmOperandClass]>;
438 def ConstantImmzAsmOperandClass : AsmOperandClass {
439 let Name = "ConstantImmz";
440 let RenderMethod = "addConstantUImmOperands<1>";
441 let PredicateMethod = "isConstantImmz";
442 let SuperClasses = [ConstantUImm1AsmOperandClass];
443 let DiagnosticType = "Immz";
446 def MipsJumpTargetAsmOperand : AsmOperandClass {
447 let Name = "JumpTarget";
448 let ParserMethod = "parseJumpTarget";
449 let PredicateMethod = "isImm";
450 let RenderMethod = "addImmOperands";
453 // Instruction operand types
454 def jmptarget : Operand<OtherVT> {
455 let EncoderMethod = "getJumpTargetOpValue";
456 let ParserMatchClass = MipsJumpTargetAsmOperand;
458 def brtarget : Operand<OtherVT> {
459 let EncoderMethod = "getBranchTargetOpValue";
460 let OperandType = "OPERAND_PCREL";
461 let DecoderMethod = "DecodeBranchTarget";
462 let ParserMatchClass = MipsJumpTargetAsmOperand;
464 def calltarget : Operand<iPTR> {
465 let EncoderMethod = "getJumpTargetOpValue";
466 let ParserMatchClass = MipsJumpTargetAsmOperand;
469 def imm64: Operand<i64>;
471 def simm9 : Operand<i32>;
472 def simm10 : Operand<i32>;
473 def simm11 : Operand<i32>;
475 def simm16 : Operand<i32> {
476 let DecoderMethod= "DecodeSimm16";
479 def simm19_lsl2 : Operand<i32> {
480 let EncoderMethod = "getSimm19Lsl2Encoding";
481 let DecoderMethod = "DecodeSimm19Lsl2";
482 let ParserMatchClass = MipsJumpTargetAsmOperand;
485 def simm18_lsl3 : Operand<i32> {
486 let EncoderMethod = "getSimm18Lsl3Encoding";
487 let DecoderMethod = "DecodeSimm18Lsl3";
488 let ParserMatchClass = MipsJumpTargetAsmOperand;
491 def simm20 : Operand<i32>;
492 def simm32 : Operand<i32>;
494 def uimm20 : Operand<i32> {
497 def simm16_64 : Operand<i64> {
498 let DecoderMethod = "DecodeSimm16";
502 def uimmz : Operand<i32> {
503 let PrintMethod = "printUnsignedImm";
504 let ParserMatchClass = ConstantImmzAsmOperandClass;
508 foreach I = {1, 2, 3, 4, 5, 6, 8, 10} in
509 def uimm # I : Operand<i32> {
510 let PrintMethod = "printUnsignedImm";
511 let ParserMatchClass =
512 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
515 def uimm2_plus1 : Operand<i32> {
516 let PrintMethod = "printUnsignedImm";
517 let EncoderMethod = "getUImmWithOffsetEncoding<2, 1>";
518 let DecoderMethod = "DecodeUImmWithOffset<2, 1>";
519 let ParserMatchClass = ConstantUImm2Plus1AsmOperandClass;
522 def uimm5_plus32 : Operand<i32> {
523 let PrintMethod = "printUnsignedImm";
524 let ParserMatchClass = ConstantUImm5Plus32AsmOperandClass;
527 def uimm5_plus32_normalize : Operand<i32> {
528 let PrintMethod = "printUnsignedImm";
529 let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
532 def uimm5_lsl2 : Operand<OtherVT> {
533 let EncoderMethod = "getUImm5Lsl2Encoding";
534 let DecoderMethod = "DecodeUImm5lsl2";
535 let ParserMatchClass = ConstantUImm5Lsl2AsmOperandClass;
538 def uimm5_plus32_normalize_64 : Operand<i64> {
539 let PrintMethod = "printUnsignedImm";
540 let ParserMatchClass = ConstantUImm5Plus32NormalizeAsmOperandClass;
544 def uimm # I # _64 : Operand<i64> {
545 let PrintMethod = "printUnsignedImm";
546 let ParserMatchClass =
547 !cast<AsmOperandClass>("ConstantUImm" # I # "AsmOperandClass");
550 // Like uimm5_64 but reports a less confusing error for 32-63 when
551 // an instruction alias permits that.
552 def uimm5_64_report_uimm6 : Operand<i64> {
553 let PrintMethod = "printUnsignedImm";
554 let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass;
557 def uimm16 : Operand<i32> {
558 let PrintMethod = "printUnsignedImm";
561 def pcrel16 : Operand<i32> {
564 def MipsMemAsmOperand : AsmOperandClass {
566 let ParserMethod = "parseMemOperand";
569 def MipsMemSimm9AsmOperand : AsmOperandClass {
570 let Name = "MemOffsetSimm9";
571 let SuperClasses = [MipsMemAsmOperand];
572 let RenderMethod = "addMemOperands";
573 let ParserMethod = "parseMemOperand";
574 let PredicateMethod = "isMemWithSimmOffset<9>";
577 def MipsMemSimm9GPRAsmOperand : AsmOperandClass {
578 let Name = "MemOffsetSimm9GPR";
579 let SuperClasses = [MipsMemAsmOperand];
580 let RenderMethod = "addMemOperands";
581 let ParserMethod = "parseMemOperand";
582 let PredicateMethod = "isMemWithSimmOffsetGPR<9>";
585 def MipsMemSimm11AsmOperand : AsmOperandClass {
586 let Name = "MemOffsetSimm11";
587 let SuperClasses = [MipsMemAsmOperand];
588 let RenderMethod = "addMemOperands";
589 let ParserMethod = "parseMemOperand";
590 let PredicateMethod = "isMemWithSimmOffset<11>";
593 def MipsMemSimm16AsmOperand : AsmOperandClass {
594 let Name = "MemOffsetSimm16";
595 let SuperClasses = [MipsMemAsmOperand];
596 let RenderMethod = "addMemOperands";
597 let ParserMethod = "parseMemOperand";
598 let PredicateMethod = "isMemWithSimmOffset<16>";
601 def MipsInvertedImmoperand : AsmOperandClass {
603 let RenderMethod = "addImmOperands";
604 let ParserMethod = "parseInvNum";
607 def InvertedImOperand : Operand<i32> {
608 let ParserMatchClass = MipsInvertedImmoperand;
611 def InvertedImOperand64 : Operand<i64> {
612 let ParserMatchClass = MipsInvertedImmoperand;
615 class mem_generic : Operand<iPTR> {
616 let PrintMethod = "printMemOperand";
617 let MIOperandInfo = (ops ptr_rc, simm16);
618 let EncoderMethod = "getMemEncoding";
619 let ParserMatchClass = MipsMemAsmOperand;
620 let OperandType = "OPERAND_MEMORY";
624 def mem : mem_generic;
626 // MSA specific address operand
627 def mem_msa : mem_generic {
628 let MIOperandInfo = (ops ptr_rc, simm10);
629 let EncoderMethod = "getMSAMemEncoding";
632 def mem_simm9 : mem_generic {
633 let MIOperandInfo = (ops ptr_rc, simm9);
634 let EncoderMethod = "getMemEncoding";
635 let ParserMatchClass = MipsMemSimm9AsmOperand;
638 def mem_simm9gpr : mem_generic {
639 let MIOperandInfo = (ops ptr_rc, simm9);
640 let EncoderMethod = "getMemEncoding";
641 let ParserMatchClass = MipsMemSimm9GPRAsmOperand;
644 def mem_simm11 : mem_generic {
645 let MIOperandInfo = (ops ptr_rc, simm11);
646 let EncoderMethod = "getMemEncoding";
647 let ParserMatchClass = MipsMemSimm11AsmOperand;
650 def mem_simm16 : mem_generic {
651 let MIOperandInfo = (ops ptr_rc, simm16);
652 let EncoderMethod = "getMemEncoding";
653 let ParserMatchClass = MipsMemSimm16AsmOperand;
656 def mem_ea : Operand<iPTR> {
657 let PrintMethod = "printMemOperandEA";
658 let MIOperandInfo = (ops ptr_rc, simm16);
659 let EncoderMethod = "getMemEncoding";
660 let OperandType = "OPERAND_MEMORY";
663 def PtrRC : Operand<iPTR> {
664 let MIOperandInfo = (ops ptr_rc);
665 let DecoderMethod = "DecodePtrRegisterClass";
666 let ParserMatchClass = GPR32AsmOperand;
669 // size operand of ext instruction
670 def size_ext : Operand<i32> {
671 let EncoderMethod = "getSizeExtEncoding";
672 let DecoderMethod = "DecodeExtSize";
675 // size operand of ins instruction
676 def size_ins : Operand<i32> {
677 let EncoderMethod = "getSizeInsEncoding";
678 let DecoderMethod = "DecodeInsSize";
681 // Transformation Function - get the lower 16 bits.
682 def LO16 : SDNodeXForm<imm, [{
683 return getImm(N, N->getZExtValue() & 0xFFFF);
686 // Transformation Function - get the higher 16 bits.
687 def HI16 : SDNodeXForm<imm, [{
688 return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF);
692 def Plus1 : SDNodeXForm<imm, [{ return getImm(N, N->getSExtValue() + 1); }]>;
694 // Node immediate is zero (e.g. insve.d)
695 def immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>;
697 // Node immediate fits as 16-bit sign extended on target immediate.
699 def immSExt8 : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;
701 // Node immediate fits as 16-bit sign extended on target immediate.
703 def immSExt16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;
705 // Node immediate fits as 15-bit sign extended on target immediate.
707 def immSExt15 : PatLeaf<(imm), [{ return isInt<15>(N->getSExtValue()); }]>;
709 // Node immediate fits as 16-bit zero extended on target immediate.
710 // The LO16 param means that only the lower 16 bits of the node
711 // immediate are caught.
713 def immZExt16 : PatLeaf<(imm), [{
714 if (N->getValueType(0) == MVT::i32)
715 return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
717 return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
720 // Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared).
721 def immLow16Zero : PatLeaf<(imm), [{
722 int64_t Val = N->getSExtValue();
723 return isInt<32>(Val) && !(Val & 0xffff);
726 // shamt field must fit in 5 bits.
727 def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
729 // True if (N + 1) fits in 16-bit field.
730 def immSExt16Plus1 : PatLeaf<(imm), [{
731 return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1);
734 // Mips Address Mode! SDNode frameindex could possibily be a match
735 // since load and store instructions from stack used it.
737 ComplexPattern<iPTR, 2, "selectIntAddr", [frameindex]>;
740 ComplexPattern<iPTR, 2, "selectAddrRegImm", [frameindex]>;
743 ComplexPattern<iPTR, 2, "selectAddrRegReg", [frameindex]>;
746 ComplexPattern<iPTR, 2, "selectAddrDefault", [frameindex]>;
748 def addrimm10 : ComplexPattern<iPTR, 2, "selectIntAddrMSA", [frameindex]>;
750 //===----------------------------------------------------------------------===//
751 // Instructions specific format
752 //===----------------------------------------------------------------------===//
754 // Arithmetic and logical instructions with 3 register operands.
755 class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0,
756 InstrItinClass Itin = NoItinerary,
757 SDPatternOperator OpNode = null_frag>:
758 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
759 !strconcat(opstr, "\t$rd, $rs, $rt"),
760 [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> {
761 let isCommutable = isComm;
762 let isReMaterializable = 1;
763 let TwoOperandAliasConstraint = "$rd = $rs";
766 // Arithmetic and logical instructions with 2 register operands.
767 class ArithLogicI<string opstr, Operand Od, RegisterOperand RO,
768 InstrItinClass Itin = NoItinerary,
769 SDPatternOperator imm_type = null_frag,
770 SDPatternOperator OpNode = null_frag> :
771 InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16),
772 !strconcat(opstr, "\t$rt, $rs, $imm16"),
773 [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))],
775 let isReMaterializable = 1;
776 let TwoOperandAliasConstraint = "$rs = $rt";
779 // Arithmetic Multiply ADD/SUB
780 class MArithR<string opstr, InstrItinClass itin, bit isComm = 0> :
781 InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
782 !strconcat(opstr, "\t$rs, $rt"), [], itin, FrmR, opstr> {
783 let Defs = [HI0, LO0];
784 let Uses = [HI0, LO0];
785 let isCommutable = isComm;
789 class LogicNOR<string opstr, RegisterOperand RO>:
790 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
791 !strconcat(opstr, "\t$rd, $rs, $rt"),
792 [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], II_NOR, FrmR, opstr> {
793 let isCommutable = 1;
797 class shift_rotate_imm<string opstr, Operand ImmOpnd,
798 RegisterOperand RO, InstrItinClass itin,
799 SDPatternOperator OpNode = null_frag,
800 SDPatternOperator PF = null_frag> :
801 InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt),
802 !strconcat(opstr, "\t$rd, $rt, $shamt"),
803 [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], itin, FrmR, opstr> {
804 let TwoOperandAliasConstraint = "$rt = $rd";
807 class shift_rotate_reg<string opstr, RegisterOperand RO, InstrItinClass itin,
808 SDPatternOperator OpNode = null_frag>:
809 InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs),
810 !strconcat(opstr, "\t$rd, $rt, $rs"),
811 [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], itin, FrmR,
814 // Load Upper Immediate
815 class LoadUpper<string opstr, RegisterOperand RO, Operand Imm>:
816 InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"),
817 [], II_LUI, FrmI, opstr>, IsAsCheapAsAMove {
818 let hasSideEffects = 0;
819 let isReMaterializable = 1;
823 class Load<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
824 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
825 InstSE<(outs RO:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
826 [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> {
827 let DecoderMethod = "DecodeMem";
828 let canFoldAsLoad = 1;
832 class StoreMemory<string opstr, DAGOperand RO, DAGOperand MO,
833 SDPatternOperator OpNode = null_frag,
834 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
835 InstSE<(outs), (ins RO:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
836 [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> {
837 let DecoderMethod = "DecodeMem";
841 class Store<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
842 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
843 StoreMemory<opstr, RO, mem, OpNode, Itin, Addr>;
845 // Load/Store Left/Right
846 let canFoldAsLoad = 1 in
847 class LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
848 InstrItinClass Itin> :
849 InstSE<(outs RO:$rt), (ins mem:$addr, RO:$src),
850 !strconcat(opstr, "\t$rt, $addr"),
851 [(set RO:$rt, (OpNode addr:$addr, RO:$src))], Itin, FrmI> {
852 let DecoderMethod = "DecodeMem";
853 string Constraints = "$src = $rt";
856 class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
857 InstrItinClass Itin> :
858 InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
859 [(OpNode RO:$rt, addr:$addr)], Itin, FrmI> {
860 let DecoderMethod = "DecodeMem";
864 class LW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
865 SDPatternOperator OpNode= null_frag> :
866 InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
867 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
868 let DecoderMethod = "DecodeFMem2";
872 class SW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
873 SDPatternOperator OpNode= null_frag> :
874 InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
875 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
876 let DecoderMethod = "DecodeFMem2";
881 class LW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
882 SDPatternOperator OpNode= null_frag> :
883 InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
884 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
885 let DecoderMethod = "DecodeFMem3";
889 class SW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
890 SDPatternOperator OpNode= null_frag> :
891 InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
892 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
893 let DecoderMethod = "DecodeFMem3";
897 // Conditional Branch
898 class CBranch<string opstr, DAGOperand opnd, PatFrag cond_op,
899 RegisterOperand RO, bit DelaySlot = 1> :
900 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
901 !strconcat(opstr, "\t$rs, $rt, $offset"),
902 [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], II_BCC,
905 let isTerminator = 1;
906 let hasDelaySlot = DelaySlot;
910 class CBranchZero<string opstr, DAGOperand opnd, PatFrag cond_op,
911 RegisterOperand RO, bit DelaySlot = 1> :
912 InstSE<(outs), (ins RO:$rs, opnd:$offset),
913 !strconcat(opstr, "\t$rs, $offset"),
914 [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], II_BCCZ,
917 let isTerminator = 1;
918 let hasDelaySlot = DelaySlot;
923 class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> :
924 InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt),
925 !strconcat(opstr, "\t$rd, $rs, $rt"),
926 [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))],
927 II_SLT_SLTU, FrmR, opstr>;
929 class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
931 InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16),
932 !strconcat(opstr, "\t$rt, $rs, $imm16"),
933 [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))],
934 II_SLTI_SLTIU, FrmI, opstr>;
937 class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
938 SDPatternOperator targetoperator, string bopstr> :
939 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
940 [(operator targetoperator:$target)], II_J, FrmJ, bopstr> {
943 let hasDelaySlot = 1;
944 let DecoderMethod = "DecodeJumpTarget";
948 // Unconditional branch
949 class UncondBranch<Instruction BEQInst> :
950 PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], II_B>,
951 PseudoInstExpansion<(BEQInst ZERO, ZERO, brtarget:$offset)> {
953 let isTerminator = 1;
955 let hasDelaySlot = 1;
956 let AdditionalPredicates = [RelocPIC];
960 // Base class for indirect branch and return instruction classes.
961 let isTerminator=1, isBarrier=1, hasDelaySlot = 1 in
962 class JumpFR<string opstr, RegisterOperand RO,
963 SDPatternOperator operator = null_frag>:
964 InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], II_JR,
968 class IndirectBranch<string opstr, RegisterOperand RO> : JumpFR<opstr, RO> {
970 let isIndirectBranch = 1;
973 // Jump and Link (Call)
974 let isCall=1, hasDelaySlot=1, Defs = [RA] in {
975 class JumpLink<string opstr, DAGOperand opnd> :
976 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
977 [(MipsJmpLink imm:$target)], II_JAL, FrmJ, opstr> {
978 let DecoderMethod = "DecodeJumpTarget";
981 class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst,
982 Register RetReg, RegisterOperand ResRO = RO>:
983 PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], II_JALR>,
984 PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)>;
986 class JumpLinkReg<string opstr, RegisterOperand RO>:
987 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
988 [], II_JALR, FrmR, opstr>;
990 class BGEZAL_FT<string opstr, DAGOperand opnd,
991 RegisterOperand RO, bit DelaySlot = 1> :
992 InstSE<(outs), (ins RO:$rs, opnd:$offset),
993 !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZAL, FrmI, opstr> {
994 let hasDelaySlot = DelaySlot;
999 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
1000 hasExtraSrcRegAllocReq = 1, Defs = [AT] in {
1001 class TailCall<Instruction JumpInst> :
1002 PseudoSE<(outs), (ins calltarget:$target), [], II_J>,
1003 PseudoInstExpansion<(JumpInst jmptarget:$target)>;
1005 class TailCallReg<RegisterOperand RO, Instruction JRInst,
1006 RegisterOperand ResRO = RO> :
1007 PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>,
1008 PseudoInstExpansion<(JRInst ResRO:$rs)>;
1011 class BAL_BR_Pseudo<Instruction RealInst> :
1012 PseudoSE<(outs), (ins brtarget:$offset), [], II_BCCZAL>,
1013 PseudoInstExpansion<(RealInst ZERO, brtarget:$offset)> {
1015 let isTerminator = 1;
1017 let hasDelaySlot = 1;
1022 class SYS_FT<string opstr> :
1023 InstSE<(outs), (ins uimm20:$code_),
1024 !strconcat(opstr, "\t$code_"), [], NoItinerary, FrmI, opstr>;
1026 class BRK_FT<string opstr> :
1027 InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
1028 !strconcat(opstr, "\t$code_1, $code_2"), [], NoItinerary,
1032 class ER_FT<string opstr> :
1033 InstSE<(outs), (ins),
1034 opstr, [], NoItinerary, FrmOther, opstr>;
1037 class DEI_FT<string opstr, RegisterOperand RO> :
1038 InstSE<(outs RO:$rt), (ins),
1039 !strconcat(opstr, "\t$rt"), [], NoItinerary, FrmOther, opstr>;
1042 class WAIT_FT<string opstr> :
1043 InstSE<(outs), (ins), opstr, [], NoItinerary, FrmOther, opstr>;
1046 let hasSideEffects = 1 in
1047 class SYNC_FT<string opstr> :
1048 InstSE<(outs), (ins i32imm:$stype), "sync $stype", [(MipsSync imm:$stype)],
1049 NoItinerary, FrmOther, opstr>;
1051 class SYNCI_FT<string opstr> :
1052 InstSE<(outs), (ins mem_simm16:$addr), !strconcat(opstr, "\t$addr"), [],
1053 NoItinerary, FrmOther, opstr> {
1054 let hasSideEffects = 1;
1055 let DecoderMethod = "DecodeSyncI";
1058 let hasSideEffects = 1 in
1059 class TEQ_FT<string opstr, RegisterOperand RO> :
1060 InstSE<(outs), (ins RO:$rs, RO:$rt, uimm16:$code_),
1061 !strconcat(opstr, "\t$rs, $rt, $code_"), [], NoItinerary,
1064 class TEQI_FT<string opstr, RegisterOperand RO> :
1065 InstSE<(outs), (ins RO:$rs, uimm16:$imm16),
1066 !strconcat(opstr, "\t$rs, $imm16"), [], NoItinerary, FrmOther, opstr>;
1068 class Mult<string opstr, InstrItinClass itin, RegisterOperand RO,
1069 list<Register> DefRegs> :
1070 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [],
1071 itin, FrmR, opstr> {
1072 let isCommutable = 1;
1074 let hasSideEffects = 0;
1077 // Pseudo multiply/divide instruction with explicit accumulator register
1079 class MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1,
1080 SDPatternOperator OpNode, InstrItinClass Itin,
1081 bit IsComm = 1, bit HasSideEffects = 0,
1082 bit UsesCustomInserter = 0> :
1083 PseudoSE<(outs R0:$ac), (ins R1:$rs, R1:$rt),
1084 [(set R0:$ac, (OpNode R1:$rs, R1:$rt))], Itin>,
1085 PseudoInstExpansion<(RealInst R1:$rs, R1:$rt)> {
1086 let isCommutable = IsComm;
1087 let hasSideEffects = HasSideEffects;
1088 let usesCustomInserter = UsesCustomInserter;
1091 // Pseudo multiply add/sub instruction with explicit accumulator register
1093 class MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode,
1094 InstrItinClass itin>
1095 : PseudoSE<(outs ACC64:$ac),
1096 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin),
1098 (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))],
1100 PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> {
1101 string Constraints = "$acin = $ac";
1104 class Div<string opstr, InstrItinClass itin, RegisterOperand RO,
1105 list<Register> DefRegs> :
1106 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$$zero, $rs, $rt"),
1107 [], itin, FrmR, opstr> {
1112 class PseudoMFLOHI<RegisterClass DstRC, RegisterClass SrcRC, SDNode OpNode>
1113 : PseudoSE<(outs DstRC:$rd), (ins SrcRC:$hilo),
1114 [(set DstRC:$rd, (OpNode SrcRC:$hilo))], II_MFHI_MFLO>;
1116 class MoveFromLOHI<string opstr, RegisterOperand RO, Register UseReg>:
1117 InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO,
1119 let Uses = [UseReg];
1120 let hasSideEffects = 0;
1123 class PseudoMTLOHI<RegisterClass DstRC, RegisterClass SrcRC>
1124 : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi),
1125 [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))],
1128 class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>:
1129 InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO,
1132 let hasSideEffects = 0;
1135 class EffectiveAddress<string opstr, RegisterOperand RO> :
1136 InstSE<(outs RO:$rt), (ins mem_ea:$addr), !strconcat(opstr, "\t$rt, $addr"),
1137 [(set RO:$rt, addr:$addr)], NoItinerary, FrmI,
1138 !strconcat(opstr, "_lea")> {
1139 let isCodeGenOnly = 1;
1140 let DecoderMethod = "DecodeMem";
1143 // Count Leading Ones/Zeros in Word
1144 class CountLeading0<string opstr, RegisterOperand RO>:
1145 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1146 [(set RO:$rd, (ctlz RO:$rs))], II_CLZ, FrmR, opstr>;
1148 class CountLeading1<string opstr, RegisterOperand RO>:
1149 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1150 [(set RO:$rd, (ctlz (not RO:$rs)))], II_CLO, FrmR, opstr>;
1152 // Sign Extend in Register.
1153 class SignExtInReg<string opstr, ValueType vt, RegisterOperand RO,
1154 InstrItinClass itin> :
1155 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"),
1156 [(set RO:$rd, (sext_inreg RO:$rt, vt))], itin, FrmR, opstr>;
1159 class SubwordSwap<string opstr, RegisterOperand RO,
1160 InstrItinClass itin = NoItinerary>:
1161 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [], itin,
1163 let hasSideEffects = 0;
1167 class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> :
1168 InstSE<(outs CPURegOperand:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [],
1169 II_RDHWR, FrmR, "rdhwr">;
1172 class ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1173 SDPatternOperator Op = null_frag>:
1174 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, size_ext:$size),
1175 !strconcat(opstr, " $rt, $rs, $pos, $size"),
1176 [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size))], II_EXT,
1177 FrmR, opstr>, ISA_MIPS32R2;
1179 class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1180 SDPatternOperator Op = null_frag>:
1181 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, size_ins:$size, RO:$src),
1182 !strconcat(opstr, " $rt, $rs, $pos, $size"),
1183 [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size, RO:$src))],
1184 II_INS, FrmR, opstr>, ISA_MIPS32R2 {
1185 let Constraints = "$src = $rt";
1188 // Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*).
1189 class Atomic2Ops<PatFrag Op, RegisterClass DRC> :
1190 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr),
1191 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]>;
1193 // Atomic Compare & Swap.
1194 class AtomicCmpSwap<PatFrag Op, RegisterClass DRC> :
1195 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap),
1196 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]>;
1198 class LLBase<string opstr, RegisterOperand RO> :
1199 InstSE<(outs RO:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1200 [], NoItinerary, FrmI> {
1201 let DecoderMethod = "DecodeMem";
1205 class SCBase<string opstr, RegisterOperand RO> :
1206 InstSE<(outs RO:$dst), (ins RO:$rt, mem:$addr),
1207 !strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> {
1208 let DecoderMethod = "DecodeMem";
1210 let Constraints = "$rt = $dst";
1213 class MFC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD> :
1214 InstSE<(outs RO:$rt), (ins RD:$rd, uimm16:$sel),
1215 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], NoItinerary, FrmFR>;
1217 class MTC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD> :
1218 InstSE<(outs RO:$rd), (ins RD:$rt, uimm16:$sel),
1219 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], NoItinerary, FrmFR>;
1221 class TrapBase<Instruction RealInst>
1222 : PseudoSE<(outs), (ins), [(trap)], NoItinerary>,
1223 PseudoInstExpansion<(RealInst 0, 0)> {
1225 let isTerminator = 1;
1226 let isCodeGenOnly = 1;
1229 //===----------------------------------------------------------------------===//
1230 // Pseudo instructions
1231 //===----------------------------------------------------------------------===//
1234 let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1 in
1235 def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
1237 let isReturn=1, isTerminator=1, isBarrier=1, hasCtrlDep=1, hasSideEffects=1 in
1238 def ERet : PseudoSE<(outs), (ins), [(MipsERet)]>;
1240 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
1241 def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt),
1242 [(callseq_start timm:$amt)]>;
1243 def ADJCALLSTACKUP : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1244 [(callseq_end timm:$amt1, timm:$amt2)]>;
1247 let usesCustomInserter = 1 in {
1248 def ATOMIC_LOAD_ADD_I8 : Atomic2Ops<atomic_load_add_8, GPR32>;
1249 def ATOMIC_LOAD_ADD_I16 : Atomic2Ops<atomic_load_add_16, GPR32>;
1250 def ATOMIC_LOAD_ADD_I32 : Atomic2Ops<atomic_load_add_32, GPR32>;
1251 def ATOMIC_LOAD_SUB_I8 : Atomic2Ops<atomic_load_sub_8, GPR32>;
1252 def ATOMIC_LOAD_SUB_I16 : Atomic2Ops<atomic_load_sub_16, GPR32>;
1253 def ATOMIC_LOAD_SUB_I32 : Atomic2Ops<atomic_load_sub_32, GPR32>;
1254 def ATOMIC_LOAD_AND_I8 : Atomic2Ops<atomic_load_and_8, GPR32>;
1255 def ATOMIC_LOAD_AND_I16 : Atomic2Ops<atomic_load_and_16, GPR32>;
1256 def ATOMIC_LOAD_AND_I32 : Atomic2Ops<atomic_load_and_32, GPR32>;
1257 def ATOMIC_LOAD_OR_I8 : Atomic2Ops<atomic_load_or_8, GPR32>;
1258 def ATOMIC_LOAD_OR_I16 : Atomic2Ops<atomic_load_or_16, GPR32>;
1259 def ATOMIC_LOAD_OR_I32 : Atomic2Ops<atomic_load_or_32, GPR32>;
1260 def ATOMIC_LOAD_XOR_I8 : Atomic2Ops<atomic_load_xor_8, GPR32>;
1261 def ATOMIC_LOAD_XOR_I16 : Atomic2Ops<atomic_load_xor_16, GPR32>;
1262 def ATOMIC_LOAD_XOR_I32 : Atomic2Ops<atomic_load_xor_32, GPR32>;
1263 def ATOMIC_LOAD_NAND_I8 : Atomic2Ops<atomic_load_nand_8, GPR32>;
1264 def ATOMIC_LOAD_NAND_I16 : Atomic2Ops<atomic_load_nand_16, GPR32>;
1265 def ATOMIC_LOAD_NAND_I32 : Atomic2Ops<atomic_load_nand_32, GPR32>;
1267 def ATOMIC_SWAP_I8 : Atomic2Ops<atomic_swap_8, GPR32>;
1268 def ATOMIC_SWAP_I16 : Atomic2Ops<atomic_swap_16, GPR32>;
1269 def ATOMIC_SWAP_I32 : Atomic2Ops<atomic_swap_32, GPR32>;
1271 def ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap<atomic_cmp_swap_8, GPR32>;
1272 def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap<atomic_cmp_swap_16, GPR32>;
1273 def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_32, GPR32>;
1276 /// Pseudo instructions for loading and storing accumulator registers.
1277 let isPseudo = 1, isCodeGenOnly = 1 in {
1278 def LOAD_ACC64 : Load<"", ACC64>;
1279 def STORE_ACC64 : Store<"", ACC64>;
1282 // We need these two pseudo instructions to avoid offset calculation for long
1283 // branches. See the comment in file MipsLongBranch.cpp for detailed
1286 // Expands to: lui $dst, %hi($tgt - $baltgt)
1287 def LONG_BRANCH_LUi : PseudoSE<(outs GPR32Opnd:$dst),
1288 (ins brtarget:$tgt, brtarget:$baltgt), []>;
1290 // Expands to: addiu $dst, $src, %lo($tgt - $baltgt)
1291 def LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst),
1292 (ins GPR32Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []>;
1294 //===----------------------------------------------------------------------===//
1295 // Instruction definition
1296 //===----------------------------------------------------------------------===//
1297 //===----------------------------------------------------------------------===//
1298 // MipsI Instructions
1299 //===----------------------------------------------------------------------===//
1301 /// Arithmetic Instructions (ALU Immediate)
1302 let AdditionalPredicates = [NotInMicroMips] in {
1303 def ADDiu : MMRel, StdMMR6Rel, ArithLogicI<"addiu", simm16, GPR32Opnd,
1304 II_ADDIU, immSExt16, add>,
1305 ADDI_FM<0x9>, IsAsCheapAsAMove;
1307 def ADDi : MMRel, ArithLogicI<"addi", simm16, GPR32Opnd>, ADDI_FM<0x8>,
1308 ISA_MIPS1_NOT_32R6_64R6;
1309 def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
1311 def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
1313 let AdditionalPredicates = [NotInMicroMips] in {
1314 def ANDi : MMRel, StdMMR6Rel,
1315 ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16, and>,
1318 def ORi : MMRel, StdMMR6Rel,
1319 ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16, or>,
1321 def XORi : MMRel, StdMMR6Rel,
1322 ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16, xor>,
1324 def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16>, LUI_FM;
1325 let AdditionalPredicates = [NotInMicroMips] in {
1326 /// Arithmetic Instructions (3-Operand, R-Type)
1327 def ADDu : MMRel, StdMMR6Rel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
1329 def SUBu : MMRel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
1332 let Defs = [HI0, LO0] in
1333 def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>,
1334 ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6;
1335 def ADD : MMRel, StdMMR6Rel, ArithLogicR<"add", GPR32Opnd>, ADD_FM<0, 0x20>;
1336 def SUB : MMRel, ArithLogicR<"sub", GPR32Opnd>, ADD_FM<0, 0x22>;
1337 def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>;
1338 def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>;
1339 let AdditionalPredicates = [NotInMicroMips] in {
1340 def AND : MMRel, StdMMR6Rel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
1342 def OR : MMRel, StdMMR6Rel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
1344 def XOR : MMRel, StdMMR6Rel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
1347 def NOR : MMRel, StdMMR6Rel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>;
1349 /// Shift Instructions
1350 let AdditionalPredicates = [NotInMicroMips] in {
1351 def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl,
1352 immZExt5>, SRA_FM<0, 0>;
1353 def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl,
1354 immZExt5>, SRA_FM<2, 0>;
1356 def SRA : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, sra,
1357 immZExt5>, SRA_FM<3, 0>;
1358 def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, shl>,
1360 def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, srl>,
1362 def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, sra>,
1365 // Rotate Instructions
1366 def ROTR : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr,
1368 SRA_FM<2, 1>, ISA_MIPS32R2;
1369 def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>,
1370 SRLV_FM<6, 1>, ISA_MIPS32R2;
1372 /// Load and Store Instructions
1374 def LB : Load<"lb", GPR32Opnd, sextloadi8, II_LB>, MMRel, LW_FM<0x20>;
1375 def LBu : Load<"lbu", GPR32Opnd, zextloadi8, II_LBU, addrDefault>, MMRel,
1377 def LH : Load<"lh", GPR32Opnd, sextloadi16, II_LH, addrDefault>, MMRel,
1379 def LHu : Load<"lhu", GPR32Opnd, zextloadi16, II_LHU>, MMRel, LW_FM<0x25>;
1380 let AdditionalPredicates = [NotInMicroMips] in {
1381 def LW : StdMMR6Rel, Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel,
1384 def SB : StdMMR6Rel, Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel,
1386 def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>;
1387 let AdditionalPredicates = [NotInMicroMips] in {
1388 def SW : Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>;
1391 /// load/store left/right
1392 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1393 AdditionalPredicates = [NotInMicroMips] in {
1394 def LWL : LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>,
1395 ISA_MIPS1_NOT_32R6_64R6;
1396 def LWR : LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>,
1397 ISA_MIPS1_NOT_32R6_64R6;
1398 def SWL : StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>,
1399 ISA_MIPS1_NOT_32R6_64R6;
1400 def SWR : StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>,
1401 ISA_MIPS1_NOT_32R6_64R6;
1404 let AdditionalPredicates = [NotInMicroMips] in {
1405 // COP2 Memory Instructions
1406 def LWC2 : LW_FT2<"lwc2", COP2Opnd, NoItinerary, load>, LW_FM<0x32>,
1407 ISA_MIPS1_NOT_32R6_64R6;
1408 def SWC2 : SW_FT2<"swc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3a>,
1409 ISA_MIPS1_NOT_32R6_64R6;
1410 def LDC2 : LW_FT2<"ldc2", COP2Opnd, NoItinerary, load>, LW_FM<0x36>,
1411 ISA_MIPS2_NOT_32R6_64R6;
1412 def SDC2 : SW_FT2<"sdc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3e>,
1413 ISA_MIPS2_NOT_32R6_64R6;
1415 // COP3 Memory Instructions
1416 let DecoderNamespace = "COP3_" in {
1417 def LWC3 : LW_FT3<"lwc3", COP3Opnd, NoItinerary, load>, LW_FM<0x33>;
1418 def SWC3 : SW_FT3<"swc3", COP3Opnd, NoItinerary, store>, LW_FM<0x3b>;
1419 def LDC3 : LW_FT3<"ldc3", COP3Opnd, NoItinerary, load>, LW_FM<0x37>,
1421 def SDC3 : SW_FT3<"sdc3", COP3Opnd, NoItinerary, store>, LW_FM<0x3f>,
1426 def SYNC : MMRel, StdMMR6Rel, SYNC_FT<"sync">, SYNC_FM, ISA_MIPS32;
1427 def SYNCI : MMRel, StdMMR6Rel, SYNCI_FT<"synci">, SYNCI_FM, ISA_MIPS32R2;
1429 let AdditionalPredicates = [NotInMicroMips] in {
1430 def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM<0x34>, ISA_MIPS2;
1431 def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM<0x30>, ISA_MIPS2;
1432 def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd>, TEQ_FM<0x31>, ISA_MIPS2;
1433 def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd>, TEQ_FM<0x32>, ISA_MIPS2;
1434 def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd>, TEQ_FM<0x33>, ISA_MIPS2;
1435 def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd>, TEQ_FM<0x36>, ISA_MIPS2;
1438 def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd>, TEQI_FM<0xc>,
1439 ISA_MIPS2_NOT_32R6_64R6;
1440 def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd>, TEQI_FM<0x8>,
1441 ISA_MIPS2_NOT_32R6_64R6;
1442 def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd>, TEQI_FM<0x9>,
1443 ISA_MIPS2_NOT_32R6_64R6;
1444 def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd>, TEQI_FM<0xa>,
1445 ISA_MIPS2_NOT_32R6_64R6;
1446 def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd>, TEQI_FM<0xb>,
1447 ISA_MIPS2_NOT_32R6_64R6;
1448 def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd>, TEQI_FM<0xe>,
1449 ISA_MIPS2_NOT_32R6_64R6;
1451 let AdditionalPredicates = [NotInMicroMips] in {
1452 def BREAK : MMRel, StdMMR6Rel, BRK_FT<"break">, BRK_FM<0xd>;
1454 def SYSCALL : MMRel, SYS_FT<"syscall">, SYS_FM<0xc>;
1455 def TRAP : TrapBase<BREAK>;
1456 def SDBBP : MMRel, SYS_FT<"sdbbp">, SDBBP_FM, ISA_MIPS32_NOT_32R6_64R6;
1458 let AdditionalPredicates = [NotInMicroMips] in {
1459 def ERET : MMRel, ER_FT<"eret">, ER_FM<0x18, 0x0>, INSN_MIPS3_32;
1460 def ERETNC : MMRel, ER_FT<"eretnc">, ER_FM<0x18, 0x1>, ISA_MIPS32R5;
1462 def DERET : MMRel, ER_FT<"deret">, ER_FM<0x1f, 0x0>, ISA_MIPS32;
1464 let AdditionalPredicates = [NotInMicroMips] in {
1465 def EI : MMRel, StdMMR6Rel, DEI_FT<"ei", GPR32Opnd>, EI_FM<1>, ISA_MIPS32R2;
1467 def DI : MMRel, DEI_FT<"di", GPR32Opnd>, EI_FM<0>, ISA_MIPS32R2;
1469 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1470 AdditionalPredicates = [NotInMicroMips] in {
1471 def WAIT : WAIT_FT<"wait">, WAIT_FM;
1473 /// Load-linked, Store-conditional
1474 def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, ISA_MIPS2_NOT_32R6_64R6;
1475 def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, ISA_MIPS2_NOT_32R6_64R6;
1478 /// Jump and Branch Instructions
1479 def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
1480 AdditionalRequires<[RelocStatic]>, IsBranch;
1481 def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>;
1482 def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>;
1483 def BEQL : MMRel, CBranch<"beql", brtarget, seteq, GPR32Opnd, 0>,
1484 BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6;
1485 def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>;
1486 def BNEL : MMRel, CBranch<"bnel", brtarget, setne, GPR32Opnd, 0>,
1487 BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6;
1488 def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
1490 def BGEZL : MMRel, CBranchZero<"bgezl", brtarget, setge, GPR32Opnd, 0>,
1491 BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6;
1492 def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
1494 def BGTZL : MMRel, CBranchZero<"bgtzl", brtarget, setgt, GPR32Opnd, 0>,
1495 BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6;
1496 def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
1498 def BLEZL : MMRel, CBranchZero<"blezl", brtarget, setle, GPR32Opnd, 0>,
1499 BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6;
1500 def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
1502 def BLTZL : MMRel, CBranchZero<"bltzl", brtarget, setlt, GPR32Opnd, 0>,
1503 BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6;
1504 def B : UncondBranch<BEQ>;
1506 def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>;
1507 let AdditionalPredicates = [NotInMicroMips] in {
1508 def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM;
1509 def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>;
1512 def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>,
1513 ISA_MIPS32_NOT_32R6_64R6;
1514 def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>,
1515 ISA_MIPS1_NOT_32R6_64R6;
1516 def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd, 0>,
1517 BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6;
1518 def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>,
1519 ISA_MIPS1_NOT_32R6_64R6;
1520 def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd, 0>,
1521 BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6;
1522 def BAL_BR : BAL_BR_Pseudo<BGEZAL>;
1523 def TAILCALL : TailCall<J>;
1524 def TAILCALL_R : TailCallReg<GPR32Opnd, JR>;
1526 // Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64
1527 // then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA.
1528 class PseudoIndirectBranchBase<RegisterOperand RO> :
1529 MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)],
1530 II_IndirectBranchPseudo> {
1533 let hasDelaySlot = 1;
1535 let isIndirectBranch = 1;
1538 def PseudoIndirectBranch : PseudoIndirectBranchBase<GPR32Opnd>;
1540 // Return instructions are matched as a RetRA instruction, then are expanded
1541 // into PseudoReturn/PseudoReturn64 after register allocation. Finally,
1542 // MipsAsmPrinter expands this into JR, JR64, JALR, or JALR64 depending on the
1544 class PseudoReturnBase<RegisterOperand RO> : MipsPseudo<(outs), (ins RO:$rs),
1545 [], II_ReturnPseudo> {
1546 let isTerminator = 1;
1548 let hasDelaySlot = 1;
1550 let isCodeGenOnly = 1;
1552 let hasExtraSrcRegAllocReq = 1;
1555 def PseudoReturn : PseudoReturnBase<GPR32Opnd>;
1557 // Exception handling related node and instructions.
1558 // The conversion sequence is:
1559 // ISD::EH_RETURN -> MipsISD::EH_RETURN ->
1560 // MIPSeh_return -> (stack change + indirect branch)
1562 // MIPSeh_return takes the place of regular return instruction
1563 // but takes two arguments (V1, V0) which are used for storing
1564 // the offset and return address respectively.
1565 def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
1567 def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
1568 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
1570 let Uses = [V0, V1], isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1571 def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
1572 [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
1573 def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff,
1575 [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
1578 /// Multiply and Divide Instructions.
1579 def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
1580 MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6;
1581 def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
1582 MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6;
1583 def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
1584 MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6;
1585 def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
1586 MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6;
1588 def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>,
1589 ISA_MIPS1_NOT_32R6_64R6;
1590 def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>,
1591 ISA_MIPS1_NOT_32R6_64R6;
1592 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1593 AdditionalPredicates = [NotInMicroMips] in {
1594 def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>,
1595 ISA_MIPS1_NOT_32R6_64R6;
1596 def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>,
1597 ISA_MIPS1_NOT_32R6_64R6;
1600 /// Sign Ext In Register Instructions.
1601 def SEB : MMRel, StdMMR6Rel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,
1602 SEB_FM<0x10, 0x20>, ISA_MIPS32R2;
1603 def SEH : MMRel, StdMMR6Rel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
1604 SEB_FM<0x18, 0x20>, ISA_MIPS32R2;
1607 def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd>, CLO_FM<0x20>,
1608 ISA_MIPS32_NOT_32R6_64R6;
1609 def CLO : MMRel, CountLeading1<"clo", GPR32Opnd>, CLO_FM<0x21>,
1610 ISA_MIPS32_NOT_32R6_64R6;
1612 let AdditionalPredicates = [NotInMicroMips] in {
1613 /// Word Swap Bytes Within Halfwords
1614 def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd, II_WSBH>, SEB_FM<2, 0x20>,
1619 def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>;
1621 // FrameIndexes are legalized when they are operands from load/store
1622 // instructions. The same not happens for stack address copies, so an
1623 // add op with mem ComplexPattern is used and the stack address copy
1624 // can be matched. It's similar to Sparc LEA_ADDRi
1625 def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>;
1628 def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>,
1629 ISA_MIPS32_NOT_32R6_64R6;
1630 def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>,
1631 ISA_MIPS32_NOT_32R6_64R6;
1632 def MSUB : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>,
1633 ISA_MIPS32_NOT_32R6_64R6;
1634 def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>,
1635 ISA_MIPS32_NOT_32R6_64R6;
1637 let AdditionalPredicates = [NotDSP] in {
1638 def PseudoMULT : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>,
1639 ISA_MIPS1_NOT_32R6_64R6;
1640 def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>,
1641 ISA_MIPS1_NOT_32R6_64R6;
1642 def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>, ISA_MIPS1_NOT_32R6_64R6;
1643 def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>, ISA_MIPS1_NOT_32R6_64R6;
1644 def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>, ISA_MIPS1_NOT_32R6_64R6;
1645 def PseudoMADD : MAddSubPseudo<MADD, MipsMAdd, II_MADD>,
1646 ISA_MIPS32_NOT_32R6_64R6;
1647 def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>,
1648 ISA_MIPS32_NOT_32R6_64R6;
1649 def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>,
1650 ISA_MIPS32_NOT_32R6_64R6;
1651 def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>,
1652 ISA_MIPS32_NOT_32R6_64R6;
1655 def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV,
1656 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
1657 def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU,
1658 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
1659 let AdditionalPredicates = [NotInMicroMips] in {
1660 def RDHWR : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM;
1662 def EXT : MMRel, ExtBase<"ext", GPR32Opnd, uimm5, MipsExt>, EXT_FM<0>;
1663 def INS : MMRel, InsBase<"ins", GPR32Opnd, uimm5, MipsIns>, EXT_FM<4>;
1665 /// Move Control Registers From/To CPU Registers
1666 def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd>, MFC3OP_FM<0x10, 0>, ISA_MIPS32;
1667 def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd>, MFC3OP_FM<0x10, 4>, ISA_MIPS32;
1668 def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd>, MFC3OP_FM<0x12, 0>;
1669 def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd>, MFC3OP_FM<0x12, 4>;
1671 class Barrier<string asmstr> : InstSE<(outs), (ins), asmstr, [], NoItinerary,
1673 def SSNOP : MMRel, StdMMR6Rel, Barrier<"ssnop">, BARRIER_FM<1>;
1674 def EHB : MMRel, Barrier<"ehb">, BARRIER_FM<3>;
1675 def PAUSE : MMRel, StdMMR6Rel, Barrier<"pause">, BARRIER_FM<5>, ISA_MIPS32R2;
1677 // JR_HB and JALR_HB are defined here using the new style naming
1678 // scheme because some of this code is shared with Mips32r6InstrInfo.td
1679 // and because of that it doesn't follow the naming convention of the
1680 // rest of the file. To avoid a mixture of old vs new style, the new
1681 // style was chosen.
1682 class JR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
1683 dag OutOperandList = (outs);
1684 dag InOperandList = (ins GPROpnd:$rs);
1685 string AsmString = !strconcat(instr_asm, "\t$rs");
1686 list<dag> Pattern = [];
1689 class JALR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
1690 dag OutOperandList = (outs GPROpnd:$rd);
1691 dag InOperandList = (ins GPROpnd:$rs);
1692 string AsmString = !strconcat(instr_asm, "\t$rd, $rs");
1693 list<dag> Pattern = [];
1696 class JR_HB_DESC : InstSE<(outs), (ins), "", [], NoItinerary, FrmJ>,
1697 JR_HB_DESC_BASE<"jr.hb", GPR32Opnd> {
1699 let isIndirectBranch=1;
1705 class JALR_HB_DESC : InstSE<(outs), (ins), "", [], NoItinerary, FrmJ>,
1706 JALR_HB_DESC_BASE<"jalr.hb", GPR32Opnd> {
1707 let isIndirectBranch=1;
1711 class JR_HB_ENC : JR_HB_FM<8>;
1712 class JALR_HB_ENC : JALR_HB_FM<9>;
1714 def JR_HB : JR_HB_DESC, JR_HB_ENC, ISA_MIPS32_NOT_32R6_64R6;
1715 def JALR_HB : JALR_HB_DESC, JALR_HB_ENC, ISA_MIPS32;
1717 class TLB<string asmstr> : InstSE<(outs), (ins), asmstr, [], NoItinerary,
1719 def TLBP : MMRel, TLB<"tlbp">, COP0_TLB_FM<0x08>;
1720 def TLBR : MMRel, TLB<"tlbr">, COP0_TLB_FM<0x01>;
1721 def TLBWI : MMRel, TLB<"tlbwi">, COP0_TLB_FM<0x02>;
1722 def TLBWR : MMRel, TLB<"tlbwr">, COP0_TLB_FM<0x06>;
1724 class CacheOp<string instr_asm, Operand MemOpnd> :
1725 InstSE<(outs), (ins MemOpnd:$addr, uimm5:$hint),
1726 !strconcat(instr_asm, "\t$hint, $addr"), [], NoItinerary, FrmOther,
1728 let DecoderMethod = "DecodeCacheOp";
1731 def CACHE : MMRel, CacheOp<"cache", mem>, CACHEOP_FM<0b101111>,
1732 INSN_MIPS3_32_NOT_32R6_64R6;
1733 def PREF : MMRel, CacheOp<"pref", mem>, CACHEOP_FM<0b110011>,
1734 INSN_MIPS3_32_NOT_32R6_64R6;
1736 def ROL : MipsAsmPseudoInst<(outs),
1737 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
1738 "rol\t$rs, $rt, $rd">;
1739 def ROLImm : MipsAsmPseudoInst<(outs),
1740 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
1741 "rol\t$rs, $rt, $imm">;
1742 def : MipsInstAlias<"rol $rd, $rs",
1743 (ROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
1744 def : MipsInstAlias<"rol $rd, $imm",
1745 (ROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
1747 def ROR : MipsAsmPseudoInst<(outs),
1748 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
1749 "ror\t$rs, $rt, $rd">;
1750 def RORImm : MipsAsmPseudoInst<(outs),
1751 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
1752 "ror\t$rs, $rt, $imm">;
1753 def : MipsInstAlias<"ror $rd, $rs",
1754 (ROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
1755 def : MipsInstAlias<"ror $rd, $imm",
1756 (RORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>;
1758 def DROL : MipsAsmPseudoInst<(outs),
1759 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
1760 "drol\t$rs, $rt, $rd">, ISA_MIPS64;
1761 def DROLImm : MipsAsmPseudoInst<(outs),
1762 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
1763 "drol\t$rs, $rt, $imm">, ISA_MIPS64;
1764 def : MipsInstAlias<"drol $rd, $rs",
1765 (DROL GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
1766 def : MipsInstAlias<"drol $rd, $imm",
1767 (DROLImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
1769 def DROR : MipsAsmPseudoInst<(outs),
1770 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, GPR32Opnd:$rd),
1771 "dror\t$rs, $rt, $rd">, ISA_MIPS64;
1772 def DRORImm : MipsAsmPseudoInst<(outs),
1773 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
1774 "dror\t$rs, $rt, $imm">, ISA_MIPS64;
1775 def : MipsInstAlias<"dror $rd, $rs",
1776 (DROR GPR32Opnd:$rd, GPR32Opnd:$rd, GPR32Opnd:$rs), 0>, ISA_MIPS64;
1777 def : MipsInstAlias<"dror $rd, $imm",
1778 (DRORImm GPR32Opnd:$rd, GPR32Opnd:$rd, simm16:$imm), 0>, ISA_MIPS64;
1780 //===----------------------------------------------------------------------===//
1781 // Instruction aliases
1782 //===----------------------------------------------------------------------===//
1783 def : MipsInstAlias<"move $dst, $src",
1784 (OR GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
1786 let AdditionalPredicates = [NotInMicroMips];
1788 def : MipsInstAlias<"move $dst, $src",
1789 (ADDu GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
1791 let AdditionalPredicates = [NotInMicroMips];
1793 def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>,
1794 ISA_MIPS1_NOT_32R6_64R6;
1795 def : MipsInstAlias<"addu $rs, $rt, $imm",
1796 (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1797 def : MipsInstAlias<"addu $rs, $imm",
1798 (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>;
1799 def : MipsInstAlias<"add $rs, $rt, $imm",
1800 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>,
1801 ISA_MIPS1_NOT_32R6_64R6;
1802 def : MipsInstAlias<"add $rs, $imm",
1803 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>,
1804 ISA_MIPS1_NOT_32R6_64R6;
1805 def : MipsInstAlias<"and $rs, $rt, $imm",
1806 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1807 def : MipsInstAlias<"and $rs, $imm",
1808 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>;
1809 def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>;
1810 let Predicates = [NotInMicroMips] in {
1811 def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
1813 def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>, ISA_MIPS32;
1814 def : MipsInstAlias<"not $rt, $rs",
1815 (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>;
1816 def : MipsInstAlias<"neg $rt, $rs",
1817 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
1818 def : MipsInstAlias<"negu $rt",
1819 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 0>;
1820 def : MipsInstAlias<"negu $rt, $rs",
1821 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
1822 def : MipsInstAlias<"slt $rs, $rt, $imm",
1823 (SLTi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1824 def : MipsInstAlias<"sltu $rt, $rs, $imm",
1825 (SLTiu GPR32Opnd:$rt, GPR32Opnd:$rs, simm16:$imm), 0>;
1826 def : MipsInstAlias<"xor $rs, $rt, $imm",
1827 (XORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
1828 def : MipsInstAlias<"xor $rs, $imm",
1829 (XORi GPR32Opnd:$rs, GPR32Opnd:$rs, uimm16:$imm), 0>;
1830 def : MipsInstAlias<"or $rs, $rt, $imm",
1831 (ORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
1832 def : MipsInstAlias<"or $rs, $imm",
1833 (ORi GPR32Opnd:$rs, GPR32Opnd:$rs, uimm16:$imm), 0>;
1834 let AdditionalPredicates = [NotInMicroMips] in {
1835 def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>;
1837 def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>;
1838 def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>;
1839 def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, COP2Opnd:$rd, 0), 0>;
1840 def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 COP2Opnd:$rd, GPR32Opnd:$rt, 0), 0>;
1841 let AdditionalPredicates = [NotInMicroMips] in {
1842 def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>;
1844 def : MipsInstAlias<"bnez $rs,$offset",
1845 (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1846 def : MipsInstAlias<"bnezl $rs,$offset",
1847 (BNEL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1848 def : MipsInstAlias<"beqz $rs,$offset",
1849 (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1850 def : MipsInstAlias<"beqzl $rs,$offset",
1851 (BEQL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1852 def : MipsInstAlias<"syscall", (SYSCALL 0), 1>;
1854 def : MipsInstAlias<"break", (BREAK 0, 0), 1>;
1855 def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>;
1856 let AdditionalPredicates = [NotInMicroMips] in {
1857 def : MipsInstAlias<"ei", (EI ZERO), 1>, ISA_MIPS32R2;
1859 def : MipsInstAlias<"di", (DI ZERO), 1>, ISA_MIPS32R2;
1860 let AdditionalPredicates = [NotInMicroMips] in {
1861 def : MipsInstAlias<"teq $rs, $rt",
1862 (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1863 def : MipsInstAlias<"tge $rs, $rt",
1864 (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1865 def : MipsInstAlias<"tgeu $rs, $rt",
1866 (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1867 def : MipsInstAlias<"tlt $rs, $rt",
1868 (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1869 def : MipsInstAlias<"tltu $rs, $rt",
1870 (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1871 def : MipsInstAlias<"tne $rs, $rt",
1872 (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1874 def : MipsInstAlias<"sll $rd, $rt, $rs",
1875 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1876 def : MipsInstAlias<"sub, $rd, $rs, $imm",
1877 (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs,
1878 InvertedImOperand:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6;
1879 def : MipsInstAlias<"sub $rs, $imm",
1880 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm),
1881 0>, ISA_MIPS1_NOT_32R6_64R6;
1882 def : MipsInstAlias<"subu, $rd, $rs, $imm",
1883 (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs,
1884 InvertedImOperand:$imm), 0>;
1885 def : MipsInstAlias<"subu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs,
1886 InvertedImOperand:$imm), 0>;
1887 def : MipsInstAlias<"sra $rd, $rt, $rs",
1888 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1889 def : MipsInstAlias<"srl $rd, $rt, $rs",
1890 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1891 def : MipsInstAlias<"sdbbp", (SDBBP 0)>, ISA_MIPS32_NOT_32R6_64R6;
1892 def : MipsInstAlias<"sync",
1893 (SYNC 0), 1>, ISA_MIPS2;
1894 //===----------------------------------------------------------------------===//
1895 // Assembler Pseudo Instructions
1896 //===----------------------------------------------------------------------===//
1898 class LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> :
1899 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
1900 !strconcat(instr_asm, "\t$rt, $imm32")> ;
1901 def LoadImm32 : LoadImmediate32<"li", simm32, GPR32Opnd>;
1903 class LoadAddressFromReg32<string instr_asm, Operand MemOpnd,
1904 RegisterOperand RO> :
1905 MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
1906 !strconcat(instr_asm, "\t$rt, $addr")> ;
1907 def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>;
1909 class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> :
1910 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
1911 !strconcat(instr_asm, "\t$rt, $imm32")> ;
1912 def LoadAddrImm32 : LoadAddressFromImm32<"la", simm32, GPR32Opnd>;
1914 def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
1916 def JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs),
1919 def NORImm : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
1920 "nor\t$rs, $rt, $imm"> ;
1922 let hasDelaySlot = 1 in {
1923 def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
1924 (ins imm64:$imm64, brtarget:$offset),
1925 "bne\t$rt, $imm64, $offset">;
1926 def BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
1927 (ins imm64:$imm64, brtarget:$offset),
1928 "beq\t$rt, $imm64, $offset">;
1930 class CondBranchPseudo<string instr_asm> :
1931 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt,
1933 !strconcat(instr_asm, "\t$rs, $rt, $offset")>;
1936 def BLT : CondBranchPseudo<"blt">;
1937 def BLE : CondBranchPseudo<"ble">;
1938 def BGE : CondBranchPseudo<"bge">;
1939 def BGT : CondBranchPseudo<"bgt">;
1940 def BLTU : CondBranchPseudo<"bltu">;
1941 def BLEU : CondBranchPseudo<"bleu">;
1942 def BGEU : CondBranchPseudo<"bgeu">;
1943 def BGTU : CondBranchPseudo<"bgtu">;
1944 def BLTL : CondBranchPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
1945 def BLEL : CondBranchPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
1946 def BGEL : CondBranchPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
1947 def BGTL : CondBranchPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
1948 def BLTUL: CondBranchPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
1949 def BLEUL: CondBranchPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
1950 def BGEUL: CondBranchPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
1951 def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
1953 class CondBranchImmPseudo<string instr_asm> :
1954 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, imm64:$imm, brtarget:$offset),
1955 !strconcat(instr_asm, "\t$rs, $imm, $offset")>;
1957 def BLTImmMacro : CondBranchImmPseudo<"blt">;
1958 def BLEImmMacro : CondBranchImmPseudo<"ble">;
1959 def BGEImmMacro : CondBranchImmPseudo<"bge">;
1960 def BGTImmMacro : CondBranchImmPseudo<"bgt">;
1961 def BLTUImmMacro : CondBranchImmPseudo<"bltu">;
1962 def BLEUImmMacro : CondBranchImmPseudo<"bleu">;
1963 def BGEUImmMacro : CondBranchImmPseudo<"bgeu">;
1964 def BGTUImmMacro : CondBranchImmPseudo<"bgtu">;
1965 def BLTLImmMacro : CondBranchImmPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
1966 def BLELImmMacro : CondBranchImmPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
1967 def BGELImmMacro : CondBranchImmPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
1968 def BGTLImmMacro : CondBranchImmPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
1969 def BLTULImmMacro : CondBranchImmPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
1970 def BLEULImmMacro : CondBranchImmPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
1971 def BGEULImmMacro : CondBranchImmPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
1972 def BGTULImmMacro : CondBranchImmPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
1974 // FIXME: Predicates are removed because instructions are matched regardless of
1975 // predicates, because PredicateControl was not in the hierarchy. This was
1976 // done to emit more precise error message from expansion function.
1977 // Once the tablegen-erated errors are made better, this needs to be fixed and
1978 // predicates needs to be restored.
1980 def SDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1981 "div\t$rs, $rt">; //, ISA_MIPS1_NOT_32R6_64R6;
1983 def UDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1984 "divu\t$rs, $rt">; //, ISA_MIPS1_NOT_32R6_64R6;
1986 def DSDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1987 "ddiv\t$rs, $rt">; //, ISA_MIPS64_NOT_64R6;
1989 def DUDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1990 "ddivu\t$rs, $rt">; //, ISA_MIPS64_NOT_64R6;
1992 def Ulh : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
1993 "ulh\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
1995 def Ulhu : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
1996 "ulhu\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
1998 def Ulw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
1999 "ulw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
2001 //===----------------------------------------------------------------------===//
2002 // Arbitrary patterns that map to one or more instructions
2003 //===----------------------------------------------------------------------===//
2005 // Load/store pattern templates.
2006 class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
2007 MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
2009 class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
2010 MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
2013 let AdditionalPredicates = [NotInMicroMips] in {
2014 def : MipsPat<(i32 immSExt16:$in),
2015 (ADDiu ZERO, imm:$in)>;
2016 def : MipsPat<(i32 immZExt16:$in),
2017 (ORi ZERO, imm:$in)>;
2019 def : MipsPat<(i32 immLow16Zero:$in),
2020 (LUi (HI16 imm:$in))>;
2022 // Arbitrary immediates
2023 def : MipsPat<(i32 imm:$imm),
2024 (ORi (LUi (HI16 imm:$imm)), (LO16 imm:$imm))>;
2026 // Carry MipsPatterns
2027 def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
2028 (SUBu GPR32:$lhs, GPR32:$rhs)>;
2029 let AdditionalPredicates = [NotDSP] in {
2030 def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
2031 (ADDu GPR32:$lhs, GPR32:$rhs)>;
2032 def : MipsPat<(addc GPR32:$src, immSExt16:$imm),
2033 (ADDiu GPR32:$src, imm:$imm)>;
2036 // Support multiplication for pre-Mips32 targets that don't have
2037 // the MUL instruction.
2038 def : MipsPat<(mul GPR32:$lhs, GPR32:$rhs),
2039 (PseudoMFLO (PseudoMULT GPR32:$lhs, GPR32:$rhs))>,
2040 ISA_MIPS1_NOT_32R6_64R6;
2043 def : MipsPat<(MipsSync (i32 immz)),
2044 (SYNC 0)>, ISA_MIPS2;
2047 def : MipsPat<(MipsJmpLink (i32 tglobaladdr:$dst)),
2048 (JAL tglobaladdr:$dst)>;
2049 def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
2050 (JAL texternalsym:$dst)>;
2051 //def : MipsPat<(MipsJmpLink GPR32:$dst),
2052 // (JALR GPR32:$dst)>;
2055 def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
2056 (TAILCALL tglobaladdr:$dst)>;
2057 def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
2058 (TAILCALL texternalsym:$dst)>;
2060 def : MipsPat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
2061 def : MipsPat<(MipsHi tblockaddress:$in), (LUi tblockaddress:$in)>;
2062 def : MipsPat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>;
2063 def : MipsPat<(MipsHi tconstpool:$in), (LUi tconstpool:$in)>;
2064 def : MipsPat<(MipsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>;
2065 def : MipsPat<(MipsHi texternalsym:$in), (LUi texternalsym:$in)>;
2067 def : MipsPat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
2068 def : MipsPat<(MipsLo tblockaddress:$in), (ADDiu ZERO, tblockaddress:$in)>;
2069 def : MipsPat<(MipsLo tjumptable:$in), (ADDiu ZERO, tjumptable:$in)>;
2070 def : MipsPat<(MipsLo tconstpool:$in), (ADDiu ZERO, tconstpool:$in)>;
2071 def : MipsPat<(MipsLo tglobaltlsaddr:$in), (ADDiu ZERO, tglobaltlsaddr:$in)>;
2072 def : MipsPat<(MipsLo texternalsym:$in), (ADDiu ZERO, texternalsym:$in)>;
2074 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaladdr:$lo)),
2075 (ADDiu GPR32:$hi, tglobaladdr:$lo)>;
2076 def : MipsPat<(add GPR32:$hi, (MipsLo tblockaddress:$lo)),
2077 (ADDiu GPR32:$hi, tblockaddress:$lo)>;
2078 def : MipsPat<(add GPR32:$hi, (MipsLo tjumptable:$lo)),
2079 (ADDiu GPR32:$hi, tjumptable:$lo)>;
2080 def : MipsPat<(add GPR32:$hi, (MipsLo tconstpool:$lo)),
2081 (ADDiu GPR32:$hi, tconstpool:$lo)>;
2082 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaltlsaddr:$lo)),
2083 (ADDiu GPR32:$hi, tglobaltlsaddr:$lo)>;
2086 def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
2087 (ADDiu GPR32:$gp, tglobaladdr:$in)>;
2088 def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
2089 (ADDiu GPR32:$gp, tconstpool:$in)>;
2092 class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
2093 MipsPat<(MipsWrapper RC:$gp, node:$in),
2094 (ADDiuOp RC:$gp, node:$in)>;
2096 def : WrapperPat<tglobaladdr, ADDiu, GPR32>;
2097 def : WrapperPat<tconstpool, ADDiu, GPR32>;
2098 def : WrapperPat<texternalsym, ADDiu, GPR32>;
2099 def : WrapperPat<tblockaddress, ADDiu, GPR32>;
2100 def : WrapperPat<tjumptable, ADDiu, GPR32>;
2101 def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>;
2103 let AdditionalPredicates = [NotInMicroMips] in {
2104 // Mips does not have "not", so we expand our way
2105 def : MipsPat<(not GPR32:$in),
2106 (NOR GPR32Opnd:$in, ZERO)>;
2110 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>;
2111 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>;
2112 def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
2115 def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>;
2118 multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BNEOp,
2119 Instruction SLTOp, Instruction SLTuOp, Instruction SLTiOp,
2120 Instruction SLTiuOp, Register ZEROReg> {
2121 def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
2122 (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
2123 def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
2124 (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
2126 def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
2127 (BEQ (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
2128 def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
2129 (BEQ (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
2130 def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
2131 (BEQ (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
2132 def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
2133 (BEQ (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
2134 def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
2135 (BEQ (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
2136 def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
2137 (BEQ (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
2139 def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
2140 (BEQ (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
2141 def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
2142 (BEQ (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
2144 def : MipsPat<(brcond RC:$cond, bb:$dst),
2145 (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
2148 defm : BrcondPats<GPR32, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>;
2150 def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
2151 (BLEZ i32:$lhs, bb:$dst)>;
2152 def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
2153 (BGEZ i32:$lhs, bb:$dst)>;
2156 multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp,
2157 Instruction SLTuOp, Register ZEROReg> {
2158 def : MipsPat<(seteq RC:$lhs, 0),
2159 (SLTiuOp RC:$lhs, 1)>;
2160 def : MipsPat<(setne RC:$lhs, 0),
2161 (SLTuOp ZEROReg, RC:$lhs)>;
2162 def : MipsPat<(seteq RC:$lhs, RC:$rhs),
2163 (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>;
2164 def : MipsPat<(setne RC:$lhs, RC:$rhs),
2165 (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
2168 multiclass SetlePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
2169 def : MipsPat<(setle RC:$lhs, RC:$rhs),
2170 (XORi (SLTOp RC:$rhs, RC:$lhs), 1)>;
2171 def : MipsPat<(setule RC:$lhs, RC:$rhs),
2172 (XORi (SLTuOp RC:$rhs, RC:$lhs), 1)>;
2175 multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
2176 def : MipsPat<(setgt RC:$lhs, RC:$rhs),
2177 (SLTOp RC:$rhs, RC:$lhs)>;
2178 def : MipsPat<(setugt RC:$lhs, RC:$rhs),
2179 (SLTuOp RC:$rhs, RC:$lhs)>;
2182 multiclass SetgePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
2183 def : MipsPat<(setge RC:$lhs, RC:$rhs),
2184 (XORi (SLTOp RC:$lhs, RC:$rhs), 1)>;
2185 def : MipsPat<(setuge RC:$lhs, RC:$rhs),
2186 (XORi (SLTuOp RC:$lhs, RC:$rhs), 1)>;
2189 multiclass SetgeImmPats<RegisterClass RC, Instruction SLTiOp,
2190 Instruction SLTiuOp> {
2191 def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
2192 (XORi (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
2193 def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
2194 (XORi (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
2197 defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>;
2198 defm : SetlePats<GPR32, SLT, SLTu>;
2199 defm : SetgtPats<GPR32, SLT, SLTu>;
2200 defm : SetgePats<GPR32, SLT, SLTu>;
2201 defm : SetgeImmPats<GPR32, SLTi, SLTiu>;
2204 def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>;
2206 // Load halfword/word patterns.
2207 let AddedComplexity = 40 in {
2208 def : LoadRegImmPat<LBu, i32, zextloadi8>;
2209 def : LoadRegImmPat<LH, i32, sextloadi16>;
2210 let AdditionalPredicates = [NotInMicroMips] in {
2211 def : LoadRegImmPat<LW, i32, load>;
2215 // Atomic load patterns.
2216 def : MipsPat<(atomic_load_8 addr:$a), (LB addr:$a)>;
2217 def : MipsPat<(atomic_load_16 addr:$a), (LH addr:$a)>;
2218 def : MipsPat<(atomic_load_32 addr:$a), (LW addr:$a)>;
2220 // Atomic store patterns.
2221 def : MipsPat<(atomic_store_8 addr:$a, GPR32:$v), (SB GPR32:$v, addr:$a)>;
2222 def : MipsPat<(atomic_store_16 addr:$a, GPR32:$v), (SH GPR32:$v, addr:$a)>;
2223 def : MipsPat<(atomic_store_32 addr:$a, GPR32:$v), (SW GPR32:$v, addr:$a)>;
2225 //===----------------------------------------------------------------------===//
2226 // Floating Point Support
2227 //===----------------------------------------------------------------------===//
2229 include "MipsInstrFPU.td"
2230 include "Mips64InstrInfo.td"
2231 include "MipsCondMov.td"
2233 include "Mips32r6InstrInfo.td"
2234 include "Mips64r6InstrInfo.td"
2239 include "Mips16InstrFormats.td"
2240 include "Mips16InstrInfo.td"
2243 include "MipsDSPInstrFormats.td"
2244 include "MipsDSPInstrInfo.td"
2247 include "MipsMSAInstrFormats.td"
2248 include "MipsMSAInstrInfo.td"
2251 include "MipsEVAInstrFormats.td"
2252 include "MipsEVAInstrInfo.td"
2255 include "MicroMipsInstrFormats.td"
2256 include "MicroMipsInstrInfo.td"
2257 include "MicroMipsInstrFPU.td"
2260 include "MicroMips32r6InstrFormats.td"
2261 include "MicroMips32r6InstrInfo.td"
2264 include "MicroMips64r6InstrFormats.td"
2265 include "MicroMips64r6InstrInfo.td"
2268 include "MicroMipsDSPInstrFormats.td"
2269 include "MicroMipsDSPInstrInfo.td"