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 InstrItinClass itin = NoItinerary>:
1053 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [], itin,
1055 let hasSideEffects = 0;
1059 class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> :
1060 InstSE<(outs CPURegOperand:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [],
1061 II_RDHWR, FrmR, "rdhwr">;
1064 class ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1065 SDPatternOperator Op = null_frag>:
1066 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, size_ext:$size),
1067 !strconcat(opstr, " $rt, $rs, $pos, $size"),
1068 [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size))], II_EXT,
1069 FrmR, opstr>, ISA_MIPS32R2;
1071 class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1072 SDPatternOperator Op = null_frag>:
1073 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, size_ins:$size, RO:$src),
1074 !strconcat(opstr, " $rt, $rs, $pos, $size"),
1075 [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size, RO:$src))],
1076 II_INS, FrmR, opstr>, ISA_MIPS32R2 {
1077 let Constraints = "$src = $rt";
1080 // Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*).
1081 class Atomic2Ops<PatFrag Op, RegisterClass DRC> :
1082 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr),
1083 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]>;
1085 // Atomic Compare & Swap.
1086 class AtomicCmpSwap<PatFrag Op, RegisterClass DRC> :
1087 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap),
1088 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]>;
1090 class LLBase<string opstr, RegisterOperand RO> :
1091 InstSE<(outs RO:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1092 [], NoItinerary, FrmI> {
1093 let DecoderMethod = "DecodeMem";
1097 class SCBase<string opstr, RegisterOperand RO> :
1098 InstSE<(outs RO:$dst), (ins RO:$rt, mem:$addr),
1099 !strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> {
1100 let DecoderMethod = "DecodeMem";
1102 let Constraints = "$rt = $dst";
1105 class MFC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD> :
1106 InstSE<(outs RO:$rt), (ins RD:$rd, uimm16:$sel),
1107 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], NoItinerary, FrmFR>;
1109 class MTC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD> :
1110 InstSE<(outs RO:$rd), (ins RD:$rt, uimm16:$sel),
1111 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], NoItinerary, FrmFR>;
1113 class TrapBase<Instruction RealInst>
1114 : PseudoSE<(outs), (ins), [(trap)], NoItinerary>,
1115 PseudoInstExpansion<(RealInst 0, 0)> {
1117 let isTerminator = 1;
1118 let isCodeGenOnly = 1;
1121 //===----------------------------------------------------------------------===//
1122 // Pseudo instructions
1123 //===----------------------------------------------------------------------===//
1126 let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1 in
1127 def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
1129 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
1130 def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt),
1131 [(callseq_start timm:$amt)]>;
1132 def ADJCALLSTACKUP : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1133 [(callseq_end timm:$amt1, timm:$amt2)]>;
1136 let usesCustomInserter = 1 in {
1137 def ATOMIC_LOAD_ADD_I8 : Atomic2Ops<atomic_load_add_8, GPR32>;
1138 def ATOMIC_LOAD_ADD_I16 : Atomic2Ops<atomic_load_add_16, GPR32>;
1139 def ATOMIC_LOAD_ADD_I32 : Atomic2Ops<atomic_load_add_32, GPR32>;
1140 def ATOMIC_LOAD_SUB_I8 : Atomic2Ops<atomic_load_sub_8, GPR32>;
1141 def ATOMIC_LOAD_SUB_I16 : Atomic2Ops<atomic_load_sub_16, GPR32>;
1142 def ATOMIC_LOAD_SUB_I32 : Atomic2Ops<atomic_load_sub_32, GPR32>;
1143 def ATOMIC_LOAD_AND_I8 : Atomic2Ops<atomic_load_and_8, GPR32>;
1144 def ATOMIC_LOAD_AND_I16 : Atomic2Ops<atomic_load_and_16, GPR32>;
1145 def ATOMIC_LOAD_AND_I32 : Atomic2Ops<atomic_load_and_32, GPR32>;
1146 def ATOMIC_LOAD_OR_I8 : Atomic2Ops<atomic_load_or_8, GPR32>;
1147 def ATOMIC_LOAD_OR_I16 : Atomic2Ops<atomic_load_or_16, GPR32>;
1148 def ATOMIC_LOAD_OR_I32 : Atomic2Ops<atomic_load_or_32, GPR32>;
1149 def ATOMIC_LOAD_XOR_I8 : Atomic2Ops<atomic_load_xor_8, GPR32>;
1150 def ATOMIC_LOAD_XOR_I16 : Atomic2Ops<atomic_load_xor_16, GPR32>;
1151 def ATOMIC_LOAD_XOR_I32 : Atomic2Ops<atomic_load_xor_32, GPR32>;
1152 def ATOMIC_LOAD_NAND_I8 : Atomic2Ops<atomic_load_nand_8, GPR32>;
1153 def ATOMIC_LOAD_NAND_I16 : Atomic2Ops<atomic_load_nand_16, GPR32>;
1154 def ATOMIC_LOAD_NAND_I32 : Atomic2Ops<atomic_load_nand_32, GPR32>;
1156 def ATOMIC_SWAP_I8 : Atomic2Ops<atomic_swap_8, GPR32>;
1157 def ATOMIC_SWAP_I16 : Atomic2Ops<atomic_swap_16, GPR32>;
1158 def ATOMIC_SWAP_I32 : Atomic2Ops<atomic_swap_32, GPR32>;
1160 def ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap<atomic_cmp_swap_8, GPR32>;
1161 def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap<atomic_cmp_swap_16, GPR32>;
1162 def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_32, GPR32>;
1165 /// Pseudo instructions for loading and storing accumulator registers.
1166 let isPseudo = 1, isCodeGenOnly = 1 in {
1167 def LOAD_ACC64 : Load<"", ACC64>;
1168 def STORE_ACC64 : Store<"", ACC64>;
1171 // We need these two pseudo instructions to avoid offset calculation for long
1172 // branches. See the comment in file MipsLongBranch.cpp for detailed
1175 // Expands to: lui $dst, %hi($tgt - $baltgt)
1176 def LONG_BRANCH_LUi : PseudoSE<(outs GPR32Opnd:$dst),
1177 (ins brtarget:$tgt, brtarget:$baltgt), []>;
1179 // Expands to: addiu $dst, $src, %lo($tgt - $baltgt)
1180 def LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst),
1181 (ins GPR32Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []>;
1183 //===----------------------------------------------------------------------===//
1184 // Instruction definition
1185 //===----------------------------------------------------------------------===//
1186 //===----------------------------------------------------------------------===//
1187 // MipsI Instructions
1188 //===----------------------------------------------------------------------===//
1190 /// Arithmetic Instructions (ALU Immediate)
1191 let AdditionalPredicates = [NotInMicroMips] in {
1192 def ADDiu : MMRel, StdMMR6Rel, ArithLogicI<"addiu", simm16, GPR32Opnd,
1193 II_ADDIU, immSExt16, add>,
1194 ADDI_FM<0x9>, IsAsCheapAsAMove;
1196 def ADDi : MMRel, ArithLogicI<"addi", simm16, GPR32Opnd>, ADDI_FM<0x8>,
1197 ISA_MIPS1_NOT_32R6_64R6;
1198 def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
1200 def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
1202 let AdditionalPredicates = [NotInMicroMips] in {
1203 def ANDi : MMRel, StdMMR6Rel,
1204 ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16, and>,
1207 def ORi : MMRel, StdMMR6Rel,
1208 ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16, or>,
1210 def XORi : MMRel, StdMMR6Rel,
1211 ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16, xor>,
1213 def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16>, LUI_FM;
1214 let AdditionalPredicates = [NotInMicroMips] in {
1215 /// Arithmetic Instructions (3-Operand, R-Type)
1216 def ADDu : MMRel, StdMMR6Rel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
1218 def SUBu : MMRel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
1221 let Defs = [HI0, LO0] in
1222 def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>,
1223 ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6;
1224 def ADD : MMRel, StdMMR6Rel, ArithLogicR<"add", GPR32Opnd>, ADD_FM<0, 0x20>;
1225 def SUB : MMRel, ArithLogicR<"sub", GPR32Opnd>, ADD_FM<0, 0x22>;
1226 def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>;
1227 def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>;
1228 let AdditionalPredicates = [NotInMicroMips] in {
1229 def AND : MMRel, StdMMR6Rel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
1231 def OR : MMRel, StdMMR6Rel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
1233 def XOR : MMRel, StdMMR6Rel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
1236 def NOR : MMRel, StdMMR6Rel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>;
1238 /// Shift Instructions
1239 let AdditionalPredicates = [NotInMicroMips] in {
1240 def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl,
1241 immZExt5>, SRA_FM<0, 0>;
1242 def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl,
1243 immZExt5>, SRA_FM<2, 0>;
1245 def SRA : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, sra,
1246 immZExt5>, SRA_FM<3, 0>;
1247 def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, shl>,
1249 def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, srl>,
1251 def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, sra>,
1254 // Rotate Instructions
1255 def ROTR : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr,
1257 SRA_FM<2, 1>, ISA_MIPS32R2;
1258 def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>,
1259 SRLV_FM<6, 1>, ISA_MIPS32R2;
1261 /// Load and Store Instructions
1263 def LB : Load<"lb", GPR32Opnd, sextloadi8, II_LB>, MMRel, LW_FM<0x20>;
1264 def LBu : Load<"lbu", GPR32Opnd, zextloadi8, II_LBU, addrDefault>, MMRel,
1266 def LH : Load<"lh", GPR32Opnd, sextloadi16, II_LH, addrDefault>, MMRel,
1268 def LHu : Load<"lhu", GPR32Opnd, zextloadi16, II_LHU>, MMRel, LW_FM<0x25>;
1269 let AdditionalPredicates = [NotInMicroMips] in {
1270 def LW : StdMMR6Rel, Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel,
1273 def SB : StdMMR6Rel, Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel,
1275 def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>;
1276 let AdditionalPredicates = [NotInMicroMips] in {
1277 def SW : Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>;
1280 /// load/store left/right
1281 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1282 AdditionalPredicates = [NotInMicroMips] in {
1283 def LWL : LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>,
1284 ISA_MIPS1_NOT_32R6_64R6;
1285 def LWR : LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>,
1286 ISA_MIPS1_NOT_32R6_64R6;
1287 def SWL : StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>,
1288 ISA_MIPS1_NOT_32R6_64R6;
1289 def SWR : StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>,
1290 ISA_MIPS1_NOT_32R6_64R6;
1293 let AdditionalPredicates = [NotInMicroMips] in {
1294 // COP2 Memory Instructions
1295 def LWC2 : LW_FT2<"lwc2", COP2Opnd, NoItinerary, load>, LW_FM<0x32>,
1296 ISA_MIPS1_NOT_32R6_64R6;
1297 def SWC2 : SW_FT2<"swc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3a>,
1298 ISA_MIPS1_NOT_32R6_64R6;
1299 def LDC2 : LW_FT2<"ldc2", COP2Opnd, NoItinerary, load>, LW_FM<0x36>,
1300 ISA_MIPS2_NOT_32R6_64R6;
1301 def SDC2 : SW_FT2<"sdc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3e>,
1302 ISA_MIPS2_NOT_32R6_64R6;
1304 // COP3 Memory Instructions
1305 let DecoderNamespace = "COP3_" in {
1306 def LWC3 : LW_FT3<"lwc3", COP3Opnd, NoItinerary, load>, LW_FM<0x33>;
1307 def SWC3 : SW_FT3<"swc3", COP3Opnd, NoItinerary, store>, LW_FM<0x3b>;
1308 def LDC3 : LW_FT3<"ldc3", COP3Opnd, NoItinerary, load>, LW_FM<0x37>,
1310 def SDC3 : SW_FT3<"sdc3", COP3Opnd, NoItinerary, store>, LW_FM<0x3f>,
1315 def SYNC : MMRel, SYNC_FT<"sync">, SYNC_FM, ISA_MIPS32;
1316 def SYNCI : MMRel, SYNCI_FT<"synci">, SYNCI_FM, ISA_MIPS32R2;
1318 let AdditionalPredicates = [NotInMicroMips] in {
1319 def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM<0x34>, ISA_MIPS2;
1320 def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM<0x30>, ISA_MIPS2;
1321 def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd>, TEQ_FM<0x31>, ISA_MIPS2;
1322 def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd>, TEQ_FM<0x32>, ISA_MIPS2;
1323 def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd>, TEQ_FM<0x33>, ISA_MIPS2;
1324 def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd>, TEQ_FM<0x36>, ISA_MIPS2;
1327 def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd>, TEQI_FM<0xc>,
1328 ISA_MIPS2_NOT_32R6_64R6;
1329 def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd>, TEQI_FM<0x8>,
1330 ISA_MIPS2_NOT_32R6_64R6;
1331 def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd>, TEQI_FM<0x9>,
1332 ISA_MIPS2_NOT_32R6_64R6;
1333 def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd>, TEQI_FM<0xa>,
1334 ISA_MIPS2_NOT_32R6_64R6;
1335 def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd>, TEQI_FM<0xb>,
1336 ISA_MIPS2_NOT_32R6_64R6;
1337 def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd>, TEQI_FM<0xe>,
1338 ISA_MIPS2_NOT_32R6_64R6;
1340 let AdditionalPredicates = [NotInMicroMips] in {
1341 def BREAK : MMRel, StdMMR6Rel, BRK_FT<"break">, BRK_FM<0xd>;
1343 def SYSCALL : MMRel, SYS_FT<"syscall">, SYS_FM<0xc>;
1344 def TRAP : TrapBase<BREAK>;
1345 def SDBBP : MMRel, SYS_FT<"sdbbp">, SDBBP_FM, ISA_MIPS32_NOT_32R6_64R6;
1347 let AdditionalPredicates = [NotInMicroMips] in {
1348 def ERET : MMRel, ER_FT<"eret">, ER_FM<0x18, 0x0>, INSN_MIPS3_32;
1349 def ERETNC : MMRel, ER_FT<"eretnc">, ER_FM<0x18, 0x1>, ISA_MIPS32R5;
1351 def DERET : MMRel, ER_FT<"deret">, ER_FM<0x1f, 0x0>, ISA_MIPS32;
1353 let AdditionalPredicates = [NotInMicroMips] in {
1354 def EI : MMRel, StdMMR6Rel, DEI_FT<"ei", GPR32Opnd>, EI_FM<1>, ISA_MIPS32R2;
1356 def DI : MMRel, DEI_FT<"di", GPR32Opnd>, EI_FM<0>, ISA_MIPS32R2;
1358 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1359 AdditionalPredicates = [NotInMicroMips] in {
1360 def WAIT : WAIT_FT<"wait">, WAIT_FM;
1362 /// Load-linked, Store-conditional
1363 def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, ISA_MIPS2_NOT_32R6_64R6;
1364 def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, ISA_MIPS2_NOT_32R6_64R6;
1367 /// Jump and Branch Instructions
1368 def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
1369 AdditionalRequires<[RelocStatic]>, IsBranch;
1370 def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>;
1371 def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>;
1372 def BEQL : MMRel, CBranch<"beql", brtarget, seteq, GPR32Opnd, 0>,
1373 BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6;
1374 def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>;
1375 def BNEL : MMRel, CBranch<"bnel", brtarget, setne, GPR32Opnd, 0>,
1376 BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6;
1377 def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
1379 def BGEZL : MMRel, CBranchZero<"bgezl", brtarget, setge, GPR32Opnd, 0>,
1380 BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6;
1381 def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
1383 def BGTZL : MMRel, CBranchZero<"bgtzl", brtarget, setgt, GPR32Opnd, 0>,
1384 BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6;
1385 def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
1387 def BLEZL : MMRel, CBranchZero<"blezl", brtarget, setle, GPR32Opnd, 0>,
1388 BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6;
1389 def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
1391 def BLTZL : MMRel, CBranchZero<"bltzl", brtarget, setlt, GPR32Opnd, 0>,
1392 BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6;
1393 def B : UncondBranch<BEQ>;
1395 def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>;
1396 let AdditionalPredicates = [NotInMicroMips] in {
1397 def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM;
1398 def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>;
1401 def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>,
1402 ISA_MIPS32_NOT_32R6_64R6;
1403 def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>,
1404 ISA_MIPS1_NOT_32R6_64R6;
1405 def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd, 0>,
1406 BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6;
1407 def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>,
1408 ISA_MIPS1_NOT_32R6_64R6;
1409 def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd, 0>,
1410 BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6;
1411 def BAL_BR : BAL_BR_Pseudo<BGEZAL>;
1412 def TAILCALL : TailCall<J>;
1413 def TAILCALL_R : TailCallReg<GPR32Opnd, JR>;
1415 // Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64
1416 // then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA.
1417 class PseudoIndirectBranchBase<RegisterOperand RO> :
1418 MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)], IIBranch> {
1421 let hasDelaySlot = 1;
1423 let isIndirectBranch = 1;
1426 def PseudoIndirectBranch : PseudoIndirectBranchBase<GPR32Opnd>;
1428 // Return instructions are matched as a RetRA instruction, then ar expanded
1429 // into PseudoReturn/PseudoReturn64 after register allocation. Finally,
1430 // MipsAsmPrinter expands this into JR, JR64, JALR, or JALR64 depending on the
1432 class PseudoReturnBase<RegisterOperand RO> : MipsPseudo<(outs), (ins RO:$rs),
1434 let isTerminator = 1;
1436 let hasDelaySlot = 1;
1438 let isCodeGenOnly = 1;
1440 let hasExtraSrcRegAllocReq = 1;
1443 def PseudoReturn : PseudoReturnBase<GPR32Opnd>;
1445 // Exception handling related node and instructions.
1446 // The conversion sequence is:
1447 // ISD::EH_RETURN -> MipsISD::EH_RETURN ->
1448 // MIPSeh_return -> (stack change + indirect branch)
1450 // MIPSeh_return takes the place of regular return instruction
1451 // but takes two arguments (V1, V0) which are used for storing
1452 // the offset and return address respectively.
1453 def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
1455 def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
1456 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
1458 let Uses = [V0, V1], isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1459 def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
1460 [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
1461 def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff,
1463 [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
1466 /// Multiply and Divide Instructions.
1467 def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
1468 MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6;
1469 def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
1470 MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6;
1471 def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
1472 MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6;
1473 def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
1474 MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6;
1476 def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>,
1477 ISA_MIPS1_NOT_32R6_64R6;
1478 def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>,
1479 ISA_MIPS1_NOT_32R6_64R6;
1480 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1481 AdditionalPredicates = [NotInMicroMips] in {
1482 def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>,
1483 ISA_MIPS1_NOT_32R6_64R6;
1484 def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>,
1485 ISA_MIPS1_NOT_32R6_64R6;
1488 /// Sign Ext In Register Instructions.
1489 def SEB : MMRel, StdMMR6Rel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,
1490 SEB_FM<0x10, 0x20>, ISA_MIPS32R2;
1491 def SEH : MMRel, StdMMR6Rel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
1492 SEB_FM<0x18, 0x20>, ISA_MIPS32R2;
1495 def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd>, CLO_FM<0x20>,
1496 ISA_MIPS32_NOT_32R6_64R6;
1497 def CLO : MMRel, CountLeading1<"clo", GPR32Opnd>, CLO_FM<0x21>,
1498 ISA_MIPS32_NOT_32R6_64R6;
1500 /// Word Swap Bytes Within Halfwords
1501 def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd, II_WSBH>, SEB_FM<2, 0x20>,
1505 def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>;
1507 // FrameIndexes are legalized when they are operands from load/store
1508 // instructions. The same not happens for stack address copies, so an
1509 // add op with mem ComplexPattern is used and the stack address copy
1510 // can be matched. It's similar to Sparc LEA_ADDRi
1511 def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>;
1514 def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>,
1515 ISA_MIPS32_NOT_32R6_64R6;
1516 def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>,
1517 ISA_MIPS32_NOT_32R6_64R6;
1518 def MSUB : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>,
1519 ISA_MIPS32_NOT_32R6_64R6;
1520 def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>,
1521 ISA_MIPS32_NOT_32R6_64R6;
1523 let AdditionalPredicates = [NotDSP] in {
1524 def PseudoMULT : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>,
1525 ISA_MIPS1_NOT_32R6_64R6;
1526 def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>,
1527 ISA_MIPS1_NOT_32R6_64R6;
1528 def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>, ISA_MIPS1_NOT_32R6_64R6;
1529 def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>, ISA_MIPS1_NOT_32R6_64R6;
1530 def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>, ISA_MIPS1_NOT_32R6_64R6;
1531 def PseudoMADD : MAddSubPseudo<MADD, MipsMAdd, II_MADD>,
1532 ISA_MIPS32_NOT_32R6_64R6;
1533 def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>,
1534 ISA_MIPS32_NOT_32R6_64R6;
1535 def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>,
1536 ISA_MIPS32_NOT_32R6_64R6;
1537 def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>,
1538 ISA_MIPS32_NOT_32R6_64R6;
1541 def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV,
1542 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
1543 def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU,
1544 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
1546 def RDHWR : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM;
1548 def EXT : MMRel, ExtBase<"ext", GPR32Opnd, uimm5, MipsExt>, EXT_FM<0>;
1549 def INS : MMRel, InsBase<"ins", GPR32Opnd, uimm5, MipsIns>, EXT_FM<4>;
1551 /// Move Control Registers From/To CPU Registers
1552 def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd>, MFC3OP_FM<0x10, 0>, ISA_MIPS32;
1553 def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd>, MFC3OP_FM<0x10, 4>, ISA_MIPS32;
1554 def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd>, MFC3OP_FM<0x12, 0>;
1555 def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd>, MFC3OP_FM<0x12, 4>;
1557 class Barrier<string asmstr> : InstSE<(outs), (ins), asmstr, [], NoItinerary,
1559 def SSNOP : MMRel, Barrier<"ssnop">, BARRIER_FM<1>;
1560 def EHB : MMRel, Barrier<"ehb">, BARRIER_FM<3>;
1561 def PAUSE : MMRel, Barrier<"pause">, BARRIER_FM<5>, ISA_MIPS32R2;
1563 // JR_HB and JALR_HB are defined here using the new style naming
1564 // scheme because some of this code is shared with Mips32r6InstrInfo.td
1565 // and because of that it doesn't follow the naming convention of the
1566 // rest of the file. To avoid a mixture of old vs new style, the new
1567 // style was chosen.
1568 class JR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
1569 dag OutOperandList = (outs);
1570 dag InOperandList = (ins GPROpnd:$rs);
1571 string AsmString = !strconcat(instr_asm, "\t$rs");
1572 list<dag> Pattern = [];
1575 class JALR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
1576 dag OutOperandList = (outs GPROpnd:$rd);
1577 dag InOperandList = (ins GPROpnd:$rs);
1578 string AsmString = !strconcat(instr_asm, "\t$rd, $rs");
1579 list<dag> Pattern = [];
1582 class JR_HB_DESC : InstSE<(outs), (ins), "", [], NoItinerary, FrmJ>,
1583 JR_HB_DESC_BASE<"jr.hb", GPR32Opnd> {
1585 let isIndirectBranch=1;
1591 class JALR_HB_DESC : InstSE<(outs), (ins), "", [], NoItinerary, FrmJ>,
1592 JALR_HB_DESC_BASE<"jalr.hb", GPR32Opnd> {
1593 let isIndirectBranch=1;
1597 class JR_HB_ENC : JR_HB_FM<8>;
1598 class JALR_HB_ENC : JALR_HB_FM<9>;
1600 def JR_HB : JR_HB_DESC, JR_HB_ENC, ISA_MIPS32_NOT_32R6_64R6;
1601 def JALR_HB : JALR_HB_DESC, JALR_HB_ENC, ISA_MIPS32;
1603 class TLB<string asmstr> : InstSE<(outs), (ins), asmstr, [], NoItinerary,
1605 def TLBP : MMRel, TLB<"tlbp">, COP0_TLB_FM<0x08>;
1606 def TLBR : MMRel, TLB<"tlbr">, COP0_TLB_FM<0x01>;
1607 def TLBWI : MMRel, TLB<"tlbwi">, COP0_TLB_FM<0x02>;
1608 def TLBWR : MMRel, TLB<"tlbwr">, COP0_TLB_FM<0x06>;
1610 class CacheOp<string instr_asm, Operand MemOpnd> :
1611 InstSE<(outs), (ins MemOpnd:$addr, uimm5:$hint),
1612 !strconcat(instr_asm, "\t$hint, $addr"), [], NoItinerary, FrmOther,
1614 let DecoderMethod = "DecodeCacheOp";
1617 def CACHE : MMRel, CacheOp<"cache", mem>, CACHEOP_FM<0b101111>,
1618 INSN_MIPS3_32_NOT_32R6_64R6;
1619 def PREF : MMRel, CacheOp<"pref", mem>, CACHEOP_FM<0b110011>,
1620 INSN_MIPS3_32_NOT_32R6_64R6;
1622 //===----------------------------------------------------------------------===//
1623 // Instruction aliases
1624 //===----------------------------------------------------------------------===//
1625 def : MipsInstAlias<"move $dst, $src",
1626 (OR GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
1628 let AdditionalPredicates = [NotInMicroMips];
1630 def : MipsInstAlias<"move $dst, $src",
1631 (ADDu GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
1633 let AdditionalPredicates = [NotInMicroMips];
1635 def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>,
1636 ISA_MIPS1_NOT_32R6_64R6;
1637 def : MipsInstAlias<"addu $rs, $rt, $imm",
1638 (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1639 def : MipsInstAlias<"addu $rs, $imm",
1640 (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>;
1641 def : MipsInstAlias<"add $rs, $rt, $imm",
1642 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>,
1643 ISA_MIPS1_NOT_32R6_64R6;
1644 def : MipsInstAlias<"add $rs, $imm",
1645 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>,
1646 ISA_MIPS1_NOT_32R6_64R6;
1647 def : MipsInstAlias<"and $rs, $rt, $imm",
1648 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1649 def : MipsInstAlias<"and $rs, $imm",
1650 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>;
1651 def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>;
1652 let Predicates = [NotInMicroMips] in {
1653 def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
1655 def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>, ISA_MIPS32;
1656 def : MipsInstAlias<"not $rt, $rs",
1657 (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>;
1658 def : MipsInstAlias<"neg $rt, $rs",
1659 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
1660 def : MipsInstAlias<"negu $rt",
1661 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 0>;
1662 def : MipsInstAlias<"negu $rt, $rs",
1663 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
1664 def : MipsInstAlias<"slt $rs, $rt, $imm",
1665 (SLTi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1666 def : MipsInstAlias<"sltu $rt, $rs, $imm",
1667 (SLTiu GPR32Opnd:$rt, GPR32Opnd:$rs, simm16:$imm), 0>;
1668 def : MipsInstAlias<"xor $rs, $rt, $imm",
1669 (XORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
1670 def : MipsInstAlias<"xor $rs, $imm",
1671 (XORi GPR32Opnd:$rs, GPR32Opnd:$rs, uimm16:$imm), 0>;
1672 def : MipsInstAlias<"or $rs, $rt, $imm",
1673 (ORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
1674 def : MipsInstAlias<"or $rs, $imm",
1675 (ORi GPR32Opnd:$rs, GPR32Opnd:$rs, uimm16:$imm), 0>;
1676 let AdditionalPredicates = [NotInMicroMips] in {
1677 def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>;
1679 def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>;
1680 def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>;
1681 def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, COP2Opnd:$rd, 0), 0>;
1682 def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 COP2Opnd:$rd, GPR32Opnd:$rt, 0), 0>;
1683 let AdditionalPredicates = [NotInMicroMips] in {
1684 def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>;
1686 def : MipsInstAlias<"bnez $rs,$offset",
1687 (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1688 def : MipsInstAlias<"bnezl $rs,$offset",
1689 (BNEL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1690 def : MipsInstAlias<"beqz $rs,$offset",
1691 (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1692 def : MipsInstAlias<"beqzl $rs,$offset",
1693 (BEQL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1694 def : MipsInstAlias<"syscall", (SYSCALL 0), 1>;
1696 def : MipsInstAlias<"break", (BREAK 0, 0), 1>;
1697 def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>;
1698 let AdditionalPredicates = [NotInMicroMips] in {
1699 def : MipsInstAlias<"ei", (EI ZERO), 1>, ISA_MIPS32R2;
1701 def : MipsInstAlias<"di", (DI ZERO), 1>, ISA_MIPS32R2;
1702 let AdditionalPredicates = [NotInMicroMips] in {
1703 def : MipsInstAlias<"teq $rs, $rt",
1704 (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1705 def : MipsInstAlias<"tge $rs, $rt",
1706 (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1707 def : MipsInstAlias<"tgeu $rs, $rt",
1708 (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1709 def : MipsInstAlias<"tlt $rs, $rt",
1710 (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1711 def : MipsInstAlias<"tltu $rs, $rt",
1712 (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1713 def : MipsInstAlias<"tne $rs, $rt",
1714 (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1716 def : MipsInstAlias<"sll $rd, $rt, $rs",
1717 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1718 def : MipsInstAlias<"sub, $rd, $rs, $imm",
1719 (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs,
1720 InvertedImOperand:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6;
1721 def : MipsInstAlias<"sub $rs, $imm",
1722 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm),
1723 0>, ISA_MIPS1_NOT_32R6_64R6;
1724 def : MipsInstAlias<"subu, $rd, $rs, $imm",
1725 (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs,
1726 InvertedImOperand:$imm), 0>;
1727 def : MipsInstAlias<"subu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs,
1728 InvertedImOperand:$imm), 0>;
1729 def : MipsInstAlias<"sra $rd, $rt, $rs",
1730 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1731 def : MipsInstAlias<"srl $rd, $rt, $rs",
1732 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1733 def : MipsInstAlias<"sdbbp", (SDBBP 0)>, ISA_MIPS32_NOT_32R6_64R6;
1734 def : MipsInstAlias<"sync",
1735 (SYNC 0), 1>, ISA_MIPS2;
1736 //===----------------------------------------------------------------------===//
1737 // Assembler Pseudo Instructions
1738 //===----------------------------------------------------------------------===//
1740 class LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> :
1741 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
1742 !strconcat(instr_asm, "\t$rt, $imm32")> ;
1743 def LoadImm32 : LoadImmediate32<"li", uimm5, GPR32Opnd>;
1745 class LoadAddressFromReg32<string instr_asm, Operand MemOpnd,
1746 RegisterOperand RO> :
1747 MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
1748 !strconcat(instr_asm, "\t$rt, $addr")> ;
1749 def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>;
1751 class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> :
1752 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
1753 !strconcat(instr_asm, "\t$rt, $imm32")> ;
1754 def LoadAddrImm32 : LoadAddressFromImm32<"la", uimm5, GPR32Opnd>;
1756 def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
1758 def JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs),
1761 let hasDelaySlot = 1 in {
1762 def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
1763 (ins imm64:$imm64, brtarget:$offset),
1764 "bne\t$rt, $imm64, $offset">;
1765 def BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
1766 (ins imm64:$imm64, brtarget:$offset),
1767 "beq\t$rt, $imm64, $offset">;
1769 class CondBranchPseudo<string instr_asm> :
1770 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt,
1772 !strconcat(instr_asm, "\t$rs, $rt, $offset")>;
1775 def BLT : CondBranchPseudo<"blt">;
1776 def BLE : CondBranchPseudo<"ble">;
1777 def BGE : CondBranchPseudo<"bge">;
1778 def BGT : CondBranchPseudo<"bgt">;
1779 def BLTU : CondBranchPseudo<"bltu">;
1780 def BLEU : CondBranchPseudo<"bleu">;
1781 def BGEU : CondBranchPseudo<"bgeu">;
1782 def BGTU : CondBranchPseudo<"bgtu">;
1783 def BLTL : CondBranchPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
1784 def BLEL : CondBranchPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
1785 def BGEL : CondBranchPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
1786 def BGTL : CondBranchPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
1787 def BLTUL: CondBranchPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
1788 def BLEUL: CondBranchPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
1789 def BGEUL: CondBranchPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
1790 def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
1792 // FIXME: Predicates are removed because instructions are matched regardless of
1793 // predicates, because PredicateControl was not in the hierarchy. This was
1794 // done to emit more precise error message from expansion function.
1795 // Once the tablegen-erated errors are made better, this needs to be fixed and
1796 // predicates needs to be restored.
1798 def SDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1799 "div\t$rs, $rt">; //, ISA_MIPS1_NOT_32R6_64R6;
1801 def UDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1802 "divu\t$rs, $rt">; //, ISA_MIPS1_NOT_32R6_64R6;
1804 def DSDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1805 "ddiv\t$rs, $rt">; //, ISA_MIPS64_NOT_64R6;
1807 def DUDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1808 "ddivu\t$rs, $rt">; //, ISA_MIPS64_NOT_64R6;
1810 def Ulhu : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
1811 "ulhu\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
1813 def Ulw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
1814 "ulw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
1816 //===----------------------------------------------------------------------===//
1817 // Arbitrary patterns that map to one or more instructions
1818 //===----------------------------------------------------------------------===//
1820 // Load/store pattern templates.
1821 class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
1822 MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
1824 class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
1825 MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
1828 let AdditionalPredicates = [NotInMicroMips] in {
1829 def : MipsPat<(i32 immSExt16:$in),
1830 (ADDiu ZERO, imm:$in)>;
1831 def : MipsPat<(i32 immZExt16:$in),
1832 (ORi ZERO, imm:$in)>;
1834 def : MipsPat<(i32 immLow16Zero:$in),
1835 (LUi (HI16 imm:$in))>;
1837 // Arbitrary immediates
1838 def : MipsPat<(i32 imm:$imm),
1839 (ORi (LUi (HI16 imm:$imm)), (LO16 imm:$imm))>;
1841 // Carry MipsPatterns
1842 def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
1843 (SUBu GPR32:$lhs, GPR32:$rhs)>;
1844 let AdditionalPredicates = [NotDSP] in {
1845 def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
1846 (ADDu GPR32:$lhs, GPR32:$rhs)>;
1847 def : MipsPat<(addc GPR32:$src, immSExt16:$imm),
1848 (ADDiu GPR32:$src, imm:$imm)>;
1851 // Support multiplication for pre-Mips32 targets that don't have
1852 // the MUL instruction.
1853 def : MipsPat<(mul GPR32:$lhs, GPR32:$rhs),
1854 (PseudoMFLO (PseudoMULT GPR32:$lhs, GPR32:$rhs))>,
1855 ISA_MIPS1_NOT_32R6_64R6;
1858 def : MipsPat<(MipsSync (i32 immz)),
1859 (SYNC 0)>, ISA_MIPS2;
1862 def : MipsPat<(MipsJmpLink (i32 tglobaladdr:$dst)),
1863 (JAL tglobaladdr:$dst)>;
1864 def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
1865 (JAL texternalsym:$dst)>;
1866 //def : MipsPat<(MipsJmpLink GPR32:$dst),
1867 // (JALR GPR32:$dst)>;
1870 def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
1871 (TAILCALL tglobaladdr:$dst)>;
1872 def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
1873 (TAILCALL texternalsym:$dst)>;
1875 def : MipsPat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
1876 def : MipsPat<(MipsHi tblockaddress:$in), (LUi tblockaddress:$in)>;
1877 def : MipsPat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>;
1878 def : MipsPat<(MipsHi tconstpool:$in), (LUi tconstpool:$in)>;
1879 def : MipsPat<(MipsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>;
1880 def : MipsPat<(MipsHi texternalsym:$in), (LUi texternalsym:$in)>;
1882 def : MipsPat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
1883 def : MipsPat<(MipsLo tblockaddress:$in), (ADDiu ZERO, tblockaddress:$in)>;
1884 def : MipsPat<(MipsLo tjumptable:$in), (ADDiu ZERO, tjumptable:$in)>;
1885 def : MipsPat<(MipsLo tconstpool:$in), (ADDiu ZERO, tconstpool:$in)>;
1886 def : MipsPat<(MipsLo tglobaltlsaddr:$in), (ADDiu ZERO, tglobaltlsaddr:$in)>;
1887 def : MipsPat<(MipsLo texternalsym:$in), (ADDiu ZERO, texternalsym:$in)>;
1889 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaladdr:$lo)),
1890 (ADDiu GPR32:$hi, tglobaladdr:$lo)>;
1891 def : MipsPat<(add GPR32:$hi, (MipsLo tblockaddress:$lo)),
1892 (ADDiu GPR32:$hi, tblockaddress:$lo)>;
1893 def : MipsPat<(add GPR32:$hi, (MipsLo tjumptable:$lo)),
1894 (ADDiu GPR32:$hi, tjumptable:$lo)>;
1895 def : MipsPat<(add GPR32:$hi, (MipsLo tconstpool:$lo)),
1896 (ADDiu GPR32:$hi, tconstpool:$lo)>;
1897 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaltlsaddr:$lo)),
1898 (ADDiu GPR32:$hi, tglobaltlsaddr:$lo)>;
1901 def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
1902 (ADDiu GPR32:$gp, tglobaladdr:$in)>;
1903 def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
1904 (ADDiu GPR32:$gp, tconstpool:$in)>;
1907 class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
1908 MipsPat<(MipsWrapper RC:$gp, node:$in),
1909 (ADDiuOp RC:$gp, node:$in)>;
1911 def : WrapperPat<tglobaladdr, ADDiu, GPR32>;
1912 def : WrapperPat<tconstpool, ADDiu, GPR32>;
1913 def : WrapperPat<texternalsym, ADDiu, GPR32>;
1914 def : WrapperPat<tblockaddress, ADDiu, GPR32>;
1915 def : WrapperPat<tjumptable, ADDiu, GPR32>;
1916 def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>;
1918 let AdditionalPredicates = [NotInMicroMips] in {
1919 // Mips does not have "not", so we expand our way
1920 def : MipsPat<(not GPR32:$in),
1921 (NOR GPR32Opnd:$in, ZERO)>;
1925 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>;
1926 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>;
1927 def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
1930 def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>;
1933 multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BNEOp,
1934 Instruction SLTOp, Instruction SLTuOp, Instruction SLTiOp,
1935 Instruction SLTiuOp, Register ZEROReg> {
1936 def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
1937 (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
1938 def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
1939 (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
1941 def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
1942 (BEQ (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
1943 def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
1944 (BEQ (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
1945 def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
1946 (BEQ (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
1947 def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
1948 (BEQ (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
1949 def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
1950 (BEQ (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
1951 def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
1952 (BEQ (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
1954 def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
1955 (BEQ (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
1956 def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
1957 (BEQ (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
1959 def : MipsPat<(brcond RC:$cond, bb:$dst),
1960 (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
1963 defm : BrcondPats<GPR32, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>;
1965 def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
1966 (BLEZ i32:$lhs, bb:$dst)>;
1967 def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
1968 (BGEZ i32:$lhs, bb:$dst)>;
1971 multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp,
1972 Instruction SLTuOp, Register ZEROReg> {
1973 def : MipsPat<(seteq RC:$lhs, 0),
1974 (SLTiuOp RC:$lhs, 1)>;
1975 def : MipsPat<(setne RC:$lhs, 0),
1976 (SLTuOp ZEROReg, RC:$lhs)>;
1977 def : MipsPat<(seteq RC:$lhs, RC:$rhs),
1978 (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>;
1979 def : MipsPat<(setne RC:$lhs, RC:$rhs),
1980 (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
1983 multiclass SetlePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1984 def : MipsPat<(setle RC:$lhs, RC:$rhs),
1985 (XORi (SLTOp RC:$rhs, RC:$lhs), 1)>;
1986 def : MipsPat<(setule RC:$lhs, RC:$rhs),
1987 (XORi (SLTuOp RC:$rhs, RC:$lhs), 1)>;
1990 multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1991 def : MipsPat<(setgt RC:$lhs, RC:$rhs),
1992 (SLTOp RC:$rhs, RC:$lhs)>;
1993 def : MipsPat<(setugt RC:$lhs, RC:$rhs),
1994 (SLTuOp RC:$rhs, RC:$lhs)>;
1997 multiclass SetgePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1998 def : MipsPat<(setge RC:$lhs, RC:$rhs),
1999 (XORi (SLTOp RC:$lhs, RC:$rhs), 1)>;
2000 def : MipsPat<(setuge RC:$lhs, RC:$rhs),
2001 (XORi (SLTuOp RC:$lhs, RC:$rhs), 1)>;
2004 multiclass SetgeImmPats<RegisterClass RC, Instruction SLTiOp,
2005 Instruction SLTiuOp> {
2006 def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
2007 (XORi (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
2008 def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
2009 (XORi (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
2012 defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>;
2013 defm : SetlePats<GPR32, SLT, SLTu>;
2014 defm : SetgtPats<GPR32, SLT, SLTu>;
2015 defm : SetgePats<GPR32, SLT, SLTu>;
2016 defm : SetgeImmPats<GPR32, SLTi, SLTiu>;
2019 def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>;
2021 // Load halfword/word patterns.
2022 let AddedComplexity = 40 in {
2023 def : LoadRegImmPat<LBu, i32, zextloadi8>;
2024 def : LoadRegImmPat<LH, i32, sextloadi16>;
2025 let AdditionalPredicates = [NotInMicroMips] in {
2026 def : LoadRegImmPat<LW, i32, load>;
2030 //===----------------------------------------------------------------------===//
2031 // Floating Point Support
2032 //===----------------------------------------------------------------------===//
2034 include "MipsInstrFPU.td"
2035 include "Mips64InstrInfo.td"
2036 include "MipsCondMov.td"
2038 include "Mips32r6InstrInfo.td"
2039 include "Mips64r6InstrInfo.td"
2044 include "Mips16InstrFormats.td"
2045 include "Mips16InstrInfo.td"
2048 include "MipsDSPInstrFormats.td"
2049 include "MipsDSPInstrInfo.td"
2052 include "MipsMSAInstrFormats.td"
2053 include "MipsMSAInstrInfo.td"
2056 include "MipsEVAInstrFormats.td"
2057 include "MipsEVAInstrInfo.td"
2060 include "MicroMipsInstrFormats.td"
2061 include "MicroMipsInstrInfo.td"
2062 include "MicroMipsInstrFPU.td"
2065 include "MicroMips32r6InstrFormats.td"
2066 include "MicroMips32r6InstrInfo.td"
2069 include "MicroMips64r6InstrFormats.td"
2070 include "MicroMips64r6InstrInfo.td"