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 = [HasMSA];
318 class ASE_MSA_NOT_MSA64 {
319 list<Predicate> InsnPredicates = [HasMSA, NotMips64];
323 list<Predicate> InsnPredicates = [HasMSA, HasMips64];
326 // Class used for separating microMIPSr6 and microMIPS (r3) instruction.
327 // It can be used only on instructions that doesn't inherit PredicateControl.
328 class ISA_MICROMIPS_NOT_32R6_64R6 : PredicateControl {
329 let InsnPredicates = [InMicroMips, NotMips32r6, NotMips64r6];
332 //===----------------------------------------------------------------------===//
334 class MipsPat<dag pattern, dag result> : Pat<pattern, result>, PredicateControl {
335 let EncodingPredicates = [HasStdEnc];
338 class MipsInstAlias<string Asm, dag Result, bit Emit = 0b1> :
339 InstAlias<Asm, Result, Emit>, PredicateControl;
342 bit isCommutable = 1;
359 bit isTerminator = 1;
362 bit hasExtraSrcRegAllocReq = 1;
363 bit isCodeGenOnly = 1;
366 class IsAsCheapAsAMove {
367 bit isAsCheapAsAMove = 1;
370 class NeverHasSideEffects {
371 bit hasSideEffects = 0;
374 //===----------------------------------------------------------------------===//
375 // Instruction format superclass
376 //===----------------------------------------------------------------------===//
378 include "MipsInstrFormats.td"
380 //===----------------------------------------------------------------------===//
381 // Mips Operand, Complex Patterns and Transformations Definitions.
382 //===----------------------------------------------------------------------===//
384 def MipsJumpTargetAsmOperand : AsmOperandClass {
385 let Name = "JumpTarget";
386 let ParserMethod = "parseJumpTarget";
387 let PredicateMethod = "isImm";
388 let RenderMethod = "addImmOperands";
391 // Instruction operand types
392 def jmptarget : Operand<OtherVT> {
393 let EncoderMethod = "getJumpTargetOpValue";
394 let ParserMatchClass = MipsJumpTargetAsmOperand;
396 def brtarget : Operand<OtherVT> {
397 let EncoderMethod = "getBranchTargetOpValue";
398 let OperandType = "OPERAND_PCREL";
399 let DecoderMethod = "DecodeBranchTarget";
400 let ParserMatchClass = MipsJumpTargetAsmOperand;
402 def calltarget : Operand<iPTR> {
403 let EncoderMethod = "getJumpTargetOpValue";
404 let ParserMatchClass = MipsJumpTargetAsmOperand;
407 def imm64: Operand<i64>;
409 def simm9 : Operand<i32>;
410 def simm10 : Operand<i32>;
411 def simm11 : Operand<i32>;
413 def simm16 : Operand<i32> {
414 let DecoderMethod= "DecodeSimm16";
417 def simm19_lsl2 : Operand<i32> {
418 let EncoderMethod = "getSimm19Lsl2Encoding";
419 let DecoderMethod = "DecodeSimm19Lsl2";
420 let ParserMatchClass = MipsJumpTargetAsmOperand;
423 def simm18_lsl3 : Operand<i32> {
424 let EncoderMethod = "getSimm18Lsl3Encoding";
425 let DecoderMethod = "DecodeSimm18Lsl3";
426 let ParserMatchClass = MipsJumpTargetAsmOperand;
429 def simm20 : Operand<i32> {
432 def uimm20 : Operand<i32> {
435 def MipsUImm10AsmOperand : AsmOperandClass {
437 let RenderMethod = "addImmOperands";
438 let ParserMethod = "parseImm";
439 let PredicateMethod = "isUImm<10>";
442 def uimm10 : Operand<i32> {
443 let ParserMatchClass = MipsUImm10AsmOperand;
446 def simm16_64 : Operand<i64> {
447 let DecoderMethod = "DecodeSimm16";
451 def uimmz : Operand<i32> {
452 let PrintMethod = "printUnsignedImm";
456 def uimm2 : Operand<i32> {
457 let PrintMethod = "printUnsignedImm";
460 def uimm3 : Operand<i32> {
461 let PrintMethod = "printUnsignedImm";
464 def uimm5 : Operand<i32> {
465 let PrintMethod = "printUnsignedImm";
468 def uimm6 : Operand<i32> {
469 let PrintMethod = "printUnsignedImm";
472 def uimm16 : Operand<i32> {
473 let PrintMethod = "printUnsignedImm";
476 def pcrel16 : Operand<i32> {
479 def MipsMemAsmOperand : AsmOperandClass {
481 let ParserMethod = "parseMemOperand";
484 def MipsMemSimm9AsmOperand : AsmOperandClass {
485 let Name = "MemOffsetSimm9";
486 let SuperClasses = [MipsMemAsmOperand];
487 let RenderMethod = "addMemOperands";
488 let ParserMethod = "parseMemOperand";
489 let PredicateMethod = "isMemWithSimmOffset<9>";
492 def MipsMemSimm9GPRAsmOperand : AsmOperandClass {
493 let Name = "MemOffsetSimm9GPR";
494 let SuperClasses = [MipsMemAsmOperand];
495 let RenderMethod = "addMemOperands";
496 let ParserMethod = "parseMemOperand";
497 let PredicateMethod = "isMemWithSimmOffsetGPR<9>";
500 def MipsMemSimm11AsmOperand : AsmOperandClass {
501 let Name = "MemOffsetSimm11";
502 let SuperClasses = [MipsMemAsmOperand];
503 let RenderMethod = "addMemOperands";
504 let ParserMethod = "parseMemOperand";
505 let PredicateMethod = "isMemWithSimmOffset<11>";
508 def MipsMemSimm16AsmOperand : AsmOperandClass {
509 let Name = "MemOffsetSimm16";
510 let SuperClasses = [MipsMemAsmOperand];
511 let RenderMethod = "addMemOperands";
512 let ParserMethod = "parseMemOperand";
513 let PredicateMethod = "isMemWithSimmOffset<16>";
516 def MipsInvertedImmoperand : AsmOperandClass {
518 let RenderMethod = "addImmOperands";
519 let ParserMethod = "parseInvNum";
522 def InvertedImOperand : Operand<i32> {
523 let ParserMatchClass = MipsInvertedImmoperand;
526 def InvertedImOperand64 : Operand<i64> {
527 let ParserMatchClass = MipsInvertedImmoperand;
530 class mem_generic : Operand<iPTR> {
531 let PrintMethod = "printMemOperand";
532 let MIOperandInfo = (ops ptr_rc, simm16);
533 let EncoderMethod = "getMemEncoding";
534 let ParserMatchClass = MipsMemAsmOperand;
535 let OperandType = "OPERAND_MEMORY";
539 def mem : mem_generic;
541 // MSA specific address operand
542 def mem_msa : mem_generic {
543 let MIOperandInfo = (ops ptr_rc, simm10);
544 let EncoderMethod = "getMSAMemEncoding";
547 def mem_simm9 : mem_generic {
548 let MIOperandInfo = (ops ptr_rc, simm9);
549 let EncoderMethod = "getMemEncoding";
550 let ParserMatchClass = MipsMemSimm9AsmOperand;
553 def mem_simm9gpr : mem_generic {
554 let MIOperandInfo = (ops ptr_rc, simm9);
555 let EncoderMethod = "getMemEncoding";
556 let ParserMatchClass = MipsMemSimm9GPRAsmOperand;
559 def mem_simm11 : mem_generic {
560 let MIOperandInfo = (ops ptr_rc, simm11);
561 let EncoderMethod = "getMemEncoding";
562 let ParserMatchClass = MipsMemSimm11AsmOperand;
565 def mem_simm16 : mem_generic {
566 let MIOperandInfo = (ops ptr_rc, simm16);
567 let EncoderMethod = "getMemEncoding";
568 let ParserMatchClass = MipsMemSimm16AsmOperand;
571 def mem_ea : Operand<iPTR> {
572 let PrintMethod = "printMemOperandEA";
573 let MIOperandInfo = (ops ptr_rc, simm16);
574 let EncoderMethod = "getMemEncoding";
575 let OperandType = "OPERAND_MEMORY";
578 def PtrRC : Operand<iPTR> {
579 let MIOperandInfo = (ops ptr_rc);
580 let DecoderMethod = "DecodePtrRegisterClass";
581 let ParserMatchClass = GPR32AsmOperand;
584 // size operand of ext instruction
585 def size_ext : Operand<i32> {
586 let EncoderMethod = "getSizeExtEncoding";
587 let DecoderMethod = "DecodeExtSize";
590 // size operand of ins instruction
591 def size_ins : Operand<i32> {
592 let EncoderMethod = "getSizeInsEncoding";
593 let DecoderMethod = "DecodeInsSize";
596 // Transformation Function - get the lower 16 bits.
597 def LO16 : SDNodeXForm<imm, [{
598 return getImm(N, N->getZExtValue() & 0xFFFF);
601 // Transformation Function - get the higher 16 bits.
602 def HI16 : SDNodeXForm<imm, [{
603 return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF);
607 def Plus1 : SDNodeXForm<imm, [{ return getImm(N, N->getSExtValue() + 1); }]>;
609 // Node immediate is zero (e.g. insve.d)
610 def immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>;
612 // Node immediate fits as 16-bit sign extended on target immediate.
614 def immSExt8 : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;
616 // Node immediate fits as 16-bit sign extended on target immediate.
618 def immSExt16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;
620 // Node immediate fits as 15-bit sign extended on target immediate.
622 def immSExt15 : PatLeaf<(imm), [{ return isInt<15>(N->getSExtValue()); }]>;
624 // Node immediate fits as 16-bit zero extended on target immediate.
625 // The LO16 param means that only the lower 16 bits of the node
626 // immediate are caught.
628 def immZExt16 : PatLeaf<(imm), [{
629 if (N->getValueType(0) == MVT::i32)
630 return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
632 return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
635 // Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared).
636 def immLow16Zero : PatLeaf<(imm), [{
637 int64_t Val = N->getSExtValue();
638 return isInt<32>(Val) && !(Val & 0xffff);
641 // shamt field must fit in 5 bits.
642 def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
644 // True if (N + 1) fits in 16-bit field.
645 def immSExt16Plus1 : PatLeaf<(imm), [{
646 return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1);
649 // Mips Address Mode! SDNode frameindex could possibily be a match
650 // since load and store instructions from stack used it.
652 ComplexPattern<iPTR, 2, "selectIntAddr", [frameindex]>;
655 ComplexPattern<iPTR, 2, "selectAddrRegImm", [frameindex]>;
658 ComplexPattern<iPTR, 2, "selectAddrRegReg", [frameindex]>;
661 ComplexPattern<iPTR, 2, "selectAddrDefault", [frameindex]>;
663 def addrimm10 : ComplexPattern<iPTR, 2, "selectIntAddrMSA", [frameindex]>;
665 //===----------------------------------------------------------------------===//
666 // Instructions specific format
667 //===----------------------------------------------------------------------===//
669 // Arithmetic and logical instructions with 3 register operands.
670 class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0,
671 InstrItinClass Itin = NoItinerary,
672 SDPatternOperator OpNode = null_frag>:
673 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
674 !strconcat(opstr, "\t$rd, $rs, $rt"),
675 [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> {
676 let isCommutable = isComm;
677 let isReMaterializable = 1;
678 let TwoOperandAliasConstraint = "$rd = $rs";
681 // Arithmetic and logical instructions with 2 register operands.
682 class ArithLogicI<string opstr, Operand Od, RegisterOperand RO,
683 InstrItinClass Itin = NoItinerary,
684 SDPatternOperator imm_type = null_frag,
685 SDPatternOperator OpNode = null_frag> :
686 InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16),
687 !strconcat(opstr, "\t$rt, $rs, $imm16"),
688 [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))],
690 let isReMaterializable = 1;
691 let TwoOperandAliasConstraint = "$rs = $rt";
694 // Arithmetic Multiply ADD/SUB
695 class MArithR<string opstr, InstrItinClass itin, bit isComm = 0> :
696 InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
697 !strconcat(opstr, "\t$rs, $rt"), [], itin, FrmR, opstr> {
698 let Defs = [HI0, LO0];
699 let Uses = [HI0, LO0];
700 let isCommutable = isComm;
704 class LogicNOR<string opstr, RegisterOperand RO>:
705 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
706 !strconcat(opstr, "\t$rd, $rs, $rt"),
707 [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], II_NOR, FrmR, opstr> {
708 let isCommutable = 1;
712 class shift_rotate_imm<string opstr, Operand ImmOpnd,
713 RegisterOperand RO, InstrItinClass itin,
714 SDPatternOperator OpNode = null_frag,
715 SDPatternOperator PF = null_frag> :
716 InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt),
717 !strconcat(opstr, "\t$rd, $rt, $shamt"),
718 [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], itin, FrmR, opstr> {
719 let TwoOperandAliasConstraint = "$rt = $rd";
722 class shift_rotate_reg<string opstr, RegisterOperand RO, InstrItinClass itin,
723 SDPatternOperator OpNode = null_frag>:
724 InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs),
725 !strconcat(opstr, "\t$rd, $rt, $rs"),
726 [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], itin, FrmR,
729 // Load Upper Immediate
730 class LoadUpper<string opstr, RegisterOperand RO, Operand Imm>:
731 InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"),
732 [], II_LUI, FrmI, opstr>, IsAsCheapAsAMove {
733 let hasSideEffects = 0;
734 let isReMaterializable = 1;
738 class Load<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
739 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
740 InstSE<(outs RO:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
741 [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> {
742 let DecoderMethod = "DecodeMem";
743 let canFoldAsLoad = 1;
747 class StoreMemory<string opstr, DAGOperand RO, DAGOperand MO,
748 SDPatternOperator OpNode = null_frag,
749 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
750 InstSE<(outs), (ins RO:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
751 [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> {
752 let DecoderMethod = "DecodeMem";
756 class Store<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
757 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
758 StoreMemory<opstr, RO, mem, OpNode, Itin, Addr>;
760 // Load/Store Left/Right
761 let canFoldAsLoad = 1 in
762 class LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
763 InstrItinClass Itin> :
764 InstSE<(outs RO:$rt), (ins mem:$addr, RO:$src),
765 !strconcat(opstr, "\t$rt, $addr"),
766 [(set RO:$rt, (OpNode addr:$addr, RO:$src))], Itin, FrmI> {
767 let DecoderMethod = "DecodeMem";
768 string Constraints = "$src = $rt";
771 class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
772 InstrItinClass Itin> :
773 InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
774 [(OpNode RO:$rt, addr:$addr)], Itin, FrmI> {
775 let DecoderMethod = "DecodeMem";
779 class LW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
780 SDPatternOperator OpNode= null_frag> :
781 InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
782 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
783 let DecoderMethod = "DecodeFMem2";
787 class SW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
788 SDPatternOperator OpNode= null_frag> :
789 InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
790 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
791 let DecoderMethod = "DecodeFMem2";
796 class LW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
797 SDPatternOperator OpNode= null_frag> :
798 InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
799 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
800 let DecoderMethod = "DecodeFMem3";
804 class SW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
805 SDPatternOperator OpNode= null_frag> :
806 InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
807 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
808 let DecoderMethod = "DecodeFMem3";
812 // Conditional Branch
813 class CBranch<string opstr, DAGOperand opnd, PatFrag cond_op,
814 RegisterOperand RO, bit DelaySlot = 1> :
815 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
816 !strconcat(opstr, "\t$rs, $rt, $offset"),
817 [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], II_BCC,
820 let isTerminator = 1;
821 let hasDelaySlot = DelaySlot;
825 class CBranchZero<string opstr, DAGOperand opnd, PatFrag cond_op,
826 RegisterOperand RO, bit DelaySlot = 1> :
827 InstSE<(outs), (ins RO:$rs, opnd:$offset),
828 !strconcat(opstr, "\t$rs, $offset"),
829 [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], II_BCCZ,
832 let isTerminator = 1;
833 let hasDelaySlot = DelaySlot;
838 class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> :
839 InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt),
840 !strconcat(opstr, "\t$rd, $rs, $rt"),
841 [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))],
842 II_SLT_SLTU, FrmR, opstr>;
844 class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
846 InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16),
847 !strconcat(opstr, "\t$rt, $rs, $imm16"),
848 [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))],
849 II_SLTI_SLTIU, FrmI, opstr>;
852 class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
853 SDPatternOperator targetoperator, string bopstr> :
854 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
855 [(operator targetoperator:$target)], II_J, FrmJ, bopstr> {
858 let hasDelaySlot = 1;
859 let DecoderMethod = "DecodeJumpTarget";
863 // Unconditional branch
864 class UncondBranch<Instruction BEQInst> :
865 PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], II_B>,
866 PseudoInstExpansion<(BEQInst ZERO, ZERO, brtarget:$offset)> {
868 let isTerminator = 1;
870 let hasDelaySlot = 1;
871 let AdditionalPredicates = [RelocPIC];
875 // Base class for indirect branch and return instruction classes.
876 let isTerminator=1, isBarrier=1, hasDelaySlot = 1 in
877 class JumpFR<string opstr, RegisterOperand RO,
878 SDPatternOperator operator = null_frag>:
879 InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], II_JR,
883 class IndirectBranch<string opstr, RegisterOperand RO> : JumpFR<opstr, RO> {
885 let isIndirectBranch = 1;
888 // Jump and Link (Call)
889 let isCall=1, hasDelaySlot=1, Defs = [RA] in {
890 class JumpLink<string opstr, DAGOperand opnd> :
891 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
892 [(MipsJmpLink imm:$target)], II_JAL, FrmJ, opstr> {
893 let DecoderMethod = "DecodeJumpTarget";
896 class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst,
897 Register RetReg, RegisterOperand ResRO = RO>:
898 PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], II_JALR>,
899 PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)>;
901 class JumpLinkReg<string opstr, RegisterOperand RO>:
902 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
903 [], II_JALR, FrmR, opstr>;
905 class BGEZAL_FT<string opstr, DAGOperand opnd,
906 RegisterOperand RO, bit DelaySlot = 1> :
907 InstSE<(outs), (ins RO:$rs, opnd:$offset),
908 !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZAL, FrmI, opstr> {
909 let hasDelaySlot = DelaySlot;
914 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
915 hasExtraSrcRegAllocReq = 1, Defs = [AT] in {
916 class TailCall<Instruction JumpInst> :
917 PseudoSE<(outs), (ins calltarget:$target), [], II_J>,
918 PseudoInstExpansion<(JumpInst jmptarget:$target)>;
920 class TailCallReg<RegisterOperand RO, Instruction JRInst,
921 RegisterOperand ResRO = RO> :
922 PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>,
923 PseudoInstExpansion<(JRInst ResRO:$rs)>;
926 class BAL_BR_Pseudo<Instruction RealInst> :
927 PseudoSE<(outs), (ins brtarget:$offset), [], II_BCCZAL>,
928 PseudoInstExpansion<(RealInst ZERO, brtarget:$offset)> {
930 let isTerminator = 1;
932 let hasDelaySlot = 1;
937 class SYS_FT<string opstr> :
938 InstSE<(outs), (ins uimm20:$code_),
939 !strconcat(opstr, "\t$code_"), [], NoItinerary, FrmI, opstr>;
941 class BRK_FT<string opstr> :
942 InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
943 !strconcat(opstr, "\t$code_1, $code_2"), [], NoItinerary,
947 class ER_FT<string opstr> :
948 InstSE<(outs), (ins),
949 opstr, [], NoItinerary, FrmOther, opstr>;
952 class DEI_FT<string opstr, RegisterOperand RO> :
953 InstSE<(outs RO:$rt), (ins),
954 !strconcat(opstr, "\t$rt"), [], NoItinerary, FrmOther, opstr>;
957 class WAIT_FT<string opstr> :
958 InstSE<(outs), (ins), opstr, [], NoItinerary, FrmOther, opstr>;
961 let hasSideEffects = 1 in
962 class SYNC_FT<string opstr> :
963 InstSE<(outs), (ins i32imm:$stype), "sync $stype", [(MipsSync imm:$stype)],
964 NoItinerary, FrmOther, opstr>;
966 class SYNCI_FT<string opstr> :
967 InstSE<(outs), (ins mem_simm16:$addr), !strconcat(opstr, "\t$addr"), [],
968 NoItinerary, FrmOther, opstr> {
969 let hasSideEffects = 1;
970 let DecoderMethod = "DecodeSyncI";
973 let hasSideEffects = 1 in
974 class TEQ_FT<string opstr, RegisterOperand RO> :
975 InstSE<(outs), (ins RO:$rs, RO:$rt, uimm16:$code_),
976 !strconcat(opstr, "\t$rs, $rt, $code_"), [], NoItinerary,
979 class TEQI_FT<string opstr, RegisterOperand RO> :
980 InstSE<(outs), (ins RO:$rs, uimm16:$imm16),
981 !strconcat(opstr, "\t$rs, $imm16"), [], NoItinerary, FrmOther, opstr>;
983 class Mult<string opstr, InstrItinClass itin, RegisterOperand RO,
984 list<Register> DefRegs> :
985 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [],
987 let isCommutable = 1;
989 let hasSideEffects = 0;
992 // Pseudo multiply/divide instruction with explicit accumulator register
994 class MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1,
995 SDPatternOperator OpNode, InstrItinClass Itin,
996 bit IsComm = 1, bit HasSideEffects = 0,
997 bit UsesCustomInserter = 0> :
998 PseudoSE<(outs R0:$ac), (ins R1:$rs, R1:$rt),
999 [(set R0:$ac, (OpNode R1:$rs, R1:$rt))], Itin>,
1000 PseudoInstExpansion<(RealInst R1:$rs, R1:$rt)> {
1001 let isCommutable = IsComm;
1002 let hasSideEffects = HasSideEffects;
1003 let usesCustomInserter = UsesCustomInserter;
1006 // Pseudo multiply add/sub instruction with explicit accumulator register
1008 class MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode,
1009 InstrItinClass itin>
1010 : PseudoSE<(outs ACC64:$ac),
1011 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin),
1013 (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))],
1015 PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> {
1016 string Constraints = "$acin = $ac";
1019 class Div<string opstr, InstrItinClass itin, RegisterOperand RO,
1020 list<Register> DefRegs> :
1021 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$$zero, $rs, $rt"),
1022 [], itin, FrmR, opstr> {
1027 class PseudoMFLOHI<RegisterClass DstRC, RegisterClass SrcRC, SDNode OpNode>
1028 : PseudoSE<(outs DstRC:$rd), (ins SrcRC:$hilo),
1029 [(set DstRC:$rd, (OpNode SrcRC:$hilo))], II_MFHI_MFLO>;
1031 class MoveFromLOHI<string opstr, RegisterOperand RO, Register UseReg>:
1032 InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO,
1034 let Uses = [UseReg];
1035 let hasSideEffects = 0;
1038 class PseudoMTLOHI<RegisterClass DstRC, RegisterClass SrcRC>
1039 : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi),
1040 [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))],
1043 class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>:
1044 InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO,
1047 let hasSideEffects = 0;
1050 class EffectiveAddress<string opstr, RegisterOperand RO> :
1051 InstSE<(outs RO:$rt), (ins mem_ea:$addr), !strconcat(opstr, "\t$rt, $addr"),
1052 [(set RO:$rt, addr:$addr)], NoItinerary, FrmI,
1053 !strconcat(opstr, "_lea")> {
1054 let isCodeGenOnly = 1;
1055 let DecoderMethod = "DecodeMem";
1058 // Count Leading Ones/Zeros in Word
1059 class CountLeading0<string opstr, RegisterOperand RO>:
1060 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1061 [(set RO:$rd, (ctlz RO:$rs))], II_CLZ, FrmR, opstr>;
1063 class CountLeading1<string opstr, RegisterOperand RO>:
1064 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1065 [(set RO:$rd, (ctlz (not RO:$rs)))], II_CLO, FrmR, opstr>;
1067 // Sign Extend in Register.
1068 class SignExtInReg<string opstr, ValueType vt, RegisterOperand RO,
1069 InstrItinClass itin> :
1070 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"),
1071 [(set RO:$rd, (sext_inreg RO:$rt, vt))], itin, FrmR, opstr>;
1074 class SubwordSwap<string opstr, RegisterOperand RO,
1075 InstrItinClass itin = NoItinerary>:
1076 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [], itin,
1078 let hasSideEffects = 0;
1082 class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> :
1083 InstSE<(outs CPURegOperand:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [],
1084 II_RDHWR, FrmR, "rdhwr">;
1087 class ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1088 SDPatternOperator Op = null_frag>:
1089 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, size_ext:$size),
1090 !strconcat(opstr, " $rt, $rs, $pos, $size"),
1091 [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size))], II_EXT,
1092 FrmR, opstr>, ISA_MIPS32R2;
1094 class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1095 SDPatternOperator Op = null_frag>:
1096 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, size_ins:$size, RO:$src),
1097 !strconcat(opstr, " $rt, $rs, $pos, $size"),
1098 [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size, RO:$src))],
1099 II_INS, FrmR, opstr>, ISA_MIPS32R2 {
1100 let Constraints = "$src = $rt";
1103 // Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*).
1104 class Atomic2Ops<PatFrag Op, RegisterClass DRC> :
1105 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr),
1106 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]>;
1108 // Atomic Compare & Swap.
1109 class AtomicCmpSwap<PatFrag Op, RegisterClass DRC> :
1110 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap),
1111 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]>;
1113 class LLBase<string opstr, RegisterOperand RO> :
1114 InstSE<(outs RO:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1115 [], NoItinerary, FrmI> {
1116 let DecoderMethod = "DecodeMem";
1120 class SCBase<string opstr, RegisterOperand RO> :
1121 InstSE<(outs RO:$dst), (ins RO:$rt, mem:$addr),
1122 !strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> {
1123 let DecoderMethod = "DecodeMem";
1125 let Constraints = "$rt = $dst";
1128 class MFC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD> :
1129 InstSE<(outs RO:$rt), (ins RD:$rd, uimm16:$sel),
1130 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], NoItinerary, FrmFR>;
1132 class MTC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD> :
1133 InstSE<(outs RO:$rd), (ins RD:$rt, uimm16:$sel),
1134 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], NoItinerary, FrmFR>;
1136 class TrapBase<Instruction RealInst>
1137 : PseudoSE<(outs), (ins), [(trap)], NoItinerary>,
1138 PseudoInstExpansion<(RealInst 0, 0)> {
1140 let isTerminator = 1;
1141 let isCodeGenOnly = 1;
1144 //===----------------------------------------------------------------------===//
1145 // Pseudo instructions
1146 //===----------------------------------------------------------------------===//
1149 let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1 in
1150 def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
1152 let isReturn=1, isTerminator=1, isBarrier=1, hasCtrlDep=1, hasSideEffects=1 in
1153 def ERet : PseudoSE<(outs), (ins), [(MipsERet)]>;
1155 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
1156 def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt),
1157 [(callseq_start timm:$amt)]>;
1158 def ADJCALLSTACKUP : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1159 [(callseq_end timm:$amt1, timm:$amt2)]>;
1162 let usesCustomInserter = 1 in {
1163 def ATOMIC_LOAD_ADD_I8 : Atomic2Ops<atomic_load_add_8, GPR32>;
1164 def ATOMIC_LOAD_ADD_I16 : Atomic2Ops<atomic_load_add_16, GPR32>;
1165 def ATOMIC_LOAD_ADD_I32 : Atomic2Ops<atomic_load_add_32, GPR32>;
1166 def ATOMIC_LOAD_SUB_I8 : Atomic2Ops<atomic_load_sub_8, GPR32>;
1167 def ATOMIC_LOAD_SUB_I16 : Atomic2Ops<atomic_load_sub_16, GPR32>;
1168 def ATOMIC_LOAD_SUB_I32 : Atomic2Ops<atomic_load_sub_32, GPR32>;
1169 def ATOMIC_LOAD_AND_I8 : Atomic2Ops<atomic_load_and_8, GPR32>;
1170 def ATOMIC_LOAD_AND_I16 : Atomic2Ops<atomic_load_and_16, GPR32>;
1171 def ATOMIC_LOAD_AND_I32 : Atomic2Ops<atomic_load_and_32, GPR32>;
1172 def ATOMIC_LOAD_OR_I8 : Atomic2Ops<atomic_load_or_8, GPR32>;
1173 def ATOMIC_LOAD_OR_I16 : Atomic2Ops<atomic_load_or_16, GPR32>;
1174 def ATOMIC_LOAD_OR_I32 : Atomic2Ops<atomic_load_or_32, GPR32>;
1175 def ATOMIC_LOAD_XOR_I8 : Atomic2Ops<atomic_load_xor_8, GPR32>;
1176 def ATOMIC_LOAD_XOR_I16 : Atomic2Ops<atomic_load_xor_16, GPR32>;
1177 def ATOMIC_LOAD_XOR_I32 : Atomic2Ops<atomic_load_xor_32, GPR32>;
1178 def ATOMIC_LOAD_NAND_I8 : Atomic2Ops<atomic_load_nand_8, GPR32>;
1179 def ATOMIC_LOAD_NAND_I16 : Atomic2Ops<atomic_load_nand_16, GPR32>;
1180 def ATOMIC_LOAD_NAND_I32 : Atomic2Ops<atomic_load_nand_32, GPR32>;
1182 def ATOMIC_SWAP_I8 : Atomic2Ops<atomic_swap_8, GPR32>;
1183 def ATOMIC_SWAP_I16 : Atomic2Ops<atomic_swap_16, GPR32>;
1184 def ATOMIC_SWAP_I32 : Atomic2Ops<atomic_swap_32, GPR32>;
1186 def ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap<atomic_cmp_swap_8, GPR32>;
1187 def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap<atomic_cmp_swap_16, GPR32>;
1188 def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_32, GPR32>;
1191 /// Pseudo instructions for loading and storing accumulator registers.
1192 let isPseudo = 1, isCodeGenOnly = 1 in {
1193 def LOAD_ACC64 : Load<"", ACC64>;
1194 def STORE_ACC64 : Store<"", ACC64>;
1197 // We need these two pseudo instructions to avoid offset calculation for long
1198 // branches. See the comment in file MipsLongBranch.cpp for detailed
1201 // Expands to: lui $dst, %hi($tgt - $baltgt)
1202 def LONG_BRANCH_LUi : PseudoSE<(outs GPR32Opnd:$dst),
1203 (ins brtarget:$tgt, brtarget:$baltgt), []>;
1205 // Expands to: addiu $dst, $src, %lo($tgt - $baltgt)
1206 def LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst),
1207 (ins GPR32Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []>;
1209 //===----------------------------------------------------------------------===//
1210 // Instruction definition
1211 //===----------------------------------------------------------------------===//
1212 //===----------------------------------------------------------------------===//
1213 // MipsI Instructions
1214 //===----------------------------------------------------------------------===//
1216 /// Arithmetic Instructions (ALU Immediate)
1217 let AdditionalPredicates = [NotInMicroMips] in {
1218 def ADDiu : MMRel, StdMMR6Rel, ArithLogicI<"addiu", simm16, GPR32Opnd,
1219 II_ADDIU, immSExt16, add>,
1220 ADDI_FM<0x9>, IsAsCheapAsAMove;
1222 def ADDi : MMRel, ArithLogicI<"addi", simm16, GPR32Opnd>, ADDI_FM<0x8>,
1223 ISA_MIPS1_NOT_32R6_64R6;
1224 def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
1226 def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
1228 let AdditionalPredicates = [NotInMicroMips] in {
1229 def ANDi : MMRel, StdMMR6Rel,
1230 ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16, and>,
1233 def ORi : MMRel, StdMMR6Rel,
1234 ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16, or>,
1236 def XORi : MMRel, StdMMR6Rel,
1237 ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16, xor>,
1239 def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16>, LUI_FM;
1240 let AdditionalPredicates = [NotInMicroMips] in {
1241 /// Arithmetic Instructions (3-Operand, R-Type)
1242 def ADDu : MMRel, StdMMR6Rel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
1244 def SUBu : MMRel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
1247 let Defs = [HI0, LO0] in
1248 def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>,
1249 ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6;
1250 def ADD : MMRel, StdMMR6Rel, ArithLogicR<"add", GPR32Opnd>, ADD_FM<0, 0x20>;
1251 def SUB : MMRel, ArithLogicR<"sub", GPR32Opnd>, ADD_FM<0, 0x22>;
1252 def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>;
1253 def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>;
1254 let AdditionalPredicates = [NotInMicroMips] in {
1255 def AND : MMRel, StdMMR6Rel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
1257 def OR : MMRel, StdMMR6Rel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
1259 def XOR : MMRel, StdMMR6Rel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
1262 def NOR : MMRel, StdMMR6Rel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>;
1264 /// Shift Instructions
1265 let AdditionalPredicates = [NotInMicroMips] in {
1266 def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl,
1267 immZExt5>, SRA_FM<0, 0>;
1268 def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl,
1269 immZExt5>, SRA_FM<2, 0>;
1271 def SRA : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, sra,
1272 immZExt5>, SRA_FM<3, 0>;
1273 def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, shl>,
1275 def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, srl>,
1277 def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, sra>,
1280 // Rotate Instructions
1281 def ROTR : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr,
1283 SRA_FM<2, 1>, ISA_MIPS32R2;
1284 def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>,
1285 SRLV_FM<6, 1>, ISA_MIPS32R2;
1287 /// Load and Store Instructions
1289 def LB : Load<"lb", GPR32Opnd, sextloadi8, II_LB>, MMRel, LW_FM<0x20>;
1290 def LBu : Load<"lbu", GPR32Opnd, zextloadi8, II_LBU, addrDefault>, MMRel,
1292 def LH : Load<"lh", GPR32Opnd, sextloadi16, II_LH, addrDefault>, MMRel,
1294 def LHu : Load<"lhu", GPR32Opnd, zextloadi16, II_LHU>, MMRel, LW_FM<0x25>;
1295 let AdditionalPredicates = [NotInMicroMips] in {
1296 def LW : StdMMR6Rel, Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel,
1299 def SB : StdMMR6Rel, Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel,
1301 def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>;
1302 let AdditionalPredicates = [NotInMicroMips] in {
1303 def SW : Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>;
1306 /// load/store left/right
1307 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1308 AdditionalPredicates = [NotInMicroMips] in {
1309 def LWL : LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>,
1310 ISA_MIPS1_NOT_32R6_64R6;
1311 def LWR : LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>,
1312 ISA_MIPS1_NOT_32R6_64R6;
1313 def SWL : StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>,
1314 ISA_MIPS1_NOT_32R6_64R6;
1315 def SWR : StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>,
1316 ISA_MIPS1_NOT_32R6_64R6;
1319 let AdditionalPredicates = [NotInMicroMips] in {
1320 // COP2 Memory Instructions
1321 def LWC2 : LW_FT2<"lwc2", COP2Opnd, NoItinerary, load>, LW_FM<0x32>,
1322 ISA_MIPS1_NOT_32R6_64R6;
1323 def SWC2 : SW_FT2<"swc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3a>,
1324 ISA_MIPS1_NOT_32R6_64R6;
1325 def LDC2 : LW_FT2<"ldc2", COP2Opnd, NoItinerary, load>, LW_FM<0x36>,
1326 ISA_MIPS2_NOT_32R6_64R6;
1327 def SDC2 : SW_FT2<"sdc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3e>,
1328 ISA_MIPS2_NOT_32R6_64R6;
1330 // COP3 Memory Instructions
1331 let DecoderNamespace = "COP3_" in {
1332 def LWC3 : LW_FT3<"lwc3", COP3Opnd, NoItinerary, load>, LW_FM<0x33>;
1333 def SWC3 : SW_FT3<"swc3", COP3Opnd, NoItinerary, store>, LW_FM<0x3b>;
1334 def LDC3 : LW_FT3<"ldc3", COP3Opnd, NoItinerary, load>, LW_FM<0x37>,
1336 def SDC3 : SW_FT3<"sdc3", COP3Opnd, NoItinerary, store>, LW_FM<0x3f>,
1341 def SYNC : MMRel, StdMMR6Rel, SYNC_FT<"sync">, SYNC_FM, ISA_MIPS32;
1342 def SYNCI : MMRel, StdMMR6Rel, SYNCI_FT<"synci">, SYNCI_FM, ISA_MIPS32R2;
1344 let AdditionalPredicates = [NotInMicroMips] in {
1345 def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM<0x34>, ISA_MIPS2;
1346 def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM<0x30>, ISA_MIPS2;
1347 def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd>, TEQ_FM<0x31>, ISA_MIPS2;
1348 def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd>, TEQ_FM<0x32>, ISA_MIPS2;
1349 def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd>, TEQ_FM<0x33>, ISA_MIPS2;
1350 def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd>, TEQ_FM<0x36>, ISA_MIPS2;
1353 def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd>, TEQI_FM<0xc>,
1354 ISA_MIPS2_NOT_32R6_64R6;
1355 def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd>, TEQI_FM<0x8>,
1356 ISA_MIPS2_NOT_32R6_64R6;
1357 def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd>, TEQI_FM<0x9>,
1358 ISA_MIPS2_NOT_32R6_64R6;
1359 def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd>, TEQI_FM<0xa>,
1360 ISA_MIPS2_NOT_32R6_64R6;
1361 def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd>, TEQI_FM<0xb>,
1362 ISA_MIPS2_NOT_32R6_64R6;
1363 def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd>, TEQI_FM<0xe>,
1364 ISA_MIPS2_NOT_32R6_64R6;
1366 let AdditionalPredicates = [NotInMicroMips] in {
1367 def BREAK : MMRel, StdMMR6Rel, BRK_FT<"break">, BRK_FM<0xd>;
1369 def SYSCALL : MMRel, SYS_FT<"syscall">, SYS_FM<0xc>;
1370 def TRAP : TrapBase<BREAK>;
1371 def SDBBP : MMRel, SYS_FT<"sdbbp">, SDBBP_FM, ISA_MIPS32_NOT_32R6_64R6;
1373 let AdditionalPredicates = [NotInMicroMips] in {
1374 def ERET : MMRel, ER_FT<"eret">, ER_FM<0x18, 0x0>, INSN_MIPS3_32;
1375 def ERETNC : MMRel, ER_FT<"eretnc">, ER_FM<0x18, 0x1>, ISA_MIPS32R5;
1377 def DERET : MMRel, ER_FT<"deret">, ER_FM<0x1f, 0x0>, ISA_MIPS32;
1379 let AdditionalPredicates = [NotInMicroMips] in {
1380 def EI : MMRel, StdMMR6Rel, DEI_FT<"ei", GPR32Opnd>, EI_FM<1>, ISA_MIPS32R2;
1382 def DI : MMRel, DEI_FT<"di", GPR32Opnd>, EI_FM<0>, ISA_MIPS32R2;
1384 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1385 AdditionalPredicates = [NotInMicroMips] in {
1386 def WAIT : WAIT_FT<"wait">, WAIT_FM;
1388 /// Load-linked, Store-conditional
1389 def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, ISA_MIPS2_NOT_32R6_64R6;
1390 def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, ISA_MIPS2_NOT_32R6_64R6;
1393 /// Jump and Branch Instructions
1394 def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
1395 AdditionalRequires<[RelocStatic]>, IsBranch;
1396 def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>;
1397 def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>;
1398 def BEQL : MMRel, CBranch<"beql", brtarget, seteq, GPR32Opnd, 0>,
1399 BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6;
1400 def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>;
1401 def BNEL : MMRel, CBranch<"bnel", brtarget, setne, GPR32Opnd, 0>,
1402 BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6;
1403 def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
1405 def BGEZL : MMRel, CBranchZero<"bgezl", brtarget, setge, GPR32Opnd, 0>,
1406 BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6;
1407 def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
1409 def BGTZL : MMRel, CBranchZero<"bgtzl", brtarget, setgt, GPR32Opnd, 0>,
1410 BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6;
1411 def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
1413 def BLEZL : MMRel, CBranchZero<"blezl", brtarget, setle, GPR32Opnd, 0>,
1414 BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6;
1415 def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
1417 def BLTZL : MMRel, CBranchZero<"bltzl", brtarget, setlt, GPR32Opnd, 0>,
1418 BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6;
1419 def B : UncondBranch<BEQ>;
1421 def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>;
1422 let AdditionalPredicates = [NotInMicroMips] in {
1423 def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM;
1424 def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>;
1427 def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>,
1428 ISA_MIPS32_NOT_32R6_64R6;
1429 def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>,
1430 ISA_MIPS1_NOT_32R6_64R6;
1431 def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd, 0>,
1432 BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6;
1433 def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>,
1434 ISA_MIPS1_NOT_32R6_64R6;
1435 def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd, 0>,
1436 BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6;
1437 def BAL_BR : BAL_BR_Pseudo<BGEZAL>;
1438 def TAILCALL : TailCall<J>;
1439 def TAILCALL_R : TailCallReg<GPR32Opnd, JR>;
1441 // Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64
1442 // then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA.
1443 class PseudoIndirectBranchBase<RegisterOperand RO> :
1444 MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)],
1445 II_IndirectBranchPseudo> {
1448 let hasDelaySlot = 1;
1450 let isIndirectBranch = 1;
1453 def PseudoIndirectBranch : PseudoIndirectBranchBase<GPR32Opnd>;
1455 // Return instructions are matched as a RetRA instruction, then are expanded
1456 // into PseudoReturn/PseudoReturn64 after register allocation. Finally,
1457 // MipsAsmPrinter expands this into JR, JR64, JALR, or JALR64 depending on the
1459 class PseudoReturnBase<RegisterOperand RO> : MipsPseudo<(outs), (ins RO:$rs),
1460 [], II_ReturnPseudo> {
1461 let isTerminator = 1;
1463 let hasDelaySlot = 1;
1465 let isCodeGenOnly = 1;
1467 let hasExtraSrcRegAllocReq = 1;
1470 def PseudoReturn : PseudoReturnBase<GPR32Opnd>;
1472 // Exception handling related node and instructions.
1473 // The conversion sequence is:
1474 // ISD::EH_RETURN -> MipsISD::EH_RETURN ->
1475 // MIPSeh_return -> (stack change + indirect branch)
1477 // MIPSeh_return takes the place of regular return instruction
1478 // but takes two arguments (V1, V0) which are used for storing
1479 // the offset and return address respectively.
1480 def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
1482 def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
1483 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
1485 let Uses = [V0, V1], isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1486 def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
1487 [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
1488 def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff,
1490 [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
1493 /// Multiply and Divide Instructions.
1494 def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
1495 MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6;
1496 def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
1497 MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6;
1498 def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
1499 MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6;
1500 def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
1501 MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6;
1503 def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>,
1504 ISA_MIPS1_NOT_32R6_64R6;
1505 def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>,
1506 ISA_MIPS1_NOT_32R6_64R6;
1507 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1508 AdditionalPredicates = [NotInMicroMips] in {
1509 def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>,
1510 ISA_MIPS1_NOT_32R6_64R6;
1511 def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>,
1512 ISA_MIPS1_NOT_32R6_64R6;
1515 /// Sign Ext In Register Instructions.
1516 def SEB : MMRel, StdMMR6Rel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,
1517 SEB_FM<0x10, 0x20>, ISA_MIPS32R2;
1518 def SEH : MMRel, StdMMR6Rel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
1519 SEB_FM<0x18, 0x20>, ISA_MIPS32R2;
1522 def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd>, CLO_FM<0x20>,
1523 ISA_MIPS32_NOT_32R6_64R6;
1524 def CLO : MMRel, CountLeading1<"clo", GPR32Opnd>, CLO_FM<0x21>,
1525 ISA_MIPS32_NOT_32R6_64R6;
1527 let AdditionalPredicates = [NotInMicroMips] in {
1528 /// Word Swap Bytes Within Halfwords
1529 def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd, II_WSBH>, SEB_FM<2, 0x20>,
1534 def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>;
1536 // FrameIndexes are legalized when they are operands from load/store
1537 // instructions. The same not happens for stack address copies, so an
1538 // add op with mem ComplexPattern is used and the stack address copy
1539 // can be matched. It's similar to Sparc LEA_ADDRi
1540 def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>;
1543 def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>,
1544 ISA_MIPS32_NOT_32R6_64R6;
1545 def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>,
1546 ISA_MIPS32_NOT_32R6_64R6;
1547 def MSUB : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>,
1548 ISA_MIPS32_NOT_32R6_64R6;
1549 def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>,
1550 ISA_MIPS32_NOT_32R6_64R6;
1552 let AdditionalPredicates = [NotDSP] in {
1553 def PseudoMULT : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>,
1554 ISA_MIPS1_NOT_32R6_64R6;
1555 def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>,
1556 ISA_MIPS1_NOT_32R6_64R6;
1557 def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>, ISA_MIPS1_NOT_32R6_64R6;
1558 def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>, ISA_MIPS1_NOT_32R6_64R6;
1559 def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>, ISA_MIPS1_NOT_32R6_64R6;
1560 def PseudoMADD : MAddSubPseudo<MADD, MipsMAdd, II_MADD>,
1561 ISA_MIPS32_NOT_32R6_64R6;
1562 def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>,
1563 ISA_MIPS32_NOT_32R6_64R6;
1564 def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>,
1565 ISA_MIPS32_NOT_32R6_64R6;
1566 def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>,
1567 ISA_MIPS32_NOT_32R6_64R6;
1570 def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV,
1571 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
1572 def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU,
1573 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
1574 let AdditionalPredicates = [NotInMicroMips] in {
1575 def RDHWR : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM;
1577 def EXT : MMRel, ExtBase<"ext", GPR32Opnd, uimm5, MipsExt>, EXT_FM<0>;
1578 def INS : MMRel, InsBase<"ins", GPR32Opnd, uimm5, MipsIns>, EXT_FM<4>;
1580 /// Move Control Registers From/To CPU Registers
1581 def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd>, MFC3OP_FM<0x10, 0>, ISA_MIPS32;
1582 def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd>, MFC3OP_FM<0x10, 4>, ISA_MIPS32;
1583 def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd>, MFC3OP_FM<0x12, 0>;
1584 def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd>, MFC3OP_FM<0x12, 4>;
1586 class Barrier<string asmstr> : InstSE<(outs), (ins), asmstr, [], NoItinerary,
1588 def SSNOP : MMRel, StdMMR6Rel, Barrier<"ssnop">, BARRIER_FM<1>;
1589 def EHB : MMRel, Barrier<"ehb">, BARRIER_FM<3>;
1590 def PAUSE : MMRel, StdMMR6Rel, Barrier<"pause">, BARRIER_FM<5>, ISA_MIPS32R2;
1592 // JR_HB and JALR_HB are defined here using the new style naming
1593 // scheme because some of this code is shared with Mips32r6InstrInfo.td
1594 // and because of that it doesn't follow the naming convention of the
1595 // rest of the file. To avoid a mixture of old vs new style, the new
1596 // style was chosen.
1597 class JR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
1598 dag OutOperandList = (outs);
1599 dag InOperandList = (ins GPROpnd:$rs);
1600 string AsmString = !strconcat(instr_asm, "\t$rs");
1601 list<dag> Pattern = [];
1604 class JALR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
1605 dag OutOperandList = (outs GPROpnd:$rd);
1606 dag InOperandList = (ins GPROpnd:$rs);
1607 string AsmString = !strconcat(instr_asm, "\t$rd, $rs");
1608 list<dag> Pattern = [];
1611 class JR_HB_DESC : InstSE<(outs), (ins), "", [], NoItinerary, FrmJ>,
1612 JR_HB_DESC_BASE<"jr.hb", GPR32Opnd> {
1614 let isIndirectBranch=1;
1620 class JALR_HB_DESC : InstSE<(outs), (ins), "", [], NoItinerary, FrmJ>,
1621 JALR_HB_DESC_BASE<"jalr.hb", GPR32Opnd> {
1622 let isIndirectBranch=1;
1626 class JR_HB_ENC : JR_HB_FM<8>;
1627 class JALR_HB_ENC : JALR_HB_FM<9>;
1629 def JR_HB : JR_HB_DESC, JR_HB_ENC, ISA_MIPS32_NOT_32R6_64R6;
1630 def JALR_HB : JALR_HB_DESC, JALR_HB_ENC, ISA_MIPS32;
1632 class TLB<string asmstr> : InstSE<(outs), (ins), asmstr, [], NoItinerary,
1634 def TLBP : MMRel, TLB<"tlbp">, COP0_TLB_FM<0x08>;
1635 def TLBR : MMRel, TLB<"tlbr">, COP0_TLB_FM<0x01>;
1636 def TLBWI : MMRel, TLB<"tlbwi">, COP0_TLB_FM<0x02>;
1637 def TLBWR : MMRel, TLB<"tlbwr">, COP0_TLB_FM<0x06>;
1639 class CacheOp<string instr_asm, Operand MemOpnd> :
1640 InstSE<(outs), (ins MemOpnd:$addr, uimm5:$hint),
1641 !strconcat(instr_asm, "\t$hint, $addr"), [], NoItinerary, FrmOther,
1643 let DecoderMethod = "DecodeCacheOp";
1646 def CACHE : MMRel, CacheOp<"cache", mem>, CACHEOP_FM<0b101111>,
1647 INSN_MIPS3_32_NOT_32R6_64R6;
1648 def PREF : MMRel, CacheOp<"pref", mem>, CACHEOP_FM<0b110011>,
1649 INSN_MIPS3_32_NOT_32R6_64R6;
1651 //===----------------------------------------------------------------------===//
1652 // Instruction aliases
1653 //===----------------------------------------------------------------------===//
1654 def : MipsInstAlias<"move $dst, $src",
1655 (OR GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
1657 let AdditionalPredicates = [NotInMicroMips];
1659 def : MipsInstAlias<"move $dst, $src",
1660 (ADDu GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
1662 let AdditionalPredicates = [NotInMicroMips];
1664 def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>,
1665 ISA_MIPS1_NOT_32R6_64R6;
1666 def : MipsInstAlias<"addu $rs, $rt, $imm",
1667 (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1668 def : MipsInstAlias<"addu $rs, $imm",
1669 (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>;
1670 def : MipsInstAlias<"add $rs, $rt, $imm",
1671 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>,
1672 ISA_MIPS1_NOT_32R6_64R6;
1673 def : MipsInstAlias<"add $rs, $imm",
1674 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>,
1675 ISA_MIPS1_NOT_32R6_64R6;
1676 def : MipsInstAlias<"and $rs, $rt, $imm",
1677 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1678 def : MipsInstAlias<"and $rs, $imm",
1679 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>;
1680 def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>;
1681 let Predicates = [NotInMicroMips] in {
1682 def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
1684 def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>, ISA_MIPS32;
1685 def : MipsInstAlias<"not $rt, $rs",
1686 (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>;
1687 def : MipsInstAlias<"neg $rt, $rs",
1688 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
1689 def : MipsInstAlias<"negu $rt",
1690 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 0>;
1691 def : MipsInstAlias<"negu $rt, $rs",
1692 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
1693 def : MipsInstAlias<"slt $rs, $rt, $imm",
1694 (SLTi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1695 def : MipsInstAlias<"sltu $rt, $rs, $imm",
1696 (SLTiu GPR32Opnd:$rt, GPR32Opnd:$rs, simm16:$imm), 0>;
1697 def : MipsInstAlias<"xor $rs, $rt, $imm",
1698 (XORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
1699 def : MipsInstAlias<"xor $rs, $imm",
1700 (XORi GPR32Opnd:$rs, GPR32Opnd:$rs, uimm16:$imm), 0>;
1701 def : MipsInstAlias<"or $rs, $rt, $imm",
1702 (ORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
1703 def : MipsInstAlias<"or $rs, $imm",
1704 (ORi GPR32Opnd:$rs, GPR32Opnd:$rs, uimm16:$imm), 0>;
1705 let AdditionalPredicates = [NotInMicroMips] in {
1706 def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>;
1708 def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>;
1709 def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>;
1710 def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, COP2Opnd:$rd, 0), 0>;
1711 def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 COP2Opnd:$rd, GPR32Opnd:$rt, 0), 0>;
1712 let AdditionalPredicates = [NotInMicroMips] in {
1713 def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>;
1715 def : MipsInstAlias<"bnez $rs,$offset",
1716 (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1717 def : MipsInstAlias<"bnezl $rs,$offset",
1718 (BNEL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1719 def : MipsInstAlias<"beqz $rs,$offset",
1720 (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1721 def : MipsInstAlias<"beqzl $rs,$offset",
1722 (BEQL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1723 def : MipsInstAlias<"syscall", (SYSCALL 0), 1>;
1725 def : MipsInstAlias<"break", (BREAK 0, 0), 1>;
1726 def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>;
1727 let AdditionalPredicates = [NotInMicroMips] in {
1728 def : MipsInstAlias<"ei", (EI ZERO), 1>, ISA_MIPS32R2;
1730 def : MipsInstAlias<"di", (DI ZERO), 1>, ISA_MIPS32R2;
1731 let AdditionalPredicates = [NotInMicroMips] in {
1732 def : MipsInstAlias<"teq $rs, $rt",
1733 (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1734 def : MipsInstAlias<"tge $rs, $rt",
1735 (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1736 def : MipsInstAlias<"tgeu $rs, $rt",
1737 (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1738 def : MipsInstAlias<"tlt $rs, $rt",
1739 (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1740 def : MipsInstAlias<"tltu $rs, $rt",
1741 (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1742 def : MipsInstAlias<"tne $rs, $rt",
1743 (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1745 def : MipsInstAlias<"sll $rd, $rt, $rs",
1746 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1747 def : MipsInstAlias<"sub, $rd, $rs, $imm",
1748 (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs,
1749 InvertedImOperand:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6;
1750 def : MipsInstAlias<"sub $rs, $imm",
1751 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm),
1752 0>, ISA_MIPS1_NOT_32R6_64R6;
1753 def : MipsInstAlias<"subu, $rd, $rs, $imm",
1754 (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs,
1755 InvertedImOperand:$imm), 0>;
1756 def : MipsInstAlias<"subu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs,
1757 InvertedImOperand:$imm), 0>;
1758 def : MipsInstAlias<"sra $rd, $rt, $rs",
1759 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1760 def : MipsInstAlias<"srl $rd, $rt, $rs",
1761 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1762 def : MipsInstAlias<"sdbbp", (SDBBP 0)>, ISA_MIPS32_NOT_32R6_64R6;
1763 def : MipsInstAlias<"sync",
1764 (SYNC 0), 1>, ISA_MIPS2;
1765 //===----------------------------------------------------------------------===//
1766 // Assembler Pseudo Instructions
1767 //===----------------------------------------------------------------------===//
1769 class LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> :
1770 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
1771 !strconcat(instr_asm, "\t$rt, $imm32")> ;
1772 def LoadImm32 : LoadImmediate32<"li", uimm5, GPR32Opnd>;
1774 class LoadAddressFromReg32<string instr_asm, Operand MemOpnd,
1775 RegisterOperand RO> :
1776 MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
1777 !strconcat(instr_asm, "\t$rt, $addr")> ;
1778 def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>;
1780 class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> :
1781 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
1782 !strconcat(instr_asm, "\t$rt, $imm32")> ;
1783 def LoadAddrImm32 : LoadAddressFromImm32<"la", uimm5, GPR32Opnd>;
1785 def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
1787 def JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs),
1790 def NORImm : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm),
1791 "nor\t$rs, $rt, $imm"> ;
1793 let hasDelaySlot = 1 in {
1794 def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
1795 (ins imm64:$imm64, brtarget:$offset),
1796 "bne\t$rt, $imm64, $offset">;
1797 def BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
1798 (ins imm64:$imm64, brtarget:$offset),
1799 "beq\t$rt, $imm64, $offset">;
1801 class CondBranchPseudo<string instr_asm> :
1802 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt,
1804 !strconcat(instr_asm, "\t$rs, $rt, $offset")>;
1807 def BLT : CondBranchPseudo<"blt">;
1808 def BLE : CondBranchPseudo<"ble">;
1809 def BGE : CondBranchPseudo<"bge">;
1810 def BGT : CondBranchPseudo<"bgt">;
1811 def BLTU : CondBranchPseudo<"bltu">;
1812 def BLEU : CondBranchPseudo<"bleu">;
1813 def BGEU : CondBranchPseudo<"bgeu">;
1814 def BGTU : CondBranchPseudo<"bgtu">;
1815 def BLTL : CondBranchPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
1816 def BLEL : CondBranchPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
1817 def BGEL : CondBranchPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
1818 def BGTL : CondBranchPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
1819 def BLTUL: CondBranchPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
1820 def BLEUL: CondBranchPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
1821 def BGEUL: CondBranchPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
1822 def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
1824 class CondBranchImmPseudo<string instr_asm> :
1825 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, imm64:$imm, brtarget:$offset),
1826 !strconcat(instr_asm, "\t$rs, $imm, $offset")>;
1828 def BLTImmMacro : CondBranchImmPseudo<"blt">;
1829 def BLEImmMacro : CondBranchImmPseudo<"ble">;
1830 def BGEImmMacro : CondBranchImmPseudo<"bge">;
1831 def BGTImmMacro : CondBranchImmPseudo<"bgt">;
1832 def BLTUImmMacro : CondBranchImmPseudo<"bltu">;
1833 def BLEUImmMacro : CondBranchImmPseudo<"bleu">;
1834 def BGEUImmMacro : CondBranchImmPseudo<"bgeu">;
1835 def BGTUImmMacro : CondBranchImmPseudo<"bgtu">;
1836 def BLTLImmMacro : CondBranchImmPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
1837 def BLELImmMacro : CondBranchImmPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
1838 def BGELImmMacro : CondBranchImmPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
1839 def BGTLImmMacro : CondBranchImmPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
1840 def BLTULImmMacro : CondBranchImmPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
1841 def BLEULImmMacro : CondBranchImmPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
1842 def BGEULImmMacro : CondBranchImmPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
1843 def BGTULImmMacro : CondBranchImmPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
1845 // FIXME: Predicates are removed because instructions are matched regardless of
1846 // predicates, because PredicateControl was not in the hierarchy. This was
1847 // done to emit more precise error message from expansion function.
1848 // Once the tablegen-erated errors are made better, this needs to be fixed and
1849 // predicates needs to be restored.
1851 def SDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1852 "div\t$rs, $rt">; //, ISA_MIPS1_NOT_32R6_64R6;
1854 def UDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1855 "divu\t$rs, $rt">; //, ISA_MIPS1_NOT_32R6_64R6;
1857 def DSDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1858 "ddiv\t$rs, $rt">; //, ISA_MIPS64_NOT_64R6;
1860 def DUDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1861 "ddivu\t$rs, $rt">; //, ISA_MIPS64_NOT_64R6;
1863 def Ulh : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
1864 "ulh\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
1866 def Ulhu : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
1867 "ulhu\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
1869 def Ulw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
1870 "ulw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
1872 //===----------------------------------------------------------------------===//
1873 // Arbitrary patterns that map to one or more instructions
1874 //===----------------------------------------------------------------------===//
1876 // Load/store pattern templates.
1877 class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
1878 MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
1880 class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
1881 MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
1884 let AdditionalPredicates = [NotInMicroMips] in {
1885 def : MipsPat<(i32 immSExt16:$in),
1886 (ADDiu ZERO, imm:$in)>;
1887 def : MipsPat<(i32 immZExt16:$in),
1888 (ORi ZERO, imm:$in)>;
1890 def : MipsPat<(i32 immLow16Zero:$in),
1891 (LUi (HI16 imm:$in))>;
1893 // Arbitrary immediates
1894 def : MipsPat<(i32 imm:$imm),
1895 (ORi (LUi (HI16 imm:$imm)), (LO16 imm:$imm))>;
1897 // Carry MipsPatterns
1898 def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
1899 (SUBu GPR32:$lhs, GPR32:$rhs)>;
1900 let AdditionalPredicates = [NotDSP] in {
1901 def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
1902 (ADDu GPR32:$lhs, GPR32:$rhs)>;
1903 def : MipsPat<(addc GPR32:$src, immSExt16:$imm),
1904 (ADDiu GPR32:$src, imm:$imm)>;
1907 // Support multiplication for pre-Mips32 targets that don't have
1908 // the MUL instruction.
1909 def : MipsPat<(mul GPR32:$lhs, GPR32:$rhs),
1910 (PseudoMFLO (PseudoMULT GPR32:$lhs, GPR32:$rhs))>,
1911 ISA_MIPS1_NOT_32R6_64R6;
1914 def : MipsPat<(MipsSync (i32 immz)),
1915 (SYNC 0)>, ISA_MIPS2;
1918 def : MipsPat<(MipsJmpLink (i32 tglobaladdr:$dst)),
1919 (JAL tglobaladdr:$dst)>;
1920 def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
1921 (JAL texternalsym:$dst)>;
1922 //def : MipsPat<(MipsJmpLink GPR32:$dst),
1923 // (JALR GPR32:$dst)>;
1926 def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
1927 (TAILCALL tglobaladdr:$dst)>;
1928 def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
1929 (TAILCALL texternalsym:$dst)>;
1931 def : MipsPat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
1932 def : MipsPat<(MipsHi tblockaddress:$in), (LUi tblockaddress:$in)>;
1933 def : MipsPat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>;
1934 def : MipsPat<(MipsHi tconstpool:$in), (LUi tconstpool:$in)>;
1935 def : MipsPat<(MipsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>;
1936 def : MipsPat<(MipsHi texternalsym:$in), (LUi texternalsym:$in)>;
1938 def : MipsPat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
1939 def : MipsPat<(MipsLo tblockaddress:$in), (ADDiu ZERO, tblockaddress:$in)>;
1940 def : MipsPat<(MipsLo tjumptable:$in), (ADDiu ZERO, tjumptable:$in)>;
1941 def : MipsPat<(MipsLo tconstpool:$in), (ADDiu ZERO, tconstpool:$in)>;
1942 def : MipsPat<(MipsLo tglobaltlsaddr:$in), (ADDiu ZERO, tglobaltlsaddr:$in)>;
1943 def : MipsPat<(MipsLo texternalsym:$in), (ADDiu ZERO, texternalsym:$in)>;
1945 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaladdr:$lo)),
1946 (ADDiu GPR32:$hi, tglobaladdr:$lo)>;
1947 def : MipsPat<(add GPR32:$hi, (MipsLo tblockaddress:$lo)),
1948 (ADDiu GPR32:$hi, tblockaddress:$lo)>;
1949 def : MipsPat<(add GPR32:$hi, (MipsLo tjumptable:$lo)),
1950 (ADDiu GPR32:$hi, tjumptable:$lo)>;
1951 def : MipsPat<(add GPR32:$hi, (MipsLo tconstpool:$lo)),
1952 (ADDiu GPR32:$hi, tconstpool:$lo)>;
1953 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaltlsaddr:$lo)),
1954 (ADDiu GPR32:$hi, tglobaltlsaddr:$lo)>;
1957 def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
1958 (ADDiu GPR32:$gp, tglobaladdr:$in)>;
1959 def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
1960 (ADDiu GPR32:$gp, tconstpool:$in)>;
1963 class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
1964 MipsPat<(MipsWrapper RC:$gp, node:$in),
1965 (ADDiuOp RC:$gp, node:$in)>;
1967 def : WrapperPat<tglobaladdr, ADDiu, GPR32>;
1968 def : WrapperPat<tconstpool, ADDiu, GPR32>;
1969 def : WrapperPat<texternalsym, ADDiu, GPR32>;
1970 def : WrapperPat<tblockaddress, ADDiu, GPR32>;
1971 def : WrapperPat<tjumptable, ADDiu, GPR32>;
1972 def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>;
1974 let AdditionalPredicates = [NotInMicroMips] in {
1975 // Mips does not have "not", so we expand our way
1976 def : MipsPat<(not GPR32:$in),
1977 (NOR GPR32Opnd:$in, ZERO)>;
1981 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>;
1982 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>;
1983 def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
1986 def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>;
1989 multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BNEOp,
1990 Instruction SLTOp, Instruction SLTuOp, Instruction SLTiOp,
1991 Instruction SLTiuOp, Register ZEROReg> {
1992 def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
1993 (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
1994 def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
1995 (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
1997 def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
1998 (BEQ (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
1999 def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
2000 (BEQ (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
2001 def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
2002 (BEQ (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
2003 def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
2004 (BEQ (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
2005 def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
2006 (BEQ (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
2007 def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
2008 (BEQ (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
2010 def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
2011 (BEQ (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
2012 def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
2013 (BEQ (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
2015 def : MipsPat<(brcond RC:$cond, bb:$dst),
2016 (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
2019 defm : BrcondPats<GPR32, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>;
2021 def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
2022 (BLEZ i32:$lhs, bb:$dst)>;
2023 def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
2024 (BGEZ i32:$lhs, bb:$dst)>;
2027 multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp,
2028 Instruction SLTuOp, Register ZEROReg> {
2029 def : MipsPat<(seteq RC:$lhs, 0),
2030 (SLTiuOp RC:$lhs, 1)>;
2031 def : MipsPat<(setne RC:$lhs, 0),
2032 (SLTuOp ZEROReg, RC:$lhs)>;
2033 def : MipsPat<(seteq RC:$lhs, RC:$rhs),
2034 (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>;
2035 def : MipsPat<(setne RC:$lhs, RC:$rhs),
2036 (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
2039 multiclass SetlePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
2040 def : MipsPat<(setle RC:$lhs, RC:$rhs),
2041 (XORi (SLTOp RC:$rhs, RC:$lhs), 1)>;
2042 def : MipsPat<(setule RC:$lhs, RC:$rhs),
2043 (XORi (SLTuOp RC:$rhs, RC:$lhs), 1)>;
2046 multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
2047 def : MipsPat<(setgt RC:$lhs, RC:$rhs),
2048 (SLTOp RC:$rhs, RC:$lhs)>;
2049 def : MipsPat<(setugt RC:$lhs, RC:$rhs),
2050 (SLTuOp RC:$rhs, RC:$lhs)>;
2053 multiclass SetgePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
2054 def : MipsPat<(setge RC:$lhs, RC:$rhs),
2055 (XORi (SLTOp RC:$lhs, RC:$rhs), 1)>;
2056 def : MipsPat<(setuge RC:$lhs, RC:$rhs),
2057 (XORi (SLTuOp RC:$lhs, RC:$rhs), 1)>;
2060 multiclass SetgeImmPats<RegisterClass RC, Instruction SLTiOp,
2061 Instruction SLTiuOp> {
2062 def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
2063 (XORi (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
2064 def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
2065 (XORi (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
2068 defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>;
2069 defm : SetlePats<GPR32, SLT, SLTu>;
2070 defm : SetgtPats<GPR32, SLT, SLTu>;
2071 defm : SetgePats<GPR32, SLT, SLTu>;
2072 defm : SetgeImmPats<GPR32, SLTi, SLTiu>;
2075 def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>;
2077 // Load halfword/word patterns.
2078 let AddedComplexity = 40 in {
2079 def : LoadRegImmPat<LBu, i32, zextloadi8>;
2080 def : LoadRegImmPat<LH, i32, sextloadi16>;
2081 let AdditionalPredicates = [NotInMicroMips] in {
2082 def : LoadRegImmPat<LW, i32, load>;
2086 //===----------------------------------------------------------------------===//
2087 // Floating Point Support
2088 //===----------------------------------------------------------------------===//
2090 include "MipsInstrFPU.td"
2091 include "Mips64InstrInfo.td"
2092 include "MipsCondMov.td"
2094 include "Mips32r6InstrInfo.td"
2095 include "Mips64r6InstrInfo.td"
2100 include "Mips16InstrFormats.td"
2101 include "Mips16InstrInfo.td"
2104 include "MipsDSPInstrFormats.td"
2105 include "MipsDSPInstrInfo.td"
2108 include "MipsMSAInstrFormats.td"
2109 include "MipsMSAInstrInfo.td"
2112 include "MipsEVAInstrFormats.td"
2113 include "MipsEVAInstrInfo.td"
2116 include "MicroMipsInstrFormats.td"
2117 include "MicroMipsInstrInfo.td"
2118 include "MicroMipsInstrFPU.td"
2121 include "MicroMips32r6InstrFormats.td"
2122 include "MicroMips32r6InstrInfo.td"
2125 include "MicroMips64r6InstrFormats.td"
2126 include "MicroMips64r6InstrInfo.td"
2129 include "MicroMipsDSPInstrFormats.td"
2130 include "MicroMipsDSPInstrInfo.td"