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 HasMips4_32r2 : Predicate<"Subtarget.hasMips4_32r2()">,
160 AssemblerPredicate<"FeatureMips4_32r2">;
161 def HasMips5_32r2 : Predicate<"Subtarget.hasMips5_32r2()">,
162 AssemblerPredicate<"FeatureMips5_32r2">;
163 def HasMips32 : Predicate<"Subtarget.hasMips32()">,
164 AssemblerPredicate<"FeatureMips32">;
165 def HasMips32r2 : Predicate<"Subtarget.hasMips32r2()">,
166 AssemblerPredicate<"FeatureMips32r2">;
167 def HasMips32r6 : Predicate<"Subtarget.hasMips32r6()">,
168 AssemblerPredicate<"FeatureMips32r6">;
169 def NotMips32r6 : Predicate<"!Subtarget.hasMips32r6()">,
170 AssemblerPredicate<"!FeatureMips32r6">;
171 def IsGP64bit : Predicate<"Subtarget.isGP64bit()">,
172 AssemblerPredicate<"FeatureGP64Bit">;
173 def IsGP32bit : Predicate<"!Subtarget.isGP64bit()">,
174 AssemblerPredicate<"!FeatureGP64Bit">;
175 def HasMips64 : Predicate<"Subtarget.hasMips64()">,
176 AssemblerPredicate<"FeatureMips64">;
177 def HasMips64r2 : Predicate<"Subtarget.hasMips64r2()">,
178 AssemblerPredicate<"FeatureMips64r2">;
179 def HasMips64r6 : Predicate<"Subtarget.hasMips64r6()">,
180 AssemblerPredicate<"FeatureMips64r6">;
181 def NotMips64r6 : Predicate<"!Subtarget.hasMips64r6()">,
182 AssemblerPredicate<"!FeatureMips64r6">;
183 def IsN64 : Predicate<"Subtarget.isABI_N64()">,
184 AssemblerPredicate<"FeatureN64">;
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 AssemblerPredicate<"FeatureMips32">;
191 def RelocPIC : Predicate<"TM.getRelocationModel() == Reloc::PIC_">,
192 AssemblerPredicate<"FeatureMips32">;
193 def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">;
194 def HasStdEnc : Predicate<"Subtarget.hasStandardEncoding()">,
195 AssemblerPredicate<"!FeatureMips16">;
196 def NotDSP : Predicate<"!Subtarget.hasDSP()">;
197 def InMicroMips : Predicate<"Subtarget.inMicroMipsMode()">,
198 AssemblerPredicate<"FeatureMicroMips">;
199 def NotInMicroMips : Predicate<"!Subtarget.inMicroMipsMode()">,
200 AssemblerPredicate<"!FeatureMicroMips">;
201 def IsLE : Predicate<"Subtarget.isLittle()">;
202 def IsBE : Predicate<"!Subtarget.isLittle()">;
203 def IsNotNaCl : Predicate<"!Subtarget.isTargetNaCl()">;
205 //===----------------------------------------------------------------------===//
206 // Mips GPR size adjectives.
207 // They are mutually exclusive.
208 //===----------------------------------------------------------------------===//
210 class GPR_32 { list<Predicate> GPRPredicates = [IsGP32bit]; }
211 class GPR_64 { list<Predicate> GPRPredicates = [IsGP64bit]; }
213 //===----------------------------------------------------------------------===//
214 // Mips ISA/ASE membership and instruction group membership adjectives.
215 // They are mutually exclusive.
216 //===----------------------------------------------------------------------===//
218 // FIXME: I'd prefer to use additive predicates to build the instruction sets
219 // but we are short on assembler feature bits at the moment. Using a
220 // subtractive predicate will hopefully keep us under the 32 predicate
221 // limit long enough to develop an alternative way to handle P1||P2
223 class ISA_MIPS1_NOT_32R6_64R6 {
224 list<Predicate> InsnPredicates = [NotMips32r6, NotMips64r6];
226 class ISA_MIPS2 { list<Predicate> InsnPredicates = [HasMips2]; }
227 class ISA_MIPS3 { list<Predicate> InsnPredicates = [HasMips3]; }
228 class ISA_MIPS32 { list<Predicate> InsnPredicates = [HasMips32]; }
229 class ISA_MIPS32R2 { list<Predicate> InsnPredicates = [HasMips32r2]; }
230 class ISA_MIPS64 { list<Predicate> InsnPredicates = [HasMips64]; }
231 class ISA_MIPS64R2 { list<Predicate> InsnPredicates = [HasMips64r2]; }
232 class ISA_MIPS32R6 { list<Predicate> InsnPredicates = [HasMips32r6]; }
233 class ISA_MIPS64R6 { list<Predicate> InsnPredicates = [HasMips64r6]; }
235 // The portions of MIPS-III that were also added to MIPS32
236 class INSN_MIPS3_32 { list<Predicate> InsnPredicates = [HasMips3_32]; }
238 // The portions of MIPS-III that were also added to MIPS32
239 class INSN_MIPS3_32R2 { list<Predicate> InsnPredicates = [HasMips3_32r2]; }
241 // The portions of MIPS-IV that were also added to MIPS32
242 class INSN_MIPS4_32 { list<Predicate> InsnPredicates = [HasMips4_32]; }
244 // The portions of MIPS-IV that were also added to MIPS32R2
245 class INSN_MIPS4_32R2 { list<Predicate> InsnPredicates = [HasMips4_32r2]; }
247 // The portions of MIPS-V that were also added to MIPS32R2
248 class INSN_MIPS5_32R2 { list<Predicate> InsnPredicates = [HasMips5_32r2]; }
250 //===----------------------------------------------------------------------===//
252 class MipsPat<dag pattern, dag result> : Pat<pattern, result>, PredicateControl {
253 let EncodingPredicates = [HasStdEnc];
256 class MipsInstAlias<string Asm, dag Result, bit Emit = 0b1> :
257 InstAlias<Asm, Result, Emit>, PredicateControl;
260 bit isCommutable = 1;
277 bit isTerminator = 1;
280 bit hasExtraSrcRegAllocReq = 1;
281 bit isCodeGenOnly = 1;
284 class IsAsCheapAsAMove {
285 bit isAsCheapAsAMove = 1;
288 class NeverHasSideEffects {
289 bit neverHasSideEffects = 1;
292 //===----------------------------------------------------------------------===//
293 // Instruction format superclass
294 //===----------------------------------------------------------------------===//
296 include "MipsInstrFormats.td"
298 //===----------------------------------------------------------------------===//
299 // Mips Operand, Complex Patterns and Transformations Definitions.
300 //===----------------------------------------------------------------------===//
302 def MipsJumpTargetAsmOperand : AsmOperandClass {
303 let Name = "JumpTarget";
304 let ParserMethod = "ParseJumpTarget";
305 let PredicateMethod = "isImm";
306 let RenderMethod = "addImmOperands";
309 // Instruction operand types
310 def jmptarget : Operand<OtherVT> {
311 let EncoderMethod = "getJumpTargetOpValue";
312 let ParserMatchClass = MipsJumpTargetAsmOperand;
314 def brtarget : Operand<OtherVT> {
315 let EncoderMethod = "getBranchTargetOpValue";
316 let OperandType = "OPERAND_PCREL";
317 let DecoderMethod = "DecodeBranchTarget";
318 let ParserMatchClass = MipsJumpTargetAsmOperand;
320 def calltarget : Operand<iPTR> {
321 let EncoderMethod = "getJumpTargetOpValue";
322 let ParserMatchClass = MipsJumpTargetAsmOperand;
325 def simm10 : Operand<i32>;
327 def simm16 : Operand<i32> {
328 let DecoderMethod= "DecodeSimm16";
331 def simm19_lsl2 : Operand<i32> {
332 let EncoderMethod = "getSimm19Lsl2Encoding";
333 let DecoderMethod = "DecodeSimm19Lsl2";
336 def simm20 : Operand<i32> {
339 def uimm20 : Operand<i32> {
342 def uimm10 : Operand<i32> {
345 def simm16_64 : Operand<i64> {
346 let DecoderMethod = "DecodeSimm16";
350 def uimmz : Operand<i32> {
351 let PrintMethod = "printUnsignedImm";
355 def uimm2 : Operand<i32> {
356 let PrintMethod = "printUnsignedImm";
359 def uimm3 : Operand<i32> {
360 let PrintMethod = "printUnsignedImm";
363 def uimm5 : Operand<i32> {
364 let PrintMethod = "printUnsignedImm";
367 def uimm6 : Operand<i32> {
368 let PrintMethod = "printUnsignedImm";
371 def uimm16 : Operand<i32> {
372 let PrintMethod = "printUnsignedImm";
375 def pcrel16 : Operand<i32> {
378 def MipsMemAsmOperand : AsmOperandClass {
380 let ParserMethod = "parseMemOperand";
383 def MipsInvertedImmoperand : AsmOperandClass {
385 let RenderMethod = "addImmOperands";
386 let ParserMethod = "parseInvNum";
389 def InvertedImOperand : Operand<i32> {
390 let ParserMatchClass = MipsInvertedImmoperand;
393 def InvertedImOperand64 : Operand<i64> {
394 let ParserMatchClass = MipsInvertedImmoperand;
397 class mem_generic : Operand<iPTR> {
398 let PrintMethod = "printMemOperand";
399 let MIOperandInfo = (ops ptr_rc, simm16);
400 let EncoderMethod = "getMemEncoding";
401 let ParserMatchClass = MipsMemAsmOperand;
402 let OperandType = "OPERAND_MEMORY";
406 def mem : mem_generic;
408 // MSA specific address operand
409 def mem_msa : mem_generic {
410 let MIOperandInfo = (ops ptr_rc, simm10);
411 let EncoderMethod = "getMSAMemEncoding";
414 def mem_ea : Operand<iPTR> {
415 let PrintMethod = "printMemOperandEA";
416 let MIOperandInfo = (ops ptr_rc, simm16);
417 let EncoderMethod = "getMemEncoding";
418 let OperandType = "OPERAND_MEMORY";
421 def PtrRC : Operand<iPTR> {
422 let MIOperandInfo = (ops ptr_rc);
423 let DecoderMethod = "DecodePtrRegisterClass";
424 let ParserMatchClass = GPR32AsmOperand;
427 // size operand of ext instruction
428 def size_ext : Operand<i32> {
429 let EncoderMethod = "getSizeExtEncoding";
430 let DecoderMethod = "DecodeExtSize";
433 // size operand of ins instruction
434 def size_ins : Operand<i32> {
435 let EncoderMethod = "getSizeInsEncoding";
436 let DecoderMethod = "DecodeInsSize";
439 // Transformation Function - get the lower 16 bits.
440 def LO16 : SDNodeXForm<imm, [{
441 return getImm(N, N->getZExtValue() & 0xFFFF);
444 // Transformation Function - get the higher 16 bits.
445 def HI16 : SDNodeXForm<imm, [{
446 return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF);
450 def Plus1 : SDNodeXForm<imm, [{ return getImm(N, N->getSExtValue() + 1); }]>;
452 // Node immediate is zero (e.g. insve.d)
453 def immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>;
455 // Node immediate fits as 16-bit sign extended on target immediate.
457 def immSExt8 : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;
459 // Node immediate fits as 16-bit sign extended on target immediate.
461 def immSExt16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;
463 // Node immediate fits as 15-bit sign extended on target immediate.
465 def immSExt15 : PatLeaf<(imm), [{ return isInt<15>(N->getSExtValue()); }]>;
467 // Node immediate fits as 16-bit zero extended on target immediate.
468 // The LO16 param means that only the lower 16 bits of the node
469 // immediate are caught.
471 def immZExt16 : PatLeaf<(imm), [{
472 if (N->getValueType(0) == MVT::i32)
473 return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
475 return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
478 // Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared).
479 def immLow16Zero : PatLeaf<(imm), [{
480 int64_t Val = N->getSExtValue();
481 return isInt<32>(Val) && !(Val & 0xffff);
484 // shamt field must fit in 5 bits.
485 def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
487 // True if (N + 1) fits in 16-bit field.
488 def immSExt16Plus1 : PatLeaf<(imm), [{
489 return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1);
492 // Mips Address Mode! SDNode frameindex could possibily be a match
493 // since load and store instructions from stack used it.
495 ComplexPattern<iPTR, 2, "selectIntAddr", [frameindex]>;
498 ComplexPattern<iPTR, 2, "selectAddrRegImm", [frameindex]>;
501 ComplexPattern<iPTR, 2, "selectAddrRegReg", [frameindex]>;
504 ComplexPattern<iPTR, 2, "selectAddrDefault", [frameindex]>;
506 def addrimm10 : ComplexPattern<iPTR, 2, "selectIntAddrMSA", [frameindex]>;
508 //===----------------------------------------------------------------------===//
509 // Instructions specific format
510 //===----------------------------------------------------------------------===//
512 // Arithmetic and logical instructions with 3 register operands.
513 class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0,
514 InstrItinClass Itin = NoItinerary,
515 SDPatternOperator OpNode = null_frag>:
516 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
517 !strconcat(opstr, "\t$rd, $rs, $rt"),
518 [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> {
519 let isCommutable = isComm;
520 let isReMaterializable = 1;
521 let TwoOperandAliasConstraint = "$rd = $rs";
524 // Arithmetic and logical instructions with 2 register operands.
525 class ArithLogicI<string opstr, Operand Od, RegisterOperand RO,
526 InstrItinClass Itin = NoItinerary,
527 SDPatternOperator imm_type = null_frag,
528 SDPatternOperator OpNode = null_frag> :
529 InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16),
530 !strconcat(opstr, "\t$rt, $rs, $imm16"),
531 [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))],
533 let isReMaterializable = 1;
534 let TwoOperandAliasConstraint = "$rs = $rt";
537 // Arithmetic Multiply ADD/SUB
538 class MArithR<string opstr, InstrItinClass itin, bit isComm = 0> :
539 InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
540 !strconcat(opstr, "\t$rs, $rt"), [], itin, FrmR, opstr> {
541 let Defs = [HI0, LO0];
542 let Uses = [HI0, LO0];
543 let isCommutable = isComm;
547 class LogicNOR<string opstr, RegisterOperand RO>:
548 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
549 !strconcat(opstr, "\t$rd, $rs, $rt"),
550 [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], II_NOR, FrmR, opstr> {
551 let isCommutable = 1;
555 class shift_rotate_imm<string opstr, Operand ImmOpnd,
556 RegisterOperand RO, InstrItinClass itin,
557 SDPatternOperator OpNode = null_frag,
558 SDPatternOperator PF = null_frag> :
559 InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt),
560 !strconcat(opstr, "\t$rd, $rt, $shamt"),
561 [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], itin, FrmR, opstr> {
562 let TwoOperandAliasConstraint = "$rt = $rd";
565 class shift_rotate_reg<string opstr, RegisterOperand RO, InstrItinClass itin,
566 SDPatternOperator OpNode = null_frag>:
567 InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs),
568 !strconcat(opstr, "\t$rd, $rt, $rs"),
569 [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], itin, FrmR,
572 // Load Upper Imediate
573 class LoadUpper<string opstr, RegisterOperand RO, Operand Imm>:
574 InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"),
575 [], II_LUI, FrmI, opstr>, IsAsCheapAsAMove {
576 let neverHasSideEffects = 1;
577 let isReMaterializable = 1;
581 class Load<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
582 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
583 InstSE<(outs RO:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
584 [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> {
585 let DecoderMethod = "DecodeMem";
586 let canFoldAsLoad = 1;
590 class Store<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
591 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
592 InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
593 [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> {
594 let DecoderMethod = "DecodeMem";
598 // Load/Store Left/Right
599 let canFoldAsLoad = 1 in
600 class LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
601 InstrItinClass Itin> :
602 InstSE<(outs RO:$rt), (ins mem:$addr, RO:$src),
603 !strconcat(opstr, "\t$rt, $addr"),
604 [(set RO:$rt, (OpNode addr:$addr, RO:$src))], Itin, FrmI> {
605 let DecoderMethod = "DecodeMem";
606 string Constraints = "$src = $rt";
609 class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
610 InstrItinClass Itin> :
611 InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
612 [(OpNode RO:$rt, addr:$addr)], Itin, FrmI> {
613 let DecoderMethod = "DecodeMem";
616 // Conditional Branch
617 class CBranch<string opstr, DAGOperand opnd, PatFrag cond_op,
618 RegisterOperand RO> :
619 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
620 !strconcat(opstr, "\t$rs, $rt, $offset"),
621 [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], IIBranch,
624 let isTerminator = 1;
625 let hasDelaySlot = 1;
629 class CBranchZero<string opstr, DAGOperand opnd, PatFrag cond_op,
630 RegisterOperand RO> :
631 InstSE<(outs), (ins RO:$rs, opnd:$offset),
632 !strconcat(opstr, "\t$rs, $offset"),
633 [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], IIBranch,
636 let isTerminator = 1;
637 let hasDelaySlot = 1;
642 class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> :
643 InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt),
644 !strconcat(opstr, "\t$rd, $rs, $rt"),
645 [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))],
646 II_SLT_SLTU, FrmR, opstr>;
648 class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
650 InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16),
651 !strconcat(opstr, "\t$rt, $rs, $imm16"),
652 [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))],
653 II_SLTI_SLTIU, FrmI, opstr>;
656 class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
657 SDPatternOperator targetoperator, string bopstr> :
658 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
659 [(operator targetoperator:$target)], IIBranch, FrmJ, bopstr> {
662 let hasDelaySlot = 1;
663 let DecoderMethod = "DecodeJumpTarget";
667 // Unconditional branch
668 class UncondBranch<Instruction BEQInst> :
669 PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], IIBranch>,
670 PseudoInstExpansion<(BEQInst ZERO, ZERO, brtarget:$offset)> {
672 let isTerminator = 1;
674 let hasDelaySlot = 1;
675 let AdditionalPredicates = [RelocPIC];
679 // Base class for indirect branch and return instruction classes.
680 let isTerminator=1, isBarrier=1, hasDelaySlot = 1 in
681 class JumpFR<string opstr, RegisterOperand RO,
682 SDPatternOperator operator = null_frag>:
683 InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], IIBranch,
687 class IndirectBranch<string opstr, RegisterOperand RO> :
688 JumpFR<opstr, RO, brind> {
690 let isIndirectBranch = 1;
693 // Return instruction
694 class RetBase<string opstr, RegisterOperand RO>: JumpFR<opstr, RO> {
696 let isCodeGenOnly = 1;
698 let hasExtraSrcRegAllocReq = 1;
701 // Jump and Link (Call)
702 let isCall=1, hasDelaySlot=1, Defs = [RA] in {
703 class JumpLink<string opstr, DAGOperand opnd> :
704 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
705 [(MipsJmpLink imm:$target)], IIBranch, FrmJ, opstr> {
706 let DecoderMethod = "DecodeJumpTarget";
709 class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst,
710 Register RetReg, RegisterOperand ResRO = RO>:
711 PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], IIBranch>,
712 PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)>;
714 class JumpLinkReg<string opstr, RegisterOperand RO>:
715 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
718 class BGEZAL_FT<string opstr, DAGOperand opnd, RegisterOperand RO> :
719 InstSE<(outs), (ins RO:$rs, opnd:$offset),
720 !strconcat(opstr, "\t$rs, $offset"), [], IIBranch, FrmI, opstr>;
724 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
725 hasExtraSrcRegAllocReq = 1, Defs = [AT] in {
726 class TailCall<Instruction JumpInst> :
727 PseudoSE<(outs), (ins calltarget:$target), [], IIBranch>,
728 PseudoInstExpansion<(JumpInst jmptarget:$target)>;
730 class TailCallReg<RegisterOperand RO, Instruction JRInst,
731 RegisterOperand ResRO = RO> :
732 PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], IIBranch>,
733 PseudoInstExpansion<(JRInst ResRO:$rs)>;
736 class BAL_BR_Pseudo<Instruction RealInst> :
737 PseudoSE<(outs), (ins brtarget:$offset), [], IIBranch>,
738 PseudoInstExpansion<(RealInst ZERO, brtarget:$offset)> {
740 let isTerminator = 1;
742 let hasDelaySlot = 1;
747 class SYS_FT<string opstr> :
748 InstSE<(outs), (ins uimm20:$code_),
749 !strconcat(opstr, "\t$code_"), [], NoItinerary, FrmI, opstr>;
751 class BRK_FT<string opstr> :
752 InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
753 !strconcat(opstr, "\t$code_1, $code_2"), [], NoItinerary,
757 class ER_FT<string opstr> :
758 InstSE<(outs), (ins),
759 opstr, [], NoItinerary, FrmOther, opstr>;
762 class DEI_FT<string opstr, RegisterOperand RO> :
763 InstSE<(outs RO:$rt), (ins),
764 !strconcat(opstr, "\t$rt"), [], NoItinerary, FrmOther, opstr>;
767 class WAIT_FT<string opstr> :
768 InstSE<(outs), (ins), opstr, [], NoItinerary, FrmOther, opstr>;
771 let hasSideEffects = 1 in
772 class SYNC_FT<string opstr> :
773 InstSE<(outs), (ins i32imm:$stype), "sync $stype", [(MipsSync imm:$stype)],
774 NoItinerary, FrmOther, opstr>;
776 let hasSideEffects = 1 in
777 class TEQ_FT<string opstr, RegisterOperand RO> :
778 InstSE<(outs), (ins RO:$rs, RO:$rt, uimm16:$code_),
779 !strconcat(opstr, "\t$rs, $rt, $code_"), [], NoItinerary,
782 class TEQI_FT<string opstr, RegisterOperand RO> :
783 InstSE<(outs), (ins RO:$rs, uimm16:$imm16),
784 !strconcat(opstr, "\t$rs, $imm16"), [], NoItinerary, FrmOther, opstr>;
786 class Mult<string opstr, InstrItinClass itin, RegisterOperand RO,
787 list<Register> DefRegs> :
788 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [],
790 let isCommutable = 1;
792 let neverHasSideEffects = 1;
795 // Pseudo multiply/divide instruction with explicit accumulator register
797 class MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1,
798 SDPatternOperator OpNode, InstrItinClass Itin,
799 bit IsComm = 1, bit HasSideEffects = 0,
800 bit UsesCustomInserter = 0> :
801 PseudoSE<(outs R0:$ac), (ins R1:$rs, R1:$rt),
802 [(set R0:$ac, (OpNode R1:$rs, R1:$rt))], Itin>,
803 PseudoInstExpansion<(RealInst R1:$rs, R1:$rt)> {
804 let isCommutable = IsComm;
805 let hasSideEffects = HasSideEffects;
806 let usesCustomInserter = UsesCustomInserter;
809 // Pseudo multiply add/sub instruction with explicit accumulator register
811 class MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode,
813 : PseudoSE<(outs ACC64:$ac),
814 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin),
816 (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))],
818 PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> {
819 string Constraints = "$acin = $ac";
822 class Div<string opstr, InstrItinClass itin, RegisterOperand RO,
823 list<Register> DefRegs> :
824 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$$zero, $rs, $rt"),
825 [], itin, FrmR, opstr> {
830 class PseudoMFLOHI<RegisterClass DstRC, RegisterClass SrcRC, SDNode OpNode>
831 : PseudoSE<(outs DstRC:$rd), (ins SrcRC:$hilo),
832 [(set DstRC:$rd, (OpNode SrcRC:$hilo))], II_MFHI_MFLO>;
834 class MoveFromLOHI<string opstr, RegisterOperand RO, Register UseReg>:
835 InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO,
838 let neverHasSideEffects = 1;
841 class PseudoMTLOHI<RegisterClass DstRC, RegisterClass SrcRC>
842 : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi),
843 [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))],
846 class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>:
847 InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO,
850 let neverHasSideEffects = 1;
853 class EffectiveAddress<string opstr, RegisterOperand RO> :
854 InstSE<(outs RO:$rt), (ins mem_ea:$addr), !strconcat(opstr, "\t$rt, $addr"),
855 [(set RO:$rt, addr:$addr)], NoItinerary, FrmI,
856 !strconcat(opstr, "_lea")> {
857 let isCodeGenOnly = 1;
858 let DecoderMethod = "DecodeMem";
861 // Count Leading Ones/Zeros in Word
862 class CountLeading0<string opstr, RegisterOperand RO>:
863 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
864 [(set RO:$rd, (ctlz RO:$rs))], II_CLZ, FrmR, opstr>;
866 class CountLeading1<string opstr, RegisterOperand RO>:
867 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
868 [(set RO:$rd, (ctlz (not RO:$rs)))], II_CLO, FrmR, opstr>;
870 // Sign Extend in Register.
871 class SignExtInReg<string opstr, ValueType vt, RegisterOperand RO,
872 InstrItinClass itin> :
873 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"),
874 [(set RO:$rd, (sext_inreg RO:$rt, vt))], itin, FrmR, opstr>;
877 class SubwordSwap<string opstr, RegisterOperand RO>:
878 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [],
879 NoItinerary, FrmR, opstr> {
880 let neverHasSideEffects = 1;
884 class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> :
885 InstSE<(outs CPURegOperand:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [],
889 class ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd,
890 SDPatternOperator Op = null_frag>:
891 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, size_ext:$size),
892 !strconcat(opstr, " $rt, $rs, $pos, $size"),
893 [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size))], NoItinerary,
894 FrmR, opstr>, ISA_MIPS32R2;
896 class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd,
897 SDPatternOperator Op = null_frag>:
898 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, size_ins:$size, RO:$src),
899 !strconcat(opstr, " $rt, $rs, $pos, $size"),
900 [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size, RO:$src))],
901 NoItinerary, FrmR, opstr>, ISA_MIPS32R2 {
902 let Constraints = "$src = $rt";
905 // Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*).
906 class Atomic2Ops<PatFrag Op, RegisterClass DRC> :
907 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr),
908 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]>;
910 // Atomic Compare & Swap.
911 class AtomicCmpSwap<PatFrag Op, RegisterClass DRC> :
912 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap),
913 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]>;
915 class LLBase<string opstr, RegisterOperand RO> :
916 InstSE<(outs RO:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
917 [], NoItinerary, FrmI> {
918 let DecoderMethod = "DecodeMem";
922 class SCBase<string opstr, RegisterOperand RO> :
923 InstSE<(outs RO:$dst), (ins RO:$rt, mem:$addr),
924 !strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> {
925 let DecoderMethod = "DecodeMem";
927 let Constraints = "$rt = $dst";
930 class MFC3OP<string asmstr, RegisterOperand RO> :
931 InstSE<(outs RO:$rt, RO:$rd, uimm16:$sel), (ins),
932 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], NoItinerary, FrmFR>;
934 class TrapBase<Instruction RealInst>
935 : PseudoSE<(outs), (ins), [(trap)], NoItinerary>,
936 PseudoInstExpansion<(RealInst 0, 0)> {
938 let isTerminator = 1;
939 let isCodeGenOnly = 1;
942 //===----------------------------------------------------------------------===//
943 // Pseudo instructions
944 //===----------------------------------------------------------------------===//
947 let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1 in
948 def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
950 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
951 def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt),
952 [(callseq_start timm:$amt)]>;
953 def ADJCALLSTACKUP : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
954 [(callseq_end timm:$amt1, timm:$amt2)]>;
957 let usesCustomInserter = 1 in {
958 def ATOMIC_LOAD_ADD_I8 : Atomic2Ops<atomic_load_add_8, GPR32>;
959 def ATOMIC_LOAD_ADD_I16 : Atomic2Ops<atomic_load_add_16, GPR32>;
960 def ATOMIC_LOAD_ADD_I32 : Atomic2Ops<atomic_load_add_32, GPR32>;
961 def ATOMIC_LOAD_SUB_I8 : Atomic2Ops<atomic_load_sub_8, GPR32>;
962 def ATOMIC_LOAD_SUB_I16 : Atomic2Ops<atomic_load_sub_16, GPR32>;
963 def ATOMIC_LOAD_SUB_I32 : Atomic2Ops<atomic_load_sub_32, GPR32>;
964 def ATOMIC_LOAD_AND_I8 : Atomic2Ops<atomic_load_and_8, GPR32>;
965 def ATOMIC_LOAD_AND_I16 : Atomic2Ops<atomic_load_and_16, GPR32>;
966 def ATOMIC_LOAD_AND_I32 : Atomic2Ops<atomic_load_and_32, GPR32>;
967 def ATOMIC_LOAD_OR_I8 : Atomic2Ops<atomic_load_or_8, GPR32>;
968 def ATOMIC_LOAD_OR_I16 : Atomic2Ops<atomic_load_or_16, GPR32>;
969 def ATOMIC_LOAD_OR_I32 : Atomic2Ops<atomic_load_or_32, GPR32>;
970 def ATOMIC_LOAD_XOR_I8 : Atomic2Ops<atomic_load_xor_8, GPR32>;
971 def ATOMIC_LOAD_XOR_I16 : Atomic2Ops<atomic_load_xor_16, GPR32>;
972 def ATOMIC_LOAD_XOR_I32 : Atomic2Ops<atomic_load_xor_32, GPR32>;
973 def ATOMIC_LOAD_NAND_I8 : Atomic2Ops<atomic_load_nand_8, GPR32>;
974 def ATOMIC_LOAD_NAND_I16 : Atomic2Ops<atomic_load_nand_16, GPR32>;
975 def ATOMIC_LOAD_NAND_I32 : Atomic2Ops<atomic_load_nand_32, GPR32>;
977 def ATOMIC_SWAP_I8 : Atomic2Ops<atomic_swap_8, GPR32>;
978 def ATOMIC_SWAP_I16 : Atomic2Ops<atomic_swap_16, GPR32>;
979 def ATOMIC_SWAP_I32 : Atomic2Ops<atomic_swap_32, GPR32>;
981 def ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap<atomic_cmp_swap_8, GPR32>;
982 def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap<atomic_cmp_swap_16, GPR32>;
983 def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_32, GPR32>;
986 /// Pseudo instructions for loading and storing accumulator registers.
987 let isPseudo = 1, isCodeGenOnly = 1 in {
988 def LOAD_ACC64 : Load<"", ACC64>;
989 def STORE_ACC64 : Store<"", ACC64>;
992 // We need these two pseudo instructions to avoid offset calculation for long
993 // branches. See the comment in file MipsLongBranch.cpp for detailed
996 // Expands to: lui $dst, %hi($tgt - $baltgt)
997 def LONG_BRANCH_LUi : PseudoSE<(outs GPR32Opnd:$dst),
998 (ins brtarget:$tgt, brtarget:$baltgt), []>;
1000 // Expands to: addiu $dst, $src, %lo($tgt - $baltgt)
1001 def LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst),
1002 (ins GPR32Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []>;
1004 //===----------------------------------------------------------------------===//
1005 // Instruction definition
1006 //===----------------------------------------------------------------------===//
1007 //===----------------------------------------------------------------------===//
1008 // MipsI Instructions
1009 //===----------------------------------------------------------------------===//
1011 /// Arithmetic Instructions (ALU Immediate)
1012 def ADDiu : MMRel, ArithLogicI<"addiu", simm16, GPR32Opnd, II_ADDIU, immSExt16,
1014 ADDI_FM<0x9>, IsAsCheapAsAMove;
1015 def ADDi : MMRel, ArithLogicI<"addi", simm16, GPR32Opnd>, ADDI_FM<0x8>,
1016 ISA_MIPS1_NOT_32R6_64R6;
1017 def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
1019 def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
1021 def ANDi : MMRel, ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16,
1024 def ORi : MMRel, ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16,
1027 def XORi : MMRel, ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16,
1030 def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16>, LUI_FM;
1032 /// Arithmetic Instructions (3-Operand, R-Type)
1033 def ADDu : MMRel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
1035 def SUBu : MMRel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
1037 let Defs = [HI0, LO0] in
1038 def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>,
1039 ADD_FM<0x1c, 2>, ISA_MIPS32;
1040 def ADD : MMRel, ArithLogicR<"add", GPR32Opnd>, ADD_FM<0, 0x20>;
1041 def SUB : MMRel, ArithLogicR<"sub", GPR32Opnd>, ADD_FM<0, 0x22>;
1042 def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>;
1043 def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>;
1044 def AND : MMRel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
1046 def OR : MMRel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
1048 def XOR : MMRel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
1050 def NOR : MMRel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>;
1052 /// Shift Instructions
1053 def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl,
1054 immZExt5>, SRA_FM<0, 0>;
1055 def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl,
1056 immZExt5>, SRA_FM<2, 0>;
1057 def SRA : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, sra,
1058 immZExt5>, SRA_FM<3, 0>;
1059 def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, shl>,
1061 def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, srl>,
1063 def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, sra>,
1066 // Rotate Instructions
1067 def ROTR : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr,
1069 SRA_FM<2, 1>, ISA_MIPS32R2;
1070 def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>,
1071 SRLV_FM<6, 1>, ISA_MIPS32R2;
1073 /// Load and Store Instructions
1075 def LB : Load<"lb", GPR32Opnd, sextloadi8, II_LB>, MMRel, LW_FM<0x20>;
1076 def LBu : Load<"lbu", GPR32Opnd, zextloadi8, II_LBU, addrDefault>, MMRel,
1078 def LH : Load<"lh", GPR32Opnd, sextloadi16, II_LH, addrDefault>, MMRel,
1080 def LHu : Load<"lhu", GPR32Opnd, zextloadi16, II_LHU>, MMRel, LW_FM<0x25>;
1081 def LW : Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel,
1083 def SB : Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel, LW_FM<0x28>;
1084 def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>;
1085 def SW : Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>;
1087 /// load/store left/right
1088 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1089 AdditionalPredicates = [NotInMicroMips] in {
1090 def LWL : LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>;
1091 def LWR : LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>;
1092 def SWL : StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>;
1093 def SWR : StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>;
1096 def SYNC : MMRel, SYNC_FT<"sync">, SYNC_FM;
1097 def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM<0x34>;
1098 def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM<0x30>;
1099 def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd>, TEQ_FM<0x31>;
1100 def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd>, TEQ_FM<0x32>;
1101 def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd>, TEQ_FM<0x33>;
1102 def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd>, TEQ_FM<0x36>;
1104 def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd>, TEQI_FM<0xc>, ISA_MIPS2;
1105 def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd>, TEQI_FM<0x8>, ISA_MIPS2;
1106 def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd>, TEQI_FM<0x9>, ISA_MIPS2;
1107 def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd>, TEQI_FM<0xa>, ISA_MIPS2;
1108 def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd>, TEQI_FM<0xb>, ISA_MIPS2;
1109 def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd>, TEQI_FM<0xe>, ISA_MIPS2;
1111 def BREAK : MMRel, BRK_FT<"break">, BRK_FM<0xd>;
1112 def SYSCALL : MMRel, SYS_FT<"syscall">, SYS_FM<0xc>;
1113 def TRAP : TrapBase<BREAK>;
1115 def ERET : MMRel, ER_FT<"eret">, ER_FM<0x18>, INSN_MIPS3_32;
1116 def DERET : MMRel, ER_FT<"deret">, ER_FM<0x1f>, ISA_MIPS32;
1118 def EI : MMRel, DEI_FT<"ei", GPR32Opnd>, EI_FM<1>, ISA_MIPS32R2;
1119 def DI : MMRel, DEI_FT<"di", GPR32Opnd>, EI_FM<0>, ISA_MIPS32R2;
1121 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1122 AdditionalPredicates = [NotInMicroMips] in {
1123 def WAIT : WAIT_FT<"wait">, WAIT_FM;
1125 /// Load-linked, Store-conditional
1126 def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, ISA_MIPS2;
1127 def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, ISA_MIPS2;
1130 /// Jump and Branch Instructions
1131 def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
1132 AdditionalRequires<[RelocStatic]>, IsBranch;
1133 def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>;
1134 def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>;
1135 def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>;
1136 def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
1138 def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
1140 def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
1142 def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
1144 def B : UncondBranch<BEQ>;
1146 def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>;
1147 let AdditionalPredicates = [NotInMicroMips] in {
1148 def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM;
1149 def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>;
1151 def JALX : JumpLink<"jalx", calltarget>, FJ<0x1D>;
1152 def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>;
1153 def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>;
1154 def BAL_BR : BAL_BR_Pseudo<BGEZAL>;
1155 def TAILCALL : TailCall<J>;
1156 def TAILCALL_R : TailCallReg<GPR32Opnd, JR>;
1158 def RET : MMRel, RetBase<"ret", GPR32Opnd>, MTLO_FM<8>;
1160 // Exception handling related node and instructions.
1161 // The conversion sequence is:
1162 // ISD::EH_RETURN -> MipsISD::EH_RETURN ->
1163 // MIPSeh_return -> (stack change + indirect branch)
1165 // MIPSeh_return takes the place of regular return instruction
1166 // but takes two arguments (V1, V0) which are used for storing
1167 // the offset and return address respectively.
1168 def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
1170 def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
1171 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
1173 let Uses = [V0, V1], isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1174 def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
1175 [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
1176 def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff,
1178 [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
1181 /// Multiply and Divide Instructions.
1182 def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
1184 def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
1186 def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
1188 def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
1191 def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>;
1192 def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>;
1193 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1194 AdditionalPredicates = [NotInMicroMips] in {
1195 def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>;
1196 def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>;
1199 /// Sign Ext In Register Instructions.
1200 def SEB : MMRel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,
1201 SEB_FM<0x10, 0x20>, ISA_MIPS32R2;
1202 def SEH : MMRel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
1203 SEB_FM<0x18, 0x20>, ISA_MIPS32R2;
1206 def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd>, CLO_FM<0x20>, ISA_MIPS32;
1207 def CLO : MMRel, CountLeading1<"clo", GPR32Opnd>, CLO_FM<0x21>, ISA_MIPS32;
1209 /// Word Swap Bytes Within Halfwords
1210 def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd>, SEB_FM<2, 0x20>, ISA_MIPS32R2;
1213 def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>;
1215 // FrameIndexes are legalized when they are operands from load/store
1216 // instructions. The same not happens for stack address copies, so an
1217 // add op with mem ComplexPattern is used and the stack address copy
1218 // can be matched. It's similar to Sparc LEA_ADDRi
1219 def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>;
1222 def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>, ISA_MIPS32;
1223 def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>, ISA_MIPS32;
1224 def MSUB : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>, ISA_MIPS32;
1225 def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>, ISA_MIPS32;
1227 let AdditionalPredicates = [NotDSP] in {
1228 def PseudoMULT : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>;
1229 def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>;
1230 def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>;
1231 def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>;
1232 def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>;
1233 def PseudoMADD : MAddSubPseudo<MADD, MipsMAdd, II_MADD>;
1234 def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>;
1235 def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>;
1236 def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>;
1239 def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV,
1241 def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU,
1244 def RDHWR : ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM;
1246 def EXT : MMRel, ExtBase<"ext", GPR32Opnd, uimm5, MipsExt>, EXT_FM<0>;
1247 def INS : MMRel, InsBase<"ins", GPR32Opnd, uimm5, MipsIns>, EXT_FM<4>;
1249 /// Move Control Registers From/To CPU Registers
1250 def MFC0 : MFC3OP<"mfc0", GPR32Opnd>, MFC3OP_FM<0x10, 0>, ISA_MIPS32;
1251 def MTC0 : MFC3OP<"mtc0", GPR32Opnd>, MFC3OP_FM<0x10, 4>, ISA_MIPS32;
1252 def MFC2 : MFC3OP<"mfc2", GPR32Opnd>, MFC3OP_FM<0x12, 0>;
1253 def MTC2 : MFC3OP<"mtc2", GPR32Opnd>, MFC3OP_FM<0x12, 4>;
1255 class Barrier<string asmstr> : InstSE<(outs), (ins), asmstr, [], NoItinerary,
1257 def SSNOP : Barrier<"ssnop">, BARRIER_FM<1>;
1258 def EHB : Barrier<"ehb">, BARRIER_FM<3>;
1259 def PAUSE : Barrier<"pause">, BARRIER_FM<5>, ISA_MIPS32R2;
1261 class TLB<string asmstr> : InstSE<(outs), (ins), asmstr, [], NoItinerary,
1263 def TLBP : TLB<"tlbp">, COP0_TLB_FM<0x08>;
1264 def TLBR : TLB<"tlbr">, COP0_TLB_FM<0x01>;
1265 def TLBWI : TLB<"tlbwi">, COP0_TLB_FM<0x02>;
1266 def TLBWR : TLB<"tlbwr">, COP0_TLB_FM<0x06>;
1268 //===----------------------------------------------------------------------===//
1269 // Instruction aliases
1270 //===----------------------------------------------------------------------===//
1271 def : MipsInstAlias<"move $dst, $src",
1272 (ADDu GPR32Opnd:$dst, GPR32Opnd:$src,ZERO), 1>,
1274 let AdditionalPredicates = [NotInMicroMips];
1276 def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>;
1277 def : MipsInstAlias<"addu $rs, $rt, $imm",
1278 (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1279 def : MipsInstAlias<"add $rs, $rt, $imm",
1280 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1281 def : MipsInstAlias<"and $rs, $rt, $imm",
1282 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1283 def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>;
1284 let Predicates = [NotInMicroMips] in {
1285 def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
1287 def : MipsInstAlias<"jal $rs", (JALR RA, GPR32Opnd:$rs), 0>;
1288 def : MipsInstAlias<"jal $rd,$rs", (JALR GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
1289 def : MipsInstAlias<"not $rt, $rs",
1290 (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>;
1291 def : MipsInstAlias<"neg $rt, $rs",
1292 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
1293 def : MipsInstAlias<"negu $rt",
1294 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 0>;
1295 def : MipsInstAlias<"negu $rt, $rs",
1296 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
1297 def : MipsInstAlias<"slt $rs, $rt, $imm",
1298 (SLTi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1299 def : MipsInstAlias<"sltu $rt, $rs, $imm",
1300 (SLTiu GPR32Opnd:$rt, GPR32Opnd:$rs, simm16:$imm), 0>;
1301 def : MipsInstAlias<"xor $rs, $rt, $imm",
1302 (XORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
1303 def : MipsInstAlias<"or $rs, $rt, $imm",
1304 (ORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
1305 def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>;
1306 def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>;
1307 def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>;
1308 def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>;
1309 def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>;
1310 def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>;
1311 def : MipsInstAlias<"bnez $rs,$offset",
1312 (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1313 def : MipsInstAlias<"beqz $rs,$offset",
1314 (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1315 def : MipsInstAlias<"syscall", (SYSCALL 0), 1>;
1317 def : MipsInstAlias<"break", (BREAK 0, 0), 1>;
1318 def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>;
1319 def : MipsInstAlias<"ei", (EI ZERO), 1>;
1320 def : MipsInstAlias<"di", (DI ZERO), 1>;
1322 def : MipsInstAlias<"teq $rs, $rt", (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>;
1323 def : MipsInstAlias<"tge $rs, $rt", (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>;
1324 def : MipsInstAlias<"tgeu $rs, $rt", (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0),
1326 def : MipsInstAlias<"tlt $rs, $rt", (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>;
1327 def : MipsInstAlias<"tltu $rs, $rt", (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0),
1329 def : MipsInstAlias<"tne $rs, $rt", (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>;
1330 def : MipsInstAlias<"sll $rd, $rt, $rs",
1331 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1332 def : MipsInstAlias<"sub, $rd, $rs, $imm",
1333 (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs,
1334 InvertedImOperand:$imm), 0>;
1335 def : MipsInstAlias<"sub $rs, $imm",
1336 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm),
1338 def : MipsInstAlias<"subu, $rd, $rs, $imm",
1339 (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs,
1340 InvertedImOperand:$imm), 0>;
1341 def : MipsInstAlias<"subu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs,
1342 InvertedImOperand:$imm), 0>;
1343 def : MipsInstAlias<"sra $rd, $rt, $rs",
1344 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1345 def : MipsInstAlias<"srl $rd, $rt, $rs",
1346 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1347 //===----------------------------------------------------------------------===//
1348 // Assembler Pseudo Instructions
1349 //===----------------------------------------------------------------------===//
1351 class LoadImm32< string instr_asm, Operand Od, RegisterOperand RO> :
1352 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
1353 !strconcat(instr_asm, "\t$rt, $imm32")> ;
1354 def LoadImm32Reg : LoadImm32<"li", uimm5, GPR32Opnd>;
1356 class LoadAddress<string instr_asm, Operand MemOpnd, RegisterOperand RO> :
1357 MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
1358 !strconcat(instr_asm, "\t$rt, $addr")> ;
1359 def LoadAddr32Reg : LoadAddress<"la", mem, GPR32Opnd>;
1361 class LoadAddressImm<string instr_asm, Operand Od, RegisterOperand RO> :
1362 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
1363 !strconcat(instr_asm, "\t$rt, $imm32")> ;
1364 def LoadAddr32Imm : LoadAddressImm<"la", uimm5, GPR32Opnd>;
1366 //===----------------------------------------------------------------------===//
1367 // Arbitrary patterns that map to one or more instructions
1368 //===----------------------------------------------------------------------===//
1370 // Load/store pattern templates.
1371 class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
1372 MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
1374 class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
1375 MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
1378 def : MipsPat<(i32 immSExt16:$in),
1379 (ADDiu ZERO, imm:$in)>;
1380 def : MipsPat<(i32 immZExt16:$in),
1381 (ORi ZERO, imm:$in)>;
1382 def : MipsPat<(i32 immLow16Zero:$in),
1383 (LUi (HI16 imm:$in))>;
1385 // Arbitrary immediates
1386 def : MipsPat<(i32 imm:$imm),
1387 (ORi (LUi (HI16 imm:$imm)), (LO16 imm:$imm))>;
1389 // Carry MipsPatterns
1390 def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
1391 (SUBu GPR32:$lhs, GPR32:$rhs)>;
1392 let AdditionalPredicates = [NotDSP] in {
1393 def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
1394 (ADDu GPR32:$lhs, GPR32:$rhs)>;
1395 def : MipsPat<(addc GPR32:$src, immSExt16:$imm),
1396 (ADDiu GPR32:$src, imm:$imm)>;
1400 def : MipsPat<(MipsJmpLink (i32 tglobaladdr:$dst)),
1401 (JAL tglobaladdr:$dst)>;
1402 def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
1403 (JAL texternalsym:$dst)>;
1404 //def : MipsPat<(MipsJmpLink GPR32:$dst),
1405 // (JALR GPR32:$dst)>;
1408 def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
1409 (TAILCALL tglobaladdr:$dst)>;
1410 def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
1411 (TAILCALL texternalsym:$dst)>;
1413 def : MipsPat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
1414 def : MipsPat<(MipsHi tblockaddress:$in), (LUi tblockaddress:$in)>;
1415 def : MipsPat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>;
1416 def : MipsPat<(MipsHi tconstpool:$in), (LUi tconstpool:$in)>;
1417 def : MipsPat<(MipsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>;
1418 def : MipsPat<(MipsHi texternalsym:$in), (LUi texternalsym:$in)>;
1420 def : MipsPat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
1421 def : MipsPat<(MipsLo tblockaddress:$in), (ADDiu ZERO, tblockaddress:$in)>;
1422 def : MipsPat<(MipsLo tjumptable:$in), (ADDiu ZERO, tjumptable:$in)>;
1423 def : MipsPat<(MipsLo tconstpool:$in), (ADDiu ZERO, tconstpool:$in)>;
1424 def : MipsPat<(MipsLo tglobaltlsaddr:$in), (ADDiu ZERO, tglobaltlsaddr:$in)>;
1425 def : MipsPat<(MipsLo texternalsym:$in), (ADDiu ZERO, texternalsym:$in)>;
1427 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaladdr:$lo)),
1428 (ADDiu GPR32:$hi, tglobaladdr:$lo)>;
1429 def : MipsPat<(add GPR32:$hi, (MipsLo tblockaddress:$lo)),
1430 (ADDiu GPR32:$hi, tblockaddress:$lo)>;
1431 def : MipsPat<(add GPR32:$hi, (MipsLo tjumptable:$lo)),
1432 (ADDiu GPR32:$hi, tjumptable:$lo)>;
1433 def : MipsPat<(add GPR32:$hi, (MipsLo tconstpool:$lo)),
1434 (ADDiu GPR32:$hi, tconstpool:$lo)>;
1435 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaltlsaddr:$lo)),
1436 (ADDiu GPR32:$hi, tglobaltlsaddr:$lo)>;
1439 def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
1440 (ADDiu GPR32:$gp, tglobaladdr:$in)>;
1441 def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
1442 (ADDiu GPR32:$gp, tconstpool:$in)>;
1445 class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
1446 MipsPat<(MipsWrapper RC:$gp, node:$in),
1447 (ADDiuOp RC:$gp, node:$in)>;
1449 def : WrapperPat<tglobaladdr, ADDiu, GPR32>;
1450 def : WrapperPat<tconstpool, ADDiu, GPR32>;
1451 def : WrapperPat<texternalsym, ADDiu, GPR32>;
1452 def : WrapperPat<tblockaddress, ADDiu, GPR32>;
1453 def : WrapperPat<tjumptable, ADDiu, GPR32>;
1454 def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>;
1456 // Mips does not have "not", so we expand our way
1457 def : MipsPat<(not GPR32:$in),
1458 (NOR GPR32Opnd:$in, ZERO)>;
1461 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>;
1462 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>;
1463 def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
1466 def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>;
1469 multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BNEOp,
1470 Instruction SLTOp, Instruction SLTuOp, Instruction SLTiOp,
1471 Instruction SLTiuOp, Register ZEROReg> {
1472 def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
1473 (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
1474 def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
1475 (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
1477 def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
1478 (BEQ (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
1479 def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
1480 (BEQ (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
1481 def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
1482 (BEQ (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
1483 def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
1484 (BEQ (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
1485 def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
1486 (BEQ (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
1487 def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
1488 (BEQ (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
1490 def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
1491 (BEQ (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
1492 def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
1493 (BEQ (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
1495 def : MipsPat<(brcond RC:$cond, bb:$dst),
1496 (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
1499 defm : BrcondPats<GPR32, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>;
1501 def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
1502 (BLEZ i32:$lhs, bb:$dst)>;
1503 def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
1504 (BGEZ i32:$lhs, bb:$dst)>;
1507 multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp,
1508 Instruction SLTuOp, Register ZEROReg> {
1509 def : MipsPat<(seteq RC:$lhs, 0),
1510 (SLTiuOp RC:$lhs, 1)>;
1511 def : MipsPat<(setne RC:$lhs, 0),
1512 (SLTuOp ZEROReg, RC:$lhs)>;
1513 def : MipsPat<(seteq RC:$lhs, RC:$rhs),
1514 (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>;
1515 def : MipsPat<(setne RC:$lhs, RC:$rhs),
1516 (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
1519 multiclass SetlePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1520 def : MipsPat<(setle RC:$lhs, RC:$rhs),
1521 (XORi (SLTOp RC:$rhs, RC:$lhs), 1)>;
1522 def : MipsPat<(setule RC:$lhs, RC:$rhs),
1523 (XORi (SLTuOp RC:$rhs, RC:$lhs), 1)>;
1526 multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1527 def : MipsPat<(setgt RC:$lhs, RC:$rhs),
1528 (SLTOp RC:$rhs, RC:$lhs)>;
1529 def : MipsPat<(setugt RC:$lhs, RC:$rhs),
1530 (SLTuOp RC:$rhs, RC:$lhs)>;
1533 multiclass SetgePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1534 def : MipsPat<(setge RC:$lhs, RC:$rhs),
1535 (XORi (SLTOp RC:$lhs, RC:$rhs), 1)>;
1536 def : MipsPat<(setuge RC:$lhs, RC:$rhs),
1537 (XORi (SLTuOp RC:$lhs, RC:$rhs), 1)>;
1540 multiclass SetgeImmPats<RegisterClass RC, Instruction SLTiOp,
1541 Instruction SLTiuOp> {
1542 def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
1543 (XORi (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
1544 def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
1545 (XORi (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
1548 defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>;
1549 defm : SetlePats<GPR32, SLT, SLTu>;
1550 defm : SetgtPats<GPR32, SLT, SLTu>;
1551 defm : SetgePats<GPR32, SLT, SLTu>;
1552 defm : SetgeImmPats<GPR32, SLTi, SLTiu>;
1555 def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>;
1557 // Load halfword/word patterns.
1558 let AddedComplexity = 40 in {
1559 def : LoadRegImmPat<LBu, i32, zextloadi8>;
1560 def : LoadRegImmPat<LH, i32, sextloadi16>;
1561 def : LoadRegImmPat<LW, i32, load>;
1564 //===----------------------------------------------------------------------===//
1565 // Floating Point Support
1566 //===----------------------------------------------------------------------===//
1568 include "MipsInstrFPU.td"
1569 include "Mips64InstrInfo.td"
1570 include "MipsCondMov.td"
1572 include "Mips32r6InstrInfo.td"
1573 include "Mips64r6InstrInfo.td"
1578 include "Mips16InstrFormats.td"
1579 include "Mips16InstrInfo.td"
1582 include "MipsDSPInstrFormats.td"
1583 include "MipsDSPInstrInfo.td"
1586 include "MipsMSAInstrFormats.td"
1587 include "MipsMSAInstrInfo.td"
1590 include "MicroMipsInstrFormats.td"
1591 include "MicroMipsInstrInfo.td"
1592 include "MicroMipsInstrFPU.td"