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 def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM<0x34>, ISA_MIPS2;
1318 def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM<0x30>, ISA_MIPS2;
1319 def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd>, TEQ_FM<0x31>, ISA_MIPS2;
1320 def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd>, TEQ_FM<0x32>, ISA_MIPS2;
1321 def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd>, TEQ_FM<0x33>, ISA_MIPS2;
1322 def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd>, TEQ_FM<0x36>, ISA_MIPS2;
1324 def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd>, TEQI_FM<0xc>,
1325 ISA_MIPS2_NOT_32R6_64R6;
1326 def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd>, TEQI_FM<0x8>,
1327 ISA_MIPS2_NOT_32R6_64R6;
1328 def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd>, TEQI_FM<0x9>,
1329 ISA_MIPS2_NOT_32R6_64R6;
1330 def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd>, TEQI_FM<0xa>,
1331 ISA_MIPS2_NOT_32R6_64R6;
1332 def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd>, TEQI_FM<0xb>,
1333 ISA_MIPS2_NOT_32R6_64R6;
1334 def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd>, TEQI_FM<0xe>,
1335 ISA_MIPS2_NOT_32R6_64R6;
1337 let AdditionalPredicates = [NotInMicroMips] in {
1338 def BREAK : MMRel, StdMMR6Rel, BRK_FT<"break">, BRK_FM<0xd>;
1340 def SYSCALL : MMRel, SYS_FT<"syscall">, SYS_FM<0xc>;
1341 def TRAP : TrapBase<BREAK>;
1342 def SDBBP : MMRel, SYS_FT<"sdbbp">, SDBBP_FM, ISA_MIPS32_NOT_32R6_64R6;
1344 let AdditionalPredicates = [NotInMicroMips] in {
1345 def ERET : MMRel, ER_FT<"eret">, ER_FM<0x18, 0x0>, INSN_MIPS3_32;
1346 def ERETNC : MMRel, ER_FT<"eretnc">, ER_FM<0x18, 0x1>, ISA_MIPS32R5;
1348 def DERET : MMRel, ER_FT<"deret">, ER_FM<0x1f, 0x0>, ISA_MIPS32;
1350 let AdditionalPredicates = [NotInMicroMips] in {
1351 def EI : MMRel, StdMMR6Rel, DEI_FT<"ei", GPR32Opnd>, EI_FM<1>, ISA_MIPS32R2;
1353 def DI : MMRel, DEI_FT<"di", GPR32Opnd>, EI_FM<0>, ISA_MIPS32R2;
1355 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1356 AdditionalPredicates = [NotInMicroMips] in {
1357 def WAIT : WAIT_FT<"wait">, WAIT_FM;
1359 /// Load-linked, Store-conditional
1360 def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, ISA_MIPS2_NOT_32R6_64R6;
1361 def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, ISA_MIPS2_NOT_32R6_64R6;
1364 /// Jump and Branch Instructions
1365 def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
1366 AdditionalRequires<[RelocStatic]>, IsBranch;
1367 def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>;
1368 def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>;
1369 def BEQL : MMRel, CBranch<"beql", brtarget, seteq, GPR32Opnd, 0>,
1370 BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6;
1371 def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>;
1372 def BNEL : MMRel, CBranch<"bnel", brtarget, setne, GPR32Opnd, 0>,
1373 BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6;
1374 def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
1376 def BGEZL : MMRel, CBranchZero<"bgezl", brtarget, setge, GPR32Opnd, 0>,
1377 BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6;
1378 def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
1380 def BGTZL : MMRel, CBranchZero<"bgtzl", brtarget, setgt, GPR32Opnd, 0>,
1381 BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6;
1382 def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
1384 def BLEZL : MMRel, CBranchZero<"blezl", brtarget, setle, GPR32Opnd, 0>,
1385 BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6;
1386 def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
1388 def BLTZL : MMRel, CBranchZero<"bltzl", brtarget, setlt, GPR32Opnd, 0>,
1389 BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6;
1390 def B : UncondBranch<BEQ>;
1392 def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>;
1393 let AdditionalPredicates = [NotInMicroMips] in {
1394 def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM;
1395 def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>;
1398 def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>,
1399 ISA_MIPS32_NOT_32R6_64R6;
1400 def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>,
1401 ISA_MIPS1_NOT_32R6_64R6;
1402 def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd, 0>,
1403 BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6;
1404 def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>,
1405 ISA_MIPS1_NOT_32R6_64R6;
1406 def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd, 0>,
1407 BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6;
1408 def BAL_BR : BAL_BR_Pseudo<BGEZAL>;
1409 def TAILCALL : TailCall<J>;
1410 def TAILCALL_R : TailCallReg<GPR32Opnd, JR>;
1412 // Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64
1413 // then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA.
1414 class PseudoIndirectBranchBase<RegisterOperand RO> :
1415 MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)], IIBranch> {
1418 let hasDelaySlot = 1;
1420 let isIndirectBranch = 1;
1423 def PseudoIndirectBranch : PseudoIndirectBranchBase<GPR32Opnd>;
1425 // Return instructions are matched as a RetRA instruction, then ar expanded
1426 // into PseudoReturn/PseudoReturn64 after register allocation. Finally,
1427 // MipsAsmPrinter expands this into JR, JR64, JALR, or JALR64 depending on the
1429 class PseudoReturnBase<RegisterOperand RO> : MipsPseudo<(outs), (ins RO:$rs),
1431 let isTerminator = 1;
1433 let hasDelaySlot = 1;
1435 let isCodeGenOnly = 1;
1437 let hasExtraSrcRegAllocReq = 1;
1440 def PseudoReturn : PseudoReturnBase<GPR32Opnd>;
1442 // Exception handling related node and instructions.
1443 // The conversion sequence is:
1444 // ISD::EH_RETURN -> MipsISD::EH_RETURN ->
1445 // MIPSeh_return -> (stack change + indirect branch)
1447 // MIPSeh_return takes the place of regular return instruction
1448 // but takes two arguments (V1, V0) which are used for storing
1449 // the offset and return address respectively.
1450 def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
1452 def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
1453 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
1455 let Uses = [V0, V1], isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1456 def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
1457 [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
1458 def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff,
1460 [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
1463 /// Multiply and Divide Instructions.
1464 def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
1465 MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6;
1466 def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
1467 MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6;
1468 def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
1469 MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6;
1470 def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
1471 MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6;
1473 def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>,
1474 ISA_MIPS1_NOT_32R6_64R6;
1475 def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>,
1476 ISA_MIPS1_NOT_32R6_64R6;
1477 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1478 AdditionalPredicates = [NotInMicroMips] in {
1479 def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>,
1480 ISA_MIPS1_NOT_32R6_64R6;
1481 def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>,
1482 ISA_MIPS1_NOT_32R6_64R6;
1485 /// Sign Ext In Register Instructions.
1486 def SEB : MMRel, StdMMR6Rel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,
1487 SEB_FM<0x10, 0x20>, ISA_MIPS32R2;
1488 def SEH : MMRel, StdMMR6Rel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
1489 SEB_FM<0x18, 0x20>, ISA_MIPS32R2;
1492 def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd>, CLO_FM<0x20>,
1493 ISA_MIPS32_NOT_32R6_64R6;
1494 def CLO : MMRel, CountLeading1<"clo", GPR32Opnd>, CLO_FM<0x21>,
1495 ISA_MIPS32_NOT_32R6_64R6;
1497 /// Word Swap Bytes Within Halfwords
1498 def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd>, SEB_FM<2, 0x20>, ISA_MIPS32R2;
1501 def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>;
1503 // FrameIndexes are legalized when they are operands from load/store
1504 // instructions. The same not happens for stack address copies, so an
1505 // add op with mem ComplexPattern is used and the stack address copy
1506 // can be matched. It's similar to Sparc LEA_ADDRi
1507 def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>;
1510 def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>,
1511 ISA_MIPS32_NOT_32R6_64R6;
1512 def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>,
1513 ISA_MIPS32_NOT_32R6_64R6;
1514 def MSUB : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>,
1515 ISA_MIPS32_NOT_32R6_64R6;
1516 def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>,
1517 ISA_MIPS32_NOT_32R6_64R6;
1519 let AdditionalPredicates = [NotDSP] in {
1520 def PseudoMULT : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>,
1521 ISA_MIPS1_NOT_32R6_64R6;
1522 def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>,
1523 ISA_MIPS1_NOT_32R6_64R6;
1524 def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>, ISA_MIPS1_NOT_32R6_64R6;
1525 def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>, ISA_MIPS1_NOT_32R6_64R6;
1526 def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>, ISA_MIPS1_NOT_32R6_64R6;
1527 def PseudoMADD : MAddSubPseudo<MADD, MipsMAdd, II_MADD>,
1528 ISA_MIPS32_NOT_32R6_64R6;
1529 def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>,
1530 ISA_MIPS32_NOT_32R6_64R6;
1531 def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>,
1532 ISA_MIPS32_NOT_32R6_64R6;
1533 def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>,
1534 ISA_MIPS32_NOT_32R6_64R6;
1537 def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV,
1538 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
1539 def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU,
1540 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
1542 def RDHWR : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM;
1544 def EXT : MMRel, ExtBase<"ext", GPR32Opnd, uimm5, MipsExt>, EXT_FM<0>;
1545 def INS : MMRel, InsBase<"ins", GPR32Opnd, uimm5, MipsIns>, EXT_FM<4>;
1547 /// Move Control Registers From/To CPU Registers
1548 def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd>, MFC3OP_FM<0x10, 0>, ISA_MIPS32;
1549 def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd>, MFC3OP_FM<0x10, 4>, ISA_MIPS32;
1550 def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd>, MFC3OP_FM<0x12, 0>;
1551 def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd>, MFC3OP_FM<0x12, 4>;
1553 class Barrier<string asmstr> : InstSE<(outs), (ins), asmstr, [], NoItinerary,
1555 def SSNOP : MMRel, Barrier<"ssnop">, BARRIER_FM<1>;
1556 def EHB : MMRel, Barrier<"ehb">, BARRIER_FM<3>;
1557 def PAUSE : MMRel, Barrier<"pause">, BARRIER_FM<5>, ISA_MIPS32R2;
1559 // JR_HB and JALR_HB are defined here using the new style naming
1560 // scheme because some of this code is shared with Mips32r6InstrInfo.td
1561 // and because of that it doesn't follow the naming convention of the
1562 // rest of the file. To avoid a mixture of old vs new style, the new
1563 // style was chosen.
1564 class JR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
1565 dag OutOperandList = (outs);
1566 dag InOperandList = (ins GPROpnd:$rs);
1567 string AsmString = !strconcat(instr_asm, "\t$rs");
1568 list<dag> Pattern = [];
1571 class JALR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
1572 dag OutOperandList = (outs GPROpnd:$rd);
1573 dag InOperandList = (ins GPROpnd:$rs);
1574 string AsmString = !strconcat(instr_asm, "\t$rd, $rs");
1575 list<dag> Pattern = [];
1578 class JR_HB_DESC : InstSE<(outs), (ins), "", [], NoItinerary, FrmJ>,
1579 JR_HB_DESC_BASE<"jr.hb", GPR32Opnd> {
1581 let isIndirectBranch=1;
1587 class JALR_HB_DESC : InstSE<(outs), (ins), "", [], NoItinerary, FrmJ>,
1588 JALR_HB_DESC_BASE<"jalr.hb", GPR32Opnd> {
1589 let isIndirectBranch=1;
1593 class JR_HB_ENC : JR_HB_FM<8>;
1594 class JALR_HB_ENC : JALR_HB_FM<9>;
1596 def JR_HB : JR_HB_DESC, JR_HB_ENC, ISA_MIPS32_NOT_32R6_64R6;
1597 def JALR_HB : JALR_HB_DESC, JALR_HB_ENC, ISA_MIPS32;
1599 class TLB<string asmstr> : InstSE<(outs), (ins), asmstr, [], NoItinerary,
1601 def TLBP : MMRel, TLB<"tlbp">, COP0_TLB_FM<0x08>;
1602 def TLBR : MMRel, TLB<"tlbr">, COP0_TLB_FM<0x01>;
1603 def TLBWI : MMRel, TLB<"tlbwi">, COP0_TLB_FM<0x02>;
1604 def TLBWR : MMRel, TLB<"tlbwr">, COP0_TLB_FM<0x06>;
1606 class CacheOp<string instr_asm, Operand MemOpnd> :
1607 InstSE<(outs), (ins MemOpnd:$addr, uimm5:$hint),
1608 !strconcat(instr_asm, "\t$hint, $addr"), [], NoItinerary, FrmOther,
1610 let DecoderMethod = "DecodeCacheOp";
1613 def CACHE : MMRel, CacheOp<"cache", mem>, CACHEOP_FM<0b101111>,
1614 INSN_MIPS3_32_NOT_32R6_64R6;
1615 def PREF : MMRel, CacheOp<"pref", mem>, CACHEOP_FM<0b110011>,
1616 INSN_MIPS3_32_NOT_32R6_64R6;
1618 //===----------------------------------------------------------------------===//
1619 // Instruction aliases
1620 //===----------------------------------------------------------------------===//
1621 def : MipsInstAlias<"move $dst, $src",
1622 (OR GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
1624 let AdditionalPredicates = [NotInMicroMips];
1626 def : MipsInstAlias<"move $dst, $src",
1627 (ADDu GPR32Opnd:$dst, GPR32Opnd:$src, ZERO), 1>,
1629 let AdditionalPredicates = [NotInMicroMips];
1631 def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>,
1632 ISA_MIPS1_NOT_32R6_64R6;
1633 def : MipsInstAlias<"addu $rs, $rt, $imm",
1634 (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1635 def : MipsInstAlias<"addu $rs, $imm",
1636 (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>;
1637 def : MipsInstAlias<"add $rs, $rt, $imm",
1638 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>,
1639 ISA_MIPS1_NOT_32R6_64R6;
1640 def : MipsInstAlias<"add $rs, $imm",
1641 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>,
1642 ISA_MIPS1_NOT_32R6_64R6;
1643 def : MipsInstAlias<"and $rs, $rt, $imm",
1644 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1645 def : MipsInstAlias<"and $rs, $imm",
1646 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>;
1647 def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>;
1648 let Predicates = [NotInMicroMips] in {
1649 def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
1651 def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>, ISA_MIPS32;
1652 def : MipsInstAlias<"not $rt, $rs",
1653 (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>;
1654 def : MipsInstAlias<"neg $rt, $rs",
1655 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
1656 def : MipsInstAlias<"negu $rt",
1657 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 0>;
1658 def : MipsInstAlias<"negu $rt, $rs",
1659 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
1660 def : MipsInstAlias<"slt $rs, $rt, $imm",
1661 (SLTi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1662 def : MipsInstAlias<"sltu $rt, $rs, $imm",
1663 (SLTiu GPR32Opnd:$rt, GPR32Opnd:$rs, simm16:$imm), 0>;
1664 def : MipsInstAlias<"xor $rs, $rt, $imm",
1665 (XORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
1666 def : MipsInstAlias<"xor $rs, $imm",
1667 (XORi GPR32Opnd:$rs, GPR32Opnd:$rs, uimm16:$imm), 0>;
1668 def : MipsInstAlias<"or $rs, $rt, $imm",
1669 (ORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
1670 def : MipsInstAlias<"or $rs, $imm",
1671 (ORi GPR32Opnd:$rs, GPR32Opnd:$rs, uimm16:$imm), 0>;
1672 let AdditionalPredicates = [NotInMicroMips] in {
1673 def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>;
1675 def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>;
1676 def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>;
1677 def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, COP2Opnd:$rd, 0), 0>;
1678 def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 COP2Opnd:$rd, GPR32Opnd:$rt, 0), 0>;
1679 let AdditionalPredicates = [NotInMicroMips] in {
1680 def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>;
1682 def : MipsInstAlias<"bnez $rs,$offset",
1683 (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1684 def : MipsInstAlias<"bnezl $rs,$offset",
1685 (BNEL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1686 def : MipsInstAlias<"beqz $rs,$offset",
1687 (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1688 def : MipsInstAlias<"beqzl $rs,$offset",
1689 (BEQL GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1690 def : MipsInstAlias<"syscall", (SYSCALL 0), 1>;
1692 def : MipsInstAlias<"break", (BREAK 0, 0), 1>;
1693 def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>;
1694 let AdditionalPredicates = [NotInMicroMips] in {
1695 def : MipsInstAlias<"ei", (EI ZERO), 1>, ISA_MIPS32R2;
1697 def : MipsInstAlias<"di", (DI ZERO), 1>, ISA_MIPS32R2;
1699 def : MipsInstAlias<"teq $rs, $rt",
1700 (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1701 def : MipsInstAlias<"tge $rs, $rt",
1702 (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1703 def : MipsInstAlias<"tgeu $rs, $rt",
1704 (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1705 def : MipsInstAlias<"tlt $rs, $rt",
1706 (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1707 def : MipsInstAlias<"tltu $rs, $rt",
1708 (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1709 def : MipsInstAlias<"tne $rs, $rt",
1710 (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1712 def : MipsInstAlias<"sll $rd, $rt, $rs",
1713 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1714 def : MipsInstAlias<"sub, $rd, $rs, $imm",
1715 (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs,
1716 InvertedImOperand:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6;
1717 def : MipsInstAlias<"sub $rs, $imm",
1718 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm),
1719 0>, ISA_MIPS1_NOT_32R6_64R6;
1720 def : MipsInstAlias<"subu, $rd, $rs, $imm",
1721 (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs,
1722 InvertedImOperand:$imm), 0>;
1723 def : MipsInstAlias<"subu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs,
1724 InvertedImOperand:$imm), 0>;
1725 def : MipsInstAlias<"sra $rd, $rt, $rs",
1726 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1727 def : MipsInstAlias<"srl $rd, $rt, $rs",
1728 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1729 def : MipsInstAlias<"sdbbp", (SDBBP 0)>, ISA_MIPS32_NOT_32R6_64R6;
1730 def : MipsInstAlias<"sync",
1731 (SYNC 0), 1>, ISA_MIPS2;
1732 //===----------------------------------------------------------------------===//
1733 // Assembler Pseudo Instructions
1734 //===----------------------------------------------------------------------===//
1736 class LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> :
1737 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
1738 !strconcat(instr_asm, "\t$rt, $imm32")> ;
1739 def LoadImm32 : LoadImmediate32<"li", uimm5, GPR32Opnd>;
1741 class LoadAddressFromReg32<string instr_asm, Operand MemOpnd,
1742 RegisterOperand RO> :
1743 MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
1744 !strconcat(instr_asm, "\t$rt, $addr")> ;
1745 def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>;
1747 class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> :
1748 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
1749 !strconcat(instr_asm, "\t$rt, $imm32")> ;
1750 def LoadAddrImm32 : LoadAddressFromImm32<"la", uimm5, GPR32Opnd>;
1752 def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
1754 def JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs),
1757 let hasDelaySlot = 1 in {
1758 def BneImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
1759 (ins imm64:$imm64, brtarget:$offset),
1760 "bne\t$rt, $imm64, $offset">;
1761 def BeqImm : MipsAsmPseudoInst<(outs GPR32Opnd:$rt),
1762 (ins imm64:$imm64, brtarget:$offset),
1763 "beq\t$rt, $imm64, $offset">;
1765 class CondBranchPseudo<string instr_asm> :
1766 MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt,
1768 !strconcat(instr_asm, "\t$rs, $rt, $offset")>;
1771 def BLT : CondBranchPseudo<"blt">;
1772 def BLE : CondBranchPseudo<"ble">;
1773 def BGE : CondBranchPseudo<"bge">;
1774 def BGT : CondBranchPseudo<"bgt">;
1775 def BLTU : CondBranchPseudo<"bltu">;
1776 def BLEU : CondBranchPseudo<"bleu">;
1777 def BGEU : CondBranchPseudo<"bgeu">;
1778 def BGTU : CondBranchPseudo<"bgtu">;
1779 def BLTL : CondBranchPseudo<"bltl">, ISA_MIPS2_NOT_32R6_64R6;
1780 def BLEL : CondBranchPseudo<"blel">, ISA_MIPS2_NOT_32R6_64R6;
1781 def BGEL : CondBranchPseudo<"bgel">, ISA_MIPS2_NOT_32R6_64R6;
1782 def BGTL : CondBranchPseudo<"bgtl">, ISA_MIPS2_NOT_32R6_64R6;
1783 def BLTUL: CondBranchPseudo<"bltul">, ISA_MIPS2_NOT_32R6_64R6;
1784 def BLEUL: CondBranchPseudo<"bleul">, ISA_MIPS2_NOT_32R6_64R6;
1785 def BGEUL: CondBranchPseudo<"bgeul">, ISA_MIPS2_NOT_32R6_64R6;
1786 def BGTUL: CondBranchPseudo<"bgtul">, ISA_MIPS2_NOT_32R6_64R6;
1788 // FIXME: Predicates are removed because instructions are matched regardless of
1789 // predicates, because PredicateControl was not in the hierarchy. This was
1790 // done to emit more precise error message from expansion function.
1791 // Once the tablegen-erated errors are made better, this needs to be fixed and
1792 // predicates needs to be restored.
1794 def SDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1795 "div\t$rs, $rt">; //, ISA_MIPS1_NOT_32R6_64R6;
1797 def UDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1798 "divu\t$rs, $rt">; //, ISA_MIPS1_NOT_32R6_64R6;
1800 def DSDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1801 "ddiv\t$rs, $rt">; //, ISA_MIPS64_NOT_64R6;
1803 def DUDivMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
1804 "ddivu\t$rs, $rt">; //, ISA_MIPS64_NOT_64R6;
1806 def Ulhu : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
1807 "ulhu\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
1809 def Ulw : MipsAsmPseudoInst<(outs GPR32Opnd:$rt), (ins mem:$addr),
1810 "ulw\t$rt, $addr">; //, ISA_MIPS1_NOT_32R6_64R6;
1812 //===----------------------------------------------------------------------===//
1813 // Arbitrary patterns that map to one or more instructions
1814 //===----------------------------------------------------------------------===//
1816 // Load/store pattern templates.
1817 class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
1818 MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
1820 class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
1821 MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
1824 let AdditionalPredicates = [NotInMicroMips] in {
1825 def : MipsPat<(i32 immSExt16:$in),
1826 (ADDiu ZERO, imm:$in)>;
1827 def : MipsPat<(i32 immZExt16:$in),
1828 (ORi ZERO, imm:$in)>;
1830 def : MipsPat<(i32 immLow16Zero:$in),
1831 (LUi (HI16 imm:$in))>;
1833 // Arbitrary immediates
1834 def : MipsPat<(i32 imm:$imm),
1835 (ORi (LUi (HI16 imm:$imm)), (LO16 imm:$imm))>;
1837 // Carry MipsPatterns
1838 def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
1839 (SUBu GPR32:$lhs, GPR32:$rhs)>;
1840 let AdditionalPredicates = [NotDSP] in {
1841 def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
1842 (ADDu GPR32:$lhs, GPR32:$rhs)>;
1843 def : MipsPat<(addc GPR32:$src, immSExt16:$imm),
1844 (ADDiu GPR32:$src, imm:$imm)>;
1847 // Support multiplication for pre-Mips32 targets that don't have
1848 // the MUL instruction.
1849 def : MipsPat<(mul GPR32:$lhs, GPR32:$rhs),
1850 (PseudoMFLO (PseudoMULT GPR32:$lhs, GPR32:$rhs))>,
1851 ISA_MIPS1_NOT_32R6_64R6;
1854 def : MipsPat<(MipsSync (i32 immz)),
1855 (SYNC 0)>, ISA_MIPS2;
1858 def : MipsPat<(MipsJmpLink (i32 tglobaladdr:$dst)),
1859 (JAL tglobaladdr:$dst)>;
1860 def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
1861 (JAL texternalsym:$dst)>;
1862 //def : MipsPat<(MipsJmpLink GPR32:$dst),
1863 // (JALR GPR32:$dst)>;
1866 def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
1867 (TAILCALL tglobaladdr:$dst)>;
1868 def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
1869 (TAILCALL texternalsym:$dst)>;
1871 def : MipsPat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
1872 def : MipsPat<(MipsHi tblockaddress:$in), (LUi tblockaddress:$in)>;
1873 def : MipsPat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>;
1874 def : MipsPat<(MipsHi tconstpool:$in), (LUi tconstpool:$in)>;
1875 def : MipsPat<(MipsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>;
1876 def : MipsPat<(MipsHi texternalsym:$in), (LUi texternalsym:$in)>;
1878 def : MipsPat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
1879 def : MipsPat<(MipsLo tblockaddress:$in), (ADDiu ZERO, tblockaddress:$in)>;
1880 def : MipsPat<(MipsLo tjumptable:$in), (ADDiu ZERO, tjumptable:$in)>;
1881 def : MipsPat<(MipsLo tconstpool:$in), (ADDiu ZERO, tconstpool:$in)>;
1882 def : MipsPat<(MipsLo tglobaltlsaddr:$in), (ADDiu ZERO, tglobaltlsaddr:$in)>;
1883 def : MipsPat<(MipsLo texternalsym:$in), (ADDiu ZERO, texternalsym:$in)>;
1885 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaladdr:$lo)),
1886 (ADDiu GPR32:$hi, tglobaladdr:$lo)>;
1887 def : MipsPat<(add GPR32:$hi, (MipsLo tblockaddress:$lo)),
1888 (ADDiu GPR32:$hi, tblockaddress:$lo)>;
1889 def : MipsPat<(add GPR32:$hi, (MipsLo tjumptable:$lo)),
1890 (ADDiu GPR32:$hi, tjumptable:$lo)>;
1891 def : MipsPat<(add GPR32:$hi, (MipsLo tconstpool:$lo)),
1892 (ADDiu GPR32:$hi, tconstpool:$lo)>;
1893 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaltlsaddr:$lo)),
1894 (ADDiu GPR32:$hi, tglobaltlsaddr:$lo)>;
1897 def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
1898 (ADDiu GPR32:$gp, tglobaladdr:$in)>;
1899 def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
1900 (ADDiu GPR32:$gp, tconstpool:$in)>;
1903 class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
1904 MipsPat<(MipsWrapper RC:$gp, node:$in),
1905 (ADDiuOp RC:$gp, node:$in)>;
1907 def : WrapperPat<tglobaladdr, ADDiu, GPR32>;
1908 def : WrapperPat<tconstpool, ADDiu, GPR32>;
1909 def : WrapperPat<texternalsym, ADDiu, GPR32>;
1910 def : WrapperPat<tblockaddress, ADDiu, GPR32>;
1911 def : WrapperPat<tjumptable, ADDiu, GPR32>;
1912 def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>;
1914 let AdditionalPredicates = [NotInMicroMips] in {
1915 // Mips does not have "not", so we expand our way
1916 def : MipsPat<(not GPR32:$in),
1917 (NOR GPR32Opnd:$in, ZERO)>;
1921 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>;
1922 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>;
1923 def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
1926 def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>;
1929 multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BNEOp,
1930 Instruction SLTOp, Instruction SLTuOp, Instruction SLTiOp,
1931 Instruction SLTiuOp, Register ZEROReg> {
1932 def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
1933 (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
1934 def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
1935 (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
1937 def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
1938 (BEQ (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
1939 def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
1940 (BEQ (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
1941 def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
1942 (BEQ (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
1943 def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
1944 (BEQ (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
1945 def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
1946 (BEQ (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
1947 def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
1948 (BEQ (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
1950 def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
1951 (BEQ (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
1952 def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
1953 (BEQ (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
1955 def : MipsPat<(brcond RC:$cond, bb:$dst),
1956 (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
1959 defm : BrcondPats<GPR32, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>;
1961 def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
1962 (BLEZ i32:$lhs, bb:$dst)>;
1963 def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
1964 (BGEZ i32:$lhs, bb:$dst)>;
1967 multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp,
1968 Instruction SLTuOp, Register ZEROReg> {
1969 def : MipsPat<(seteq RC:$lhs, 0),
1970 (SLTiuOp RC:$lhs, 1)>;
1971 def : MipsPat<(setne RC:$lhs, 0),
1972 (SLTuOp ZEROReg, RC:$lhs)>;
1973 def : MipsPat<(seteq RC:$lhs, RC:$rhs),
1974 (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>;
1975 def : MipsPat<(setne RC:$lhs, RC:$rhs),
1976 (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
1979 multiclass SetlePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1980 def : MipsPat<(setle RC:$lhs, RC:$rhs),
1981 (XORi (SLTOp RC:$rhs, RC:$lhs), 1)>;
1982 def : MipsPat<(setule RC:$lhs, RC:$rhs),
1983 (XORi (SLTuOp RC:$rhs, RC:$lhs), 1)>;
1986 multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1987 def : MipsPat<(setgt RC:$lhs, RC:$rhs),
1988 (SLTOp RC:$rhs, RC:$lhs)>;
1989 def : MipsPat<(setugt RC:$lhs, RC:$rhs),
1990 (SLTuOp RC:$rhs, RC:$lhs)>;
1993 multiclass SetgePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1994 def : MipsPat<(setge RC:$lhs, RC:$rhs),
1995 (XORi (SLTOp RC:$lhs, RC:$rhs), 1)>;
1996 def : MipsPat<(setuge RC:$lhs, RC:$rhs),
1997 (XORi (SLTuOp RC:$lhs, RC:$rhs), 1)>;
2000 multiclass SetgeImmPats<RegisterClass RC, Instruction SLTiOp,
2001 Instruction SLTiuOp> {
2002 def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
2003 (XORi (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
2004 def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
2005 (XORi (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
2008 defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>;
2009 defm : SetlePats<GPR32, SLT, SLTu>;
2010 defm : SetgtPats<GPR32, SLT, SLTu>;
2011 defm : SetgePats<GPR32, SLT, SLTu>;
2012 defm : SetgeImmPats<GPR32, SLTi, SLTiu>;
2015 def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>;
2017 // Load halfword/word patterns.
2018 let AddedComplexity = 40 in {
2019 def : LoadRegImmPat<LBu, i32, zextloadi8>;
2020 def : LoadRegImmPat<LH, i32, sextloadi16>;
2021 let AdditionalPredicates = [NotInMicroMips] in {
2022 def : LoadRegImmPat<LW, i32, load>;
2026 //===----------------------------------------------------------------------===//
2027 // Floating Point Support
2028 //===----------------------------------------------------------------------===//
2030 include "MipsInstrFPU.td"
2031 include "Mips64InstrInfo.td"
2032 include "MipsCondMov.td"
2034 include "Mips32r6InstrInfo.td"
2035 include "Mips64r6InstrInfo.td"
2040 include "Mips16InstrFormats.td"
2041 include "Mips16InstrInfo.td"
2044 include "MipsDSPInstrFormats.td"
2045 include "MipsDSPInstrInfo.td"
2048 include "MipsMSAInstrFormats.td"
2049 include "MipsMSAInstrInfo.td"
2052 include "MipsEVAInstrFormats.td"
2053 include "MipsEVAInstrInfo.td"
2056 include "MicroMipsInstrFormats.td"
2057 include "MicroMipsInstrInfo.td"
2058 include "MicroMipsInstrFPU.td"
2061 include "MicroMips32r6InstrFormats.td"
2062 include "MicroMips32r6InstrInfo.td"
2065 include "MicroMips64r6InstrFormats.td"
2066 include "MicroMips64r6InstrInfo.td"