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_MIPS3_NOT_32R6_64R6 {
229 list<Predicate> InsnPredicates = [HasMips3, NotMips32r6, NotMips64r6];
231 class ISA_MIPS32 { list<Predicate> InsnPredicates = [HasMips32]; }
232 class ISA_MIPS32R2 { list<Predicate> InsnPredicates = [HasMips32r2]; }
233 class ISA_MIPS64 { list<Predicate> InsnPredicates = [HasMips64]; }
234 class ISA_MIPS64R2 { list<Predicate> InsnPredicates = [HasMips64r2]; }
235 class ISA_MIPS32R6 { list<Predicate> InsnPredicates = [HasMips32r6]; }
236 class ISA_MIPS64R6 { list<Predicate> InsnPredicates = [HasMips64r6]; }
238 // The portions of MIPS-III that were also added to MIPS32
239 class INSN_MIPS3_32 { list<Predicate> InsnPredicates = [HasMips3_32]; }
241 // The portions of MIPS-III that were also added to MIPS32
242 class INSN_MIPS3_32R2 { list<Predicate> InsnPredicates = [HasMips3_32r2]; }
244 // The portions of MIPS-IV that were also added to MIPS32
245 class INSN_MIPS4_32 { list<Predicate> InsnPredicates = [HasMips4_32]; }
247 // The portions of MIPS-IV that were also added to MIPS32R2
248 class INSN_MIPS4_32R2 { list<Predicate> InsnPredicates = [HasMips4_32r2]; }
250 // The portions of MIPS-V that were also added to MIPS32R2
251 class INSN_MIPS5_32R2 { list<Predicate> InsnPredicates = [HasMips5_32r2]; }
253 //===----------------------------------------------------------------------===//
255 class MipsPat<dag pattern, dag result> : Pat<pattern, result>, PredicateControl {
256 let EncodingPredicates = [HasStdEnc];
259 class MipsInstAlias<string Asm, dag Result, bit Emit = 0b1> :
260 InstAlias<Asm, Result, Emit>, PredicateControl;
263 bit isCommutable = 1;
280 bit isTerminator = 1;
283 bit hasExtraSrcRegAllocReq = 1;
284 bit isCodeGenOnly = 1;
287 class IsAsCheapAsAMove {
288 bit isAsCheapAsAMove = 1;
291 class NeverHasSideEffects {
292 bit neverHasSideEffects = 1;
295 //===----------------------------------------------------------------------===//
296 // Instruction format superclass
297 //===----------------------------------------------------------------------===//
299 include "MipsInstrFormats.td"
301 //===----------------------------------------------------------------------===//
302 // Mips Operand, Complex Patterns and Transformations Definitions.
303 //===----------------------------------------------------------------------===//
305 def MipsJumpTargetAsmOperand : AsmOperandClass {
306 let Name = "JumpTarget";
307 let ParserMethod = "ParseJumpTarget";
308 let PredicateMethod = "isImm";
309 let RenderMethod = "addImmOperands";
312 // Instruction operand types
313 def jmptarget : Operand<OtherVT> {
314 let EncoderMethod = "getJumpTargetOpValue";
315 let ParserMatchClass = MipsJumpTargetAsmOperand;
317 def brtarget : Operand<OtherVT> {
318 let EncoderMethod = "getBranchTargetOpValue";
319 let OperandType = "OPERAND_PCREL";
320 let DecoderMethod = "DecodeBranchTarget";
321 let ParserMatchClass = MipsJumpTargetAsmOperand;
323 def calltarget : Operand<iPTR> {
324 let EncoderMethod = "getJumpTargetOpValue";
325 let ParserMatchClass = MipsJumpTargetAsmOperand;
328 def simm10 : Operand<i32>;
330 def simm16 : Operand<i32> {
331 let DecoderMethod= "DecodeSimm16";
334 def simm19_lsl2 : Operand<i32> {
335 let EncoderMethod = "getSimm19Lsl2Encoding";
336 let DecoderMethod = "DecodeSimm19Lsl2";
339 def simm20 : Operand<i32> {
342 def uimm20 : Operand<i32> {
345 def uimm10 : Operand<i32> {
348 def simm16_64 : Operand<i64> {
349 let DecoderMethod = "DecodeSimm16";
353 def uimmz : Operand<i32> {
354 let PrintMethod = "printUnsignedImm";
358 def uimm2 : Operand<i32> {
359 let PrintMethod = "printUnsignedImm";
362 def uimm3 : Operand<i32> {
363 let PrintMethod = "printUnsignedImm";
366 def uimm5 : Operand<i32> {
367 let PrintMethod = "printUnsignedImm";
370 def uimm6 : Operand<i32> {
371 let PrintMethod = "printUnsignedImm";
374 def uimm16 : Operand<i32> {
375 let PrintMethod = "printUnsignedImm";
378 def pcrel16 : Operand<i32> {
381 def MipsMemAsmOperand : AsmOperandClass {
383 let ParserMethod = "parseMemOperand";
386 def MipsInvertedImmoperand : AsmOperandClass {
388 let RenderMethod = "addImmOperands";
389 let ParserMethod = "parseInvNum";
392 def InvertedImOperand : Operand<i32> {
393 let ParserMatchClass = MipsInvertedImmoperand;
396 def InvertedImOperand64 : Operand<i64> {
397 let ParserMatchClass = MipsInvertedImmoperand;
400 class mem_generic : Operand<iPTR> {
401 let PrintMethod = "printMemOperand";
402 let MIOperandInfo = (ops ptr_rc, simm16);
403 let EncoderMethod = "getMemEncoding";
404 let ParserMatchClass = MipsMemAsmOperand;
405 let OperandType = "OPERAND_MEMORY";
409 def mem : mem_generic;
411 // MSA specific address operand
412 def mem_msa : mem_generic {
413 let MIOperandInfo = (ops ptr_rc, simm10);
414 let EncoderMethod = "getMSAMemEncoding";
417 def mem_ea : Operand<iPTR> {
418 let PrintMethod = "printMemOperandEA";
419 let MIOperandInfo = (ops ptr_rc, simm16);
420 let EncoderMethod = "getMemEncoding";
421 let OperandType = "OPERAND_MEMORY";
424 def PtrRC : Operand<iPTR> {
425 let MIOperandInfo = (ops ptr_rc);
426 let DecoderMethod = "DecodePtrRegisterClass";
427 let ParserMatchClass = GPR32AsmOperand;
430 // size operand of ext instruction
431 def size_ext : Operand<i32> {
432 let EncoderMethod = "getSizeExtEncoding";
433 let DecoderMethod = "DecodeExtSize";
436 // size operand of ins instruction
437 def size_ins : Operand<i32> {
438 let EncoderMethod = "getSizeInsEncoding";
439 let DecoderMethod = "DecodeInsSize";
442 // Transformation Function - get the lower 16 bits.
443 def LO16 : SDNodeXForm<imm, [{
444 return getImm(N, N->getZExtValue() & 0xFFFF);
447 // Transformation Function - get the higher 16 bits.
448 def HI16 : SDNodeXForm<imm, [{
449 return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF);
453 def Plus1 : SDNodeXForm<imm, [{ return getImm(N, N->getSExtValue() + 1); }]>;
455 // Node immediate is zero (e.g. insve.d)
456 def immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>;
458 // Node immediate fits as 16-bit sign extended on target immediate.
460 def immSExt8 : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;
462 // Node immediate fits as 16-bit sign extended on target immediate.
464 def immSExt16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;
466 // Node immediate fits as 15-bit sign extended on target immediate.
468 def immSExt15 : PatLeaf<(imm), [{ return isInt<15>(N->getSExtValue()); }]>;
470 // Node immediate fits as 16-bit zero extended on target immediate.
471 // The LO16 param means that only the lower 16 bits of the node
472 // immediate are caught.
474 def immZExt16 : PatLeaf<(imm), [{
475 if (N->getValueType(0) == MVT::i32)
476 return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
478 return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
481 // Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared).
482 def immLow16Zero : PatLeaf<(imm), [{
483 int64_t Val = N->getSExtValue();
484 return isInt<32>(Val) && !(Val & 0xffff);
487 // shamt field must fit in 5 bits.
488 def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
490 // True if (N + 1) fits in 16-bit field.
491 def immSExt16Plus1 : PatLeaf<(imm), [{
492 return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1);
495 // Mips Address Mode! SDNode frameindex could possibily be a match
496 // since load and store instructions from stack used it.
498 ComplexPattern<iPTR, 2, "selectIntAddr", [frameindex]>;
501 ComplexPattern<iPTR, 2, "selectAddrRegImm", [frameindex]>;
504 ComplexPattern<iPTR, 2, "selectAddrRegReg", [frameindex]>;
507 ComplexPattern<iPTR, 2, "selectAddrDefault", [frameindex]>;
509 def addrimm10 : ComplexPattern<iPTR, 2, "selectIntAddrMSA", [frameindex]>;
511 //===----------------------------------------------------------------------===//
512 // Instructions specific format
513 //===----------------------------------------------------------------------===//
515 // Arithmetic and logical instructions with 3 register operands.
516 class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0,
517 InstrItinClass Itin = NoItinerary,
518 SDPatternOperator OpNode = null_frag>:
519 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
520 !strconcat(opstr, "\t$rd, $rs, $rt"),
521 [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> {
522 let isCommutable = isComm;
523 let isReMaterializable = 1;
524 let TwoOperandAliasConstraint = "$rd = $rs";
527 // Arithmetic and logical instructions with 2 register operands.
528 class ArithLogicI<string opstr, Operand Od, RegisterOperand RO,
529 InstrItinClass Itin = NoItinerary,
530 SDPatternOperator imm_type = null_frag,
531 SDPatternOperator OpNode = null_frag> :
532 InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16),
533 !strconcat(opstr, "\t$rt, $rs, $imm16"),
534 [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))],
536 let isReMaterializable = 1;
537 let TwoOperandAliasConstraint = "$rs = $rt";
540 // Arithmetic Multiply ADD/SUB
541 class MArithR<string opstr, InstrItinClass itin, bit isComm = 0> :
542 InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
543 !strconcat(opstr, "\t$rs, $rt"), [], itin, FrmR, opstr> {
544 let Defs = [HI0, LO0];
545 let Uses = [HI0, LO0];
546 let isCommutable = isComm;
550 class LogicNOR<string opstr, RegisterOperand RO>:
551 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
552 !strconcat(opstr, "\t$rd, $rs, $rt"),
553 [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], II_NOR, FrmR, opstr> {
554 let isCommutable = 1;
558 class shift_rotate_imm<string opstr, Operand ImmOpnd,
559 RegisterOperand RO, InstrItinClass itin,
560 SDPatternOperator OpNode = null_frag,
561 SDPatternOperator PF = null_frag> :
562 InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt),
563 !strconcat(opstr, "\t$rd, $rt, $shamt"),
564 [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], itin, FrmR, opstr> {
565 let TwoOperandAliasConstraint = "$rt = $rd";
568 class shift_rotate_reg<string opstr, RegisterOperand RO, InstrItinClass itin,
569 SDPatternOperator OpNode = null_frag>:
570 InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs),
571 !strconcat(opstr, "\t$rd, $rt, $rs"),
572 [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], itin, FrmR,
575 // Load Upper Imediate
576 class LoadUpper<string opstr, RegisterOperand RO, Operand Imm>:
577 InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"),
578 [], II_LUI, FrmI, opstr>, IsAsCheapAsAMove {
579 let neverHasSideEffects = 1;
580 let isReMaterializable = 1;
584 class Load<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
585 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
586 InstSE<(outs RO:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
587 [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> {
588 let DecoderMethod = "DecodeMem";
589 let canFoldAsLoad = 1;
593 class Store<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
594 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
595 InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
596 [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> {
597 let DecoderMethod = "DecodeMem";
601 // Load/Store Left/Right
602 let canFoldAsLoad = 1 in
603 class LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
604 InstrItinClass Itin> :
605 InstSE<(outs RO:$rt), (ins mem:$addr, RO:$src),
606 !strconcat(opstr, "\t$rt, $addr"),
607 [(set RO:$rt, (OpNode addr:$addr, RO:$src))], Itin, FrmI> {
608 let DecoderMethod = "DecodeMem";
609 string Constraints = "$src = $rt";
612 class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
613 InstrItinClass Itin> :
614 InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
615 [(OpNode RO:$rt, addr:$addr)], Itin, FrmI> {
616 let DecoderMethod = "DecodeMem";
619 // Conditional Branch
620 class CBranch<string opstr, DAGOperand opnd, PatFrag cond_op,
621 RegisterOperand RO> :
622 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
623 !strconcat(opstr, "\t$rs, $rt, $offset"),
624 [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], IIBranch,
627 let isTerminator = 1;
628 let hasDelaySlot = 1;
632 class CBranchZero<string opstr, DAGOperand opnd, PatFrag cond_op,
633 RegisterOperand RO> :
634 InstSE<(outs), (ins RO:$rs, opnd:$offset),
635 !strconcat(opstr, "\t$rs, $offset"),
636 [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], IIBranch,
639 let isTerminator = 1;
640 let hasDelaySlot = 1;
645 class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> :
646 InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt),
647 !strconcat(opstr, "\t$rd, $rs, $rt"),
648 [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))],
649 II_SLT_SLTU, FrmR, opstr>;
651 class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
653 InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16),
654 !strconcat(opstr, "\t$rt, $rs, $imm16"),
655 [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))],
656 II_SLTI_SLTIU, FrmI, opstr>;
659 class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
660 SDPatternOperator targetoperator, string bopstr> :
661 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
662 [(operator targetoperator:$target)], IIBranch, FrmJ, bopstr> {
665 let hasDelaySlot = 1;
666 let DecoderMethod = "DecodeJumpTarget";
670 // Unconditional branch
671 class UncondBranch<Instruction BEQInst> :
672 PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], IIBranch>,
673 PseudoInstExpansion<(BEQInst ZERO, ZERO, brtarget:$offset)> {
675 let isTerminator = 1;
677 let hasDelaySlot = 1;
678 let AdditionalPredicates = [RelocPIC];
682 // Base class for indirect branch and return instruction classes.
683 let isTerminator=1, isBarrier=1, hasDelaySlot = 1 in
684 class JumpFR<string opstr, RegisterOperand RO,
685 SDPatternOperator operator = null_frag>:
686 InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], IIBranch,
690 class IndirectBranch<string opstr, RegisterOperand RO> :
691 JumpFR<opstr, RO, brind> {
693 let isIndirectBranch = 1;
696 // Return instruction
697 class RetBase<string opstr, RegisterOperand RO>: JumpFR<opstr, RO> {
699 let isCodeGenOnly = 1;
701 let hasExtraSrcRegAllocReq = 1;
704 // Jump and Link (Call)
705 let isCall=1, hasDelaySlot=1, Defs = [RA] in {
706 class JumpLink<string opstr, DAGOperand opnd> :
707 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
708 [(MipsJmpLink imm:$target)], IIBranch, FrmJ, opstr> {
709 let DecoderMethod = "DecodeJumpTarget";
712 class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst,
713 Register RetReg, RegisterOperand ResRO = RO>:
714 PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], IIBranch>,
715 PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)>;
717 class JumpLinkReg<string opstr, RegisterOperand RO>:
718 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
721 class BGEZAL_FT<string opstr, DAGOperand opnd, RegisterOperand RO> :
722 InstSE<(outs), (ins RO:$rs, opnd:$offset),
723 !strconcat(opstr, "\t$rs, $offset"), [], IIBranch, FrmI, opstr>;
727 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
728 hasExtraSrcRegAllocReq = 1, Defs = [AT] in {
729 class TailCall<Instruction JumpInst> :
730 PseudoSE<(outs), (ins calltarget:$target), [], IIBranch>,
731 PseudoInstExpansion<(JumpInst jmptarget:$target)>;
733 class TailCallReg<RegisterOperand RO, Instruction JRInst,
734 RegisterOperand ResRO = RO> :
735 PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], IIBranch>,
736 PseudoInstExpansion<(JRInst ResRO:$rs)>;
739 class BAL_BR_Pseudo<Instruction RealInst> :
740 PseudoSE<(outs), (ins brtarget:$offset), [], IIBranch>,
741 PseudoInstExpansion<(RealInst ZERO, brtarget:$offset)> {
743 let isTerminator = 1;
745 let hasDelaySlot = 1;
750 class SYS_FT<string opstr> :
751 InstSE<(outs), (ins uimm20:$code_),
752 !strconcat(opstr, "\t$code_"), [], NoItinerary, FrmI, opstr>;
754 class BRK_FT<string opstr> :
755 InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
756 !strconcat(opstr, "\t$code_1, $code_2"), [], NoItinerary,
760 class ER_FT<string opstr> :
761 InstSE<(outs), (ins),
762 opstr, [], NoItinerary, FrmOther, opstr>;
765 class DEI_FT<string opstr, RegisterOperand RO> :
766 InstSE<(outs RO:$rt), (ins),
767 !strconcat(opstr, "\t$rt"), [], NoItinerary, FrmOther, opstr>;
770 class WAIT_FT<string opstr> :
771 InstSE<(outs), (ins), opstr, [], NoItinerary, FrmOther, opstr>;
774 let hasSideEffects = 1 in
775 class SYNC_FT<string opstr> :
776 InstSE<(outs), (ins i32imm:$stype), "sync $stype", [(MipsSync imm:$stype)],
777 NoItinerary, FrmOther, opstr>;
779 let hasSideEffects = 1 in
780 class TEQ_FT<string opstr, RegisterOperand RO> :
781 InstSE<(outs), (ins RO:$rs, RO:$rt, uimm16:$code_),
782 !strconcat(opstr, "\t$rs, $rt, $code_"), [], NoItinerary,
785 class TEQI_FT<string opstr, RegisterOperand RO> :
786 InstSE<(outs), (ins RO:$rs, uimm16:$imm16),
787 !strconcat(opstr, "\t$rs, $imm16"), [], NoItinerary, FrmOther, opstr>;
789 class Mult<string opstr, InstrItinClass itin, RegisterOperand RO,
790 list<Register> DefRegs> :
791 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [],
793 let isCommutable = 1;
795 let neverHasSideEffects = 1;
798 // Pseudo multiply/divide instruction with explicit accumulator register
800 class MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1,
801 SDPatternOperator OpNode, InstrItinClass Itin,
802 bit IsComm = 1, bit HasSideEffects = 0,
803 bit UsesCustomInserter = 0> :
804 PseudoSE<(outs R0:$ac), (ins R1:$rs, R1:$rt),
805 [(set R0:$ac, (OpNode R1:$rs, R1:$rt))], Itin>,
806 PseudoInstExpansion<(RealInst R1:$rs, R1:$rt)> {
807 let isCommutable = IsComm;
808 let hasSideEffects = HasSideEffects;
809 let usesCustomInserter = UsesCustomInserter;
812 // Pseudo multiply add/sub instruction with explicit accumulator register
814 class MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode,
816 : PseudoSE<(outs ACC64:$ac),
817 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin),
819 (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))],
821 PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> {
822 string Constraints = "$acin = $ac";
825 class Div<string opstr, InstrItinClass itin, RegisterOperand RO,
826 list<Register> DefRegs> :
827 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$$zero, $rs, $rt"),
828 [], itin, FrmR, opstr> {
833 class PseudoMFLOHI<RegisterClass DstRC, RegisterClass SrcRC, SDNode OpNode>
834 : PseudoSE<(outs DstRC:$rd), (ins SrcRC:$hilo),
835 [(set DstRC:$rd, (OpNode SrcRC:$hilo))], II_MFHI_MFLO>;
837 class MoveFromLOHI<string opstr, RegisterOperand RO, Register UseReg>:
838 InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO,
841 let neverHasSideEffects = 1;
844 class PseudoMTLOHI<RegisterClass DstRC, RegisterClass SrcRC>
845 : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi),
846 [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))],
849 class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>:
850 InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO,
853 let neverHasSideEffects = 1;
856 class EffectiveAddress<string opstr, RegisterOperand RO> :
857 InstSE<(outs RO:$rt), (ins mem_ea:$addr), !strconcat(opstr, "\t$rt, $addr"),
858 [(set RO:$rt, addr:$addr)], NoItinerary, FrmI,
859 !strconcat(opstr, "_lea")> {
860 let isCodeGenOnly = 1;
861 let DecoderMethod = "DecodeMem";
864 // Count Leading Ones/Zeros in Word
865 class CountLeading0<string opstr, RegisterOperand RO>:
866 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
867 [(set RO:$rd, (ctlz RO:$rs))], II_CLZ, FrmR, opstr>;
869 class CountLeading1<string opstr, RegisterOperand RO>:
870 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
871 [(set RO:$rd, (ctlz (not RO:$rs)))], II_CLO, FrmR, opstr>;
873 // Sign Extend in Register.
874 class SignExtInReg<string opstr, ValueType vt, RegisterOperand RO,
875 InstrItinClass itin> :
876 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"),
877 [(set RO:$rd, (sext_inreg RO:$rt, vt))], itin, FrmR, opstr>;
880 class SubwordSwap<string opstr, RegisterOperand RO>:
881 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [],
882 NoItinerary, FrmR, opstr> {
883 let neverHasSideEffects = 1;
887 class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> :
888 InstSE<(outs CPURegOperand:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [],
892 class ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd,
893 SDPatternOperator Op = null_frag>:
894 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, size_ext:$size),
895 !strconcat(opstr, " $rt, $rs, $pos, $size"),
896 [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size))], NoItinerary,
897 FrmR, opstr>, ISA_MIPS32R2;
899 class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd,
900 SDPatternOperator Op = null_frag>:
901 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, size_ins:$size, RO:$src),
902 !strconcat(opstr, " $rt, $rs, $pos, $size"),
903 [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size, RO:$src))],
904 NoItinerary, FrmR, opstr>, ISA_MIPS32R2 {
905 let Constraints = "$src = $rt";
908 // Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*).
909 class Atomic2Ops<PatFrag Op, RegisterClass DRC> :
910 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr),
911 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]>;
913 // Atomic Compare & Swap.
914 class AtomicCmpSwap<PatFrag Op, RegisterClass DRC> :
915 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap),
916 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]>;
918 class LLBase<string opstr, RegisterOperand RO> :
919 InstSE<(outs RO:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
920 [], NoItinerary, FrmI> {
921 let DecoderMethod = "DecodeMem";
925 class SCBase<string opstr, RegisterOperand RO> :
926 InstSE<(outs RO:$dst), (ins RO:$rt, mem:$addr),
927 !strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> {
928 let DecoderMethod = "DecodeMem";
930 let Constraints = "$rt = $dst";
933 class MFC3OP<string asmstr, RegisterOperand RO> :
934 InstSE<(outs RO:$rt, RO:$rd, uimm16:$sel), (ins),
935 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], NoItinerary, FrmFR>;
937 class TrapBase<Instruction RealInst>
938 : PseudoSE<(outs), (ins), [(trap)], NoItinerary>,
939 PseudoInstExpansion<(RealInst 0, 0)> {
941 let isTerminator = 1;
942 let isCodeGenOnly = 1;
945 //===----------------------------------------------------------------------===//
946 // Pseudo instructions
947 //===----------------------------------------------------------------------===//
950 let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1 in
951 def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
953 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
954 def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt),
955 [(callseq_start timm:$amt)]>;
956 def ADJCALLSTACKUP : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
957 [(callseq_end timm:$amt1, timm:$amt2)]>;
960 let usesCustomInserter = 1 in {
961 def ATOMIC_LOAD_ADD_I8 : Atomic2Ops<atomic_load_add_8, GPR32>;
962 def ATOMIC_LOAD_ADD_I16 : Atomic2Ops<atomic_load_add_16, GPR32>;
963 def ATOMIC_LOAD_ADD_I32 : Atomic2Ops<atomic_load_add_32, GPR32>;
964 def ATOMIC_LOAD_SUB_I8 : Atomic2Ops<atomic_load_sub_8, GPR32>;
965 def ATOMIC_LOAD_SUB_I16 : Atomic2Ops<atomic_load_sub_16, GPR32>;
966 def ATOMIC_LOAD_SUB_I32 : Atomic2Ops<atomic_load_sub_32, GPR32>;
967 def ATOMIC_LOAD_AND_I8 : Atomic2Ops<atomic_load_and_8, GPR32>;
968 def ATOMIC_LOAD_AND_I16 : Atomic2Ops<atomic_load_and_16, GPR32>;
969 def ATOMIC_LOAD_AND_I32 : Atomic2Ops<atomic_load_and_32, GPR32>;
970 def ATOMIC_LOAD_OR_I8 : Atomic2Ops<atomic_load_or_8, GPR32>;
971 def ATOMIC_LOAD_OR_I16 : Atomic2Ops<atomic_load_or_16, GPR32>;
972 def ATOMIC_LOAD_OR_I32 : Atomic2Ops<atomic_load_or_32, GPR32>;
973 def ATOMIC_LOAD_XOR_I8 : Atomic2Ops<atomic_load_xor_8, GPR32>;
974 def ATOMIC_LOAD_XOR_I16 : Atomic2Ops<atomic_load_xor_16, GPR32>;
975 def ATOMIC_LOAD_XOR_I32 : Atomic2Ops<atomic_load_xor_32, GPR32>;
976 def ATOMIC_LOAD_NAND_I8 : Atomic2Ops<atomic_load_nand_8, GPR32>;
977 def ATOMIC_LOAD_NAND_I16 : Atomic2Ops<atomic_load_nand_16, GPR32>;
978 def ATOMIC_LOAD_NAND_I32 : Atomic2Ops<atomic_load_nand_32, GPR32>;
980 def ATOMIC_SWAP_I8 : Atomic2Ops<atomic_swap_8, GPR32>;
981 def ATOMIC_SWAP_I16 : Atomic2Ops<atomic_swap_16, GPR32>;
982 def ATOMIC_SWAP_I32 : Atomic2Ops<atomic_swap_32, GPR32>;
984 def ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap<atomic_cmp_swap_8, GPR32>;
985 def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap<atomic_cmp_swap_16, GPR32>;
986 def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_32, GPR32>;
989 /// Pseudo instructions for loading and storing accumulator registers.
990 let isPseudo = 1, isCodeGenOnly = 1 in {
991 def LOAD_ACC64 : Load<"", ACC64>;
992 def STORE_ACC64 : Store<"", ACC64>;
995 // We need these two pseudo instructions to avoid offset calculation for long
996 // branches. See the comment in file MipsLongBranch.cpp for detailed
999 // Expands to: lui $dst, %hi($tgt - $baltgt)
1000 def LONG_BRANCH_LUi : PseudoSE<(outs GPR32Opnd:$dst),
1001 (ins brtarget:$tgt, brtarget:$baltgt), []>;
1003 // Expands to: addiu $dst, $src, %lo($tgt - $baltgt)
1004 def LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst),
1005 (ins GPR32Opnd:$src, brtarget:$tgt, brtarget:$baltgt), []>;
1007 //===----------------------------------------------------------------------===//
1008 // Instruction definition
1009 //===----------------------------------------------------------------------===//
1010 //===----------------------------------------------------------------------===//
1011 // MipsI Instructions
1012 //===----------------------------------------------------------------------===//
1014 /// Arithmetic Instructions (ALU Immediate)
1015 def ADDiu : MMRel, ArithLogicI<"addiu", simm16, GPR32Opnd, II_ADDIU, immSExt16,
1017 ADDI_FM<0x9>, IsAsCheapAsAMove;
1018 def ADDi : MMRel, ArithLogicI<"addi", simm16, GPR32Opnd>, ADDI_FM<0x8>,
1019 ISA_MIPS1_NOT_32R6_64R6;
1020 def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
1022 def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
1024 def ANDi : MMRel, ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16,
1027 def ORi : MMRel, ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16,
1030 def XORi : MMRel, ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16,
1033 def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16>, LUI_FM;
1035 /// Arithmetic Instructions (3-Operand, R-Type)
1036 def ADDu : MMRel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
1038 def SUBu : MMRel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
1040 let Defs = [HI0, LO0] in
1041 def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>,
1042 ADD_FM<0x1c, 2>, ISA_MIPS32;
1043 def ADD : MMRel, ArithLogicR<"add", GPR32Opnd>, ADD_FM<0, 0x20>;
1044 def SUB : MMRel, ArithLogicR<"sub", GPR32Opnd>, ADD_FM<0, 0x22>;
1045 def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>;
1046 def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>;
1047 def AND : MMRel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
1049 def OR : MMRel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
1051 def XOR : MMRel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
1053 def NOR : MMRel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>;
1055 /// Shift Instructions
1056 def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl,
1057 immZExt5>, SRA_FM<0, 0>;
1058 def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl,
1059 immZExt5>, SRA_FM<2, 0>;
1060 def SRA : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, sra,
1061 immZExt5>, SRA_FM<3, 0>;
1062 def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, shl>,
1064 def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, srl>,
1066 def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, sra>,
1069 // Rotate Instructions
1070 def ROTR : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr,
1072 SRA_FM<2, 1>, ISA_MIPS32R2;
1073 def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>,
1074 SRLV_FM<6, 1>, ISA_MIPS32R2;
1076 /// Load and Store Instructions
1078 def LB : Load<"lb", GPR32Opnd, sextloadi8, II_LB>, MMRel, LW_FM<0x20>;
1079 def LBu : Load<"lbu", GPR32Opnd, zextloadi8, II_LBU, addrDefault>, MMRel,
1081 def LH : Load<"lh", GPR32Opnd, sextloadi16, II_LH, addrDefault>, MMRel,
1083 def LHu : Load<"lhu", GPR32Opnd, zextloadi16, II_LHU>, MMRel, LW_FM<0x25>;
1084 def LW : Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel,
1086 def SB : Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel, LW_FM<0x28>;
1087 def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>;
1088 def SW : Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>;
1090 /// load/store left/right
1091 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1092 AdditionalPredicates = [NotInMicroMips] in {
1093 def LWL : LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>,
1094 ISA_MIPS1_NOT_32R6_64R6;
1095 def LWR : LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>,
1096 ISA_MIPS1_NOT_32R6_64R6;
1097 def SWL : StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>,
1098 ISA_MIPS1_NOT_32R6_64R6;
1099 def SWR : StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>,
1100 ISA_MIPS1_NOT_32R6_64R6;
1103 def SYNC : MMRel, SYNC_FT<"sync">, SYNC_FM;
1104 def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM<0x34>;
1105 def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM<0x30>;
1106 def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd>, TEQ_FM<0x31>;
1107 def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd>, TEQ_FM<0x32>;
1108 def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd>, TEQ_FM<0x33>;
1109 def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd>, TEQ_FM<0x36>;
1111 def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd>, TEQI_FM<0xc>, ISA_MIPS2;
1112 def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd>, TEQI_FM<0x8>, ISA_MIPS2;
1113 def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd>, TEQI_FM<0x9>, ISA_MIPS2;
1114 def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd>, TEQI_FM<0xa>, ISA_MIPS2;
1115 def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd>, TEQI_FM<0xb>, ISA_MIPS2;
1116 def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd>, TEQI_FM<0xe>, ISA_MIPS2;
1118 def BREAK : MMRel, BRK_FT<"break">, BRK_FM<0xd>;
1119 def SYSCALL : MMRel, SYS_FT<"syscall">, SYS_FM<0xc>;
1120 def TRAP : TrapBase<BREAK>;
1122 def ERET : MMRel, ER_FT<"eret">, ER_FM<0x18>, INSN_MIPS3_32;
1123 def DERET : MMRel, ER_FT<"deret">, ER_FM<0x1f>, ISA_MIPS32;
1125 def EI : MMRel, DEI_FT<"ei", GPR32Opnd>, EI_FM<1>, ISA_MIPS32R2;
1126 def DI : MMRel, DEI_FT<"di", GPR32Opnd>, EI_FM<0>, ISA_MIPS32R2;
1128 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1129 AdditionalPredicates = [NotInMicroMips] in {
1130 def WAIT : WAIT_FT<"wait">, WAIT_FM;
1132 /// Load-linked, Store-conditional
1133 def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>, ISA_MIPS2;
1134 def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, ISA_MIPS2;
1137 /// Jump and Branch Instructions
1138 def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
1139 AdditionalRequires<[RelocStatic]>, IsBranch;
1140 def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>;
1141 def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>;
1142 def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>;
1143 def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
1145 def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
1147 def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
1149 def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
1151 def B : UncondBranch<BEQ>;
1153 def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>;
1154 let AdditionalPredicates = [NotInMicroMips] in {
1155 def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM;
1156 def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>;
1158 def JALX : JumpLink<"jalx", calltarget>, FJ<0x1D>;
1159 def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>;
1160 def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>;
1161 def BAL_BR : BAL_BR_Pseudo<BGEZAL>;
1162 def TAILCALL : TailCall<J>;
1163 def TAILCALL_R : TailCallReg<GPR32Opnd, JR>;
1165 def RET : MMRel, RetBase<"ret", GPR32Opnd>, MTLO_FM<8>;
1167 // Exception handling related node and instructions.
1168 // The conversion sequence is:
1169 // ISD::EH_RETURN -> MipsISD::EH_RETURN ->
1170 // MIPSeh_return -> (stack change + indirect branch)
1172 // MIPSeh_return takes the place of regular return instruction
1173 // but takes two arguments (V1, V0) which are used for storing
1174 // the offset and return address respectively.
1175 def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
1177 def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
1178 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
1180 let Uses = [V0, V1], isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1181 def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
1182 [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
1183 def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff,
1185 [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
1188 /// Multiply and Divide Instructions.
1189 def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
1191 def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
1193 def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
1195 def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
1198 def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>;
1199 def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>;
1200 let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
1201 AdditionalPredicates = [NotInMicroMips] in {
1202 def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>;
1203 def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>;
1206 /// Sign Ext In Register Instructions.
1207 def SEB : MMRel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,
1208 SEB_FM<0x10, 0x20>, ISA_MIPS32R2;
1209 def SEH : MMRel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
1210 SEB_FM<0x18, 0x20>, ISA_MIPS32R2;
1213 def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd>, CLO_FM<0x20>, ISA_MIPS32;
1214 def CLO : MMRel, CountLeading1<"clo", GPR32Opnd>, CLO_FM<0x21>, ISA_MIPS32;
1216 /// Word Swap Bytes Within Halfwords
1217 def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd>, SEB_FM<2, 0x20>, ISA_MIPS32R2;
1220 def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>;
1222 // FrameIndexes are legalized when they are operands from load/store
1223 // instructions. The same not happens for stack address copies, so an
1224 // add op with mem ComplexPattern is used and the stack address copy
1225 // can be matched. It's similar to Sparc LEA_ADDRi
1226 def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>;
1229 def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>, ISA_MIPS32;
1230 def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>, ISA_MIPS32;
1231 def MSUB : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>, ISA_MIPS32;
1232 def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>, ISA_MIPS32;
1234 let AdditionalPredicates = [NotDSP] in {
1235 def PseudoMULT : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>;
1236 def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>;
1237 def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>;
1238 def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>;
1239 def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>;
1240 def PseudoMADD : MAddSubPseudo<MADD, MipsMAdd, II_MADD>;
1241 def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>;
1242 def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>;
1243 def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>;
1246 def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV,
1248 def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU,
1251 def RDHWR : ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM;
1253 def EXT : MMRel, ExtBase<"ext", GPR32Opnd, uimm5, MipsExt>, EXT_FM<0>;
1254 def INS : MMRel, InsBase<"ins", GPR32Opnd, uimm5, MipsIns>, EXT_FM<4>;
1256 /// Move Control Registers From/To CPU Registers
1257 def MFC0 : MFC3OP<"mfc0", GPR32Opnd>, MFC3OP_FM<0x10, 0>, ISA_MIPS32;
1258 def MTC0 : MFC3OP<"mtc0", GPR32Opnd>, MFC3OP_FM<0x10, 4>, ISA_MIPS32;
1259 def MFC2 : MFC3OP<"mfc2", GPR32Opnd>, MFC3OP_FM<0x12, 0>;
1260 def MTC2 : MFC3OP<"mtc2", GPR32Opnd>, MFC3OP_FM<0x12, 4>;
1262 class Barrier<string asmstr> : InstSE<(outs), (ins), asmstr, [], NoItinerary,
1264 def SSNOP : Barrier<"ssnop">, BARRIER_FM<1>;
1265 def EHB : Barrier<"ehb">, BARRIER_FM<3>;
1266 def PAUSE : Barrier<"pause">, BARRIER_FM<5>, ISA_MIPS32R2;
1268 class TLB<string asmstr> : InstSE<(outs), (ins), asmstr, [], NoItinerary,
1270 def TLBP : TLB<"tlbp">, COP0_TLB_FM<0x08>;
1271 def TLBR : TLB<"tlbr">, COP0_TLB_FM<0x01>;
1272 def TLBWI : TLB<"tlbwi">, COP0_TLB_FM<0x02>;
1273 def TLBWR : TLB<"tlbwr">, COP0_TLB_FM<0x06>;
1275 //===----------------------------------------------------------------------===//
1276 // Instruction aliases
1277 //===----------------------------------------------------------------------===//
1278 def : MipsInstAlias<"move $dst, $src",
1279 (ADDu GPR32Opnd:$dst, GPR32Opnd:$src,ZERO), 1>,
1281 let AdditionalPredicates = [NotInMicroMips];
1283 def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>;
1284 def : MipsInstAlias<"addu $rs, $rt, $imm",
1285 (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1286 def : MipsInstAlias<"add $rs, $rt, $imm",
1287 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1288 def : MipsInstAlias<"and $rs, $rt, $imm",
1289 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1290 def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>;
1291 let Predicates = [NotInMicroMips] in {
1292 def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
1294 def : MipsInstAlias<"jal $rs", (JALR RA, GPR32Opnd:$rs), 0>;
1295 def : MipsInstAlias<"jal $rd,$rs", (JALR GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
1296 def : MipsInstAlias<"not $rt, $rs",
1297 (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>;
1298 def : MipsInstAlias<"neg $rt, $rs",
1299 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
1300 def : MipsInstAlias<"negu $rt",
1301 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 0>;
1302 def : MipsInstAlias<"negu $rt, $rs",
1303 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
1304 def : MipsInstAlias<"slt $rs, $rt, $imm",
1305 (SLTi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1306 def : MipsInstAlias<"sltu $rt, $rs, $imm",
1307 (SLTiu GPR32Opnd:$rt, GPR32Opnd:$rs, simm16:$imm), 0>;
1308 def : MipsInstAlias<"xor $rs, $rt, $imm",
1309 (XORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
1310 def : MipsInstAlias<"or $rs, $rt, $imm",
1311 (ORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
1312 def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>;
1313 def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>;
1314 def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>;
1315 def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>;
1316 def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>;
1317 def : MipsInstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>;
1318 def : MipsInstAlias<"bnez $rs,$offset",
1319 (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1320 def : MipsInstAlias<"beqz $rs,$offset",
1321 (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1322 def : MipsInstAlias<"syscall", (SYSCALL 0), 1>;
1324 def : MipsInstAlias<"break", (BREAK 0, 0), 1>;
1325 def : MipsInstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>;
1326 def : MipsInstAlias<"ei", (EI ZERO), 1>;
1327 def : MipsInstAlias<"di", (DI ZERO), 1>;
1329 def : MipsInstAlias<"teq $rs, $rt", (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>;
1330 def : MipsInstAlias<"tge $rs, $rt", (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>;
1331 def : MipsInstAlias<"tgeu $rs, $rt", (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0),
1333 def : MipsInstAlias<"tlt $rs, $rt", (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>;
1334 def : MipsInstAlias<"tltu $rs, $rt", (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0),
1336 def : MipsInstAlias<"tne $rs, $rt", (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>;
1337 def : MipsInstAlias<"sll $rd, $rt, $rs",
1338 (SLLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1339 def : MipsInstAlias<"sub, $rd, $rs, $imm",
1340 (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs,
1341 InvertedImOperand:$imm), 0>;
1342 def : MipsInstAlias<"sub $rs, $imm",
1343 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, InvertedImOperand:$imm),
1345 def : MipsInstAlias<"subu, $rd, $rs, $imm",
1346 (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs,
1347 InvertedImOperand:$imm), 0>;
1348 def : MipsInstAlias<"subu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs,
1349 InvertedImOperand:$imm), 0>;
1350 def : MipsInstAlias<"sra $rd, $rt, $rs",
1351 (SRAV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1352 def : MipsInstAlias<"srl $rd, $rt, $rs",
1353 (SRLV GPR32Opnd:$rd, GPR32Opnd:$rt, GPR32Opnd:$rs), 0>;
1354 //===----------------------------------------------------------------------===//
1355 // Assembler Pseudo Instructions
1356 //===----------------------------------------------------------------------===//
1358 class LoadImm32< string instr_asm, Operand Od, RegisterOperand RO> :
1359 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
1360 !strconcat(instr_asm, "\t$rt, $imm32")> ;
1361 def LoadImm32Reg : LoadImm32<"li", uimm5, GPR32Opnd>;
1363 class LoadAddress<string instr_asm, Operand MemOpnd, RegisterOperand RO> :
1364 MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
1365 !strconcat(instr_asm, "\t$rt, $addr")> ;
1366 def LoadAddr32Reg : LoadAddress<"la", mem, GPR32Opnd>;
1368 class LoadAddressImm<string instr_asm, Operand Od, RegisterOperand RO> :
1369 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
1370 !strconcat(instr_asm, "\t$rt, $imm32")> ;
1371 def LoadAddr32Imm : LoadAddressImm<"la", uimm5, GPR32Opnd>;
1373 //===----------------------------------------------------------------------===//
1374 // Arbitrary patterns that map to one or more instructions
1375 //===----------------------------------------------------------------------===//
1377 // Load/store pattern templates.
1378 class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
1379 MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
1381 class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
1382 MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
1385 def : MipsPat<(i32 immSExt16:$in),
1386 (ADDiu ZERO, imm:$in)>;
1387 def : MipsPat<(i32 immZExt16:$in),
1388 (ORi ZERO, imm:$in)>;
1389 def : MipsPat<(i32 immLow16Zero:$in),
1390 (LUi (HI16 imm:$in))>;
1392 // Arbitrary immediates
1393 def : MipsPat<(i32 imm:$imm),
1394 (ORi (LUi (HI16 imm:$imm)), (LO16 imm:$imm))>;
1396 // Carry MipsPatterns
1397 def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
1398 (SUBu GPR32:$lhs, GPR32:$rhs)>;
1399 let AdditionalPredicates = [NotDSP] in {
1400 def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
1401 (ADDu GPR32:$lhs, GPR32:$rhs)>;
1402 def : MipsPat<(addc GPR32:$src, immSExt16:$imm),
1403 (ADDiu GPR32:$src, imm:$imm)>;
1407 def : MipsPat<(MipsJmpLink (i32 tglobaladdr:$dst)),
1408 (JAL tglobaladdr:$dst)>;
1409 def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
1410 (JAL texternalsym:$dst)>;
1411 //def : MipsPat<(MipsJmpLink GPR32:$dst),
1412 // (JALR GPR32:$dst)>;
1415 def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
1416 (TAILCALL tglobaladdr:$dst)>;
1417 def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
1418 (TAILCALL texternalsym:$dst)>;
1420 def : MipsPat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
1421 def : MipsPat<(MipsHi tblockaddress:$in), (LUi tblockaddress:$in)>;
1422 def : MipsPat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>;
1423 def : MipsPat<(MipsHi tconstpool:$in), (LUi tconstpool:$in)>;
1424 def : MipsPat<(MipsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>;
1425 def : MipsPat<(MipsHi texternalsym:$in), (LUi texternalsym:$in)>;
1427 def : MipsPat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
1428 def : MipsPat<(MipsLo tblockaddress:$in), (ADDiu ZERO, tblockaddress:$in)>;
1429 def : MipsPat<(MipsLo tjumptable:$in), (ADDiu ZERO, tjumptable:$in)>;
1430 def : MipsPat<(MipsLo tconstpool:$in), (ADDiu ZERO, tconstpool:$in)>;
1431 def : MipsPat<(MipsLo tglobaltlsaddr:$in), (ADDiu ZERO, tglobaltlsaddr:$in)>;
1432 def : MipsPat<(MipsLo texternalsym:$in), (ADDiu ZERO, texternalsym:$in)>;
1434 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaladdr:$lo)),
1435 (ADDiu GPR32:$hi, tglobaladdr:$lo)>;
1436 def : MipsPat<(add GPR32:$hi, (MipsLo tblockaddress:$lo)),
1437 (ADDiu GPR32:$hi, tblockaddress:$lo)>;
1438 def : MipsPat<(add GPR32:$hi, (MipsLo tjumptable:$lo)),
1439 (ADDiu GPR32:$hi, tjumptable:$lo)>;
1440 def : MipsPat<(add GPR32:$hi, (MipsLo tconstpool:$lo)),
1441 (ADDiu GPR32:$hi, tconstpool:$lo)>;
1442 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaltlsaddr:$lo)),
1443 (ADDiu GPR32:$hi, tglobaltlsaddr:$lo)>;
1446 def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
1447 (ADDiu GPR32:$gp, tglobaladdr:$in)>;
1448 def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
1449 (ADDiu GPR32:$gp, tconstpool:$in)>;
1452 class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
1453 MipsPat<(MipsWrapper RC:$gp, node:$in),
1454 (ADDiuOp RC:$gp, node:$in)>;
1456 def : WrapperPat<tglobaladdr, ADDiu, GPR32>;
1457 def : WrapperPat<tconstpool, ADDiu, GPR32>;
1458 def : WrapperPat<texternalsym, ADDiu, GPR32>;
1459 def : WrapperPat<tblockaddress, ADDiu, GPR32>;
1460 def : WrapperPat<tjumptable, ADDiu, GPR32>;
1461 def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>;
1463 // Mips does not have "not", so we expand our way
1464 def : MipsPat<(not GPR32:$in),
1465 (NOR GPR32Opnd:$in, ZERO)>;
1468 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>;
1469 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>;
1470 def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
1473 def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>;
1476 multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BNEOp,
1477 Instruction SLTOp, Instruction SLTuOp, Instruction SLTiOp,
1478 Instruction SLTiuOp, Register ZEROReg> {
1479 def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
1480 (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
1481 def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
1482 (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
1484 def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
1485 (BEQ (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
1486 def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
1487 (BEQ (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
1488 def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
1489 (BEQ (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
1490 def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
1491 (BEQ (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
1492 def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
1493 (BEQ (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
1494 def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
1495 (BEQ (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
1497 def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
1498 (BEQ (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
1499 def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
1500 (BEQ (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
1502 def : MipsPat<(brcond RC:$cond, bb:$dst),
1503 (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
1506 defm : BrcondPats<GPR32, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>;
1508 def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
1509 (BLEZ i32:$lhs, bb:$dst)>;
1510 def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
1511 (BGEZ i32:$lhs, bb:$dst)>;
1514 multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp,
1515 Instruction SLTuOp, Register ZEROReg> {
1516 def : MipsPat<(seteq RC:$lhs, 0),
1517 (SLTiuOp RC:$lhs, 1)>;
1518 def : MipsPat<(setne RC:$lhs, 0),
1519 (SLTuOp ZEROReg, RC:$lhs)>;
1520 def : MipsPat<(seteq RC:$lhs, RC:$rhs),
1521 (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>;
1522 def : MipsPat<(setne RC:$lhs, RC:$rhs),
1523 (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
1526 multiclass SetlePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1527 def : MipsPat<(setle RC:$lhs, RC:$rhs),
1528 (XORi (SLTOp RC:$rhs, RC:$lhs), 1)>;
1529 def : MipsPat<(setule RC:$lhs, RC:$rhs),
1530 (XORi (SLTuOp RC:$rhs, RC:$lhs), 1)>;
1533 multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1534 def : MipsPat<(setgt RC:$lhs, RC:$rhs),
1535 (SLTOp RC:$rhs, RC:$lhs)>;
1536 def : MipsPat<(setugt RC:$lhs, RC:$rhs),
1537 (SLTuOp RC:$rhs, RC:$lhs)>;
1540 multiclass SetgePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1541 def : MipsPat<(setge RC:$lhs, RC:$rhs),
1542 (XORi (SLTOp RC:$lhs, RC:$rhs), 1)>;
1543 def : MipsPat<(setuge RC:$lhs, RC:$rhs),
1544 (XORi (SLTuOp RC:$lhs, RC:$rhs), 1)>;
1547 multiclass SetgeImmPats<RegisterClass RC, Instruction SLTiOp,
1548 Instruction SLTiuOp> {
1549 def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
1550 (XORi (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
1551 def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
1552 (XORi (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
1555 defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>;
1556 defm : SetlePats<GPR32, SLT, SLTu>;
1557 defm : SetgtPats<GPR32, SLT, SLTu>;
1558 defm : SetgePats<GPR32, SLT, SLTu>;
1559 defm : SetgeImmPats<GPR32, SLTi, SLTiu>;
1562 def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>;
1564 // Load halfword/word patterns.
1565 let AddedComplexity = 40 in {
1566 def : LoadRegImmPat<LBu, i32, zextloadi8>;
1567 def : LoadRegImmPat<LH, i32, sextloadi16>;
1568 def : LoadRegImmPat<LW, i32, load>;
1571 //===----------------------------------------------------------------------===//
1572 // Floating Point Support
1573 //===----------------------------------------------------------------------===//
1575 include "MipsInstrFPU.td"
1576 include "Mips64InstrInfo.td"
1577 include "MipsCondMov.td"
1579 include "Mips32r6InstrInfo.td"
1580 include "Mips64r6InstrInfo.td"
1585 include "Mips16InstrFormats.td"
1586 include "Mips16InstrInfo.td"
1589 include "MipsDSPInstrFormats.td"
1590 include "MipsDSPInstrInfo.td"
1593 include "MipsMSAInstrFormats.td"
1594 include "MipsMSAInstrInfo.td"
1597 include "MicroMipsInstrFormats.td"
1598 include "MicroMipsInstrInfo.td"
1599 include "MicroMipsInstrFPU.td"