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 HasMips32r6 : Predicate<"Subtarget->hasMips32r6()">,
170 AssemblerPredicate<"FeatureMips32r6">;
171 def NotMips32r6 : Predicate<"!Subtarget->hasMips32r6()">,
172 AssemblerPredicate<"!FeatureMips32r6">;
173 def IsGP64bit : Predicate<"Subtarget->isGP64bit()">,
174 AssemblerPredicate<"FeatureGP64Bit">;
175 def IsGP32bit : Predicate<"!Subtarget->isGP64bit()">,
176 AssemblerPredicate<"!FeatureGP64Bit">;
177 def HasMips64 : Predicate<"Subtarget->hasMips64()">,
178 AssemblerPredicate<"FeatureMips64">;
179 def HasMips64r2 : Predicate<"Subtarget->hasMips64r2()">,
180 AssemblerPredicate<"FeatureMips64r2">;
181 def HasMips64r6 : Predicate<"Subtarget->hasMips64r6()">,
182 AssemblerPredicate<"FeatureMips64r6">;
183 def NotMips64r6 : Predicate<"!Subtarget->hasMips64r6()">,
184 AssemblerPredicate<"!FeatureMips64r6">;
185 def InMips16Mode : Predicate<"Subtarget->inMips16Mode()">,
186 AssemblerPredicate<"FeatureMips16">;
187 def HasCnMips : Predicate<"Subtarget->hasCnMips()">,
188 AssemblerPredicate<"FeatureCnMips">;
189 def RelocStatic : Predicate<"TM.getRelocationModel() == Reloc::Static">;
190 def RelocPIC : Predicate<"TM.getRelocationModel() == Reloc::PIC_">;
191 def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">;
192 def HasStdEnc : Predicate<"Subtarget->hasStandardEncoding()">,
193 AssemblerPredicate<"!FeatureMips16">;
194 def NotDSP : Predicate<"!Subtarget->hasDSP()">;
195 def InMicroMips : Predicate<"Subtarget->inMicroMipsMode()">,
196 AssemblerPredicate<"FeatureMicroMips">;
197 def NotInMicroMips : Predicate<"!Subtarget->inMicroMipsMode()">,
198 AssemblerPredicate<"!FeatureMicroMips">;
199 def IsLE : Predicate<"Subtarget->isLittle()">;
200 def IsBE : Predicate<"!Subtarget->isLittle()">;
201 def IsNotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
203 //===----------------------------------------------------------------------===//
204 // Mips GPR size adjectives.
205 // They are mutually exclusive.
206 //===----------------------------------------------------------------------===//
208 class GPR_32 { list<Predicate> GPRPredicates = [IsGP32bit]; }
209 class GPR_64 { list<Predicate> GPRPredicates = [IsGP64bit]; }
211 //===----------------------------------------------------------------------===//
212 // Mips ISA/ASE membership and instruction group membership adjectives.
213 // They are mutually exclusive.
214 //===----------------------------------------------------------------------===//
216 // FIXME: I'd prefer to use additive predicates to build the instruction sets
217 // but we are short on assembler feature bits at the moment. Using a
218 // subtractive predicate will hopefully keep us under the 32 predicate
219 // limit long enough to develop an alternative way to handle P1||P2
221 class ISA_MIPS1_NOT_4_32 {
222 list<Predicate> InsnPredicates = [NotMips4_32];
224 class ISA_MIPS1_NOT_32R6_64R6 {
225 list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6];
227 class ISA_MIPS2 { list<Predicate> InsnPredicates = [HasMips2]; }
228 class ISA_MIPS2_NOT_32R6_64R6 {
229 list<Predicate> InsnPredicates = [HasMips2, NotMips32r6, NotMips64r6];
231 class ISA_MIPS3 { list<Predicate> InsnPredicates = [HasMips3]; }
232 class ISA_MIPS3_NOT_32R6_64R6 {
233 list<Predicate> InsnPredicates = [HasMips3, NotMips32r6, NotMips64r6];
235 class ISA_MIPS32 { list<Predicate> InsnPredicates = [HasMips32]; }
236 class ISA_MIPS32_NOT_32R6_64R6 {
237 list<Predicate> InsnPredicates = [HasMips32, NotMips32r6, NotMips64r6];
239 class ISA_MIPS32R2 { list<Predicate> InsnPredicates = [HasMips32r2]; }
240 class ISA_MIPS32R2_NOT_32R6_64R6 {
241 list<Predicate> InsnPredicates = [HasMips32r2, NotMips32r6, NotMips64r6];
243 class ISA_MIPS64 { list<Predicate> InsnPredicates = [HasMips64]; }
244 class ISA_MIPS64_NOT_64R6 {
245 list<Predicate> InsnPredicates = [HasMips64, NotMips64r6];
247 class ISA_MIPS64R2 { list<Predicate> InsnPredicates = [HasMips64r2]; }
248 class ISA_MIPS32R6 { list<Predicate> InsnPredicates = [HasMips32r6]; }
249 class ISA_MIPS64R6 { list<Predicate> InsnPredicates = [HasMips64r6]; }
251 // The portions of MIPS-III that were also added to MIPS32
252 class INSN_MIPS3_32 { list<Predicate> InsnPredicates = [HasMips3_32]; }
254 // The portions of MIPS-III that were also added to MIPS32 but were removed in
255 // MIPS32r6 and MIPS64r6.
256 class INSN_MIPS3_32_NOT_32R6_64R6 {
257 list<Predicate> InsnPredicates = [HasMips3_32, NotMips32r6, NotMips64r6];
260 // The portions of MIPS-III that were also added to MIPS32
261 class INSN_MIPS3_32R2 { list<Predicate> InsnPredicates = [HasMips3_32r2]; }
263 // The portions of MIPS-IV that were also added to MIPS32 but were removed in
264 // MIPS32r6 and MIPS64r6.
265 class INSN_MIPS4_32_NOT_32R6_64R6 {
266 list<Predicate> InsnPredicates = [HasMips4_32, NotMips32r6, NotMips64r6];
269 // The portions of MIPS-IV that were also added to MIPS32r2 but were removed in
270 // MIPS32r6 and MIPS64r6.
271 class INSN_MIPS4_32R2_NOT_32R6_64R6 {
272 list<Predicate> InsnPredicates = [HasMips4_32r2, NotMips32r6, NotMips64r6];
275 // The portions of MIPS-V that were also added to MIPS32r2 but were removed in
276 // MIPS32r6 and MIPS64r6.
277 class INSN_MIPS5_32R2_NOT_32R6_64R6 {
278 list<Predicate> InsnPredicates = [HasMips5_32r2, NotMips32r6, NotMips64r6];
281 //===----------------------------------------------------------------------===//
283 class MipsPat<dag pattern, dag result> : Pat<pattern, result>, PredicateControl {
284 let EncodingPredicates = [HasStdEnc];
287 class MipsInstAlias<string Asm, dag Result, bit Emit = 0b1> :
288 InstAlias<Asm, Result, Emit>, PredicateControl;
291 bit isCommutable = 1;
308 bit isTerminator = 1;
311 bit hasExtraSrcRegAllocReq = 1;
312 bit isCodeGenOnly = 1;
315 class IsAsCheapAsAMove {
316 bit isAsCheapAsAMove = 1;
319 class NeverHasSideEffects {
320 bit hasSideEffects = 0;
323 //===----------------------------------------------------------------------===//
324 // Instruction format superclass
325 //===----------------------------------------------------------------------===//
327 include "MipsInstrFormats.td"
329 //===----------------------------------------------------------------------===//
330 // Mips Operand, Complex Patterns and Transformations Definitions.
331 //===----------------------------------------------------------------------===//
333 def MipsJumpTargetAsmOperand : AsmOperandClass {
334 let Name = "JumpTarget";
335 let ParserMethod = "parseJumpTarget";
336 let PredicateMethod = "isImm";
337 let RenderMethod = "addImmOperands";
340 // Instruction operand types
341 def jmptarget : Operand<OtherVT> {
342 let EncoderMethod = "getJumpTargetOpValue";
343 let ParserMatchClass = MipsJumpTargetAsmOperand;
345 def brtarget : Operand<OtherVT> {
346 let EncoderMethod = "getBranchTargetOpValue";
347 let OperandType = "OPERAND_PCREL";
348 let DecoderMethod = "DecodeBranchTarget";
349 let ParserMatchClass = MipsJumpTargetAsmOperand;
351 def calltarget : Operand<iPTR> {
352 let EncoderMethod = "getJumpTargetOpValue";
353 let ParserMatchClass = MipsJumpTargetAsmOperand;
356 def simm9 : Operand<i32>;
357 def simm10 : Operand<i32>;
358 def simm11 : Operand<i32>;
360 def simm16 : Operand<i32> {
361 let DecoderMethod= "DecodeSimm16";
364 def simm19_lsl2 : Operand<i32> {
365 let EncoderMethod = "getSimm19Lsl2Encoding";
366 let DecoderMethod = "DecodeSimm19Lsl2";
367 let ParserMatchClass = MipsJumpTargetAsmOperand;
370 def simm18_lsl3 : Operand<i32> {
371 let EncoderMethod = "getSimm18Lsl3Encoding";
372 let DecoderMethod = "DecodeSimm18Lsl3";
373 let ParserMatchClass = MipsJumpTargetAsmOperand;
376 def simm20 : Operand<i32> {
379 def uimm20 : Operand<i32> {
382 def uimm10 : Operand<i32> {
385 def simm16_64 : Operand<i64> {
386 let DecoderMethod = "DecodeSimm16";
390 def uimmz : Operand<i32> {
391 let PrintMethod = "printUnsignedImm";
395 def uimm2 : Operand<i32> {
396 let PrintMethod = "printUnsignedImm";
399 def uimm3 : Operand<i32> {
400 let PrintMethod = "printUnsignedImm";
403 def uimm5 : Operand<i32> {
404 let PrintMethod = "printUnsignedImm";
407 def uimm6 : Operand<i32> {
408 let PrintMethod = "printUnsignedImm";
411 def uimm16 : Operand<i32> {
412 let PrintMethod = "printUnsignedImm";
415 def pcrel16 : Operand<i32> {
418 def MipsMemAsmOperand : AsmOperandClass {
420 let ParserMethod = "parseMemOperand";
423 def MipsMemSimm11AsmOperand : AsmOperandClass {
424 let Name = "MemOffsetSimm11";
425 let SuperClasses = [MipsMemAsmOperand];
426 let RenderMethod = "addMemOperands";
427 let ParserMethod = "parseMemOperand";
428 let PredicateMethod = "isMemWithSimmOffset<11>";
431 def MipsMemSimm16AsmOperand : AsmOperandClass {
432 let Name = "MemOffsetSimm16";
433 let SuperClasses = [MipsMemAsmOperand];
434 let RenderMethod = "addMemOperands";
435 let ParserMethod = "parseMemOperand";
436 let PredicateMethod = "isMemWithSimmOffset<16>";
439 def MipsInvertedImmoperand : AsmOperandClass {
441 let RenderMethod = "addImmOperands";
442 let ParserMethod = "parseInvNum";
445 def InvertedImOperand : Operand<i32> {
446 let ParserMatchClass = MipsInvertedImmoperand;
449 def InvertedImOperand64 : Operand<i64> {
450 let ParserMatchClass = MipsInvertedImmoperand;
453 class mem_generic : Operand<iPTR> {
454 let PrintMethod = "printMemOperand";
455 let MIOperandInfo = (ops ptr_rc, simm16);
456 let EncoderMethod = "getMemEncoding";
457 let ParserMatchClass = MipsMemAsmOperand;
458 let OperandType = "OPERAND_MEMORY";
462 def mem : mem_generic;
464 // MSA specific address operand
465 def mem_msa : mem_generic {
466 let MIOperandInfo = (ops ptr_rc, simm10);
467 let EncoderMethod = "getMSAMemEncoding";
470 def mem_simm9 : mem_generic {
471 let MIOperandInfo = (ops ptr_rc, simm9);
472 let EncoderMethod = "getMemEncoding";
475 def mem_simm11 : mem_generic {
476 let MIOperandInfo = (ops ptr_rc, simm11);
477 let EncoderMethod = "getMemEncoding";
478 let ParserMatchClass = MipsMemSimm11AsmOperand;
481 def mem_simm16 : mem_generic {
482 let MIOperandInfo = (ops ptr_rc, simm16);
483 let EncoderMethod = "getMemEncoding";
484 let ParserMatchClass = MipsMemSimm16AsmOperand;
487 def mem_ea : Operand<iPTR> {
488 let PrintMethod = "printMemOperandEA";
489 let MIOperandInfo = (ops ptr_rc, simm16);
490 let EncoderMethod = "getMemEncoding";
491 let OperandType = "OPERAND_MEMORY";
494 def PtrRC : Operand<iPTR> {
495 let MIOperandInfo = (ops ptr_rc);
496 let DecoderMethod = "DecodePtrRegisterClass";
497 let ParserMatchClass = GPR32AsmOperand;
500 // size operand of ext instruction
501 def size_ext : Operand<i32> {
502 let EncoderMethod = "getSizeExtEncoding";
503 let DecoderMethod = "DecodeExtSize";
506 // size operand of ins instruction
507 def size_ins : Operand<i32> {
508 let EncoderMethod = "getSizeInsEncoding";
509 let DecoderMethod = "DecodeInsSize";
512 // Transformation Function - get the lower 16 bits.
513 def LO16 : SDNodeXForm<imm, [{
514 return getImm(N, N->getZExtValue() & 0xFFFF);
517 // Transformation Function - get the higher 16 bits.
518 def HI16 : SDNodeXForm<imm, [{
519 return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF);
523 def Plus1 : SDNodeXForm<imm, [{ return getImm(N, N->getSExtValue() + 1); }]>;
525 // Node immediate is zero (e.g. insve.d)
526 def immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>;
528 // Node immediate fits as 16-bit sign extended on target immediate.
530 def immSExt8 : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;
532 // Node immediate fits as 16-bit sign extended on target immediate.
534 def immSExt16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;
536 // Node immediate fits as 15-bit sign extended on target immediate.
538 def immSExt15 : PatLeaf<(imm), [{ return isInt<15>(N->getSExtValue()); }]>;
540 // Node immediate fits as 16-bit zero extended on target immediate.
541 // The LO16 param means that only the lower 16 bits of the node
542 // immediate are caught.
544 def immZExt16 : PatLeaf<(imm), [{
545 if (N->getValueType(0) == MVT::i32)
546 return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
548 return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
551 // Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared).
552 def immLow16Zero : PatLeaf<(imm), [{
553 int64_t Val = N->getSExtValue();
554 return isInt<32>(Val) && !(Val & 0xffff);
557 // shamt field must fit in 5 bits.
558 def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
560 // True if (N + 1) fits in 16-bit field.
561 def immSExt16Plus1 : PatLeaf<(imm), [{
562 return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1);
565 // Mips Address Mode! SDNode frameindex could possibily be a match
566 // since load and store instructions from stack used it.
568 ComplexPattern<iPTR, 2, "selectIntAddr", [frameindex]>;
571 ComplexPattern<iPTR, 2, "selectAddrRegImm", [frameindex]>;
574 ComplexPattern<iPTR, 2, "selectAddrRegReg", [frameindex]>;
577 ComplexPattern<iPTR, 2, "selectAddrDefault", [frameindex]>;
579 def addrimm10 : ComplexPattern<iPTR, 2, "selectIntAddrMSA", [frameindex]>;
581 //===----------------------------------------------------------------------===//
582 // Instructions specific format
583 //===----------------------------------------------------------------------===//
585 // Arithmetic and logical instructions with 3 register operands.
586 class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0,
587 InstrItinClass Itin = NoItinerary,
588 SDPatternOperator OpNode = null_frag>:
589 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
590 !strconcat(opstr, "\t$rd, $rs, $rt"),
591 [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> {
592 let isCommutable = isComm;
593 let isReMaterializable = 1;
594 let TwoOperandAliasConstraint = "$rd = $rs";
597 // Arithmetic and logical instructions with 2 register operands.
598 class ArithLogicI<string opstr, Operand Od, RegisterOperand RO,
599 InstrItinClass Itin = NoItinerary,
600 SDPatternOperator imm_type = null_frag,
601 SDPatternOperator OpNode = null_frag> :
602 InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16),
603 !strconcat(opstr, "\t$rt, $rs, $imm16"),
604 [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))],
606 let isReMaterializable = 1;
607 let TwoOperandAliasConstraint = "$rs = $rt";
610 // Arithmetic Multiply ADD/SUB
611 class MArithR<string opstr, InstrItinClass itin, bit isComm = 0> :
612 InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
613 !strconcat(opstr, "\t$rs, $rt"), [], itin, FrmR, opstr> {
614 let Defs = [HI0, LO0];
615 let Uses = [HI0, LO0];
616 let isCommutable = isComm;
620 class LogicNOR<string opstr, RegisterOperand RO>:
621 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
622 !strconcat(opstr, "\t$rd, $rs, $rt"),
623 [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], II_NOR, FrmR, opstr> {
624 let isCommutable = 1;
628 class shift_rotate_imm<string opstr, Operand ImmOpnd,
629 RegisterOperand RO, InstrItinClass itin,
630 SDPatternOperator OpNode = null_frag,
631 SDPatternOperator PF = null_frag> :
632 InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt),
633 !strconcat(opstr, "\t$rd, $rt, $shamt"),
634 [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], itin, FrmR, opstr> {
635 let TwoOperandAliasConstraint = "$rt = $rd";
638 class shift_rotate_reg<string opstr, RegisterOperand RO, InstrItinClass itin,
639 SDPatternOperator OpNode = null_frag>:
640 InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs),
641 !strconcat(opstr, "\t$rd, $rt, $rs"),
642 [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], itin, FrmR,
645 // Load Upper Imediate
646 class LoadUpper<string opstr, RegisterOperand RO, Operand Imm>:
647 InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"),
648 [], II_LUI, FrmI, opstr>, IsAsCheapAsAMove {
649 let hasSideEffects = 0;
650 let isReMaterializable = 1;
654 class Load<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
655 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
656 InstSE<(outs RO:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
657 [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> {
658 let DecoderMethod = "DecodeMem";
659 let canFoldAsLoad = 1;
663 class Store<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
664 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
665 InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
666 [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> {
667 let DecoderMethod = "DecodeMem";
671 // Load/Store Left/Right
672 let canFoldAsLoad = 1 in
673 class LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
674 InstrItinClass Itin> :
675 InstSE<(outs RO:$rt), (ins mem:$addr, RO:$src),
676 !strconcat(opstr, "\t$rt, $addr"),
677 [(set RO:$rt, (OpNode addr:$addr, RO:$src))], Itin, FrmI> {
678 let DecoderMethod = "DecodeMem";
679 string Constraints = "$src = $rt";
682 class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
683 InstrItinClass Itin> :
684 InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
685 [(OpNode RO:$rt, addr:$addr)], Itin, FrmI> {
686 let DecoderMethod = "DecodeMem";
690 class LW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
691 SDPatternOperator OpNode= null_frag> :
692 InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
693 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
694 let DecoderMethod = "DecodeFMem2";
698 class SW_FT2<string opstr, RegisterOperand RC, InstrItinClass Itin,
699 SDPatternOperator OpNode= null_frag> :
700 InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
701 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
702 let DecoderMethod = "DecodeFMem2";
707 class LW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
708 SDPatternOperator OpNode= null_frag> :
709 InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
710 [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
711 let DecoderMethod = "DecodeFMem3";
715 class SW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin,
716 SDPatternOperator OpNode= null_frag> :
717 InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
718 [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
719 let DecoderMethod = "DecodeFMem3";
723 // Conditional Branch
724 class CBranch<string opstr, DAGOperand opnd, PatFrag cond_op,
725 RegisterOperand RO, bit DelaySlot = 1> :
726 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
727 !strconcat(opstr, "\t$rs, $rt, $offset"),
728 [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], IIBranch,
731 let isTerminator = 1;
732 let hasDelaySlot = DelaySlot;
736 class CBranchZero<string opstr, DAGOperand opnd, PatFrag cond_op,
737 RegisterOperand RO, bit DelaySlot = 1> :
738 InstSE<(outs), (ins RO:$rs, opnd:$offset),
739 !strconcat(opstr, "\t$rs, $offset"),
740 [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], IIBranch,
743 let isTerminator = 1;
744 let hasDelaySlot = DelaySlot;
749 class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> :
750 InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt),
751 !strconcat(opstr, "\t$rd, $rs, $rt"),
752 [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))],
753 II_SLT_SLTU, FrmR, opstr>;
755 class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
757 InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16),
758 !strconcat(opstr, "\t$rt, $rs, $imm16"),
759 [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))],
760 II_SLTI_SLTIU, FrmI, opstr>;
763 class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
764 SDPatternOperator targetoperator, string bopstr> :
765 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
766 [(operator targetoperator:$target)], IIBranch, FrmJ, bopstr> {
769 let hasDelaySlot = 1;
770 let DecoderMethod = "DecodeJumpTarget";
774 // Unconditional branch
775 class UncondBranch<Instruction BEQInst> :
776 PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], IIBranch>,
777 PseudoInstExpansion<(BEQInst ZERO, ZERO, brtarget:$offset)> {
779 let isTerminator = 1;
781 let hasDelaySlot = 1;
782 let AdditionalPredicates = [RelocPIC];
786 // Base class for indirect branch and return instruction classes.
787 let isTerminator=1, isBarrier=1, hasDelaySlot = 1 in
788 class JumpFR<string opstr, RegisterOperand RO,
789 SDPatternOperator operator = null_frag>:
790 InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], IIBranch,
794 class IndirectBranch<string opstr, RegisterOperand RO> : JumpFR<opstr, RO> {
796 let isIndirectBranch = 1;
799 // Jump and Link (Call)
800 let isCall=1, hasDelaySlot=1, Defs = [RA] in {
801 class JumpLink<string opstr, DAGOperand opnd> :
802 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
803 [(MipsJmpLink imm:$target)], IIBranch, FrmJ, opstr> {
804 let DecoderMethod = "DecodeJumpTarget";
807 class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst,
808 Register RetReg, RegisterOperand ResRO = RO>:
809 PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], IIBranch>,
810 PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)>;
812 class JumpLinkReg<string opstr, RegisterOperand RO>:
813 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
816 class BGEZAL_FT<string opstr, DAGOperand opnd,
817 RegisterOperand RO, bit DelaySlot = 1> :
818 InstSE<(outs), (ins RO:$rs, opnd:$offset),
819 !strconcat(opstr, "\t$rs, $offset"), [], IIBranch, FrmI, opstr> {
820 let hasDelaySlot = DelaySlot;
825 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
826 hasExtraSrcRegAllocReq = 1, Defs = [AT] in {
827 class TailCall<Instruction JumpInst> :
828 PseudoSE<(outs), (ins calltarget:$target), [], IIBranch>,
829 PseudoInstExpansion<(JumpInst jmptarget:$target)>;
831 class TailCallReg<RegisterOperand RO, Instruction JRInst,
832 RegisterOperand ResRO = RO> :
833 PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], IIBranch>,
834 PseudoInstExpansion<(JRInst ResRO:$rs)>;
837 class BAL_BR_Pseudo<Instruction RealInst> :
838 PseudoSE<(outs), (ins brtarget:$offset), [], IIBranch>,
839 PseudoInstExpansion<(RealInst ZERO, brtarget:$offset)> {
841 let isTerminator = 1;
843 let hasDelaySlot = 1;
848 class SYS_FT<string opstr> :
849 InstSE<(outs), (ins uimm20:$code_),
850 !strconcat(opstr, "\t$code_"), [], NoItinerary, FrmI, opstr>;
852 class BRK_FT<string opstr> :
853 InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
854 !strconcat(opstr, "\t$code_1, $code_2"), [], NoItinerary,
858 class ER_FT<string opstr> :
859 InstSE<(outs), (ins),
860 opstr, [], NoItinerary, FrmOther, opstr>;
863 class DEI_FT<string opstr, RegisterOperand RO> :
864 InstSE<(outs RO:$rt), (ins),
865 !strconcat(opstr, "\t$rt"), [], NoItinerary, FrmOther, opstr>;
868 class WAIT_FT<string opstr> :
869 InstSE<(outs), (ins), opstr, [], NoItinerary, FrmOther, opstr>;
872 let hasSideEffects = 1 in
873 class SYNC_FT<string opstr> :
874 InstSE<(outs), (ins i32imm:$stype), "sync $stype", [(MipsSync imm:$stype)],
875 NoItinerary, FrmOther, opstr>;
877 class SYNCI_FT<string opstr> :
878 InstSE<(outs), (ins mem_simm16:$addr), !strconcat(opstr, "\t$addr"), [],
879 NoItinerary, FrmOther, opstr> {
880 let hasSideEffects = 1;
881 let DecoderMethod = "DecodeSyncI";
884 let hasSideEffects = 1 in
885 class TEQ_FT<string opstr, RegisterOperand RO> :
886 InstSE<(outs), (ins RO:$rs, RO:$rt, uimm16:$code_),
887 !strconcat(opstr, "\t$rs, $rt, $code_"), [], NoItinerary,
890 class TEQI_FT<string opstr, RegisterOperand RO> :
891 InstSE<(outs), (ins RO:$rs, uimm16:$imm16),
892 !strconcat(opstr, "\t$rs, $imm16"), [], NoItinerary, FrmOther, opstr>;
894 class Mult<string opstr, InstrItinClass itin, RegisterOperand RO,
895 list<Register> DefRegs> :
896 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [],
898 let isCommutable = 1;
900 let hasSideEffects = 0;
903 // Pseudo multiply/divide instruction with explicit accumulator register
905 class MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1,
906 SDPatternOperator OpNode, InstrItinClass Itin,
907 bit IsComm = 1, bit HasSideEffects = 0,
908 bit UsesCustomInserter = 0> :
909 PseudoSE<(outs R0:$ac), (ins R1:$rs, R1:$rt),
910 [(set R0:$ac, (OpNode R1:$rs, R1:$rt))], Itin>,
911 PseudoInstExpansion<(RealInst R1:$rs, R1:$rt)> {
912 let isCommutable = IsComm;
913 let hasSideEffects = HasSideEffects;
914 let usesCustomInserter = UsesCustomInserter;
917 // Pseudo multiply add/sub instruction with explicit accumulator register
919 class MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode,
921 : PseudoSE<(outs ACC64:$ac),
922 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin),
924 (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))],
926 PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> {
927 string Constraints = "$acin = $ac";
930 class Div<string opstr, InstrItinClass itin, RegisterOperand RO,
931 list<Register> DefRegs> :
932 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$$zero, $rs, $rt"),
933 [], itin, FrmR, opstr> {
938 class PseudoMFLOHI<RegisterClass DstRC, RegisterClass SrcRC, SDNode OpNode>
939 : PseudoSE<(outs DstRC:$rd), (ins SrcRC:$hilo),
940 [(set DstRC:$rd, (OpNode SrcRC:$hilo))], II_MFHI_MFLO>;
942 class MoveFromLOHI<string opstr, RegisterOperand RO, Register UseReg>:
943 InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO,
946 let hasSideEffects = 0;
949 class PseudoMTLOHI<RegisterClass DstRC, RegisterClass SrcRC>
950 : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi),
951 [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))],
954 class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>:
955 InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO,
958 let hasSideEffects = 0;
961 class EffectiveAddress<string opstr, RegisterOperand RO> :
962 InstSE<(outs RO:$rt), (ins mem_ea:$addr), !strconcat(opstr, "\t$rt, $addr"),
963 [(set RO:$rt, addr:$addr)], NoItinerary, FrmI,
964 !strconcat(opstr, "_lea")> {
965 let isCodeGenOnly = 1;
966 let DecoderMethod = "DecodeMem";
969 // Count Leading Ones/Zeros in Word
970 class CountLeading0<string opstr, RegisterOperand RO>:
971 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
972 [(set RO:$rd, (ctlz RO:$rs))], II_CLZ, FrmR, opstr>;
974 class CountLeading1<string opstr, RegisterOperand RO>:
975 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
976 [(set RO:$rd, (ctlz (not RO:$rs)))], II_CLO, FrmR, opstr>;
978 // Sign Extend in Register.
979 class SignExtInReg<string opstr, ValueType vt, RegisterOperand RO,
980 InstrItinClass itin> :
981 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"),
982 [(set RO:$rd, (sext_inreg RO:$rt, vt))], itin, FrmR, opstr>;
985 class SubwordSwap<string opstr, RegisterOperand RO>:
986 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [],
987 NoItinerary, FrmR, opstr> {
988 let hasSideEffects = 0;
992 class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> :
993 InstSE<(outs CPURegOperand:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [],
994 II_RDHWR, FrmR, "rdhwr">;
997 class ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd,
998 SDPatternOperator Op = null_frag>:
999 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, size_ext:$size),
1000 !strconcat(opstr, " $rt, $rs, $pos, $size"),
1001 [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size))], II_EXT,
1002 FrmR, opstr>, ISA_MIPS32R2;
1004 class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd,
1005 SDPatternOperator Op = null_frag>:
1006 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, size_ins:$size, RO:$src),
1007 !strconcat(opstr, " $rt, $rs, $pos, $size"),
1008 [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size, RO:$src))],
1009 II_INS, FrmR, opstr>, ISA_MIPS32R2 {
1010 let Constraints = "$src = $rt";
1013 // Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*).
1014 class Atomic2Ops<PatFrag Op, RegisterClass DRC> :
1015 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr),
1016 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]>;
1018 // Atomic Compare & Swap.
1019 class AtomicCmpSwap<PatFrag Op, RegisterClass DRC> :
1020 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap),
1021 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]>;
1023 class LLBase<string opstr, RegisterOperand RO> :
1024 InstSE<(outs RO:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
1025 [], NoItinerary, FrmI> {
1026 let DecoderMethod = "DecodeMem";
1030 class SCBase<string opstr, RegisterOperand RO> :
1031 InstSE<(outs RO:$dst), (ins RO:$rt, mem:$addr),
1032 !strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> {
1033 let DecoderMethod = "DecodeMem";
1035 let Constraints = "$rt = $dst";
1038 class MFC3OP<string asmstr, RegisterOperand RO> :
1039 InstSE<(outs RO:$rt, RO:$rd, uimm16:$sel), (ins),
1040 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], NoItinerary, FrmFR>;
1042 class TrapBase<Instruction RealInst>
1043 : PseudoSE<(outs), (ins), [(trap)], NoItinerary>,
1044 PseudoInstExpansion<(RealInst 0, 0)> {
1046 let isTerminator = 1;
1047 let isCodeGenOnly = 1;
1050 //===----------------------------------------------------------------------===//
1051 // Pseudo instructions
1052 //===----------------------------------------------------------------------===//
1055 let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1 in
1056 def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
1058 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
1059 def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt),
1060 [(callseq_start timm:$amt)]>;
1061 def ADJCALLSTACKUP : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1062 [(callseq_end timm:$amt1, timm:$amt2)]>;
1065 let usesCustomInserter = 1 in {
1066 def ATOMIC_LOAD_ADD_I8 : Atomic2Ops<atomic_load_add_8, GPR32>;
1067 def ATOMIC_LOAD_ADD_I16 : Atomic2Ops<atomic_load_add_16, GPR32>;
1068 def ATOMIC_LOAD_ADD_I32 : Atomic2Ops<atomic_load_add_32, GPR32>;
1069 def ATOMIC_LOAD_SUB_I8 : Atomic2Ops<atomic_load_sub_8, GPR32>;
1070 def ATOMIC_LOAD_SUB_I16 : Atomic2Ops<atomic_load_sub_16, GPR32>;
1071 def ATOMIC_LOAD_SUB_I32 : Atomic2Ops<atomic_load_sub_32, GPR32>;
1072 def ATOMIC_LOAD_AND_I8 : Atomic2Ops<atomic_load_and_8, GPR32>;
1073 def ATOMIC_LOAD_AND_I16 : Atomic2Ops<atomic_load_and_16, GPR32>;
1074 def ATOMIC_LOAD_AND_I32 : Atomic2Ops<atomic_load_and_32, GPR32>;
1075 def ATOMIC_LOAD_OR_I8 : Atomic2Ops<atomic_load_or_8, GPR32>;
1076 def ATOMIC_LOAD_OR_I16 : Atomic2Ops<atomic_load_or_16, GPR32>;
1077 def ATOMIC_LOAD_OR_I32 : Atomic2Ops<atomic_load_or_32, GPR32>;
1078 def ATOMIC_LOAD_XOR_I8 : Atomic2Ops<atomic_load_xor_8, GPR32>;
1079 def ATOMIC_LOAD_XOR_I16 : Atomic2Ops<atomic_load_xor_16, GPR32>;
1080 def ATOMIC_LOAD_XOR_I32 : Atomic2Ops<atomic_load_xor_32, GPR32>;
1081 def ATOMIC_LOAD_NAND_I8 : Atomic2Ops<atomic_load_nand_8, GPR32>;
1082 def ATOMIC_LOAD_NAND_I16 : Atomic2Ops<atomic_load_nand_16, GPR32>;
1083 def ATOMIC_LOAD_NAND_I32 : Atomic2Ops<atomic_load_nand_32, GPR32>;
1085 def ATOMIC_SWAP_I8 : Atomic2Ops<atomic_swap_8, GPR32>;
1086 def ATOMIC_SWAP_I16 : Atomic2Ops<atomic_swap_16, GPR32>;
1087 def ATOMIC_SWAP_I32 : Atomic2Ops<atomic_swap_32, GPR32>;
1089 def ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap<atomic_cmp_swap_8, GPR32>;
1090 def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap<atomic_cmp_swap_16, GPR32>;
1091 def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_32, GPR32>;
1094 /// Pseudo instructions for loading and storing accumulator registers.
1095 let isPseudo = 1, isCodeGenOnly = 1 in {
1096 def LOAD_ACC64 : Load<"", ACC64>;
1097 def STORE_ACC64 : Store<"", ACC64>;
1100 // We need these two pseudo instructions to avoid offset calculation for long
1101 // branches. See the comment in file MipsLongBranch.cpp for detailed
1104 // Expands to: lui $dst, %hi($tgt - $baltgt)
1105 def LONG_BRANCH_LUi : PseudoSE<(outs GPR32Opnd:$dst),
1106 (ins brtarget:$tgt, brtarget:$baltgt), []>;
1108 // Expands to: addiu $dst, $src, %lo($tgt - $baltgt)
1109 def LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst),
1110 (ins GPR32Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []>;
1112 //===----------------------------------------------------------------------===//
1113 // Instruction definition
1114 //===----------------------------------------------------------------------===//
1115 //===----------------------------------------------------------------------===//
1116 // MipsI Instructions
1117 //===----------------------------------------------------------------------===//
1119 /// Arithmetic Instructions (ALU Immediate)
1120 let AdditionalPredicates = [NotInMicroMips] in {
1121 def ADDiu : MMRel, ArithLogicI<"addiu", simm16, GPR32Opnd, II_ADDIU, immSExt16,
1122 add>, ADDI_FM<0x9>, IsAsCheapAsAMove;
1124 def ADDi : MMRel, ArithLogicI<"addi", simm16, GPR32Opnd>, ADDI_FM<0x8>,
1125 ISA_MIPS1_NOT_32R6_64R6;
1126 def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
1128 def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
1130 let AdditionalPredicates = [NotInMicroMips] in {
1131 def ANDi : MMRel, ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16,
1134 def ORi : MMRel, ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16,
1137 def XORi : MMRel, ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16,
1140 def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16>, LUI_FM;
1141 let AdditionalPredicates = [NotInMicroMips] in {
1142 /// Arithmetic Instructions (3-Operand, R-Type)
1143 def ADDu : MMRel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
1145 def SUBu : MMRel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
1148 let Defs = [HI0, LO0] in
1149 def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>,
1150 ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6;
1151 def ADD : MMRel, ArithLogicR<"add", GPR32Opnd>, ADD_FM<0, 0x20>;
1152 def SUB : MMRel, ArithLogicR<"sub", GPR32Opnd>, ADD_FM<0, 0x22>;
1153 def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>;
1154 def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>;
1155 let AdditionalPredicates = [NotInMicroMips] in {
1156 def AND : MMRel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
1158 def OR : MMRel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
1160 def XOR : MMRel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
1163 def NOR : MMRel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>;
1165 /// Shift Instructions
1166 let AdditionalPredicates = [NotInMicroMips] in {
1167 def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl,
1168 immZExt5>, SRA_FM<0, 0>;
1169 def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl,
1170 immZExt5>, SRA_FM<2, 0>;
1172 def SRA : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, sra,
1173 immZExt5>, SRA_FM<3, 0>;
1174 def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, shl>,
1176 def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, srl>,
1178 def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, sra>,
1181 // Rotate Instructions
1182 def ROTR : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr,
1184 SRA_FM<2, 1>, ISA_MIPS32R2;
1185 def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>,
1186 SRLV_FM<6, 1>, ISA_MIPS32R2;
1188 /// Load and Store Instructions
1190 def LB : Load<"lb", GPR32Opnd, sextloadi8, II_LB>, MMRel, LW_FM<0x20>;
1191 def LBu : Load<"lbu", GPR32Opnd, zextloadi8, II_LBU, addrDefault>, MMRel,
1193 def LH : Load<"lh", GPR32Opnd, sextloadi16, II_LH, addrDefault>, MMRel,
1195 def LHu : Load<"lhu", GPR32Opnd, zextloadi16, II_LHU>, MMRel, LW_FM<0x25>;
1196 let AdditionalPredicates = [NotInMicroMips] in {
1197 def LW : Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel,
1200 def SB : Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel, LW_FM<0x28>;
1201 def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>;
1202 let AdditionalPredicates = [NotInMicroMips] in {
1203 def SW : Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>;
1206 /// load/store left/right
1207 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1208 AdditionalPredicates = [NotInMicroMips] in {
1209 def LWL : LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>,
1210 ISA_MIPS1_NOT_32R6_64R6;
1211 def LWR : LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>,
1212 ISA_MIPS1_NOT_32R6_64R6;
1213 def SWL : StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>,
1214 ISA_MIPS1_NOT_32R6_64R6;
1215 def SWR : StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>,
1216 ISA_MIPS1_NOT_32R6_64R6;
1219 let AdditionalPredicates = [NotInMicroMips] in {
1220 // COP2 Memory Instructions
1221 def LWC2 : LW_FT2<"lwc2", COP2Opnd, NoItinerary, load>, LW_FM<0x32>,
1222 ISA_MIPS1_NOT_32R6_64R6;
1223 def SWC2 : SW_FT2<"swc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3a>,
1224 ISA_MIPS1_NOT_32R6_64R6;
1225 def LDC2 : LW_FT2<"ldc2", COP2Opnd, NoItinerary, load>, LW_FM<0x36>,
1226 ISA_MIPS2_NOT_32R6_64R6;
1227 def SDC2 : SW_FT2<"sdc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3e>,
1228 ISA_MIPS2_NOT_32R6_64R6;
1230 // COP3 Memory Instructions
1231 let DecoderNamespace = "COP3_" in {
1232 def LWC3 : LW_FT3<"lwc3", COP3Opnd, NoItinerary, load>, LW_FM<0x33>;
1233 def SWC3 : SW_FT3<"swc3", COP3Opnd, NoItinerary, store>, LW_FM<0x3b>;
1234 def LDC3 : LW_FT3<"ldc3", COP3Opnd, NoItinerary, load>, LW_FM<0x37>,
1236 def SDC3 : SW_FT3<"sdc3", COP3Opnd, NoItinerary, store>, LW_FM<0x3f>,
1241 def SYNC : MMRel, SYNC_FT<"sync">, SYNC_FM, ISA_MIPS32;
1242 def SYNCI : MMRel, SYNCI_FT<"synci">, SYNCI_FM, ISA_MIPS32R2;
1244 def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM<0x34>, ISA_MIPS2;
1245 def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM<0x30>, ISA_MIPS2;
1246 def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd>, TEQ_FM<0x31>, ISA_MIPS2;
1247 def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd>, TEQ_FM<0x32>, ISA_MIPS2;
1248 def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd>, TEQ_FM<0x33>, ISA_MIPS2;
1249 def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd>, TEQ_FM<0x36>, ISA_MIPS2;
1251 def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd>, TEQI_FM<0xc>,
1252 ISA_MIPS2_NOT_32R6_64R6;
1253 def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd>, TEQI_FM<0x8>,
1254 ISA_MIPS2_NOT_32R6_64R6;
1255 def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd>, TEQI_FM<0x9>,
1256 ISA_MIPS2_NOT_32R6_64R6;
1257 def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd>, TEQI_FM<0xa>,
1258 ISA_MIPS2_NOT_32R6_64R6;
1259 def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd>, TEQI_FM<0xb>,
1260 ISA_MIPS2_NOT_32R6_64R6;
1261 def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd>, TEQI_FM<0xe>,
1262 ISA_MIPS2_NOT_32R6_64R6;
1264 def BREAK : MMRel, BRK_FT<"break">, BRK_FM<0xd>;
1265 def SYSCALL : MMRel, SYS_FT<"syscall">, SYS_FM<0xc>;
1266 def TRAP : TrapBase<BREAK>;
1267 def SDBBP : MMRel, SYS_FT<"sdbbp">, SDBBP_FM, ISA_MIPS32_NOT_32R6_64R6;
1269 def ERET : MMRel, ER_FT<"eret">, ER_FM<0x18>, INSN_MIPS3_32;
1270 def DERET : MMRel, ER_FT<"deret">, ER_FM<0x1f>, ISA_MIPS32;
1272 def EI : MMRel, DEI_FT<"ei", GPR32Opnd>, EI_FM<1>, ISA_MIPS32R2;
1273 def DI : MMRel, DEI_FT<"di", GPR32Opnd>, EI_FM<0>, ISA_MIPS32R2;
1275 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1276 AdditionalPredicates = [NotInMicroMips] in {
1277 def WAIT : WAIT_FT<"wait">, WAIT_FM;
1279 /// Load-linked, Store-conditional
1280 def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, ISA_MIPS2_NOT_32R6_64R6;
1281 def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, ISA_MIPS2_NOT_32R6_64R6;
1284 /// Jump and Branch Instructions
1285 def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
1286 AdditionalRequires<[RelocStatic]>, IsBranch;
1287 def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>;
1288 def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>;
1289 def BEQL : MMRel, CBranch<"beql", brtarget, seteq, GPR32Opnd, 0>,
1290 BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6;
1291 def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>;
1292 def BNEL : MMRel, CBranch<"bnel", brtarget, setne, GPR32Opnd, 0>,
1293 BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6;
1294 def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
1296 def BGEZL : MMRel, CBranchZero<"bgezl", brtarget, setge, GPR32Opnd, 0>,
1297 BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6;
1298 def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
1300 def BGTZL : MMRel, CBranchZero<"bgtzl", brtarget, setgt, GPR32Opnd, 0>,
1301 BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6;
1302 def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
1304 def BLEZL : MMRel, CBranchZero<"blezl", brtarget, setle, GPR32Opnd, 0>,
1305 BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6;
1306 def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
1308 def BLTZL : MMRel, CBranchZero<"bltzl", brtarget, setlt, GPR32Opnd, 0>,
1309 BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6;
1310 def B : UncondBranch<BEQ>;
1312 def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>;
1313 let AdditionalPredicates = [NotInMicroMips] in {
1314 def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM;
1315 def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>;
1318 def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>,
1319 ISA_MIPS32_NOT_32R6_64R6;
1320 def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>,
1321 ISA_MIPS1_NOT_32R6_64R6;
1322 def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd, 0>,
1323 BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6;
1324 def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>,
1325 ISA_MIPS1_NOT_32R6_64R6;
1326 def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd, 0>,
1327 BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6;
1328 def BAL_BR : BAL_BR_Pseudo<BGEZAL>;
1329 def TAILCALL : TailCall<J>;
1330 def TAILCALL_R : TailCallReg<GPR32Opnd, JR>;
1332 // Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64
1333 // then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA.
1334 class PseudoIndirectBranchBase<RegisterOperand RO> :
1335 MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)], IIBranch> {
1338 let hasDelaySlot = 1;
1340 let isIndirectBranch = 1;
1343 def PseudoIndirectBranch : PseudoIndirectBranchBase<GPR32Opnd>;
1345 // Return instructions are matched as a RetRA instruction, then ar expanded
1346 // into PseudoReturn/PseudoReturn64 after register allocation. Finally,
1347 // MipsAsmPrinter expands this into JR, JR64, JALR, or JALR64 depending on the
1349 class PseudoReturnBase<RegisterOperand RO> : MipsPseudo<(outs), (ins RO:$rs),
1351 let isTerminator = 1;
1353 let hasDelaySlot = 1;
1355 let isCodeGenOnly = 1;
1357 let hasExtraSrcRegAllocReq = 1;
1360 def PseudoReturn : PseudoReturnBase<GPR32Opnd>;
1362 // Exception handling related node and instructions.
1363 // The conversion sequence is:
1364 // ISD::EH_RETURN -> MipsISD::EH_RETURN ->
1365 // MIPSeh_return -> (stack change + indirect branch)
1367 // MIPSeh_return takes the place of regular return instruction
1368 // but takes two arguments (V1, V0) which are used for storing
1369 // the offset and return address respectively.
1370 def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
1372 def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
1373 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
1375 let Uses = [V0, V1], isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1376 def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
1377 [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
1378 def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff,
1380 [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
1383 /// Multiply and Divide Instructions.
1384 def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
1385 MULT_FM<0, 0x18>, ISA_MIPS1_NOT_32R6_64R6;
1386 def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
1387 MULT_FM<0, 0x19>, ISA_MIPS1_NOT_32R6_64R6;
1388 def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
1389 MULT_FM<0, 0x1a>, ISA_MIPS1_NOT_32R6_64R6;
1390 def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
1391 MULT_FM<0, 0x1b>, ISA_MIPS1_NOT_32R6_64R6;
1393 def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>,
1394 ISA_MIPS1_NOT_32R6_64R6;
1395 def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>,
1396 ISA_MIPS1_NOT_32R6_64R6;
1397 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1398 AdditionalPredicates = [NotInMicroMips] in {
1399 def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>,
1400 ISA_MIPS1_NOT_32R6_64R6;
1401 def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>,
1402 ISA_MIPS1_NOT_32R6_64R6;
1405 /// Sign Ext In Register Instructions.
1406 def SEB : MMRel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,
1407 SEB_FM<0x10, 0x20>, ISA_MIPS32R2;
1408 def SEH : MMRel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
1409 SEB_FM<0x18, 0x20>, ISA_MIPS32R2;
1412 def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd>, CLO_FM<0x20>,
1413 ISA_MIPS32_NOT_32R6_64R6;
1414 def CLO : MMRel, CountLeading1<"clo", GPR32Opnd>, CLO_FM<0x21>,
1415 ISA_MIPS32_NOT_32R6_64R6;
1417 /// Word Swap Bytes Within Halfwords
1418 def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd>, SEB_FM<2, 0x20>, ISA_MIPS32R2;
1421 def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>;
1423 // FrameIndexes are legalized when they are operands from load/store
1424 // instructions. The same not happens for stack address copies, so an
1425 // add op with mem ComplexPattern is used and the stack address copy
1426 // can be matched. It's similar to Sparc LEA_ADDRi
1427 def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>;
1430 def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>,
1431 ISA_MIPS32_NOT_32R6_64R6;
1432 def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>,
1433 ISA_MIPS32_NOT_32R6_64R6;
1434 def MSUB : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>,
1435 ISA_MIPS32_NOT_32R6_64R6;
1436 def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>,
1437 ISA_MIPS32_NOT_32R6_64R6;
1439 let AdditionalPredicates = [NotDSP] in {
1440 def PseudoMULT : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>,
1441 ISA_MIPS1_NOT_32R6_64R6;
1442 def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>,
1443 ISA_MIPS1_NOT_32R6_64R6;
1444 def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>, ISA_MIPS1_NOT_32R6_64R6;
1445 def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>, ISA_MIPS1_NOT_32R6_64R6;
1446 def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>, ISA_MIPS1_NOT_32R6_64R6;
1447 def PseudoMADD : MAddSubPseudo<MADD, MipsMAdd, II_MADD>,
1448 ISA_MIPS32_NOT_32R6_64R6;
1449 def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>,
1450 ISA_MIPS32_NOT_32R6_64R6;
1451 def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>,
1452 ISA_MIPS32_NOT_32R6_64R6;
1453 def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>,
1454 ISA_MIPS32_NOT_32R6_64R6;
1457 def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV,
1458 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
1459 def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU,
1460 0, 1, 1>, ISA_MIPS1_NOT_32R6_64R6;
1462 def RDHWR : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM;
1464 def EXT : MMRel, ExtBase<"ext", GPR32Opnd, uimm5, MipsExt>, EXT_FM<0>;
1465 def INS : MMRel, InsBase<"ins", GPR32Opnd, uimm5, MipsIns>, EXT_FM<4>;
1467 /// Move Control Registers From/To CPU Registers
1468 def MFC0 : MFC3OP<"mfc0", GPR32Opnd>, MFC3OP_FM<0x10, 0>, ISA_MIPS32;
1469 def MTC0 : MFC3OP<"mtc0", GPR32Opnd>, MFC3OP_FM<0x10, 4>, ISA_MIPS32;
1470 def MFC2 : MFC3OP<"mfc2", GPR32Opnd>, MFC3OP_FM<0x12, 0>;
1471 def MTC2 : MFC3OP<"mtc2", GPR32Opnd>, MFC3OP_FM<0x12, 4>;
1473 class Barrier<string asmstr> : InstSE<(outs), (ins), asmstr, [], NoItinerary,
1475 def SSNOP : MMRel, Barrier<"ssnop">, BARRIER_FM<1>;
1476 def EHB : MMRel, Barrier<"ehb">, BARRIER_FM<3>;
1477 def PAUSE : MMRel, Barrier<"pause">, BARRIER_FM<5>, ISA_MIPS32R2;
1479 // JR_HB and JALR_HB are defined here using the new style naming
1480 // scheme because some of this code is shared with Mips32r6InstrInfo.td
1481 // and because of that it doesn't follow the naming convention of the
1482 // rest of the file. To avoid a mixture of old vs new style, the new
1483 // style was chosen.
1484 class JR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
1485 dag OutOperandList = (outs);
1486 dag InOperandList = (ins GPROpnd:$rs);
1487 string AsmString = !strconcat(instr_asm, "\t$rs");
1488 list<dag> Pattern = [];
1491 class JALR_HB_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
1492 dag OutOperandList = (outs GPROpnd:$rd);
1493 dag InOperandList = (ins GPROpnd:$rs);
1494 string AsmString = !strconcat(instr_asm, "\t$rd, $rs");
1495 list<dag> Pattern = [];
1498 class JR_HB_DESC : InstSE<(outs), (ins), "", [], NoItinerary, FrmJ>,
1499 JR_HB_DESC_BASE<"jr.hb", GPR32Opnd> {
1501 let isIndirectBranch=1;
1507 class JALR_HB_DESC : InstSE<(outs), (ins), "", [], NoItinerary, FrmJ>,
1508 JALR_HB_DESC_BASE<"jalr.hb", GPR32Opnd> {
1509 let isIndirectBranch=1;
1513 class JR_HB_ENC : JR_HB_FM<8>;
1514 class JALR_HB_ENC : JALR_HB_FM<9>;
1516 def JR_HB : JR_HB_DESC, JR_HB_ENC, ISA_MIPS32_NOT_32R6_64R6;
1517 def JALR_HB : JALR_HB_DESC, JALR_HB_ENC, ISA_MIPS32;
1519 class TLB<string asmstr> : InstSE<(outs), (ins), asmstr, [], NoItinerary,
1521 def TLBP : MMRel, TLB<"tlbp">, COP0_TLB_FM<0x08>;
1522 def TLBR : MMRel, TLB<"tlbr">, COP0_TLB_FM<0x01>;
1523 def TLBWI : MMRel, TLB<"tlbwi">, COP0_TLB_FM<0x02>;
1524 def TLBWR : MMRel, TLB<"tlbwr">, COP0_TLB_FM<0x06>;
1526 class CacheOp<string instr_asm, Operand MemOpnd> :
1527 InstSE<(outs), (ins MemOpnd:$addr, uimm5:$hint),
1528 !strconcat(instr_asm, "\t$hint, $addr"), [], NoItinerary, FrmOther,
1530 let DecoderMethod = "DecodeCacheOp";
1533 def CACHE : MMRel, CacheOp<"cache", mem>, CACHEOP_FM<0b101111>,
1534 INSN_MIPS3_32_NOT_32R6_64R6;
1535 def PREF : MMRel, CacheOp<"pref", mem>, CACHEOP_FM<0b110011>,
1536 INSN_MIPS3_32_NOT_32R6_64R6;
1538 //===----------------------------------------------------------------------===//
1539 // Instruction aliases
1540 //===----------------------------------------------------------------------===//
1541 def : MipsInstAlias<"move $dst, $src",
1542 (ADDu GPR32Opnd:$dst, GPR32Opnd:$src,ZERO), 1>,
1544 let AdditionalPredicates = [NotInMicroMips];
1546 def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>,
1547 ISA_MIPS1_NOT_32R6_64R6;
1548 def : MipsInstAlias<"addu $rs, $rt, $imm",
1549 (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1550 def : MipsInstAlias<"addu $rs, $imm",
1551 (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>;
1552 def : MipsInstAlias<"add $rs, $rt, $imm",
1553 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>,
1554 ISA_MIPS1_NOT_32R6_64R6;
1555 def : MipsInstAlias<"add $rs, $imm",
1556 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>,
1557 ISA_MIPS1_NOT_32R6_64R6;
1558 def : MipsInstAlias<"and $rs, $rt, $imm",
1559 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1560 def : MipsInstAlias<"and $rs, $imm",
1561 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm), 0>;
1562 def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>;
1563 let Predicates = [NotInMicroMips] in {
1564 def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
1566 def : MipsInstAlias<"jalr.hb $rs", (JALR_HB RA, GPR32Opnd:$rs), 1>, ISA_MIPS32;
1567 def : MipsInstAlias<"not $rt, $rs",
1568 (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>;
1569 def : MipsInstAlias<"neg $rt, $rs",
1570 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
1571 def : MipsInstAlias<"negu $rt",
1572 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 0>;
1573 def : MipsInstAlias<"negu $rt, $rs",
1574 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
1575 def : MipsInstAlias<"slt $rs, $rt, $imm",
1576 (SLTi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1577 def : MipsInstAlias<"sltu $rt, $rs, $imm",
1578 (SLTiu GPR32Opnd:$rt, GPR32Opnd:$rs, simm16:$imm), 0>;
1579 def : MipsInstAlias<"xor $rs, $rt, $imm",
1580 (XORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
1581 def : MipsInstAlias<"xor $rs, $imm",
1582 (XORi GPR32Opnd:$rs, GPR32Opnd:$rs, uimm16:$imm), 0>;
1583 def : MipsInstAlias<"or $rs, $rt, $imm",
1584 (ORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
1585 def : MipsInstAlias<"or $rs, $imm",
1586 (ORi GPR32Opnd:$rs, GPR32Opnd:$rs, uimm16:$imm), 0>;
1587 def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>;
1588 def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>;
1589 def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>;
1590 def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>;
1591 def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>;
1592 let AdditionalPredicates = [NotInMicroMips] in {
1593 def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>;
1595 def : MipsInstAlias<"bnez $rs,$offset",
1596 (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1597 def : MipsInstAlias<"beqz $rs,$offset",
1598 (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1599 def : MipsInstAlias<"syscall", (SYSCALL 0), 1>;
1601 def : MipsInstAlias<"break", (BREAK 0, 0), 1>;
1602 def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>;
1603 def : MipsInstAlias<"ei", (EI ZERO), 1>, ISA_MIPS32R2;
1604 def : MipsInstAlias<"di", (DI ZERO), 1>, ISA_MIPS32R2;
1606 def : MipsInstAlias<"teq $rs, $rt",
1607 (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1608 def : MipsInstAlias<"tge $rs, $rt",
1609 (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1610 def : MipsInstAlias<"tgeu $rs, $rt",
1611 (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1612 def : MipsInstAlias<"tlt $rs, $rt",
1613 (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1614 def : MipsInstAlias<"tltu $rs, $rt",
1615 (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1616 def : MipsInstAlias<"tne $rs, $rt",
1617 (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>, ISA_MIPS2;
1619 def : MipsInstAlias<"sll $rd, $rt, $rs",
1620 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1621 def : MipsInstAlias<"sub, $rd, $rs, $imm",
1622 (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs,
1623 InvertedImOperand:$imm), 0>, ISA_MIPS1_NOT_32R6_64R6;
1624 def : MipsInstAlias<"sub $rs, $imm",
1625 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm),
1626 0>, ISA_MIPS1_NOT_32R6_64R6;
1627 def : MipsInstAlias<"subu, $rd, $rs, $imm",
1628 (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs,
1629 InvertedImOperand:$imm), 0>;
1630 def : MipsInstAlias<"subu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs,
1631 InvertedImOperand:$imm), 0>;
1632 def : MipsInstAlias<"sra $rd, $rt, $rs",
1633 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1634 def : MipsInstAlias<"srl $rd, $rt, $rs",
1635 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1636 def : MipsInstAlias<"sdbbp", (SDBBP 0)>, ISA_MIPS32_NOT_32R6_64R6;
1637 def : MipsInstAlias<"sync",
1638 (SYNC 0), 1>, ISA_MIPS2;
1639 //===----------------------------------------------------------------------===//
1640 // Assembler Pseudo Instructions
1641 //===----------------------------------------------------------------------===//
1643 class LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> :
1644 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
1645 !strconcat(instr_asm, "\t$rt, $imm32")> ;
1646 def LoadImm32 : LoadImmediate32<"li", uimm5, GPR32Opnd>;
1648 class LoadAddressFromReg32<string instr_asm, Operand MemOpnd,
1649 RegisterOperand RO> :
1650 MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
1651 !strconcat(instr_asm, "\t$rt, $addr")> ;
1652 def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>;
1654 class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> :
1655 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
1656 !strconcat(instr_asm, "\t$rt, $imm32")> ;
1657 def LoadAddrImm32 : LoadAddressFromImm32<"la", uimm5, GPR32Opnd>;
1659 def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
1661 def JalOneReg : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rs),
1664 //===----------------------------------------------------------------------===//
1665 // Arbitrary patterns that map to one or more instructions
1666 //===----------------------------------------------------------------------===//
1668 // Load/store pattern templates.
1669 class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
1670 MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
1672 class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
1673 MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
1676 let AdditionalPredicates = [NotInMicroMips] in {
1677 def : MipsPat<(i32 immSExt16:$in),
1678 (ADDiu ZERO, imm:$in)>;
1679 def : MipsPat<(i32 immZExt16:$in),
1680 (ORi ZERO, imm:$in)>;
1682 def : MipsPat<(i32 immLow16Zero:$in),
1683 (LUi (HI16 imm:$in))>;
1685 // Arbitrary immediates
1686 def : MipsPat<(i32 imm:$imm),
1687 (ORi (LUi (HI16 imm:$imm)), (LO16 imm:$imm))>;
1689 // Carry MipsPatterns
1690 def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
1691 (SUBu GPR32:$lhs, GPR32:$rhs)>;
1692 let AdditionalPredicates = [NotDSP] in {
1693 def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
1694 (ADDu GPR32:$lhs, GPR32:$rhs)>;
1695 def : MipsPat<(addc GPR32:$src, immSExt16:$imm),
1696 (ADDiu GPR32:$src, imm:$imm)>;
1699 // Support multiplication for pre-Mips32 targets that don't have
1700 // the MUL instruction.
1701 def : MipsPat<(mul GPR32:$lhs, GPR32:$rhs),
1702 (PseudoMFLO (PseudoMULT GPR32:$lhs, GPR32:$rhs))>,
1703 ISA_MIPS1_NOT_32R6_64R6;
1706 def : MipsPat<(MipsSync (i32 immz)),
1707 (SYNC 0)>, ISA_MIPS2;
1710 def : MipsPat<(MipsJmpLink (i32 tglobaladdr:$dst)),
1711 (JAL tglobaladdr:$dst)>;
1712 def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
1713 (JAL texternalsym:$dst)>;
1714 //def : MipsPat<(MipsJmpLink GPR32:$dst),
1715 // (JALR GPR32:$dst)>;
1718 def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
1719 (TAILCALL tglobaladdr:$dst)>;
1720 def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
1721 (TAILCALL texternalsym:$dst)>;
1723 def : MipsPat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
1724 def : MipsPat<(MipsHi tblockaddress:$in), (LUi tblockaddress:$in)>;
1725 def : MipsPat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>;
1726 def : MipsPat<(MipsHi tconstpool:$in), (LUi tconstpool:$in)>;
1727 def : MipsPat<(MipsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>;
1728 def : MipsPat<(MipsHi texternalsym:$in), (LUi texternalsym:$in)>;
1730 def : MipsPat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
1731 def : MipsPat<(MipsLo tblockaddress:$in), (ADDiu ZERO, tblockaddress:$in)>;
1732 def : MipsPat<(MipsLo tjumptable:$in), (ADDiu ZERO, tjumptable:$in)>;
1733 def : MipsPat<(MipsLo tconstpool:$in), (ADDiu ZERO, tconstpool:$in)>;
1734 def : MipsPat<(MipsLo tglobaltlsaddr:$in), (ADDiu ZERO, tglobaltlsaddr:$in)>;
1735 def : MipsPat<(MipsLo texternalsym:$in), (ADDiu ZERO, texternalsym:$in)>;
1737 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaladdr:$lo)),
1738 (ADDiu GPR32:$hi, tglobaladdr:$lo)>;
1739 def : MipsPat<(add GPR32:$hi, (MipsLo tblockaddress:$lo)),
1740 (ADDiu GPR32:$hi, tblockaddress:$lo)>;
1741 def : MipsPat<(add GPR32:$hi, (MipsLo tjumptable:$lo)),
1742 (ADDiu GPR32:$hi, tjumptable:$lo)>;
1743 def : MipsPat<(add GPR32:$hi, (MipsLo tconstpool:$lo)),
1744 (ADDiu GPR32:$hi, tconstpool:$lo)>;
1745 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaltlsaddr:$lo)),
1746 (ADDiu GPR32:$hi, tglobaltlsaddr:$lo)>;
1749 def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
1750 (ADDiu GPR32:$gp, tglobaladdr:$in)>;
1751 def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
1752 (ADDiu GPR32:$gp, tconstpool:$in)>;
1755 class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
1756 MipsPat<(MipsWrapper RC:$gp, node:$in),
1757 (ADDiuOp RC:$gp, node:$in)>;
1759 def : WrapperPat<tglobaladdr, ADDiu, GPR32>;
1760 def : WrapperPat<tconstpool, ADDiu, GPR32>;
1761 def : WrapperPat<texternalsym, ADDiu, GPR32>;
1762 def : WrapperPat<tblockaddress, ADDiu, GPR32>;
1763 def : WrapperPat<tjumptable, ADDiu, GPR32>;
1764 def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>;
1766 let AdditionalPredicates = [NotInMicroMips] in {
1767 // Mips does not have "not", so we expand our way
1768 def : MipsPat<(not GPR32:$in),
1769 (NOR GPR32Opnd:$in, ZERO)>;
1773 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>;
1774 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>;
1775 def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
1778 def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>;
1781 multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BNEOp,
1782 Instruction SLTOp, Instruction SLTuOp, Instruction SLTiOp,
1783 Instruction SLTiuOp, Register ZEROReg> {
1784 def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
1785 (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
1786 def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
1787 (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
1789 def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
1790 (BEQ (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
1791 def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
1792 (BEQ (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
1793 def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
1794 (BEQ (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
1795 def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
1796 (BEQ (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
1797 def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
1798 (BEQ (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
1799 def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
1800 (BEQ (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
1802 def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
1803 (BEQ (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
1804 def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
1805 (BEQ (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
1807 def : MipsPat<(brcond RC:$cond, bb:$dst),
1808 (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
1811 defm : BrcondPats<GPR32, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>;
1813 def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
1814 (BLEZ i32:$lhs, bb:$dst)>;
1815 def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
1816 (BGEZ i32:$lhs, bb:$dst)>;
1819 multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp,
1820 Instruction SLTuOp, Register ZEROReg> {
1821 def : MipsPat<(seteq RC:$lhs, 0),
1822 (SLTiuOp RC:$lhs, 1)>;
1823 def : MipsPat<(setne RC:$lhs, 0),
1824 (SLTuOp ZEROReg, RC:$lhs)>;
1825 def : MipsPat<(seteq RC:$lhs, RC:$rhs),
1826 (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>;
1827 def : MipsPat<(setne RC:$lhs, RC:$rhs),
1828 (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
1831 multiclass SetlePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1832 def : MipsPat<(setle RC:$lhs, RC:$rhs),
1833 (XORi (SLTOp RC:$rhs, RC:$lhs), 1)>;
1834 def : MipsPat<(setule RC:$lhs, RC:$rhs),
1835 (XORi (SLTuOp RC:$rhs, RC:$lhs), 1)>;
1838 multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1839 def : MipsPat<(setgt RC:$lhs, RC:$rhs),
1840 (SLTOp RC:$rhs, RC:$lhs)>;
1841 def : MipsPat<(setugt RC:$lhs, RC:$rhs),
1842 (SLTuOp RC:$rhs, RC:$lhs)>;
1845 multiclass SetgePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1846 def : MipsPat<(setge RC:$lhs, RC:$rhs),
1847 (XORi (SLTOp RC:$lhs, RC:$rhs), 1)>;
1848 def : MipsPat<(setuge RC:$lhs, RC:$rhs),
1849 (XORi (SLTuOp RC:$lhs, RC:$rhs), 1)>;
1852 multiclass SetgeImmPats<RegisterClass RC, Instruction SLTiOp,
1853 Instruction SLTiuOp> {
1854 def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
1855 (XORi (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
1856 def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
1857 (XORi (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
1860 defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>;
1861 defm : SetlePats<GPR32, SLT, SLTu>;
1862 defm : SetgtPats<GPR32, SLT, SLTu>;
1863 defm : SetgePats<GPR32, SLT, SLTu>;
1864 defm : SetgeImmPats<GPR32, SLTi, SLTiu>;
1867 def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>;
1869 // Load halfword/word patterns.
1870 let AddedComplexity = 40 in {
1871 def : LoadRegImmPat<LBu, i32, zextloadi8>;
1872 def : LoadRegImmPat<LH, i32, sextloadi16>;
1873 let AdditionalPredicates = [NotInMicroMips] in {
1874 def : LoadRegImmPat<LW, i32, load>;
1878 //===----------------------------------------------------------------------===//
1879 // Floating Point Support
1880 //===----------------------------------------------------------------------===//
1882 include "MipsInstrFPU.td"
1883 include "Mips64InstrInfo.td"
1884 include "MipsCondMov.td"
1886 include "Mips32r6InstrInfo.td"
1887 include "Mips64r6InstrInfo.td"
1892 include "Mips16InstrFormats.td"
1893 include "Mips16InstrInfo.td"
1896 include "MipsDSPInstrFormats.td"
1897 include "MipsDSPInstrInfo.td"
1900 include "MipsMSAInstrFormats.td"
1901 include "MipsMSAInstrInfo.td"
1904 include "MicroMipsInstrFormats.td"
1905 include "MicroMipsInstrInfo.td"
1906 include "MicroMipsInstrFPU.td"