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 // These are target-independent nodes, but have target-specific formats.
81 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MipsCallSeqStart,
82 [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>;
83 def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeqEnd,
84 [SDNPHasChain, SDNPSideEffect,
85 SDNPOptInGlue, SDNPOutGlue]>;
87 // Nodes used to extract LO/HI registers.
88 def MipsMFHI : SDNode<"MipsISD::MFHI", SDT_MFLOHI>;
89 def MipsMFLO : SDNode<"MipsISD::MFLO", SDT_MFLOHI>;
91 // Node used to insert 32-bit integers to LOHI register pair.
92 def MipsMTLOHI : SDNode<"MipsISD::MTLOHI", SDT_MTLOHI>;
95 def MipsMult : SDNode<"MipsISD::Mult", SDT_MipsMultDiv>;
96 def MipsMultu : SDNode<"MipsISD::Multu", SDT_MipsMultDiv>;
99 def MipsMAdd : SDNode<"MipsISD::MAdd", SDT_MipsMAddMSub>;
100 def MipsMAddu : SDNode<"MipsISD::MAddu", SDT_MipsMAddMSub>;
101 def MipsMSub : SDNode<"MipsISD::MSub", SDT_MipsMAddMSub>;
102 def MipsMSubu : SDNode<"MipsISD::MSubu", SDT_MipsMAddMSub>;
105 def MipsDivRem : SDNode<"MipsISD::DivRem", SDT_MipsMultDiv>;
106 def MipsDivRemU : SDNode<"MipsISD::DivRemU", SDT_MipsMultDiv>;
107 def MipsDivRem16 : SDNode<"MipsISD::DivRem16", SDT_MipsDivRem16,
109 def MipsDivRemU16 : SDNode<"MipsISD::DivRemU16", SDT_MipsDivRem16,
112 // Target constant nodes that are not part of any isel patterns and remain
113 // unchanged can cause instructions with illegal operands to be emitted.
114 // Wrapper node patterns give the instruction selector a chance to replace
115 // target constant nodes that would otherwise remain unchanged with ADDiu
116 // nodes. Without these wrapper node patterns, the following conditional move
117 // instruction is emitted when function cmov2 in test/CodeGen/Mips/cmov.ll is
119 // movn %got(d)($gp), %got(c)($gp), $4
120 // This instruction is illegal since movn can take only register operands.
122 def MipsWrapper : SDNode<"MipsISD::Wrapper", SDTIntBinOp>;
124 def MipsSync : SDNode<"MipsISD::Sync", SDT_Sync, [SDNPHasChain,SDNPSideEffect]>;
126 def MipsExt : SDNode<"MipsISD::Ext", SDT_Ext>;
127 def MipsIns : SDNode<"MipsISD::Ins", SDT_Ins>;
129 def MipsLWL : SDNode<"MipsISD::LWL", SDTMipsLoadLR,
130 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
131 def MipsLWR : SDNode<"MipsISD::LWR", SDTMipsLoadLR,
132 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
133 def MipsSWL : SDNode<"MipsISD::SWL", SDTStore,
134 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
135 def MipsSWR : SDNode<"MipsISD::SWR", SDTStore,
136 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
137 def MipsLDL : SDNode<"MipsISD::LDL", SDTMipsLoadLR,
138 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
139 def MipsLDR : SDNode<"MipsISD::LDR", SDTMipsLoadLR,
140 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
141 def MipsSDL : SDNode<"MipsISD::SDL", SDTStore,
142 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
143 def MipsSDR : SDNode<"MipsISD::SDR", SDTStore,
144 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
146 //===----------------------------------------------------------------------===//
147 // Mips Instruction Predicate Definitions.
148 //===----------------------------------------------------------------------===//
149 def HasMips2 : Predicate<"Subtarget->hasMips2()">,
150 AssemblerPredicate<"FeatureMips2">;
151 def HasMips3_32 : Predicate<"Subtarget->hasMips3_32()">,
152 AssemblerPredicate<"FeatureMips3_32">;
153 def HasMips3_32r2 : Predicate<"Subtarget->hasMips3_32r2()">,
154 AssemblerPredicate<"FeatureMips3_32r2">;
155 def HasMips3 : Predicate<"Subtarget->hasMips3()">,
156 AssemblerPredicate<"FeatureMips3">;
157 def HasMips4_32 : Predicate<"Subtarget->hasMips4_32()">,
158 AssemblerPredicate<"FeatureMips4_32">;
159 def NotMips4_32 : Predicate<"!Subtarget->hasMips4_32()">,
160 AssemblerPredicate<"!FeatureMips4_32">;
161 def HasMips4_32r2 : Predicate<"Subtarget->hasMips4_32r2()">,
162 AssemblerPredicate<"FeatureMips4_32r2">;
163 def HasMips5_32r2 : Predicate<"Subtarget->hasMips5_32r2()">,
164 AssemblerPredicate<"FeatureMips5_32r2">;
165 def HasMips32 : Predicate<"Subtarget->hasMips32()">,
166 AssemblerPredicate<"FeatureMips32">;
167 def HasMips32r2 : Predicate<"Subtarget->hasMips32r2()">,
168 AssemblerPredicate<"FeatureMips32r2">;
169 def HasMips32r5 : Predicate<"Subtarget->hasMips32r5()">,
170 AssemblerPredicate<"FeatureMips32r5">;
171 def HasMips32r6 : Predicate<"Subtarget->hasMips32r6()">,
172 AssemblerPredicate<"FeatureMips32r6">;
173 def NotMips32r6 : Predicate<"!Subtarget->hasMips32r6()">,
174 AssemblerPredicate<"!FeatureMips32r6">;
175 def IsGP64bit : Predicate<"Subtarget->isGP64bit()">,
176 AssemblerPredicate<"FeatureGP64Bit">;
177 def IsGP32bit : Predicate<"!Subtarget->isGP64bit()">,
178 AssemblerPredicate<"!FeatureGP64Bit">;
179 def HasMips64 : Predicate<"Subtarget->hasMips64()">,
180 AssemblerPredicate<"FeatureMips64">;
181 def HasMips64r2 : Predicate<"Subtarget->hasMips64r2()">,
182 AssemblerPredicate<"FeatureMips64r2">;
183 def HasMips64r6 : Predicate<"Subtarget->hasMips64r6()">,
184 AssemblerPredicate<"FeatureMips64r6">;
185 def NotMips64r6 : Predicate<"!Subtarget->hasMips64r6()">,
186 AssemblerPredicate<"!FeatureMips64r6">;
187 def HasMicroMips32r6 : Predicate<"Subtarget->inMicroMips32r6Mode()">,
188 AssemblerPredicate<"FeatureMicroMips,FeatureMips32r6">;
189 def HasMicroMips64r6 : Predicate<"Subtarget->inMicroMips64r6Mode()">,
190 AssemblerPredicate<"FeatureMicroMips,FeatureMips64r6">;
191 def InMips16Mode : Predicate<"Subtarget->inMips16Mode()">,
192 AssemblerPredicate<"FeatureMips16">;
193 def HasCnMips : Predicate<"Subtarget->hasCnMips()">,
194 AssemblerPredicate<"FeatureCnMips">;
195 def RelocStatic : Predicate<"TM.getRelocationModel() == Reloc::Static">;
196 def RelocPIC : Predicate<"TM.getRelocationModel() == Reloc::PIC_">;
197 def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">;
198 def HasStdEnc : Predicate<"Subtarget->hasStandardEncoding()">,
199 AssemblerPredicate<"!FeatureMips16">;
200 def NotDSP : Predicate<"!Subtarget->hasDSP()">;
201 def InMicroMips : Predicate<"Subtarget->inMicroMipsMode()">,
202 AssemblerPredicate<"FeatureMicroMips">;
203 def NotInMicroMips : Predicate<"!Subtarget->inMicroMipsMode()">,
204 AssemblerPredicate<"!FeatureMicroMips">;
205 def IsLE : Predicate<"Subtarget->isLittle()">;
206 def IsBE : Predicate<"!Subtarget->isLittle()">;
207 def IsNotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
208 def UseTCCInDIV : AssemblerPredicate<"FeatureUseTCCInDIV">;
209 def HasEVA : Predicate<"Subtarget->hasEVA()">,
210 AssemblerPredicate<"FeatureEVA,FeatureMips32r2">;
212 //===----------------------------------------------------------------------===//
213 // Mips GPR size adjectives.
214 // They are mutually exclusive.
215 //===----------------------------------------------------------------------===//
217 class GPR_32 { list<Predicate> GPRPredicates = [IsGP32bit]; }
218 class GPR_64 { list<Predicate> GPRPredicates = [IsGP64bit]; }
220 //===----------------------------------------------------------------------===//
221 // Mips ISA/ASE membership and instruction group membership adjectives.
222 // They are mutually exclusive.
223 //===----------------------------------------------------------------------===//
225 // FIXME: I'd prefer to use additive predicates to build the instruction sets
226 // but we are short on assembler feature bits at the moment. Using a
227 // subtractive predicate will hopefully keep us under the 32 predicate
228 // limit long enough to develop an alternative way to handle P1||P2
230 class ISA_MIPS1_NOT_4_32 {
231 list<Predicate> InsnPredicates = [NotMips4_32];
233 class ISA_MIPS1_NOT_32R6_64R6 {
234 list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6];
236 class ISA_MIPS2 { list<Predicate> InsnPredicates = [HasMips2]; }
237 class ISA_MIPS2_NOT_32R6_64R6 {
238 list<Predicate> InsnPredicates = [HasMips2, NotMips32r6, NotMips64r6];
240 class ISA_MIPS3 { list<Predicate> InsnPredicates = [HasMips3]; }
241 class ISA_MIPS3_NOT_32R6_64R6 {
242 list<Predicate> InsnPredicates = [HasMips3, NotMips32r6, NotMips64r6];
244 class ISA_MIPS32 { list<Predicate> InsnPredicates = [HasMips32]; }
245 class ISA_MIPS32_NOT_32R6_64R6 {
246 list<Predicate> InsnPredicates = [HasMips32, NotMips32r6, NotMips64r6];
248 class ISA_MIPS32R2 { list<Predicate> InsnPredicates = [HasMips32r2]; }
249 class ISA_MIPS32R2_NOT_32R6_64R6 {
250 list<Predicate> InsnPredicates = [HasMips32r2, NotMips32r6, NotMips64r6];
252 class ISA_MIPS32R5 { list<Predicate> InsnPredicates = [HasMips32r5]; }
253 class ISA_MIPS64 { list<Predicate> InsnPredicates = [HasMips64]; }
254 class ISA_MIPS64_NOT_64R6 {
255 list<Predicate> InsnPredicates = [HasMips64, NotMips64r6];
257 class ISA_MIPS64R2 { list<Predicate> InsnPredicates = [HasMips64r2]; }
258 class ISA_MIPS32R6 { list<Predicate> InsnPredicates = [HasMips32r6]; }
259 class ISA_MIPS64R6 { list<Predicate> InsnPredicates = [HasMips64r6]; }
260 class ISA_MICROMIPS { list<Predicate> InsnPredicates = [InMicroMips]; }
261 class ISA_MICROMIPS32R6 {
262 list<Predicate> InsnPredicates = [HasMicroMips32r6];
264 class ISA_MICROMIPS64R6 {
265 list<Predicate> InsnPredicates = [HasMicroMips64r6];
268 class INSN_EVA { list<Predicate> InsnPredicates = [HasEVA]; }
269 class INSN_EVA_NOT_32R6_64R6 {
270 list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6, HasEVA];
273 // The portions of MIPS-III that were also added to MIPS32
274 class INSN_MIPS3_32 { list<Predicate> InsnPredicates = [HasMips3_32]; }
276 // The portions of MIPS-III that were also added to MIPS32 but were removed in
277 // MIPS32r6 and MIPS64r6.
278 class INSN_MIPS3_32_NOT_32R6_64R6 {
279 list<Predicate> InsnPredicates = [HasMips3_32, NotMips32r6, NotMips64r6];
282 // The portions of MIPS-III that were also added to MIPS32
283 class INSN_MIPS3_32R2 { list<Predicate> InsnPredicates = [HasMips3_32r2]; }
285 // The portions of MIPS-IV that were also added to MIPS32 but were removed in
286 // MIPS32r6 and MIPS64r6.
287 class INSN_MIPS4_32_NOT_32R6_64R6 {
288 list<Predicate> InsnPredicates = [HasMips4_32, NotMips32r6, NotMips64r6];
291 // The portions of MIPS-IV that were also added to MIPS32r2 but were removed in
292 // MIPS32r6 and MIPS64r6.
293 class INSN_MIPS4_32R2_NOT_32R6_64R6 {
294 list<Predicate> InsnPredicates = [HasMips4_32r2, NotMips32r6, NotMips64r6];
297 // The portions of MIPS-V that were also added to MIPS32r2 but were removed in
298 // MIPS32r6 and MIPS64r6.
299 class INSN_MIPS5_32R2_NOT_32R6_64R6 {
300 list<Predicate> InsnPredicates = [HasMips5_32r2, NotMips32r6, NotMips64r6];
303 // Class used for separating microMIPSr6 and microMIPS (r3) instruction.
304 // It can be used only on instructions that doesn't inherit PredicateControl.
305 class ISA_MICROMIPS_NOT_32R6_64R6 : PredicateControl {
306 let InsnPredicates = [InMicroMips, NotMips32r6, NotMips64r6];
309 //===----------------------------------------------------------------------===//
311 class MipsPat<dag pattern, dag result> : Pat<pattern, result>, PredicateControl {
312 let EncodingPredicates = [HasStdEnc];
315 class MipsInstAlias<string Asm, dag Result, bit Emit = 0b1> :
316 InstAlias<Asm, Result, Emit>, PredicateControl;
319 bit isCommutable = 1;
336 bit isTerminator = 1;
339 bit hasExtraSrcRegAllocReq = 1;
340 bit isCodeGenOnly = 1;
343 class IsAsCheapAsAMove {
344 bit isAsCheapAsAMove = 1;
347 class NeverHasSideEffects {
348 bit hasSideEffects = 0;
351 //===----------------------------------------------------------------------===//
352 // Instruction format superclass
353 //===----------------------------------------------------------------------===//
355 include "MipsInstrFormats.td"
357 //===----------------------------------------------------------------------===//
358 // Mips Operand, Complex Patterns and Transformations Definitions.
359 //===----------------------------------------------------------------------===//
361 def MipsJumpTargetAsmOperand : AsmOperandClass {
362 let Name = "JumpTarget";
363 let ParserMethod = "parseJumpTarget";
364 let PredicateMethod = "isImm";
365 let RenderMethod = "addImmOperands";
368 // Instruction operand types
369 def jmptarget : Operand<OtherVT> {
370 let EncoderMethod = "getJumpTargetOpValue";
371 let ParserMatchClass = MipsJumpTargetAsmOperand;
373 def brtarget : Operand<OtherVT> {
374 let EncoderMethod = "getBranchTargetOpValue";
375 let OperandType = "OPERAND_PCREL";
376 let DecoderMethod = "DecodeBranchTarget";
377 let ParserMatchClass = MipsJumpTargetAsmOperand;
379 def calltarget : Operand<iPTR> {
380 let EncoderMethod = "getJumpTargetOpValue";
381 let ParserMatchClass = MipsJumpTargetAsmOperand;
384 def imm64: Operand<i64>;
386 def simm9 : Operand<i32>;
387 def simm10 : Operand<i32>;
388 def simm11 : Operand<i32>;
390 def simm16 : Operand<i32> {
391 let DecoderMethod= "DecodeSimm16";
394 def simm19_lsl2 : Operand<i32> {
395 let EncoderMethod = "getSimm19Lsl2Encoding";
396 let DecoderMethod = "DecodeSimm19Lsl2";
397 let ParserMatchClass = MipsJumpTargetAsmOperand;
400 def simm18_lsl3 : Operand<i32> {
401 let EncoderMethod = "getSimm18Lsl3Encoding";
402 let DecoderMethod = "DecodeSimm18Lsl3";
403 let ParserMatchClass = MipsJumpTargetAsmOperand;
406 def simm20 : Operand<i32> {
409 def uimm20 : Operand<i32> {
412 def MipsUImm10AsmOperand : AsmOperandClass {
414 let RenderMethod = "addImmOperands";
415 let ParserMethod = "parseImm";
416 let PredicateMethod = "isUImm<10>";
419 def uimm10 : Operand<i32> {
420 let ParserMatchClass = MipsUImm10AsmOperand;
423 def simm16_64 : Operand<i64> {
424 let DecoderMethod = "DecodeSimm16";
428 def uimmz : Operand<i32> {
429 let PrintMethod = "printUnsignedImm";
433 def uimm2 : Operand<i32> {
434 let PrintMethod = "printUnsignedImm";
437 def uimm3 : Operand<i32> {
438 let PrintMethod = "printUnsignedImm";
441 def uimm5 : Operand<i32> {
442 let PrintMethod = "printUnsignedImm";
445 def uimm6 : Operand<i32> {
446 let PrintMethod = "printUnsignedImm";
449 def uimm16 : Operand<i32> {
450 let PrintMethod = "printUnsignedImm";
453 def pcrel16 : Operand<i32> {
456 def MipsMemAsmOperand : AsmOperandClass {
458 let ParserMethod = "parseMemOperand";
461 def MipsMemSimm9AsmOperand : AsmOperandClass {
462 let Name = "MemOffsetSimm9";
463 let SuperClasses = [MipsMemAsmOperand];
464 let RenderMethod = "addMemOperands";
465 let ParserMethod = "parseMemOperand";
466 let PredicateMethod = "isMemWithSimmOffset<9>";
469 def MipsMemSimm9GPRAsmOperand : AsmOperandClass {
470 let Name = "MemOffsetSimm9GPR";
471 let SuperClasses = [MipsMemAsmOperand];
472 let RenderMethod = "addMemOperands";
473 let ParserMethod = "parseMemOperand";
474 let PredicateMethod = "isMemWithSimmOffsetGPR<9>";
477 def MipsMemSimm11AsmOperand : AsmOperandClass {
478 let Name = "MemOffsetSimm11";
479 let SuperClasses = [MipsMemAsmOperand];
480 let RenderMethod = "addMemOperands";
481 let ParserMethod = "parseMemOperand";
482 let PredicateMethod = "isMemWithSimmOffset<11>";
485 def MipsMemSimm16AsmOperand : AsmOperandClass {
486 let Name = "MemOffsetSimm16";
487 let SuperClasses = [MipsMemAsmOperand];
488 let RenderMethod = "addMemOperands";
489 let ParserMethod = "parseMemOperand";
490 let PredicateMethod = "isMemWithSimmOffset<16>";
493 def MipsInvertedImmoperand : AsmOperandClass {
495 let RenderMethod = "addImmOperands";
496 let ParserMethod = "parseInvNum";
499 def InvertedImOperand : Operand<i32> {
500 let ParserMatchClass = MipsInvertedImmoperand;
503 def InvertedImOperand64 : Operand<i64> {
504 let ParserMatchClass = MipsInvertedImmoperand;
507 class mem_generic : Operand<iPTR> {
508 let PrintMethod = "printMemOperand";
509 let MIOperandInfo = (ops ptr_rc, simm16);
510 let EncoderMethod = "getMemEncoding";
511 let ParserMatchClass = MipsMemAsmOperand;
512 let OperandType = "OPERAND_MEMORY";
516 def mem : mem_generic;
518 // MSA specific address operand
519 def mem_msa : mem_generic {
520 let MIOperandInfo = (ops ptr_rc, simm10);
521 let EncoderMethod = "getMSAMemEncoding";
524 def mem_simm9 : mem_generic {
525 let MIOperandInfo = (ops ptr_rc, simm9);
526 let EncoderMethod = "getMemEncoding";
527 let ParserMatchClass = MipsMemSimm9AsmOperand;
530 def mem_simm9gpr : mem_generic {
531 let MIOperandInfo = (ops ptr_rc, simm9);
532 let EncoderMethod = "getMemEncoding";
533 let ParserMatchClass = MipsMemSimm9GPRAsmOperand;
536 def mem_simm11 : mem_generic {
537 let MIOperandInfo = (ops ptr_rc, simm11);
538 let EncoderMethod = "getMemEncoding";
539 let ParserMatchClass = MipsMemSimm11AsmOperand;
542 def mem_simm16 : mem_generic {
543 let MIOperandInfo = (ops ptr_rc, simm16);
544 let EncoderMethod = "getMemEncoding";
545 let ParserMatchClass = MipsMemSimm16AsmOperand;
548 def mem_ea : Operand<iPTR> {
549 let PrintMethod = "printMemOperandEA";
550 let MIOperandInfo = (ops ptr_rc, simm16);
551 let EncoderMethod = "getMemEncoding";
552 let OperandType = "OPERAND_MEMORY";
555 def PtrRC : Operand<iPTR> {
556 let MIOperandInfo = (ops ptr_rc);
557 let DecoderMethod = "DecodePtrRegisterClass";
558 let ParserMatchClass = GPR32AsmOperand;
561 // size operand of ext instruction
562 def size_ext : Operand<i32> {
563 let EncoderMethod = "getSizeExtEncoding";
564 let DecoderMethod = "DecodeExtSize";
567 // size operand of ins instruction
568 def size_ins : Operand<i32> {
569 let EncoderMethod = "getSizeInsEncoding";
570 let DecoderMethod = "DecodeInsSize";
573 // Transformation Function - get the lower 16 bits.
574 def LO16 : SDNodeXForm<imm, [{
575 return getImm(N, N->getZExtValue() & 0xFFFF);
578 // Transformation Function - get the higher 16 bits.
579 def HI16 : SDNodeXForm<imm, [{
580 return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF);
584 def Plus1 : SDNodeXForm<imm, [{ return getImm(N, N->getSExtValue() + 1); }]>;
586 // Node immediate is zero (e.g. insve.d)
587 def immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>;
589 // Node immediate fits as 16-bit sign extended on target immediate.
591 def immSExt8 : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;
593 // Node immediate fits as 16-bit sign extended on target immediate.
595 def immSExt16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;
597 // Node immediate fits as 15-bit sign extended on target immediate.
599 def immSExt15 : PatLeaf<(imm), [{ return isInt<15>(N->getSExtValue()); }]>;
601 // Node immediate fits as 16-bit zero extended on target immediate.
602 // The LO16 param means that only the lower 16 bits of the node
603 // immediate are caught.
605 def immZExt16 : PatLeaf<(imm), [{
606 if (N->getValueType(0) == MVT::i32)
607 return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
609 return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
612 // Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared).
613 def immLow16Zero : PatLeaf<(imm), [{
614 int64_t Val = N->getSExtValue();
615 return isInt<32>(Val) && !(Val & 0xffff);
618 // shamt field must fit in 5 bits.
619 def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
621 // True if (N + 1) fits in 16-bit field.
622 def immSExt16Plus1 : PatLeaf<(imm), [{
623 return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1);
626 // Mips Address Mode! SDNode frameindex could possibily be a match
627 // since load and store instructions from stack used it.
629 ComplexPattern<iPTR, 2, "selectIntAddr", [frameindex]>;
632 ComplexPattern<iPTR, 2, "selectAddrRegImm", [frameindex]>;
635 ComplexPattern<iPTR, 2, "selectAddrRegReg", [frameindex]>;
638 ComplexPattern<iPTR, 2, "selectAddrDefault", [frameindex]>;
640 def addrimm10 : ComplexPattern<iPTR, 2, "selectIntAddrMSA", [frameindex]>;
642 //===----------------------------------------------------------------------===//
643 // Instructions specific format
644 //===----------------------------------------------------------------------===//
646 // Arithmetic and logical instructions with 3 register operands.
647 class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0,
648 InstrItinClass Itin = NoItinerary,
649 SDPatternOperator OpNode = null_frag>:
650 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
651 !strconcat(opstr, "\t$rd, $rs, $rt"),
652 [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> {
653 let isCommutable = isComm;
654 let isReMaterializable = 1;
655 let TwoOperandAliasConstraint = "$rd = $rs";
658 // Arithmetic and logical instructions with 2 register operands.
659 class ArithLogicI<string opstr, Operand Od, RegisterOperand RO,
660 InstrItinClass Itin = NoItinerary,
661 SDPatternOperator imm_type = null_frag,
662 SDPatternOperator OpNode = null_frag> :
663 InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16),
664 !strconcat(opstr, "\t$rt, $rs, $imm16"),
665 [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))],
667 let isReMaterializable = 1;
668 let TwoOperandAliasConstraint = "$rs = $rt";
671 // Arithmetic Multiply ADD/SUB
672 class MArithR<string opstr, InstrItinClass itin, bit isComm = 0> :
673 InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
674 !strconcat(opstr, "\t$rs, $rt"), [], itin, FrmR, opstr> {
675 let Defs = [HI0, LO0];
676 let Uses = [HI0, LO0];
677 let isCommutable = isComm;
681 class LogicNOR<string opstr, RegisterOperand RO>:
682 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
683 !strconcat(opstr, "\t$rd, $rs, $rt"),
684 [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], II_NOR, FrmR, opstr> {
685 let isCommutable = 1;
689 class shift_rotate_imm<string opstr, Operand ImmOpnd,
690 RegisterOperand RO, InstrItinClass itin,
691 SDPatternOperator OpNode = null_frag,
692 SDPatternOperator PF = null_frag> :
693 InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt),
694 !strconcat(opstr, "\t$rd, $rt, $shamt"),
695 [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], itin, FrmR, opstr> {
696 let TwoOperandAliasConstraint = "$rt = $rd";
699 class shift_rotate_reg<string opstr, RegisterOperand RO, InstrItinClass itin,
700 SDPatternOperator OpNode = null_frag>:
701 InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs),
702 !strconcat(opstr, "\t$rd, $rt, $rs"),
703 [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], itin, FrmR,
706 // Load Upper Immediate
707 class LoadUpper<string opstr, RegisterOperand RO, Operand Imm>:
708 InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"),
709 [], II_LUI, FrmI, opstr>, IsAsCheapAsAMove {
710 let hasSideEffects = 0;
711 let isReMaterializable = 1;
715 class Load<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
716 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
717 InstSE<(outs RO:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
718 [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> {
719 let DecoderMethod = "DecodeMem";
720 let canFoldAsLoad = 1;
724 class StoreMemory<string opstr, DAGOperand RO, DAGOperand MO,
725 SDPatternOperator OpNode = null_frag,
726 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
727 InstSE<(outs), (ins RO:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
728 [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> {
729 let DecoderMethod = "DecodeMem";
733 class Store<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
734 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
735 StoreMemory<opstr, RO, mem, OpNode, Itin, Addr>;
737 // Load/Store Left/Right
738 let canFoldAsLoad = 1 in
739 class LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
740 InstrItinClass Itin> :
741 InstSE<(outs RO:$rt), (ins mem:$addr, RO:$src),
742 !strconcat(opstr, "\t$rt, $addr"),
743 [(set RO:$rt, (OpNode addr:$addr, RO:$src))], Itin, FrmI> {
744 let DecoderMethod = "DecodeMem";
745 string Constraints = "$src = $rt";
748 class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
749 InstrItinClass Itin> :
750 InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
751 [(OpNode RO:$rt, addr:$addr)], Itin, FrmI> {
752 let DecoderMethod = "DecodeMem";
756 class LW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
757 SDPatternOperator OpNode= null_frag> :
758 InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
759 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
760 let DecoderMethod = "DecodeFMem2";
764 class SW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
765 SDPatternOperator OpNode= null_frag> :
766 InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
767 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
768 let DecoderMethod = "DecodeFMem2";
773 class LW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
774 SDPatternOperator OpNode= null_frag> :
775 InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
776 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
777 let DecoderMethod = "DecodeFMem3";
781 class SW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
782 SDPatternOperator OpNode= null_frag> :
783 InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
784 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
785 let DecoderMethod = "DecodeFMem3";
789 // Conditional Branch
790 class CBranch<string opstr, DAGOperand opnd, PatFrag cond_op,
791 RegisterOperand RO, bit DelaySlot = 1> :
792 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
793 !strconcat(opstr, "\t$rs, $rt, $offset"),
794 [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], IIBranch,
797 let isTerminator = 1;
798 let hasDelaySlot = DelaySlot;
802 class CBranchZero<string opstr, DAGOperand opnd, PatFrag cond_op,
803 RegisterOperand RO, bit DelaySlot = 1> :
804 InstSE<(outs), (ins RO:$rs, opnd:$offset),
805 !strconcat(opstr, "\t$rs, $offset"),
806 [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], IIBranch,
809 let isTerminator = 1;
810 let hasDelaySlot = DelaySlot;
815 class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> :
816 InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt),
817 !strconcat(opstr, "\t$rd, $rs, $rt"),
818 [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))],
819 II_SLT_SLTU, FrmR, opstr>;
821 class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
823 InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16),
824 !strconcat(opstr, "\t$rt, $rs, $imm16"),
825 [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))],
826 II_SLTI_SLTIU, FrmI, opstr>;
829 class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
830 SDPatternOperator targetoperator, string bopstr> :
831 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
832 [(operator targetoperator:$target)], IIBranch, FrmJ, bopstr> {
835 let hasDelaySlot = 1;
836 let DecoderMethod = "DecodeJumpTarget";
840 // Unconditional branch
841 class UncondBranch<Instruction BEQInst> :
842 PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], IIBranch>,
843 PseudoInstExpansion<(BEQInst ZERO, ZERO, brtarget:$offset)> {
845 let isTerminator = 1;
847 let hasDelaySlot = 1;
848 let AdditionalPredicates = [RelocPIC];
852 // Base class for indirect branch and return instruction classes.
853 let isTerminator=1, isBarrier=1, hasDelaySlot = 1 in
854 class JumpFR<string opstr, RegisterOperand RO,
855 SDPatternOperator operator = null_frag>:
856 InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], IIBranch,
860 class IndirectBranch<string opstr, RegisterOperand RO> : JumpFR<opstr, RO> {
862 let isIndirectBranch = 1;
865 // Jump and Link (Call)
866 let isCall=1, hasDelaySlot=1, Defs = [RA] in {
867 class JumpLink<string opstr, DAGOperand opnd> :
868 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
869 [(MipsJmpLink imm:$target)], IIBranch, FrmJ, opstr> {
870 let DecoderMethod = "DecodeJumpTarget";
873 class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst,
874 Register RetReg, RegisterOperand ResRO = RO>:
875 PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], IIBranch>,
876 PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)>;
878 class JumpLinkReg<string opstr, RegisterOperand RO>:
879 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
882 class BGEZAL_FT<string opstr, DAGOperand opnd,
883 RegisterOperand RO, bit DelaySlot = 1> :
884 InstSE<(outs), (ins RO:$rs, opnd:$offset),
885 !strconcat(opstr, "\t$rs, $offset"), [], IIBranch, FrmI, opstr> {
886 let hasDelaySlot = DelaySlot;
891 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
892 hasExtraSrcRegAllocReq = 1, Defs = [AT] in {
893 class TailCall<Instruction JumpInst> :
894 PseudoSE<(outs), (ins calltarget:$target), [], IIBranch>,
895 PseudoInstExpansion<(JumpInst jmptarget:$target)>;
897 class TailCallReg<RegisterOperand RO, Instruction JRInst,
898 RegisterOperand ResRO = RO> :
899 PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], IIBranch>,
900 PseudoInstExpansion<(JRInst ResRO:$rs)>;
903 class BAL_BR_Pseudo<Instruction RealInst> :
904 PseudoSE<(outs), (ins brtarget:$offset), [], IIBranch>,
905 PseudoInstExpansion<(RealInst ZERO, brtarget:$offset)> {
907 let isTerminator = 1;
909 let hasDelaySlot = 1;
914 class SYS_FT<string opstr> :
915 InstSE<(outs), (ins uimm20:$code_),
916 !strconcat(opstr, "\t$code_"), [], NoItinerary, FrmI, opstr>;
918 class BRK_FT<string opstr> :
919 InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
920 !strconcat(opstr, "\t$code_1, $code_2"), [], NoItinerary,
924 class ER_FT<string opstr> :
925 InstSE<(outs), (ins),
926 opstr, [], NoItinerary, FrmOther, opstr>;
929 class DEI_FT<string opstr, RegisterOperand RO> :
930 InstSE<(outs RO:$rt), (ins),
931 !strconcat(opstr, "\t$rt"), [], NoItinerary, FrmOther, opstr>;
934 class WAIT_FT<string opstr> :
935 InstSE<(outs), (ins), opstr, [], NoItinerary, FrmOther, opstr>;
938 let hasSideEffects = 1 in
939 class SYNC_FT<string opstr> :
940 InstSE<(outs), (ins i32imm:$stype), "sync $stype", [(MipsSync imm:$stype)],
941 NoItinerary, FrmOther, opstr>;
943 class SYNCI_FT<string opstr> :
944 InstSE<(outs), (ins mem_simm16:$addr), !strconcat(opstr, "\t$addr"), [],
945 NoItinerary, FrmOther, opstr> {
946 let hasSideEffects = 1;
947 let DecoderMethod = "DecodeSyncI";
950 let hasSideEffects = 1 in
951 class TEQ_FT<string opstr, RegisterOperand RO> :
952 InstSE<(outs), (ins RO:$rs, RO:$rt, uimm16:$code_),
953 !strconcat(opstr, "\t$rs, $rt, $code_"), [], NoItinerary,
956 class TEQI_FT<string opstr, RegisterOperand RO> :
957 InstSE<(outs), (ins RO:$rs, uimm16:$imm16),
958 !strconcat(opstr, "\t$rs, $imm16"), [], NoItinerary, FrmOther, opstr>;
960 class Mult<string opstr, InstrItinClass itin, RegisterOperand RO,
961 list<Register> DefRegs> :
962 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [],
964 let isCommutable = 1;
966 let hasSideEffects = 0;
969 // Pseudo multiply/divide instruction with explicit accumulator register
971 class MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1,
972 SDPatternOperator OpNode, InstrItinClass Itin,
973 bit IsComm = 1, bit HasSideEffects = 0,
974 bit UsesCustomInserter = 0> :
975 PseudoSE<(outs R0:$ac), (ins R1:$rs, R1:$rt),
976 [(set R0:$ac, (OpNode R1:$rs, R1:$rt))], Itin>,
977 PseudoInstExpansion<(RealInst R1:$rs, R1:$rt)> {
978 let isCommutable = IsComm;
979 let hasSideEffects = HasSideEffects;
980 let usesCustomInserter = UsesCustomInserter;
983 // Pseudo multiply add/sub instruction with explicit accumulator register
985 class MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode,
987 : PseudoSE<(outs ACC64:$ac),
988 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin),
990 (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))],
992 PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> {
993 string Constraints = "$acin = $ac";
996 class Div<string opstr, InstrItinClass itin, RegisterOperand RO,
997 list<Register> DefRegs> :
998 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$$zero, $rs, $rt"),
999 [], itin, FrmR, opstr> {
1004 class PseudoMFLOHI<RegisterClass DstRC, RegisterClass SrcRC, SDNode OpNode>
1005 : PseudoSE<(outs DstRC:$rd), (ins SrcRC:$hilo),
1006 [(set DstRC:$rd, (OpNode SrcRC:$hilo))], II_MFHI_MFLO>;
1008 class MoveFromLOHI<string opstr, RegisterOperand RO, Register UseReg>:
1009 InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO,
1011 let Uses = [UseReg];
1012 let hasSideEffects = 0;
1015 class PseudoMTLOHI<RegisterClass DstRC, RegisterClass SrcRC>
1016 : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi),
1017 [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))],
1020 class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>:
1021 InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO,
1024 let hasSideEffects = 0;
1027 class EffectiveAddress<string opstr, RegisterOperand RO> :
1028 InstSE<(outs RO:$rt), (ins mem_ea:$addr), !strconcat(opstr, "\t$rt, $addr"),
1029 [(set RO:$rt, addr:$addr)], NoItinerary, FrmI,
1030 !strconcat(opstr, "_lea")> {
1031 let isCodeGenOnly = 1;
1032 let DecoderMethod = "DecodeMem";
1035 // Count Leading Ones/Zeros in Word
1036 class CountLeading0<string opstr, RegisterOperand RO>:
1037 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1038 [(set RO:$rd, (ctlz RO:$rs))], II_CLZ, FrmR, opstr>;
1040 class CountLeading1<string opstr, RegisterOperand RO>:
1041 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
1042 [(set RO:$rd, (ctlz (not RO:$rs)))], II_CLO, FrmR, opstr>;
1044 // Sign Extend in Register.
1045 class SignExtInReg<string opstr, ValueType vt, RegisterOperand RO,
1046 InstrItinClass itin> :
1047 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"),
1048 [(set RO:$rd, (sext_inreg RO:$rt, vt))], itin, FrmR, opstr>;
1051 class SubwordSwap<string opstr, RegisterOperand RO>:
1052 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [],
1053 NoItinerary, FrmR, opstr> {
1054 let hasSideEffects = 0;
1058 class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> :
1059 InstSE<(outs CPURegOperand:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [],
1060 II_RDHWR, FrmR, "rdhwr">;
1063 class ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1064 SDPatternOperator Op = null_frag>:
1065 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, size_ext:$size),
1066 !strconcat(opstr, " $rt, $rs, $pos, $size"),
1067 [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size))], II_EXT,
1068 FrmR, opstr>, ISA_MIPS32R2;
1070 class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1071 SDPatternOperator Op = null_frag>:
1072 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, size_ins:$size, RO:$src),
1073 !strconcat(opstr, " $rt, $rs, $pos, $size"),
1074 [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size, RO:$src))],
1075 II_INS, FrmR, opstr>, ISA_MIPS32R2 {
1076 let Constraints = "$src = $rt";
1079 // Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*).
1080 class Atomic2Ops<PatFrag Op, RegisterClass DRC> :
1081 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr),
1082 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]>;
1084 // Atomic Compare & Swap.
1085 class AtomicCmpSwap<PatFrag Op, RegisterClass DRC> :
1086 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap),
1087 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]>;
1089 class LLBase<string opstr, RegisterOperand RO> :
1090 InstSE<(outs RO:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1091 [], NoItinerary, FrmI> {
1092 let DecoderMethod = "DecodeMem";
1096 class SCBase<string opstr, RegisterOperand RO> :
1097 InstSE<(outs RO:$dst), (ins RO:$rt, mem:$addr),
1098 !strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> {
1099 let DecoderMethod = "DecodeMem";
1101 let Constraints = "$rt = $dst";
1104 class MFC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD> :
1105 InstSE<(outs RO:$rt), (ins RD:$rd, uimm16:$sel),
1106 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], NoItinerary, FrmFR>;
1108 class MTC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD> :
1109 InstSE<(outs RO:$rd), (ins RD:$rt, uimm16:$sel),
1110 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], NoItinerary, FrmFR>;
1112 class TrapBase<Instruction RealInst>
1113 : PseudoSE<(outs), (ins), [(trap)], NoItinerary>,
1114 PseudoInstExpansion<(RealInst 0, 0)> {
1116 let isTerminator = 1;
1117 let isCodeGenOnly = 1;
1120 //===----------------------------------------------------------------------===//
1121 // Pseudo instructions
1122 //===----------------------------------------------------------------------===//
1125 let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1 in
1126 def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
1128 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
1129 def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt),
1130 [(callseq_start timm:$amt)]>;
1131 def ADJCALLSTACKUP : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1132 [(callseq_end timm:$amt1, timm:$amt2)]>;
1135 let usesCustomInserter = 1 in {
1136 def ATOMIC_LOAD_ADD_I8 : Atomic2Ops<atomic_load_add_8, GPR32>;
1137 def ATOMIC_LOAD_ADD_I16 : Atomic2Ops<atomic_load_add_16, GPR32>;
1138 def ATOMIC_LOAD_ADD_I32 : Atomic2Ops<atomic_load_add_32, GPR32>;
1139 def ATOMIC_LOAD_SUB_I8 : Atomic2Ops<atomic_load_sub_8, GPR32>;
1140 def ATOMIC_LOAD_SUB_I16 : Atomic2Ops<atomic_load_sub_16, GPR32>;
1141 def ATOMIC_LOAD_SUB_I32 : Atomic2Ops<atomic_load_sub_32, GPR32>;
1142 def ATOMIC_LOAD_AND_I8 : Atomic2Ops<atomic_load_and_8, GPR32>;
1143 def ATOMIC_LOAD_AND_I16 : Atomic2Ops<atomic_load_and_16, GPR32>;
1144 def ATOMIC_LOAD_AND_I32 : Atomic2Ops<atomic_load_and_32, GPR32>;
1145 def ATOMIC_LOAD_OR_I8 : Atomic2Ops<atomic_load_or_8, GPR32>;
1146 def ATOMIC_LOAD_OR_I16 : Atomic2Ops<atomic_load_or_16, GPR32>;
1147 def ATOMIC_LOAD_OR_I32 : Atomic2Ops<atomic_load_or_32, GPR32>;
1148 def ATOMIC_LOAD_XOR_I8 : Atomic2Ops<atomic_load_xor_8, GPR32>;
1149 def ATOMIC_LOAD_XOR_I16 : Atomic2Ops<atomic_load_xor_16, GPR32>;
1150 def ATOMIC_LOAD_XOR_I32 : Atomic2Ops<atomic_load_xor_32, GPR32>;
1151 def ATOMIC_LOAD_NAND_I8 : Atomic2Ops<atomic_load_nand_8, GPR32>;
1152 def ATOMIC_LOAD_NAND_I16 : Atomic2Ops<atomic_load_nand_16, GPR32>;
1153 def ATOMIC_LOAD_NAND_I32 : Atomic2Ops<atomic_load_nand_32, GPR32>;
1155 def ATOMIC_SWAP_I8 : Atomic2Ops<atomic_swap_8, GPR32>;
1156 def ATOMIC_SWAP_I16 : Atomic2Ops<atomic_swap_16, GPR32>;
1157 def ATOMIC_SWAP_I32 : Atomic2Ops<atomic_swap_32, GPR32>;
1159 def ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap<atomic_cmp_swap_8, GPR32>;
1160 def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap<atomic_cmp_swap_16, GPR32>;
1161 def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_32, GPR32>;
1164 /// Pseudo instructions for loading and storing accumulator registers.
1165 let isPseudo = 1, isCodeGenOnly = 1 in {
1166 def LOAD_ACC64 : Load<"", ACC64>;
1167 def STORE_ACC64 : Store<"", ACC64>;
1170 // We need these two pseudo instructions to avoid offset calculation for long
1171 // branches. See the comment in file MipsLongBranch.cpp for detailed
1174 // Expands to: lui $dst, %hi($tgt - $baltgt)
1175 def LONG_BRANCH_LUi : PseudoSE<(outs GPR32Opnd:$dst),
1176 (ins brtarget:$tgt, brtarget:$baltgt), []>;
1178 // Expands to: addiu $dst, $src, %lo($tgt - $baltgt)
1179 def LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst),
1180 (ins GPR32Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []>;
1182 //===----------------------------------------------------------------------===//
1183 // Instruction definition
1184 //===----------------------------------------------------------------------===//
1185 //===----------------------------------------------------------------------===//
1186 // MipsI Instructions
1187 //===----------------------------------------------------------------------===//
1189 /// Arithmetic Instructions (ALU Immediate)
1190 let AdditionalPredicates = [NotInMicroMips] in {
1191 def ADDiu : MMRel, StdMMR6Rel, ArithLogicI<"addiu", simm16, GPR32Opnd,
1192 II_ADDIU, immSExt16, add>,
1193 ADDI_FM<0x9>, IsAsCheapAsAMove;
1195 def ADDi : MMRel, ArithLogicI<"addi", simm16, GPR32Opnd>, ADDI_FM<0x8>,
1196 ISA_MIPS1_NOT_32R6_64R6;
1197 def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
1199 def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
1201 let AdditionalPredicates = [NotInMicroMips] in {
1202 def ANDi : MMRel, StdMMR6Rel,
1203 ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16, and>,
1206 def ORi : MMRel, StdMMR6Rel,
1207 ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16, or>,
1209 def XORi : MMRel, StdMMR6Rel,
1210 ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16, xor>,
1212 def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16>, LUI_FM;
1213 let AdditionalPredicates = [NotInMicroMips] in {
1214 /// Arithmetic Instructions (3-Operand, R-Type)
1215 def ADDu : MMRel, StdMMR6Rel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
1217 def SUBu : MMRel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
1220 let Defs = [HI0, LO0] in
1221 def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>,
1222 ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6;
1223 def ADD : MMRel, StdMMR6Rel, ArithLogicR<"add", GPR32Opnd>, ADD_FM<0, 0x20>;
1224 def SUB : MMRel, ArithLogicR<"sub", GPR32Opnd>, ADD_FM<0, 0x22>;
1225 def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>;
1226 def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>;
1227 let AdditionalPredicates = [NotInMicroMips] in {
1228 def AND : MMRel, StdMMR6Rel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
1230 def OR : MMRel, StdMMR6Rel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
1232 def XOR : MMRel, StdMMR6Rel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
1235 def NOR : MMRel, StdMMR6Rel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>;
1237 /// Shift Instructions
1238 let AdditionalPredicates = [NotInMicroMips] in {
1239 def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl,
1240 immZExt5>, SRA_FM<0, 0>;
1241 def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl,
1242 immZExt5>, SRA_FM<2, 0>;
1244 def SRA : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, sra,
1245 immZExt5>, SRA_FM<3, 0>;
1246 def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, shl>,
1248 def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, srl>,
1250 def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, sra>,
1253 // Rotate Instructions
1254 def ROTR : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr,
1256 SRA_FM<2, 1>, ISA_MIPS32R2;
1257 def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>,
1258 SRLV_FM<6, 1>, ISA_MIPS32R2;
1260 /// Load and Store Instructions
1262 def LB : Load<"lb", GPR32Opnd, sextloadi8, II_LB>, MMRel, LW_FM<0x20>;
1263 def LBu : Load<"lbu", GPR32Opnd, zextloadi8, II_LBU, addrDefault>, MMRel,
1265 def LH : Load<"lh", GPR32Opnd, sextloadi16, II_LH, addrDefault>, MMRel,
1267 def LHu : Load<"lhu", GPR32Opnd, zextloadi16, II_LHU>, MMRel, LW_FM<0x25>;
1268 let AdditionalPredicates = [NotInMicroMips] in {
1269 def LW : StdMMR6Rel, Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel,
1272 def SB : StdMMR6Rel, Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel,
1274 def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>;
1275 let AdditionalPredicates = [NotInMicroMips] in {
1276 def SW : Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>;
1279 /// load/store left/right
1280 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1281 AdditionalPredicates = [NotInMicroMips] in {
1282 def LWL : LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>,
1283 ISA_MIPS1_NOT_32R6_64R6;
1284 def LWR : LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>,
1285 ISA_MIPS1_NOT_32R6_64R6;
1286 def SWL : StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>,
1287 ISA_MIPS1_NOT_32R6_64R6;
1288 def SWR : StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>,
1289 ISA_MIPS1_NOT_32R6_64R6;
1292 let AdditionalPredicates = [NotInMicroMips] in {
1293 // COP2 Memory Instructions
1294 def LWC2 : LW_FT2<"lwc2", COP2Opnd, NoItinerary, load>, LW_FM<0x32>,
1295 ISA_MIPS1_NOT_32R6_64R6;
1296 def SWC2 : SW_FT2<"swc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3a>,
1297 ISA_MIPS1_NOT_32R6_64R6;
1298 def LDC2 : LW_FT2<"ldc2", COP2Opnd, NoItinerary, load>, LW_FM<0x36>,
1299 ISA_MIPS2_NOT_32R6_64R6;
1300 def SDC2 : SW_FT2<"sdc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3e>,
1301 ISA_MIPS2_NOT_32R6_64R6;
1303 // COP3 Memory Instructions
1304 let DecoderNamespace = "COP3_" in {
1305 def LWC3 : LW_FT3<"lwc3", COP3Opnd, NoItinerary, load>, LW_FM<0x33>;
1306 def SWC3 : SW_FT3<"swc3", COP3Opnd, NoItinerary, store>, LW_FM<0x3b>;
1307 def LDC3 : LW_FT3<"ldc3", COP3Opnd, NoItinerary, load>, LW_FM<0x37>,
1309 def SDC3 : SW_FT3<"sdc3", COP3Opnd, NoItinerary, store>, LW_FM<0x3f>,
1314 def SYNC : MMRel, SYNC_FT<"sync">, SYNC_FM, ISA_MIPS32;
1315 def SYNCI : MMRel, SYNCI_FT<"synci">, SYNCI_FM, ISA_MIPS32R2;
1317 let AdditionalPredicates = [NotInMicroMips] in {
1318 def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM<0x34>, ISA_MIPS2;
1319 def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM<0x30>, ISA_MIPS2;
1320 def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd>, TEQ_FM<0x31>, ISA_MIPS2;
1321 def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd>, TEQ_FM<0x32>, ISA_MIPS2;
1322 def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd>, TEQ_FM<0x33>, ISA_MIPS2;
1323 def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd>, TEQ_FM<0x36>, ISA_MIPS2;
1326 def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd>, TEQI_FM<0xc>,
1327 ISA_MIPS2_NOT_32R6_64R6;
1328 def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd>, TEQI_FM<0x8>,
1329 ISA_MIPS2_NOT_32R6_64R6;
1330 def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd>, TEQI_FM<0x9>,
1331 ISA_MIPS2_NOT_32R6_64R6;
1332 def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd>, TEQI_FM<0xa>,
1333 ISA_MIPS2_NOT_32R6_64R6;
1334 def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd>, TEQI_FM<0xb>,
1335 ISA_MIPS2_NOT_32R6_64R6;
1336 def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd>, TEQI_FM<0xe>,
1337 ISA_MIPS2_NOT_32R6_64R6;
1339 let AdditionalPredicates = [NotInMicroMips] in {
1340 def BREAK : MMRel, StdMMR6Rel, BRK_FT<"break">, BRK_FM<0xd>;
1342 def SYSCALL : MMRel, SYS_FT<"syscall">, SYS_FM<0xc>;
1343 def TRAP : TrapBase<BREAK>;
1344 def SDBBP : MMRel, SYS_FT<"sdbbp">, SDBBP_FM, ISA_MIPS32_NOT_32R6_64R6;
1346 let AdditionalPredicates = [NotInMicroMips] in {
1347 def ERET : MMRel, ER_FT<"eret">, ER_FM<0x18, 0x0>, INSN_MIPS3_32;
1348 def ERETNC : MMRel, ER_FT<"eretnc">, ER_FM<0x18, 0x1>, ISA_MIPS32R5;
1350 def DERET : MMRel, ER_FT<"deret">, ER_FM<0x1f, 0x0>, ISA_MIPS32;
1352 let AdditionalPredicates = [NotInMicroMips] in {
1353 def EI : MMRel, StdMMR6Rel, DEI_FT<"ei", GPR32Opnd>, EI_FM<1>, ISA_MIPS32R2;
1355 def DI : MMRel, DEI_FT<"di", GPR32Opnd>, EI_FM<0>, ISA_MIPS32R2;
1357 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1358 AdditionalPredicates = [NotInMicroMips] in {
1359 def WAIT : WAIT_FT<"wait">, WAIT_FM;
1361 /// Load-linked, Store-conditional
1362 def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, ISA_MIPS2_NOT_32R6_64R6;
1363 def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, ISA_MIPS2_NOT_32R6_64R6;
1366 /// Jump and Branch Instructions
1367 def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
1368 AdditionalRequires<[RelocStatic]>, IsBranch;
1369 def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>;
1370 def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>;
1371 def BEQL : MMRel, CBranch<"beql", brtarget, seteq, GPR32Opnd, 0>,
1372 BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6;
1373 def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>;
1374 def BNEL : MMRel, CBranch<"bnel", brtarget, setne, GPR32Opnd, 0>,
1375 BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6;
1376 def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
1378 def BGEZL : MMRel, CBranchZero<"bgezl", brtarget, setge, GPR32Opnd, 0>,
1379 BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6;
1380 def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
1382 def BGTZL : MMRel, CBranchZero<"bgtzl", brtarget, setgt, GPR32Opnd, 0>,
1383 BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6;
1384 def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
1386 def BLEZL : MMRel, CBranchZero<"blezl", brtarget, setle, GPR32Opnd, 0>,
1387 BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6;
1388 def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
1390 def BLTZL : MMRel, CBranchZero<"bltzl", brtarget, setlt, GPR32Opnd, 0>,
1391 BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6;
1392 def B : UncondBranch<BEQ>;
1394 def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>;
1395 let AdditionalPredicates = [NotInMicroMips] in {
1396 def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM;
1397 def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>;
1400 def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>,
1401 ISA_MIPS32_NOT_32R6_64R6;
1402 def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>,
1403 ISA_MIPS1_NOT_32R6_64R6;
1404 def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd, 0>,
1405 BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6;
1406 def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>,
1407 ISA_MIPS1_NOT_32R6_64R6;
1408 def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd, 0>,
1409 BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6;
1410 def BAL_BR : BAL_BR_Pseudo<BGEZAL>;
1411 def TAILCALL : TailCall<J>;
1412 def TAILCALL_R : TailCallReg<GPR32Opnd, JR>;
1414 // Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64
1415 // then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA.
1416 class PseudoIndirectBranchBase<RegisterOperand RO> :
1417 MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)], IIBranch> {
1420 let hasDelaySlot = 1;
1422 let isIndirectBranch = 1;
1425 def PseudoIndirectBranch : PseudoIndirectBranchBase<GPR32Opnd>;
1427 // Return instructions are matched as a RetRA instruction, then ar expanded
1428 // into PseudoReturn/PseudoReturn64 after register allocation. Finally,
1429 // MipsAsmPrinter expands this into JR, JR64, JALR, or JALR64 depending on the
1431 class PseudoReturnBase<RegisterOperand RO> : MipsPseudo<(outs), (ins RO:$rs),
1433 let isTerminator = 1;
1435 let hasDelaySlot = 1;
1437 let isCodeGenOnly = 1;
1439 let hasExtraSrcRegAllocReq = 1;
1442 def PseudoReturn : PseudoReturnBase<GPR32Opnd>;
1444 // Exception handling related node and instructions.
1445 // The conversion sequence is:
1446 // ISD::EH_RETURN -> MipsISD::EH_RETURN ->
1447 // MIPSeh_return -> (stack change + indirect branch)
1449 // MIPSeh_return takes the place of regular return instruction
1450 // but takes two arguments (V1, V0) which are used for storing
1451 // the offset and return address respectively.
1452 def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
1454 def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
1455 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
1457 let Uses = [V0, V1], isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1458 def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
1459 [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
1460 def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff,
1462 [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
1465 /// Multiply and Divide Instructions.
1466 def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
1467 MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6;
1468 def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
1469 MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6;
1470 def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
1471 MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6;
1472 def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
1473 MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6;
1475 def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>,
1476 ISA_MIPS1_NOT_32R6_64R6;
1477 def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>,
1478 ISA_MIPS1_NOT_32R6_64R6;
1479 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1480 AdditionalPredicates = [NotInMicroMips] in {
1481 def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>,
1482 ISA_MIPS1_NOT_32R6_64R6;
1483 def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>,
1484 ISA_MIPS1_NOT_32R6_64R6;
1487 /// Sign Ext In Register Instructions.
1488 def SEB : MMRel, StdMMR6Rel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,
1489 SEB_FM<0x10, 0x20>, ISA_MIPS32R2;
1490 def SEH : MMRel, StdMMR6Rel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
1491 SEB_FM<0x18, 0x20>, ISA_MIPS32R2;
1494 def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd>, CLO_FM<0x20>,
1495 ISA_MIPS32_NOT_32R6_64R6;
1496 def CLO : MMRel, CountLeading1<"clo", GPR32Opnd>, CLO_FM<0x21>,
1497 ISA_MIPS32_NOT_32R6_64R6;
1499 /// Word Swap Bytes Within Halfwords
1500 def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd>, SEB_FM<2, 0x20>, ISA_MIPS32R2;
1503 def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>;
1505 // FrameIndexes are legalized when they are operands from load/store
1506 // instructions. The same not happens for stack address copies, so an
1507 // add op with mem ComplexPattern is used and the stack address copy
1508 // can be matched. It's similar to Sparc LEA_ADDRi
1509 def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>;
1512 def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>,
1513 ISA_MIPS32_NOT_32R6_64R6;
1514 def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>,
1515 ISA_MIPS32_NOT_32R6_64R6;
1516 def MSUB : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>,
1517 ISA_MIPS32_NOT_32R6_64R6;
1518 def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>,
1519 ISA_MIPS32_NOT_32R6_64R6;
1521 let AdditionalPredicates = [NotDSP] in {
1522 def PseudoMULT : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>,
1523 ISA_MIPS1_NOT_32R6_64R6;
1524 def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>,
1525 ISA_MIPS1_NOT_32R6_64R6;
1526 def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>, ISA_MIPS1_NOT_32R6_64R6;
1527 def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>, ISA_MIPS1_NOT_32R6_64R6;
1528 def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>, ISA_MIPS1_NOT_32R6_64R6;
1529 def PseudoMADD : MAddSubPseudo<MADD, MipsMAdd, II_MADD>,
1530 ISA_MIPS32_NOT_32R6_64R6;
1531 def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>,
1532 ISA_MIPS32_NOT_32R6_64R6;
1533 def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>,
1534 ISA_MIPS32_NOT_32R6_64R6;
1535 def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>,
1536 ISA_MIPS32_NOT_32R6_64R6;
1539 def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV,
1540 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
1541 def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU,
1542 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
1544 def RDHWR : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM;
1546 def EXT : MMRel, ExtBase<"ext", GPR32Opnd, uimm5, MipsExt>, EXT_FM<0>;
1547 def INS : MMRel, InsBase<"ins", GPR32Opnd, uimm5, MipsIns>, EXT_FM<4>;
1549 /// Move Control Registers From/To CPU Registers
1550 def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd>, MFC3OP_FM<0x10, 0>, ISA_MIPS32;
1551 def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd>, MFC3OP_FM<0x10, 4>, ISA_MIPS32;
1552 def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd>, MFC3OP_FM<0x12, 0>;
1553 def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd>, MFC3OP_FM<0x12, 4>;
1555 class Barrier<string asmstr> : InstSE<(outs), (ins), asmstr, [], NoItinerary,
1557 def SSNOP : MMRel, Barrier<"ssnop">, BARRIER_FM<1>;
1558 def EHB : MMRel, Barrier<"ehb">, BARRIER_FM<3>;
1559 def PAUSE : MMRel, Barrier<"pause">, BARRIER_FM<5>, ISA_MIPS32R2;
1561 // JR_HB and JALR_HB are defined here using the new style naming
1562 // scheme because some of this code is shared with Mips32r6InstrInfo.td
1563 // and because of that it doesn't follow the naming convention of the
1564 // rest of the file. To avoid a mixture of old vs new style, the new
1565 // style was chosen.
1566 class JR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
1567 dag OutOperandList = (outs);
1568 dag InOperandList = (ins GPROpnd:$rs);
1569 string AsmString = !strconcat(instr_asm, "\t$rs");
1570 list<dag> Pattern = [];
1573 class JALR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
1574 dag OutOperandList = (outs GPROpnd:$rd);
1575 dag InOperandList = (ins GPROpnd:$rs);
1576 string AsmString = !strconcat(instr_asm, "\t$rd, $rs");
1577 list<dag> Pattern = [];
1580 class JR_HB_DESC : InstSE<(outs), (ins), "", [], NoItinerary, FrmJ>,
1581 JR_HB_DESC_BASE<"jr.hb", GPR32Opnd> {
1583 let isIndirectBranch=1;
1589 class JALR_HB_DESC : InstSE<(outs), (ins), "", [], NoItinerary, FrmJ>,
1590 JALR_HB_DESC_BASE<"jalr.hb", GPR32Opnd> {
1591 let isIndirectBranch=1;
1595 class JR_HB_ENC : JR_HB_FM<8>;
1596 class JALR_HB_ENC : JALR_HB_FM<9>;
1598 def JR_HB : JR_HB_DESC, JR_HB_ENC, ISA_MIPS32_NOT_32R6_64R6;
1599 def JALR_HB : JALR_HB_DESC, JALR_HB_ENC, ISA_MIPS32;
1601 class TLB<string asmstr> : InstSE<(outs), (ins), asmstr, [], NoItinerary,
1603 def TLBP : MMRel, TLB<"tlbp">, COP0_TLB_FM<0x08>;
1604 def TLBR : MMRel, TLB<"tlbr">, COP0_TLB_FM<0x01>;
1605 def TLBWI : MMRel, TLB<"tlbwi">, COP0_TLB_FM<0x02>;
1606 def TLBWR : MMRel, TLB<"tlbwr">, COP0_TLB_FM<0x06>;
1608 class CacheOp<string instr_asm, Operand MemOpnd> :
1609 InstSE<(outs), (ins MemOpnd:$addr, uimm5:$hint),
1610 !strconcat(instr_asm, "\t$hint, $addr"), [], NoItinerary, FrmOther,
1612 let DecoderMethod = "DecodeCacheOp";
1615 def CACHE : MMRel, CacheOp<"cache", mem>, CACHEOP_FM<0b101111>,
1616 INSN_MIPS3_32_NOT_32R6_64R6;
1617 def PREF : MMRel, CacheOp<"pref", mem>, CACHEOP_FM<0b110011>,
1618 INSN_MIPS3_32_NOT_32R6_64R6;
1620 //===----------------------------------------------------------------------===//
1621 // Instruction aliases
1622 //===----------------------------------------------------------------------===//
1623 def : MipsInstAlias<"move $dst, $src",
1624 (OR GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
1626 let AdditionalPredicates = [NotInMicroMips];
1628 def : MipsInstAlias<"move $dst, $src",
1629 (ADDu GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
1631 let AdditionalPredicates = [NotInMicroMips];
1633 def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>,
1634 ISA_MIPS1_NOT_32R6_64R6;
1635 def : MipsInstAlias<"addu $rs, $rt, $imm",
1636 (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1637 def : MipsInstAlias<"addu $rs, $imm",
1638 (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>;
1639 def : MipsInstAlias<"add $rs, $rt, $imm",
1640 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>,
1641 ISA_MIPS1_NOT_32R6_64R6;
1642 def : MipsInstAlias<"add $rs, $imm",
1643 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>,
1644 ISA_MIPS1_NOT_32R6_64R6;
1645 def : MipsInstAlias<"and $rs, $rt, $imm",
1646 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1647 def : MipsInstAlias<"and $rs, $imm",
1648 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>;
1649 def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>;
1650 let Predicates = [NotInMicroMips] in {
1651 def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
1653 def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>, ISA_MIPS32;
1654 def : MipsInstAlias<"not $rt, $rs",
1655 (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>;
1656 def : MipsInstAlias<"neg $rt, $rs",
1657 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
1658 def : MipsInstAlias<"negu $rt",
1659 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 0>;
1660 def : MipsInstAlias<"negu $rt, $rs",
1661 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
1662 def : MipsInstAlias<"slt $rs, $rt, $imm",
1663 (SLTi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1664 def : MipsInstAlias<"sltu $rt, $rs, $imm",
1665 (SLTiu GPR32Opnd:$rt, GPR32Opnd:$rs, simm16:$imm), 0>;
1666 def : MipsInstAlias<"xor $rs, $rt, $imm",
1667 (XORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
1668 def : MipsInstAlias<"xor $rs, $imm",
1669 (XORi GPR32Opnd:$rs, GPR32Opnd:$rs, uimm16:$imm), 0>;
1670 def : MipsInstAlias<"or $rs, $rt, $imm",
1671 (ORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
1672 def : MipsInstAlias<"or $rs, $imm",
1673 (ORi GPR32Opnd:$rs, GPR32Opnd:$rs, uimm16:$imm), 0>;
1674 let AdditionalPredicates = [NotInMicroMips] in {
1675 def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>;
1677 def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>;
1678 def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>;
1679 def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, COP2Opnd:$rd, 0), 0>;
1680 def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 COP2Opnd:$rd, GPR32Opnd:$rt, 0), 0>;
1681 let AdditionalPredicates = [NotInMicroMips] in {
1682 def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>;
1684 def : MipsInstAlias<"bnez $rs,$offset",
1685 (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1686 def : MipsInstAlias<"bnezl $rs,$offset",
1687 (BNEL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1688 def : MipsInstAlias<"beqz $rs,$offset",
1689 (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1690 def : MipsInstAlias<"beqzl $rs,$offset",
1691 (BEQL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1692 def : MipsInstAlias<"syscall", (SYSCALL 0), 1>;
1694 def : MipsInstAlias<"break", (BREAK 0, 0), 1>;
1695 def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>;
1696 let AdditionalPredicates = [NotInMicroMips] in {
1697 def : MipsInstAlias<"ei", (EI ZERO), 1>, ISA_MIPS32R2;
1699 def : MipsInstAlias<"di", (DI ZERO), 1>, ISA_MIPS32R2;
1700 let AdditionalPredicates = [NotInMicroMips] in {
1701 def : MipsInstAlias<"teq $rs, $rt",
1702 (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1703 def : MipsInstAlias<"tge $rs, $rt",
1704 (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1705 def : MipsInstAlias<"tgeu $rs, $rt",
1706 (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1707 def : MipsInstAlias<"tlt $rs, $rt",
1708 (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1709 def : MipsInstAlias<"tltu $rs, $rt",
1710 (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1711 def : MipsInstAlias<"tne $rs, $rt",
1712 (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1714 def : MipsInstAlias<"sll $rd, $rt, $rs",
1715 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1716 def : MipsInstAlias<"sub, $rd, $rs, $imm",
1717 (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs,
1718 InvertedImOperand:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6;
1719 def : MipsInstAlias<"sub $rs, $imm",
1720 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm),
1721 0>, ISA_MIPS1_NOT_32R6_64R6;
1722 def : MipsInstAlias<"subu, $rd, $rs, $imm",
1723 (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs,
1724 InvertedImOperand:$imm), 0>;
1725 def : MipsInstAlias<"subu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs,
1726 InvertedImOperand:$imm), 0>;
1727 def : MipsInstAlias<"sra $rd, $rt, $rs",
1728 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1729 def : MipsInstAlias<"srl $rd, $rt, $rs",
1730 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1731 def : MipsInstAlias<"sdbbp", (SDBBP 0)>, ISA_MIPS32_NOT_32R6_64R6;
1732 def : MipsInstAlias<"sync",
1733 (SYNC 0), 1>, ISA_MIPS2;
1734 //===----------------------------------------------------------------------===//
1735 // Assembler Pseudo Instructions
1736 //===----------------------------------------------------------------------===//
1738 class LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> :
1739 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
1740 !strconcat(instr_asm, "\t$rt, $imm32")> ;
1741 def LoadImm32 : LoadImmediate32<"li", uimm5, GPR32Opnd>;
1743 class LoadAddressFromReg32<string instr_asm, Operand MemOpnd,
1744 RegisterOperand RO> :
1745 MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
1746 !strconcat(instr_asm, "\t$rt, $addr")> ;
1747 def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>;
1749 class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> :
1750 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
1751 !strconcat(instr_asm, "\t$rt, $imm32")> ;
1752 def LoadAddrImm32 : LoadAddressFromImm32<"la", uimm5, GPR32Opnd>;
1754 def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
1756 def JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs),
1759 let hasDelaySlot = 1 in {
1760 def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
1761 (ins imm64:$imm64, brtarget:$offset),
1762 "bne\t$rt, $imm64, $offset">;
1763 def BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
1764 (ins imm64:$imm64, brtarget:$offset),
1765 "beq\t$rt, $imm64, $offset">;
1767 class CondBranchPseudo<string instr_asm> :
1768 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt,
1770 !strconcat(instr_asm, "\t$rs, $rt, $offset")>;
1773 def BLT : CondBranchPseudo<"blt">;
1774 def BLE : CondBranchPseudo<"ble">;
1775 def BGE : CondBranchPseudo<"bge">;
1776 def BGT : CondBranchPseudo<"bgt">;
1777 def BLTU : CondBranchPseudo<"bltu">;
1778 def BLEU : CondBranchPseudo<"bleu">;
1779 def BGEU : CondBranchPseudo<"bgeu">;
1780 def BGTU : CondBranchPseudo<"bgtu">;
1781 def BLTL : CondBranchPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
1782 def BLEL : CondBranchPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
1783 def BGEL : CondBranchPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
1784 def BGTL : CondBranchPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
1785 def BLTUL: CondBranchPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
1786 def BLEUL: CondBranchPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
1787 def BGEUL: CondBranchPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
1788 def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
1790 // FIXME: Predicates are removed because instructions are matched regardless of
1791 // predicates, because PredicateControl was not in the hierarchy. This was
1792 // done to emit more precise error message from expansion function.
1793 // Once the tablegen-erated errors are made better, this needs to be fixed and
1794 // predicates needs to be restored.
1796 def SDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1797 "div\t$rs, $rt">; //, ISA_MIPS1_NOT_32R6_64R6;
1799 def UDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1800 "divu\t$rs, $rt">; //, ISA_MIPS1_NOT_32R6_64R6;
1802 def DSDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1803 "ddiv\t$rs, $rt">; //, ISA_MIPS64_NOT_64R6;
1805 def DUDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1806 "ddivu\t$rs, $rt">; //, ISA_MIPS64_NOT_64R6;
1808 def Ulhu : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
1809 "ulhu\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
1811 def Ulw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
1812 "ulw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
1814 //===----------------------------------------------------------------------===//
1815 // Arbitrary patterns that map to one or more instructions
1816 //===----------------------------------------------------------------------===//
1818 // Load/store pattern templates.
1819 class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
1820 MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
1822 class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
1823 MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
1826 let AdditionalPredicates = [NotInMicroMips] in {
1827 def : MipsPat<(i32 immSExt16:$in),
1828 (ADDiu ZERO, imm:$in)>;
1829 def : MipsPat<(i32 immZExt16:$in),
1830 (ORi ZERO, imm:$in)>;
1832 def : MipsPat<(i32 immLow16Zero:$in),
1833 (LUi (HI16 imm:$in))>;
1835 // Arbitrary immediates
1836 def : MipsPat<(i32 imm:$imm),
1837 (ORi (LUi (HI16 imm:$imm)), (LO16 imm:$imm))>;
1839 // Carry MipsPatterns
1840 def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
1841 (SUBu GPR32:$lhs, GPR32:$rhs)>;
1842 let AdditionalPredicates = [NotDSP] in {
1843 def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
1844 (ADDu GPR32:$lhs, GPR32:$rhs)>;
1845 def : MipsPat<(addc GPR32:$src, immSExt16:$imm),
1846 (ADDiu GPR32:$src, imm:$imm)>;
1849 // Support multiplication for pre-Mips32 targets that don't have
1850 // the MUL instruction.
1851 def : MipsPat<(mul GPR32:$lhs, GPR32:$rhs),
1852 (PseudoMFLO (PseudoMULT GPR32:$lhs, GPR32:$rhs))>,
1853 ISA_MIPS1_NOT_32R6_64R6;
1856 def : MipsPat<(MipsSync (i32 immz)),
1857 (SYNC 0)>, ISA_MIPS2;
1860 def : MipsPat<(MipsJmpLink (i32 tglobaladdr:$dst)),
1861 (JAL tglobaladdr:$dst)>;
1862 def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
1863 (JAL texternalsym:$dst)>;
1864 //def : MipsPat<(MipsJmpLink GPR32:$dst),
1865 // (JALR GPR32:$dst)>;
1868 def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
1869 (TAILCALL tglobaladdr:$dst)>;
1870 def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
1871 (TAILCALL texternalsym:$dst)>;
1873 def : MipsPat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
1874 def : MipsPat<(MipsHi tblockaddress:$in), (LUi tblockaddress:$in)>;
1875 def : MipsPat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>;
1876 def : MipsPat<(MipsHi tconstpool:$in), (LUi tconstpool:$in)>;
1877 def : MipsPat<(MipsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>;
1878 def : MipsPat<(MipsHi texternalsym:$in), (LUi texternalsym:$in)>;
1880 def : MipsPat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
1881 def : MipsPat<(MipsLo tblockaddress:$in), (ADDiu ZERO, tblockaddress:$in)>;
1882 def : MipsPat<(MipsLo tjumptable:$in), (ADDiu ZERO, tjumptable:$in)>;
1883 def : MipsPat<(MipsLo tconstpool:$in), (ADDiu ZERO, tconstpool:$in)>;
1884 def : MipsPat<(MipsLo tglobaltlsaddr:$in), (ADDiu ZERO, tglobaltlsaddr:$in)>;
1885 def : MipsPat<(MipsLo texternalsym:$in), (ADDiu ZERO, texternalsym:$in)>;
1887 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaladdr:$lo)),
1888 (ADDiu GPR32:$hi, tglobaladdr:$lo)>;
1889 def : MipsPat<(add GPR32:$hi, (MipsLo tblockaddress:$lo)),
1890 (ADDiu GPR32:$hi, tblockaddress:$lo)>;
1891 def : MipsPat<(add GPR32:$hi, (MipsLo tjumptable:$lo)),
1892 (ADDiu GPR32:$hi, tjumptable:$lo)>;
1893 def : MipsPat<(add GPR32:$hi, (MipsLo tconstpool:$lo)),
1894 (ADDiu GPR32:$hi, tconstpool:$lo)>;
1895 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaltlsaddr:$lo)),
1896 (ADDiu GPR32:$hi, tglobaltlsaddr:$lo)>;
1899 def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
1900 (ADDiu GPR32:$gp, tglobaladdr:$in)>;
1901 def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
1902 (ADDiu GPR32:$gp, tconstpool:$in)>;
1905 class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
1906 MipsPat<(MipsWrapper RC:$gp, node:$in),
1907 (ADDiuOp RC:$gp, node:$in)>;
1909 def : WrapperPat<tglobaladdr, ADDiu, GPR32>;
1910 def : WrapperPat<tconstpool, ADDiu, GPR32>;
1911 def : WrapperPat<texternalsym, ADDiu, GPR32>;
1912 def : WrapperPat<tblockaddress, ADDiu, GPR32>;
1913 def : WrapperPat<tjumptable, ADDiu, GPR32>;
1914 def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>;
1916 let AdditionalPredicates = [NotInMicroMips] in {
1917 // Mips does not have "not", so we expand our way
1918 def : MipsPat<(not GPR32:$in),
1919 (NOR GPR32Opnd:$in, ZERO)>;
1923 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>;
1924 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>;
1925 def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
1928 def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>;
1931 multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BNEOp,
1932 Instruction SLTOp, Instruction SLTuOp, Instruction SLTiOp,
1933 Instruction SLTiuOp, Register ZEROReg> {
1934 def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
1935 (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
1936 def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
1937 (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
1939 def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
1940 (BEQ (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
1941 def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
1942 (BEQ (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
1943 def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
1944 (BEQ (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
1945 def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
1946 (BEQ (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
1947 def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
1948 (BEQ (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
1949 def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
1950 (BEQ (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
1952 def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
1953 (BEQ (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
1954 def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
1955 (BEQ (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
1957 def : MipsPat<(brcond RC:$cond, bb:$dst),
1958 (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
1961 defm : BrcondPats<GPR32, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>;
1963 def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
1964 (BLEZ i32:$lhs, bb:$dst)>;
1965 def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
1966 (BGEZ i32:$lhs, bb:$dst)>;
1969 multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp,
1970 Instruction SLTuOp, Register ZEROReg> {
1971 def : MipsPat<(seteq RC:$lhs, 0),
1972 (SLTiuOp RC:$lhs, 1)>;
1973 def : MipsPat<(setne RC:$lhs, 0),
1974 (SLTuOp ZEROReg, RC:$lhs)>;
1975 def : MipsPat<(seteq RC:$lhs, RC:$rhs),
1976 (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>;
1977 def : MipsPat<(setne RC:$lhs, RC:$rhs),
1978 (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
1981 multiclass SetlePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1982 def : MipsPat<(setle RC:$lhs, RC:$rhs),
1983 (XORi (SLTOp RC:$rhs, RC:$lhs), 1)>;
1984 def : MipsPat<(setule RC:$lhs, RC:$rhs),
1985 (XORi (SLTuOp RC:$rhs, RC:$lhs), 1)>;
1988 multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1989 def : MipsPat<(setgt RC:$lhs, RC:$rhs),
1990 (SLTOp RC:$rhs, RC:$lhs)>;
1991 def : MipsPat<(setugt RC:$lhs, RC:$rhs),
1992 (SLTuOp RC:$rhs, RC:$lhs)>;
1995 multiclass SetgePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1996 def : MipsPat<(setge RC:$lhs, RC:$rhs),
1997 (XORi (SLTOp RC:$lhs, RC:$rhs), 1)>;
1998 def : MipsPat<(setuge RC:$lhs, RC:$rhs),
1999 (XORi (SLTuOp RC:$lhs, RC:$rhs), 1)>;
2002 multiclass SetgeImmPats<RegisterClass RC, Instruction SLTiOp,
2003 Instruction SLTiuOp> {
2004 def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
2005 (XORi (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
2006 def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
2007 (XORi (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
2010 defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>;
2011 defm : SetlePats<GPR32, SLT, SLTu>;
2012 defm : SetgtPats<GPR32, SLT, SLTu>;
2013 defm : SetgePats<GPR32, SLT, SLTu>;
2014 defm : SetgeImmPats<GPR32, SLTi, SLTiu>;
2017 def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>;
2019 // Load halfword/word patterns.
2020 let AddedComplexity = 40 in {
2021 def : LoadRegImmPat<LBu, i32, zextloadi8>;
2022 def : LoadRegImmPat<LH, i32, sextloadi16>;
2023 let AdditionalPredicates = [NotInMicroMips] in {
2024 def : LoadRegImmPat<LW, i32, load>;
2028 //===----------------------------------------------------------------------===//
2029 // Floating Point Support
2030 //===----------------------------------------------------------------------===//
2032 include "MipsInstrFPU.td"
2033 include "Mips64InstrInfo.td"
2034 include "MipsCondMov.td"
2036 include "Mips32r6InstrInfo.td"
2037 include "Mips64r6InstrInfo.td"
2042 include "Mips16InstrFormats.td"
2043 include "Mips16InstrInfo.td"
2046 include "MipsDSPInstrFormats.td"
2047 include "MipsDSPInstrInfo.td"
2050 include "MipsMSAInstrFormats.td"
2051 include "MipsMSAInstrInfo.td"
2054 include "MipsEVAInstrFormats.td"
2055 include "MipsEVAInstrInfo.td"
2058 include "MicroMipsInstrFormats.td"
2059 include "MicroMipsInstrInfo.td"
2060 include "MicroMipsInstrFPU.td"
2063 include "MicroMips32r6InstrFormats.td"
2064 include "MicroMips32r6InstrInfo.td"
2067 include "MicroMips64r6InstrFormats.td"
2068 include "MicroMips64r6InstrInfo.td"