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_ExtractLOHI : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisVT<1, untyped>,
28 def SDT_InsertLOHI : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>,
31 def SDT_MipsMultDiv : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>, SDTCisInt<1>,
33 def SDT_MipsMAddMSub : SDTypeProfile<1, 3,
34 [SDTCisVT<0, untyped>, SDTCisSameAs<0, 3>,
35 SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>;
36 def SDT_MipsDivRem16 : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>]>;
38 def SDT_MipsThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
40 def SDT_Sync : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
42 def SDT_Ext : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
43 SDTCisVT<2, i32>, SDTCisSameAs<2, 3>]>;
44 def SDT_Ins : SDTypeProfile<1, 4, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
45 SDTCisVT<2, i32>, SDTCisSameAs<2, 3>,
48 def SDTMipsLoadLR : SDTypeProfile<1, 2,
49 [SDTCisInt<0>, SDTCisPtrTy<1>,
53 def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink,
54 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,
58 def MipsTailCall : SDNode<"MipsISD::TailCall", SDT_MipsJmpLink,
59 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
61 // Hi and Lo nodes are used to handle global addresses. Used on
62 // MipsISelLowering to lower stuff like GlobalAddress, ExternalSymbol
63 // static model. (nothing to do with Mips Registers Hi and Lo)
64 def MipsHi : SDNode<"MipsISD::Hi", SDTIntUnaryOp>;
65 def MipsLo : SDNode<"MipsISD::Lo", SDTIntUnaryOp>;
66 def MipsGPRel : SDNode<"MipsISD::GPRel", SDTIntUnaryOp>;
68 // TlsGd node is used to handle General Dynamic TLS
69 def MipsTlsGd : SDNode<"MipsISD::TlsGd", SDTIntUnaryOp>;
71 // TprelHi and TprelLo nodes are used to handle Local Exec TLS
72 def MipsTprelHi : SDNode<"MipsISD::TprelHi", SDTIntUnaryOp>;
73 def MipsTprelLo : SDNode<"MipsISD::TprelLo", SDTIntUnaryOp>;
76 def MipsThreadPointer: SDNode<"MipsISD::ThreadPointer", SDT_MipsThreadPointer>;
79 def MipsRet : SDNode<"MipsISD::Ret", SDTNone,
80 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
82 // These are target-independent nodes, but have target-specific formats.
83 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MipsCallSeqStart,
84 [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>;
85 def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeqEnd,
86 [SDNPHasChain, SDNPSideEffect,
87 SDNPOptInGlue, SDNPOutGlue]>;
89 // Node used to extract integer from LO/HI register.
90 def ExtractLOHI : SDNode<"MipsISD::ExtractLOHI", SDT_ExtractLOHI>;
92 // Node used to insert 32-bit integers to LOHI register pair.
93 def InsertLOHI : SDNode<"MipsISD::InsertLOHI", SDT_InsertLOHI>;
96 def MipsMult : SDNode<"MipsISD::Mult", SDT_MipsMultDiv>;
97 def MipsMultu : SDNode<"MipsISD::Multu", SDT_MipsMultDiv>;
100 def MipsMAdd : SDNode<"MipsISD::MAdd", SDT_MipsMAddMSub>;
101 def MipsMAddu : SDNode<"MipsISD::MAddu", SDT_MipsMAddMSub>;
102 def MipsMSub : SDNode<"MipsISD::MSub", SDT_MipsMAddMSub>;
103 def MipsMSubu : SDNode<"MipsISD::MSubu", SDT_MipsMAddMSub>;
106 def MipsDivRem : SDNode<"MipsISD::DivRem", SDT_MipsMultDiv>;
107 def MipsDivRemU : SDNode<"MipsISD::DivRemU", SDT_MipsMultDiv>;
108 def MipsDivRem16 : SDNode<"MipsISD::DivRem16", SDT_MipsDivRem16,
110 def MipsDivRemU16 : SDNode<"MipsISD::DivRemU16", SDT_MipsDivRem16,
113 // Target constant nodes that are not part of any isel patterns and remain
114 // unchanged can cause instructions with illegal operands to be emitted.
115 // Wrapper node patterns give the instruction selector a chance to replace
116 // target constant nodes that would otherwise remain unchanged with ADDiu
117 // nodes. Without these wrapper node patterns, the following conditional move
118 // instrucion is emitted when function cmov2 in test/CodeGen/Mips/cmov.ll is
120 // movn %got(d)($gp), %got(c)($gp), $4
121 // This instruction is illegal since movn can take only register operands.
123 def MipsWrapper : SDNode<"MipsISD::Wrapper", SDTIntBinOp>;
125 def MipsSync : SDNode<"MipsISD::Sync", SDT_Sync, [SDNPHasChain,SDNPSideEffect]>;
127 def MipsExt : SDNode<"MipsISD::Ext", SDT_Ext>;
128 def MipsIns : SDNode<"MipsISD::Ins", SDT_Ins>;
130 def MipsLWL : SDNode<"MipsISD::LWL", SDTMipsLoadLR,
131 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
132 def MipsLWR : SDNode<"MipsISD::LWR", SDTMipsLoadLR,
133 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
134 def MipsSWL : SDNode<"MipsISD::SWL", SDTStore,
135 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
136 def MipsSWR : SDNode<"MipsISD::SWR", SDTStore,
137 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
138 def MipsLDL : SDNode<"MipsISD::LDL", SDTMipsLoadLR,
139 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
140 def MipsLDR : SDNode<"MipsISD::LDR", SDTMipsLoadLR,
141 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
142 def MipsSDL : SDNode<"MipsISD::SDL", SDTStore,
143 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
144 def MipsSDR : SDNode<"MipsISD::SDR", SDTStore,
145 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
147 //===----------------------------------------------------------------------===//
148 // Mips Instruction Predicate Definitions.
149 //===----------------------------------------------------------------------===//
150 def HasSEInReg : Predicate<"Subtarget.hasSEInReg()">,
151 AssemblerPredicate<"FeatureSEInReg">;
152 def HasBitCount : Predicate<"Subtarget.hasBitCount()">,
153 AssemblerPredicate<"FeatureBitCount">;
154 def HasSwap : Predicate<"Subtarget.hasSwap()">,
155 AssemblerPredicate<"FeatureSwap">;
156 def HasCondMov : Predicate<"Subtarget.hasCondMov()">,
157 AssemblerPredicate<"FeatureCondMov">;
158 def HasFPIdx : Predicate<"Subtarget.hasFPIdx()">,
159 AssemblerPredicate<"FeatureFPIdx">;
160 def HasMips32 : Predicate<"Subtarget.hasMips32()">,
161 AssemblerPredicate<"FeatureMips32">;
162 def HasMips32r2 : Predicate<"Subtarget.hasMips32r2()">,
163 AssemblerPredicate<"FeatureMips32r2">;
164 def HasMips64 : Predicate<"Subtarget.hasMips64()">,
165 AssemblerPredicate<"FeatureMips64">;
166 def NotMips64 : Predicate<"!Subtarget.hasMips64()">,
167 AssemblerPredicate<"!FeatureMips64">;
168 def HasMips64r2 : Predicate<"Subtarget.hasMips64r2()">,
169 AssemblerPredicate<"FeatureMips64r2">;
170 def IsN64 : Predicate<"Subtarget.isABI_N64()">,
171 AssemblerPredicate<"FeatureN64">;
172 def NotN64 : Predicate<"!Subtarget.isABI_N64()">,
173 AssemblerPredicate<"!FeatureN64">;
174 def InMips16Mode : Predicate<"Subtarget.inMips16Mode()">,
175 AssemblerPredicate<"FeatureMips16">;
176 def RelocStatic : Predicate<"TM.getRelocationModel() == Reloc::Static">,
177 AssemblerPredicate<"FeatureMips32">;
178 def RelocPIC : Predicate<"TM.getRelocationModel() == Reloc::PIC_">,
179 AssemblerPredicate<"FeatureMips32">;
180 def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">,
181 AssemblerPredicate<"FeatureMips32">;
182 def HasStdEnc : Predicate<"Subtarget.hasStandardEncoding()">,
183 AssemblerPredicate<"!FeatureMips16">;
184 def NotDSP : Predicate<"!Subtarget.hasDSP()">;
185 def InMicroMips : Predicate<"Subtarget.inMicroMipsMode()">,
186 AssemblerPredicate<"FeatureMicroMips">;
187 def NotInMicroMips : Predicate<"!Subtarget.inMicroMipsMode()">,
188 AssemblerPredicate<"!FeatureMicroMips">;
190 class MipsPat<dag pattern, dag result> : Pat<pattern, result> {
191 let Predicates = [HasStdEnc];
195 bit isCommutable = 1;
212 bit isTerminator = 1;
215 bit hasExtraSrcRegAllocReq = 1;
216 bit isCodeGenOnly = 1;
219 class IsAsCheapAsAMove {
220 bit isAsCheapAsAMove = 1;
223 class NeverHasSideEffects {
224 bit neverHasSideEffects = 1;
227 //===----------------------------------------------------------------------===//
228 // Instruction format superclass
229 //===----------------------------------------------------------------------===//
231 include "MipsInstrFormats.td"
233 //===----------------------------------------------------------------------===//
234 // Mips Operand, Complex Patterns and Transformations Definitions.
235 //===----------------------------------------------------------------------===//
237 // Instruction operand types
238 def jmptarget : Operand<OtherVT> {
239 let EncoderMethod = "getJumpTargetOpValue";
241 def brtarget : Operand<OtherVT> {
242 let EncoderMethod = "getBranchTargetOpValue";
243 let OperandType = "OPERAND_PCREL";
244 let DecoderMethod = "DecodeBranchTarget";
246 def calltarget : Operand<iPTR> {
247 let EncoderMethod = "getJumpTargetOpValue";
249 def calltarget64: Operand<i64>;
250 def simm16 : Operand<i32> {
251 let DecoderMethod= "DecodeSimm16";
254 def simm20 : Operand<i32> {
257 def uimm20 : Operand<i32> {
260 def uimm10 : Operand<i32> {
263 def simm16_64 : Operand<i64>;
264 def shamt : Operand<i32>;
267 def uimm16 : Operand<i32> {
268 let PrintMethod = "printUnsignedImm";
271 def MipsMemAsmOperand : AsmOperandClass {
273 let ParserMethod = "parseMemOperand";
277 def mem : Operand<i32> {
278 let PrintMethod = "printMemOperand";
279 let MIOperandInfo = (ops GPR32, simm16);
280 let EncoderMethod = "getMemEncoding";
281 let ParserMatchClass = MipsMemAsmOperand;
282 let OperandType = "OPERAND_MEMORY";
285 def mem64 : Operand<i64> {
286 let PrintMethod = "printMemOperand";
287 let MIOperandInfo = (ops GPR64, simm16_64);
288 let EncoderMethod = "getMemEncoding";
289 let ParserMatchClass = MipsMemAsmOperand;
290 let OperandType = "OPERAND_MEMORY";
293 def mem_ea : Operand<i32> {
294 let PrintMethod = "printMemOperandEA";
295 let MIOperandInfo = (ops GPR32, simm16);
296 let EncoderMethod = "getMemEncoding";
297 let OperandType = "OPERAND_MEMORY";
300 def mem_ea_64 : Operand<i64> {
301 let PrintMethod = "printMemOperandEA";
302 let MIOperandInfo = (ops GPR64, simm16_64);
303 let EncoderMethod = "getMemEncoding";
304 let OperandType = "OPERAND_MEMORY";
307 // size operand of ext instruction
308 def size_ext : Operand<i32> {
309 let EncoderMethod = "getSizeExtEncoding";
310 let DecoderMethod = "DecodeExtSize";
313 // size operand of ins instruction
314 def size_ins : Operand<i32> {
315 let EncoderMethod = "getSizeInsEncoding";
316 let DecoderMethod = "DecodeInsSize";
319 // Transformation Function - get the lower 16 bits.
320 def LO16 : SDNodeXForm<imm, [{
321 return getImm(N, N->getZExtValue() & 0xFFFF);
324 // Transformation Function - get the higher 16 bits.
325 def HI16 : SDNodeXForm<imm, [{
326 return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF);
330 def Plus1 : SDNodeXForm<imm, [{ return getImm(N, N->getSExtValue() + 1); }]>;
332 // Node immediate fits as 16-bit sign extended on target immediate.
334 def immSExt8 : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;
336 // Node immediate fits as 16-bit sign extended on target immediate.
338 def immSExt16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;
340 // Node immediate fits as 15-bit sign extended on target immediate.
342 def immSExt15 : PatLeaf<(imm), [{ return isInt<15>(N->getSExtValue()); }]>;
344 // Node immediate fits as 16-bit zero extended on target immediate.
345 // The LO16 param means that only the lower 16 bits of the node
346 // immediate are caught.
348 def immZExt16 : PatLeaf<(imm), [{
349 if (N->getValueType(0) == MVT::i32)
350 return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
352 return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
355 // Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared).
356 def immLow16Zero : PatLeaf<(imm), [{
357 int64_t Val = N->getSExtValue();
358 return isInt<32>(Val) && !(Val & 0xffff);
361 // shamt field must fit in 5 bits.
362 def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
364 // True if (N + 1) fits in 16-bit field.
365 def immSExt16Plus1 : PatLeaf<(imm), [{
366 return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1);
369 // Mips Address Mode! SDNode frameindex could possibily be a match
370 // since load and store instructions from stack used it.
372 ComplexPattern<iPTR, 2, "selectIntAddr", [frameindex]>;
375 ComplexPattern<iPTR, 2, "selectAddrRegImm", [frameindex]>;
378 ComplexPattern<iPTR, 2, "selectAddrDefault", [frameindex]>;
380 //===----------------------------------------------------------------------===//
381 // Instructions specific format
382 //===----------------------------------------------------------------------===//
384 // Arithmetic and logical instructions with 3 register operands.
385 class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0,
386 InstrItinClass Itin = NoItinerary,
387 SDPatternOperator OpNode = null_frag>:
388 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
389 !strconcat(opstr, "\t$rd, $rs, $rt"),
390 [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> {
391 let isCommutable = isComm;
392 let isReMaterializable = 1;
395 // Arithmetic and logical instructions with 2 register operands.
396 class ArithLogicI<string opstr, Operand Od, RegisterOperand RO,
397 InstrItinClass Itin = NoItinerary,
398 SDPatternOperator imm_type = null_frag,
399 SDPatternOperator OpNode = null_frag> :
400 InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16),
401 !strconcat(opstr, "\t$rt, $rs, $imm16"),
402 [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))],
404 let isReMaterializable = 1;
405 let TwoOperandAliasConstraint = "$rs = $rt";
408 // Arithmetic Multiply ADD/SUB
409 class MArithR<string opstr, bit isComm = 0> :
410 InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
411 !strconcat(opstr, "\t$rs, $rt"), [], IIImult, FrmR> {
412 let Defs = [HI0, LO0];
413 let Uses = [HI0, LO0];
414 let isCommutable = isComm;
418 class LogicNOR<string opstr, RegisterOperand RO>:
419 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
420 !strconcat(opstr, "\t$rd, $rs, $rt"),
421 [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], IIArith, FrmR, opstr> {
422 let isCommutable = 1;
426 class shift_rotate_imm<string opstr, Operand ImmOpnd,
427 RegisterOperand RO, SDPatternOperator OpNode = null_frag,
428 SDPatternOperator PF = null_frag> :
429 InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt),
430 !strconcat(opstr, "\t$rd, $rt, $shamt"),
431 [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], IIArith, FrmR, opstr>;
433 class shift_rotate_reg<string opstr, RegisterOperand RO,
434 SDPatternOperator OpNode = null_frag>:
435 InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs),
436 !strconcat(opstr, "\t$rd, $rt, $rs"),
437 [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], IIArith, FrmR, opstr>;
439 // Load Upper Imediate
440 class LoadUpper<string opstr, RegisterOperand RO, Operand Imm>:
441 InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"),
442 [], IIArith, FrmI>, IsAsCheapAsAMove {
443 let neverHasSideEffects = 1;
444 let isReMaterializable = 1;
447 class FMem<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
448 InstrItinClass itin>: FFI<op, outs, ins, asmstr, pattern> {
450 let Inst{25-21} = addr{20-16};
451 let Inst{15-0} = addr{15-0};
452 let DecoderMethod = "DecodeMem";
456 class Load<string opstr, SDPatternOperator OpNode, DAGOperand RO,
457 InstrItinClass Itin, Operand MemOpnd, ComplexPattern Addr,
459 InstSE<(outs RO:$rt), (ins MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"),
460 [(set RO:$rt, (OpNode Addr:$addr))], NoItinerary, FrmI,
461 !strconcat(opstr, ofsuffix)> {
462 let DecoderMethod = "DecodeMem";
463 let canFoldAsLoad = 1;
467 class Store<string opstr, SDPatternOperator OpNode, DAGOperand RO,
468 InstrItinClass Itin, Operand MemOpnd, ComplexPattern Addr,
470 InstSE<(outs), (ins RO:$rt, MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"),
471 [(OpNode RO:$rt, Addr:$addr)], NoItinerary, FrmI,
472 !strconcat(opstr, ofsuffix)> {
473 let DecoderMethod = "DecodeMem";
477 multiclass LoadM<string opstr, DAGOperand RO,
478 SDPatternOperator OpNode = null_frag,
479 InstrItinClass Itin = NoItinerary,
480 ComplexPattern Addr = addr> {
481 def NAME : Load<opstr, OpNode, RO, Itin, mem, Addr, "">,
482 Requires<[NotN64, HasStdEnc]>;
483 def _P8 : Load<opstr, OpNode, RO, Itin, mem64, Addr, "_p8">,
484 Requires<[IsN64, HasStdEnc]> {
485 let DecoderNamespace = "Mips64";
486 let isCodeGenOnly = 1;
490 multiclass StoreM<string opstr, DAGOperand RO,
491 SDPatternOperator OpNode = null_frag,
492 InstrItinClass Itin = NoItinerary,
493 ComplexPattern Addr = addr> {
494 def NAME : Store<opstr, OpNode, RO, Itin, mem, Addr, "">,
495 Requires<[NotN64, HasStdEnc]>;
496 def _P8 : Store<opstr, OpNode, RO, Itin, mem64, Addr, "_p8">,
497 Requires<[IsN64, HasStdEnc]> {
498 let DecoderNamespace = "Mips64";
499 let isCodeGenOnly = 1;
503 // Load/Store Left/Right
504 let canFoldAsLoad = 1 in
505 class LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
507 InstSE<(outs RO:$rt), (ins MemOpnd:$addr, RO:$src),
508 !strconcat(opstr, "\t$rt, $addr"),
509 [(set RO:$rt, (OpNode addr:$addr, RO:$src))], NoItinerary, FrmI> {
510 let DecoderMethod = "DecodeMem";
511 string Constraints = "$src = $rt";
514 class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
516 InstSE<(outs), (ins RO:$rt, MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"),
517 [(OpNode RO:$rt, addr:$addr)], NoItinerary, FrmI> {
518 let DecoderMethod = "DecodeMem";
521 multiclass LoadLeftRightM<string opstr, SDNode OpNode, RegisterOperand RO> {
522 def NAME : LoadLeftRight<opstr, OpNode, RO, mem>,
523 Requires<[NotN64, HasStdEnc, NotInMicroMips]>;
524 def _P8 : LoadLeftRight<opstr, OpNode, RO, mem64>,
525 Requires<[IsN64, HasStdEnc]> {
526 let DecoderNamespace = "Mips64";
527 let isCodeGenOnly = 1;
531 multiclass StoreLeftRightM<string opstr, SDNode OpNode, RegisterOperand RO> {
532 def NAME : StoreLeftRight<opstr, OpNode, RO, mem>,
533 Requires<[NotN64, HasStdEnc, NotInMicroMips]>;
534 def _P8 : StoreLeftRight<opstr, OpNode, RO, mem64>,
535 Requires<[IsN64, HasStdEnc]> {
536 let DecoderNamespace = "Mips64";
537 let isCodeGenOnly = 1;
541 // Conditional Branch
542 class CBranch<string opstr, PatFrag cond_op, RegisterOperand RO> :
543 InstSE<(outs), (ins RO:$rs, RO:$rt, brtarget:$offset),
544 !strconcat(opstr, "\t$rs, $rt, $offset"),
545 [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], IIBranch,
548 let isTerminator = 1;
549 let hasDelaySlot = 1;
553 class CBranchZero<string opstr, PatFrag cond_op, RegisterOperand RO> :
554 InstSE<(outs), (ins RO:$rs, brtarget:$offset),
555 !strconcat(opstr, "\t$rs, $offset"),
556 [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], IIBranch, FrmI> {
558 let isTerminator = 1;
559 let hasDelaySlot = 1;
564 class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> :
565 InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt),
566 !strconcat(opstr, "\t$rd, $rs, $rt"),
567 [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))],
570 class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
572 InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16),
573 !strconcat(opstr, "\t$rt, $rs, $imm16"),
574 [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))],
578 class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
579 SDPatternOperator targetoperator> :
580 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
581 [(operator targetoperator:$target)], IIBranch, FrmJ> {
584 let hasDelaySlot = 1;
585 let DecoderMethod = "DecodeJumpTarget";
589 // Unconditional branch
590 class UncondBranch<string opstr> :
591 InstSE<(outs), (ins brtarget:$offset), !strconcat(opstr, "\t$offset"),
592 [(br bb:$offset)], IIBranch, FrmI> {
594 let isTerminator = 1;
596 let hasDelaySlot = 1;
597 let Predicates = [RelocPIC, HasStdEnc];
601 // Base class for indirect branch and return instruction classes.
602 let isTerminator=1, isBarrier=1, hasDelaySlot = 1 in
603 class JumpFR<RegisterOperand RO, SDPatternOperator operator = null_frag>:
604 InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], IIBranch, FrmR>;
607 class IndirectBranch<RegisterOperand RO>: JumpFR<RO, brind> {
609 let isIndirectBranch = 1;
612 // Return instruction
613 class RetBase<RegisterOperand RO>: JumpFR<RO> {
615 let isCodeGenOnly = 1;
617 let hasExtraSrcRegAllocReq = 1;
620 // Jump and Link (Call)
621 let isCall=1, hasDelaySlot=1, Defs = [RA] in {
622 class JumpLink<string opstr> :
623 InstSE<(outs), (ins calltarget:$target), !strconcat(opstr, "\t$target"),
624 [(MipsJmpLink imm:$target)], IIBranch, FrmJ> {
625 let DecoderMethod = "DecodeJumpTarget";
628 class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst,
629 Register RetReg, RegisterOperand ResRO = RO>:
630 PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], IIBranch>,
631 PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)>;
633 class JumpLinkReg<string opstr, RegisterOperand RO>:
634 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
637 class BGEZAL_FT<string opstr, RegisterOperand RO> :
638 InstSE<(outs), (ins RO:$rs, brtarget:$offset),
639 !strconcat(opstr, "\t$rs, $offset"), [], IIBranch, FrmI>;
643 class BAL_BR_Pseudo<Instruction RealInst> :
644 PseudoSE<(outs), (ins brtarget:$offset), [], IIBranch>,
645 PseudoInstExpansion<(RealInst ZERO, brtarget:$offset)> {
647 let isTerminator = 1;
649 let hasDelaySlot = 1;
654 class SYS_FT<string opstr> :
655 InstSE<(outs), (ins uimm20:$code_),
656 !strconcat(opstr, "\t$code_"), [], NoItinerary, FrmI>;
658 class BRK_FT<string opstr> :
659 InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
660 !strconcat(opstr, "\t$code_1, $code_2"), [], NoItinerary, FrmOther>;
663 class ER_FT<string opstr> :
664 InstSE<(outs), (ins),
665 opstr, [], NoItinerary, FrmOther>;
668 class DEI_FT<string opstr, RegisterOperand RO> :
669 InstSE<(outs RO:$rt), (ins),
670 !strconcat(opstr, "\t$rt"), [], NoItinerary, FrmOther>;
673 let hasSideEffects = 1 in
675 InstSE<(outs), (ins i32imm:$stype), "sync $stype", [(MipsSync imm:$stype)],
676 NoItinerary, FrmOther>;
678 let hasSideEffects = 1 in
679 class TEQ_FT<string opstr, RegisterOperand RO> :
680 InstSE<(outs), (ins RO:$rs, RO:$rt, uimm16:$code_),
681 !strconcat(opstr, "\t$rs, $rt, $code_"), [], NoItinerary, FrmI>;
684 class Mult<string opstr, InstrItinClass itin, RegisterOperand RO,
685 list<Register> DefRegs> :
686 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [],
688 let isCommutable = 1;
690 let neverHasSideEffects = 1;
693 // Pseudo multiply/divide instruction with explicit accumulator register
695 class MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1,
696 SDPatternOperator OpNode, InstrItinClass Itin,
697 bit IsComm = 1, bit HasSideEffects = 0,
698 bit UsesCustomInserter = 0> :
699 PseudoSE<(outs R0:$ac), (ins R1:$rs, R1:$rt),
700 [(set R0:$ac, (OpNode R1:$rs, R1:$rt))], Itin>,
701 PseudoInstExpansion<(RealInst R1:$rs, R1:$rt)> {
702 let isCommutable = IsComm;
703 let hasSideEffects = HasSideEffects;
704 let usesCustomInserter = UsesCustomInserter;
707 // Pseudo multiply add/sub instruction with explicit accumulator register
709 class MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode>
710 : PseudoSE<(outs ACC64:$ac),
711 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin),
713 (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))],
715 PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> {
716 string Constraints = "$acin = $ac";
719 class Div<string opstr, InstrItinClass itin, RegisterOperand RO,
720 list<Register> DefRegs> :
721 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$$zero, $rs, $rt"),
727 class MoveFromLOHI<string opstr, RegisterOperand RO, list<Register> UseRegs>:
728 InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], IIHiLo, FrmR> {
730 let neverHasSideEffects = 1;
733 class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>:
734 InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], IIHiLo, FrmR> {
736 let neverHasSideEffects = 1;
739 class EffectiveAddress<string opstr, RegisterOperand RO, Operand Mem> :
740 InstSE<(outs RO:$rt), (ins Mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
741 [(set RO:$rt, addr:$addr)], NoItinerary, FrmI> {
742 let isCodeGenOnly = 1;
743 let DecoderMethod = "DecodeMem";
746 // Count Leading Ones/Zeros in Word
747 class CountLeading0<string opstr, RegisterOperand RO>:
748 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
749 [(set RO:$rd, (ctlz RO:$rs))], IIArith, FrmR>,
750 Requires<[HasBitCount, HasStdEnc]>;
752 class CountLeading1<string opstr, RegisterOperand RO>:
753 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
754 [(set RO:$rd, (ctlz (not RO:$rs)))], IIArith, FrmR>,
755 Requires<[HasBitCount, HasStdEnc]>;
758 // Sign Extend in Register.
759 class SignExtInReg<string opstr, ValueType vt, RegisterOperand RO> :
760 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"),
761 [(set RO:$rd, (sext_inreg RO:$rt, vt))], IIseb, FrmR> {
762 let Predicates = [HasSEInReg, HasStdEnc];
766 class SubwordSwap<string opstr, RegisterOperand RO>:
767 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [],
769 let Predicates = [HasSwap, HasStdEnc];
770 let neverHasSideEffects = 1;
774 class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> :
775 InstSE<(outs CPURegOperand:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [],
779 class ExtBase<string opstr, RegisterOperand RO>:
780 InstSE<(outs RO:$rt), (ins RO:$rs, uimm16:$pos, size_ext:$size),
781 !strconcat(opstr, " $rt, $rs, $pos, $size"),
782 [(set RO:$rt, (MipsExt RO:$rs, imm:$pos, imm:$size))], NoItinerary,
784 let Predicates = [HasMips32r2, HasStdEnc];
787 class InsBase<string opstr, RegisterOperand RO>:
788 InstSE<(outs RO:$rt), (ins RO:$rs, uimm16:$pos, size_ins:$size, RO:$src),
789 !strconcat(opstr, " $rt, $rs, $pos, $size"),
790 [(set RO:$rt, (MipsIns RO:$rs, imm:$pos, imm:$size, RO:$src))],
792 let Predicates = [HasMips32r2, HasStdEnc];
793 let Constraints = "$src = $rt";
796 // Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*).
797 class Atomic2Ops<PatFrag Op, RegisterClass DRC, RegisterClass PRC> :
798 PseudoSE<(outs DRC:$dst), (ins PRC:$ptr, DRC:$incr),
799 [(set DRC:$dst, (Op PRC:$ptr, DRC:$incr))]>;
801 multiclass Atomic2Ops32<PatFrag Op> {
802 def NAME : Atomic2Ops<Op, GPR32, GPR32>, Requires<[NotN64, HasStdEnc]>;
803 def _P8 : Atomic2Ops<Op, GPR32, GPR64>, Requires<[IsN64, HasStdEnc]>;
806 // Atomic Compare & Swap.
807 class AtomicCmpSwap<PatFrag Op, RegisterClass DRC, RegisterClass PRC> :
808 PseudoSE<(outs DRC:$dst), (ins PRC:$ptr, DRC:$cmp, DRC:$swap),
809 [(set DRC:$dst, (Op PRC:$ptr, DRC:$cmp, DRC:$swap))]>;
811 multiclass AtomicCmpSwap32<PatFrag Op> {
812 def NAME : AtomicCmpSwap<Op, GPR32, GPR32>,
813 Requires<[NotN64, HasStdEnc]>;
814 def _P8 : AtomicCmpSwap<Op, GPR32, GPR64>,
815 Requires<[IsN64, HasStdEnc]>;
818 class LLBase<string opstr, RegisterOperand RO, Operand Mem> :
819 InstSE<(outs RO:$rt), (ins Mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
820 [], NoItinerary, FrmI> {
821 let DecoderMethod = "DecodeMem";
825 class SCBase<string opstr, RegisterOperand RO, Operand Mem> :
826 InstSE<(outs RO:$dst), (ins RO:$rt, Mem:$addr),
827 !strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> {
828 let DecoderMethod = "DecodeMem";
830 let Constraints = "$rt = $dst";
833 class MFC3OP<dag outs, dag ins, string asmstr> :
834 InstSE<outs, ins, asmstr, [], NoItinerary, FrmFR>;
836 let isBarrier = 1, isTerminator = 1, isCodeGenOnly = 1 in
837 def TRAP : InstSE<(outs), (ins), "break", [(trap)], NoItinerary, FrmOther> {
838 let Inst = 0x0000000d;
841 //===----------------------------------------------------------------------===//
842 // Pseudo instructions
843 //===----------------------------------------------------------------------===//
846 let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1 in
847 def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
849 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
850 def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt),
851 [(callseq_start timm:$amt)]>;
852 def ADJCALLSTACKUP : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
853 [(callseq_end timm:$amt1, timm:$amt2)]>;
856 let usesCustomInserter = 1 in {
857 defm ATOMIC_LOAD_ADD_I8 : Atomic2Ops32<atomic_load_add_8>;
858 defm ATOMIC_LOAD_ADD_I16 : Atomic2Ops32<atomic_load_add_16>;
859 defm ATOMIC_LOAD_ADD_I32 : Atomic2Ops32<atomic_load_add_32>;
860 defm ATOMIC_LOAD_SUB_I8 : Atomic2Ops32<atomic_load_sub_8>;
861 defm ATOMIC_LOAD_SUB_I16 : Atomic2Ops32<atomic_load_sub_16>;
862 defm ATOMIC_LOAD_SUB_I32 : Atomic2Ops32<atomic_load_sub_32>;
863 defm ATOMIC_LOAD_AND_I8 : Atomic2Ops32<atomic_load_and_8>;
864 defm ATOMIC_LOAD_AND_I16 : Atomic2Ops32<atomic_load_and_16>;
865 defm ATOMIC_LOAD_AND_I32 : Atomic2Ops32<atomic_load_and_32>;
866 defm ATOMIC_LOAD_OR_I8 : Atomic2Ops32<atomic_load_or_8>;
867 defm ATOMIC_LOAD_OR_I16 : Atomic2Ops32<atomic_load_or_16>;
868 defm ATOMIC_LOAD_OR_I32 : Atomic2Ops32<atomic_load_or_32>;
869 defm ATOMIC_LOAD_XOR_I8 : Atomic2Ops32<atomic_load_xor_8>;
870 defm ATOMIC_LOAD_XOR_I16 : Atomic2Ops32<atomic_load_xor_16>;
871 defm ATOMIC_LOAD_XOR_I32 : Atomic2Ops32<atomic_load_xor_32>;
872 defm ATOMIC_LOAD_NAND_I8 : Atomic2Ops32<atomic_load_nand_8>;
873 defm ATOMIC_LOAD_NAND_I16 : Atomic2Ops32<atomic_load_nand_16>;
874 defm ATOMIC_LOAD_NAND_I32 : Atomic2Ops32<atomic_load_nand_32>;
876 defm ATOMIC_SWAP_I8 : Atomic2Ops32<atomic_swap_8>;
877 defm ATOMIC_SWAP_I16 : Atomic2Ops32<atomic_swap_16>;
878 defm ATOMIC_SWAP_I32 : Atomic2Ops32<atomic_swap_32>;
880 defm ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap32<atomic_cmp_swap_8>;
881 defm ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap32<atomic_cmp_swap_16>;
882 defm ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap32<atomic_cmp_swap_32>;
885 /// Pseudo instructions for loading and storing accumulator registers.
886 let isPseudo = 1, isCodeGenOnly = 1 in {
887 defm LOAD_ACC64 : LoadM<"", ACC64>;
888 defm STORE_ACC64 : StoreM<"", ACC64>;
891 //===----------------------------------------------------------------------===//
892 // Instruction definition
893 //===----------------------------------------------------------------------===//
894 //===----------------------------------------------------------------------===//
895 // MipsI Instructions
896 //===----------------------------------------------------------------------===//
898 /// Arithmetic Instructions (ALU Immediate)
899 def ADDiu : MMRel, ArithLogicI<"addiu", simm16, GPR32Opnd, IIArith, immSExt16,
901 ADDI_FM<0x9>, IsAsCheapAsAMove;
902 def ADDi : MMRel, ArithLogicI<"addi", simm16, GPR32Opnd>, ADDI_FM<0x8>;
903 def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
905 def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
907 def ANDi : MMRel, ArithLogicI<"andi", uimm16, GPR32Opnd, IILogic, immZExt16,
910 def ORi : MMRel, ArithLogicI<"ori", uimm16, GPR32Opnd, IILogic, immZExt16,
913 def XORi : MMRel, ArithLogicI<"xori", uimm16, GPR32Opnd, IILogic, immZExt16,
916 def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16>, LUI_FM;
918 /// Arithmetic Instructions (3-Operand, R-Type)
919 def ADDu : MMRel, ArithLogicR<"addu", GPR32Opnd, 1, IIArith, add>,
921 def SUBu : MMRel, ArithLogicR<"subu", GPR32Opnd, 0, IIArith, sub>,
923 def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, IIImul, mul>,
925 def ADD : MMRel, ArithLogicR<"add", GPR32Opnd>, ADD_FM<0, 0x20>;
926 def SUB : MMRel, ArithLogicR<"sub", GPR32Opnd>, ADD_FM<0, 0x22>;
927 def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>;
928 def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>;
929 def AND : MMRel, ArithLogicR<"and", GPR32Opnd, 1, IILogic, and>,
931 def OR : MMRel, ArithLogicR<"or", GPR32Opnd, 1, IILogic, or>,
933 def XOR : MMRel, ArithLogicR<"xor", GPR32Opnd, 1, IILogic, xor>,
935 def NOR : MMRel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>;
937 /// Shift Instructions
938 def SLL : MMRel, shift_rotate_imm<"sll", shamt, GPR32Opnd, shl, immZExt5>,
940 def SRL : MMRel, shift_rotate_imm<"srl", shamt, GPR32Opnd, srl, immZExt5>,
942 def SRA : MMRel, shift_rotate_imm<"sra", shamt, GPR32Opnd, sra, immZExt5>,
944 def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, shl>, SRLV_FM<4, 0>;
945 def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, srl>, SRLV_FM<6, 0>;
946 def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, sra>, SRLV_FM<7, 0>;
948 // Rotate Instructions
949 let Predicates = [HasMips32r2, HasStdEnc] in {
950 def ROTR : MMRel, shift_rotate_imm<"rotr", shamt, GPR32Opnd, rotr,
953 def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, rotr>,
957 /// Load and Store Instructions
959 defm LB : LoadM<"lb", GPR32Opnd, sextloadi8, IILoad>, MMRel, LW_FM<0x20>;
960 defm LBu : LoadM<"lbu", GPR32Opnd, zextloadi8, IILoad, addrDefault>, MMRel,
962 defm LH : LoadM<"lh", GPR32Opnd, sextloadi16, IILoad, addrDefault>, MMRel,
964 defm LHu : LoadM<"lhu", GPR32Opnd, zextloadi16, IILoad>, MMRel, LW_FM<0x25>;
965 defm LW : LoadM<"lw", GPR32Opnd, load, IILoad, addrDefault>, MMRel,
967 defm SB : StoreM<"sb", GPR32Opnd, truncstorei8, IIStore>, MMRel, LW_FM<0x28>;
968 defm SH : StoreM<"sh", GPR32Opnd, truncstorei16, IIStore>, MMRel, LW_FM<0x29>;
969 defm SW : StoreM<"sw", GPR32Opnd, store, IIStore>, MMRel, LW_FM<0x2b>;
971 /// load/store left/right
972 defm LWL : LoadLeftRightM<"lwl", MipsLWL, GPR32Opnd>, LW_FM<0x22>;
973 defm LWR : LoadLeftRightM<"lwr", MipsLWR, GPR32Opnd>, LW_FM<0x26>;
974 defm SWL : StoreLeftRightM<"swl", MipsSWL, GPR32Opnd>, LW_FM<0x2a>;
975 defm SWR : StoreLeftRightM<"swr", MipsSWR, GPR32Opnd>, LW_FM<0x2e>;
977 def SYNC : SYNC_FT, SYNC_FM;
978 def TEQ : TEQ_FT<"teq", GPR32Opnd>, TEQ_FM<0x34>;
980 def BREAK : BRK_FT<"break">, BRK_FM<0xd>;
981 def SYSCALL : SYS_FT<"syscall">, SYS_FM<0xc>;
983 def ERET : ER_FT<"eret">, ER_FM<0x18>;
984 def DERET : ER_FT<"deret">, ER_FM<0x1f>;
986 def EI : DEI_FT<"ei", GPR32Opnd>, EI_FM<1>;
987 def DI : DEI_FT<"di", GPR32Opnd>, EI_FM<0>;
989 /// Load-linked, Store-conditional
990 let Predicates = [NotN64, HasStdEnc] in {
991 def LL : LLBase<"ll", GPR32Opnd, mem>, LW_FM<0x30>;
992 def SC : SCBase<"sc", GPR32Opnd, mem>, LW_FM<0x38>;
995 let Predicates = [IsN64, HasStdEnc], DecoderNamespace = "Mips64" in {
996 def LL_P8 : LLBase<"ll", GPR32Opnd, mem64>, LW_FM<0x30>;
997 def SC_P8 : SCBase<"sc", GPR32Opnd, mem64>, LW_FM<0x38>;
1000 /// Jump and Branch Instructions
1001 def J : JumpFJ<jmptarget, "j", br, bb>, FJ<2>,
1002 Requires<[RelocStatic, HasStdEnc]>, IsBranch;
1003 def JR : IndirectBranch<GPR32Opnd>, MTLO_FM<8>;
1004 def B : UncondBranch<"b">, B_FM;
1005 def BEQ : CBranch<"beq", seteq, GPR32Opnd>, BEQ_FM<4>;
1006 def BNE : CBranch<"bne", setne, GPR32Opnd>, BEQ_FM<5>;
1007 def BGEZ : CBranchZero<"bgez", setge, GPR32Opnd>, BGEZ_FM<1, 1>;
1008 def BGTZ : CBranchZero<"bgtz", setgt, GPR32Opnd>, BGEZ_FM<7, 0>;
1009 def BLEZ : CBranchZero<"blez", setle, GPR32Opnd>, BGEZ_FM<6, 0>;
1010 def BLTZ : CBranchZero<"bltz", setlt, GPR32Opnd>, BGEZ_FM<1, 0>;
1012 def JAL : JumpLink<"jal">, FJ<3>;
1013 def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM;
1014 def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>;
1015 def BGEZAL : BGEZAL_FT<"bgezal", GPR32Opnd>, BGEZAL_FM<0x11>;
1016 def BLTZAL : BGEZAL_FT<"bltzal", GPR32Opnd>, BGEZAL_FM<0x10>;
1017 def BAL_BR : BAL_BR_Pseudo<BGEZAL>;
1018 def TAILCALL : JumpFJ<calltarget, "j", MipsTailCall, imm>, FJ<2>, IsTailCall;
1019 def TAILCALL_R : JumpFR<GPR32Opnd, MipsTailCall>, MTLO_FM<8>, IsTailCall;
1021 def RET : RetBase<GPR32Opnd>, MTLO_FM<8>;
1023 // Exception handling related node and instructions.
1024 // The conversion sequence is:
1025 // ISD::EH_RETURN -> MipsISD::EH_RETURN ->
1026 // MIPSeh_return -> (stack change + indirect branch)
1028 // MIPSeh_return takes the place of regular return instruction
1029 // but takes two arguments (V1, V0) which are used for storing
1030 // the offset and return address respectively.
1031 def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
1033 def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
1034 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
1036 let Uses = [V0, V1], isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1037 def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
1038 [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
1039 def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff,
1041 [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
1044 /// Multiply and Divide Instructions.
1045 def MULT : MMRel, Mult<"mult", IIImult, GPR32Opnd, [HI0, LO0]>,
1047 def MULTu : MMRel, Mult<"multu", IIImult, GPR32Opnd, [HI0, LO0]>,
1049 def PseudoMULT : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, IIImult>;
1050 def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, IIImult>;
1051 def SDIV : Div<"div", IIIdiv, GPR32Opnd, [HI0, LO0]>, MULT_FM<0, 0x1a>;
1052 def UDIV : Div<"divu", IIIdiv, GPR32Opnd, [HI0, LO0]>, MULT_FM<0, 0x1b>;
1053 def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, IIIdiv,
1055 def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, IIIdiv,
1058 def MTHI : MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>;
1059 def MTLO : MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>;
1060 def MFHI : MoveFromLOHI<"mfhi", GPR32Opnd, [HI0]>, MFLO_FM<0x10>;
1061 def MFLO : MoveFromLOHI<"mflo", GPR32Opnd, [LO0]>, MFLO_FM<0x12>;
1063 /// Sign Ext In Register Instructions.
1064 def SEB : SignExtInReg<"seb", i8, GPR32Opnd>, SEB_FM<0x10, 0x20>;
1065 def SEH : SignExtInReg<"seh", i16, GPR32Opnd>, SEB_FM<0x18, 0x20>;
1068 def CLZ : CountLeading0<"clz", GPR32Opnd>, CLO_FM<0x20>;
1069 def CLO : CountLeading1<"clo", GPR32Opnd>, CLO_FM<0x21>;
1071 /// Word Swap Bytes Within Halfwords
1072 def WSBH : SubwordSwap<"wsbh", GPR32Opnd>, SEB_FM<2, 0x20>;
1075 def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>;
1077 // FrameIndexes are legalized when they are operands from load/store
1078 // instructions. The same not happens for stack address copies, so an
1079 // add op with mem ComplexPattern is used and the stack address copy
1080 // can be matched. It's similar to Sparc LEA_ADDRi
1081 def LEA_ADDiu : EffectiveAddress<"addiu", GPR32Opnd, mem_ea>, LW_FM<9>;
1084 def MADD : MArithR<"madd", 1>, MULT_FM<0x1c, 0>;
1085 def MADDU : MArithR<"maddu", 1>, MULT_FM<0x1c, 1>;
1086 def MSUB : MArithR<"msub">, MULT_FM<0x1c, 4>;
1087 def MSUBU : MArithR<"msubu">, MULT_FM<0x1c, 5>;
1088 def PseudoMADD : MAddSubPseudo<MADD, MipsMAdd>;
1089 def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu>;
1090 def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub>;
1091 def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu>;
1093 def RDHWR : ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM;
1095 def EXT : ExtBase<"ext", GPR32Opnd>, EXT_FM<0>;
1096 def INS : InsBase<"ins", GPR32Opnd>, EXT_FM<4>;
1098 /// Move Control Registers From/To CPU Registers
1099 def MFC0_3OP : MFC3OP<(outs GPR32Opnd:$rt),
1100 (ins GPR32Opnd:$rd, uimm16:$sel),
1101 "mfc0\t$rt, $rd, $sel">, MFC3OP_FM<0x10, 0>;
1103 def MTC0_3OP : MFC3OP<(outs GPR32Opnd:$rd, uimm16:$sel),
1104 (ins GPR32Opnd:$rt),
1105 "mtc0\t$rt, $rd, $sel">, MFC3OP_FM<0x10, 4>;
1107 def MFC2_3OP : MFC3OP<(outs GPR32Opnd:$rt),
1108 (ins GPR32Opnd:$rd, uimm16:$sel),
1109 "mfc2\t$rt, $rd, $sel">, MFC3OP_FM<0x12, 0>;
1111 def MTC2_3OP : MFC3OP<(outs GPR32Opnd:$rd, uimm16:$sel),
1112 (ins GPR32Opnd:$rt),
1113 "mtc2\t$rt, $rd, $sel">, MFC3OP_FM<0x12, 4>;
1115 //===----------------------------------------------------------------------===//
1116 // Instruction aliases
1117 //===----------------------------------------------------------------------===//
1118 def : InstAlias<"move $dst, $src",
1119 (ADDu GPR32Opnd:$dst, GPR32Opnd:$src,ZERO), 1>,
1120 Requires<[NotMips64]>;
1121 def : InstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>;
1122 def : InstAlias<"addu $rs, $rt, $imm",
1123 (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1124 def : InstAlias<"add $rs, $rt, $imm",
1125 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1126 def : InstAlias<"and $rs, $rt, $imm",
1127 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1128 def : InstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>;
1129 def : InstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
1130 def : InstAlias<"jal $rs", (JALR RA, GPR32Opnd:$rs), 0>;
1131 def : InstAlias<"jal $rd,$rs", (JALR GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
1132 def : InstAlias<"not $rt, $rs",
1133 (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>;
1134 def : InstAlias<"neg $rt, $rs",
1135 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
1136 def : InstAlias<"negu $rt, $rs",
1137 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
1138 def : InstAlias<"slt $rs, $rt, $imm",
1139 (SLTi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1140 def : InstAlias<"xor $rs, $rt, $imm",
1141 (XORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
1142 def : InstAlias<"or $rs, $rt, $imm",
1143 (ORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
1144 def : InstAlias<"nop", (SLL ZERO, ZERO, 0), 1>;
1145 def : InstAlias<"mfc0 $rt, $rd",
1146 (MFC0_3OP GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>;
1147 def : InstAlias<"mtc0 $rt, $rd",
1148 (MTC0_3OP GPR32Opnd:$rd, 0, GPR32Opnd:$rt), 0>;
1149 def : InstAlias<"mfc2 $rt, $rd",
1150 (MFC2_3OP GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>;
1151 def : InstAlias<"mtc2 $rt, $rd",
1152 (MTC2_3OP GPR32Opnd:$rd, 0, GPR32Opnd:$rt), 0>;
1153 def : InstAlias<"bnez $rs,$offset",
1154 (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1155 def : InstAlias<"beqz $rs,$offset",
1156 (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1157 def : InstAlias<"syscall", (SYSCALL 0), 1>;
1159 def : InstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>;
1160 def : InstAlias<"break", (BREAK 0, 0), 1>;
1161 def : InstAlias<"ei", (EI ZERO), 1>;
1162 def : InstAlias<"di", (DI ZERO), 1>;
1163 //===----------------------------------------------------------------------===//
1164 // Assembler Pseudo Instructions
1165 //===----------------------------------------------------------------------===//
1167 class LoadImm32< string instr_asm, Operand Od, RegisterOperand RO> :
1168 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
1169 !strconcat(instr_asm, "\t$rt, $imm32")> ;
1170 def LoadImm32Reg : LoadImm32<"li", shamt,GPR32Opnd>;
1172 class LoadAddress<string instr_asm, Operand MemOpnd, RegisterOperand RO> :
1173 MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
1174 !strconcat(instr_asm, "\t$rt, $addr")> ;
1175 def LoadAddr32Reg : LoadAddress<"la", mem, GPR32Opnd>;
1177 class LoadAddressImm<string instr_asm, Operand Od, RegisterOperand RO> :
1178 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
1179 !strconcat(instr_asm, "\t$rt, $imm32")> ;
1180 def LoadAddr32Imm : LoadAddressImm<"la", shamt,GPR32Opnd>;
1184 //===----------------------------------------------------------------------===//
1185 // Arbitrary patterns that map to one or more instructions
1186 //===----------------------------------------------------------------------===//
1188 // Load/store pattern templates.
1189 class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
1190 MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
1192 class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
1193 MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
1196 def : MipsPat<(i32 immSExt16:$in),
1197 (ADDiu ZERO, imm:$in)>;
1198 def : MipsPat<(i32 immZExt16:$in),
1199 (ORi ZERO, imm:$in)>;
1200 def : MipsPat<(i32 immLow16Zero:$in),
1201 (LUi (HI16 imm:$in))>;
1203 // Arbitrary immediates
1204 def : MipsPat<(i32 imm:$imm),
1205 (ORi (LUi (HI16 imm:$imm)), (LO16 imm:$imm))>;
1207 // Carry MipsPatterns
1208 def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
1209 (SUBu GPR32:$lhs, GPR32:$rhs)>;
1210 let Predicates = [HasStdEnc, NotDSP] in {
1211 def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
1212 (ADDu GPR32:$lhs, GPR32:$rhs)>;
1213 def : MipsPat<(addc GPR32:$src, immSExt16:$imm),
1214 (ADDiu GPR32:$src, imm:$imm)>;
1218 def : MipsPat<(MipsJmpLink (i32 tglobaladdr:$dst)),
1219 (JAL tglobaladdr:$dst)>;
1220 def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
1221 (JAL texternalsym:$dst)>;
1222 //def : MipsPat<(MipsJmpLink GPR32:$dst),
1223 // (JALR GPR32:$dst)>;
1226 def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
1227 (TAILCALL tglobaladdr:$dst)>;
1228 def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
1229 (TAILCALL texternalsym:$dst)>;
1231 def : MipsPat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
1232 def : MipsPat<(MipsHi tblockaddress:$in), (LUi tblockaddress:$in)>;
1233 def : MipsPat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>;
1234 def : MipsPat<(MipsHi tconstpool:$in), (LUi tconstpool:$in)>;
1235 def : MipsPat<(MipsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>;
1236 def : MipsPat<(MipsHi texternalsym:$in), (LUi texternalsym:$in)>;
1238 def : MipsPat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
1239 def : MipsPat<(MipsLo tblockaddress:$in), (ADDiu ZERO, tblockaddress:$in)>;
1240 def : MipsPat<(MipsLo tjumptable:$in), (ADDiu ZERO, tjumptable:$in)>;
1241 def : MipsPat<(MipsLo tconstpool:$in), (ADDiu ZERO, tconstpool:$in)>;
1242 def : MipsPat<(MipsLo tglobaltlsaddr:$in), (ADDiu ZERO, tglobaltlsaddr:$in)>;
1243 def : MipsPat<(MipsLo texternalsym:$in), (ADDiu ZERO, texternalsym:$in)>;
1245 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaladdr:$lo)),
1246 (ADDiu GPR32:$hi, tglobaladdr:$lo)>;
1247 def : MipsPat<(add GPR32:$hi, (MipsLo tblockaddress:$lo)),
1248 (ADDiu GPR32:$hi, tblockaddress:$lo)>;
1249 def : MipsPat<(add GPR32:$hi, (MipsLo tjumptable:$lo)),
1250 (ADDiu GPR32:$hi, tjumptable:$lo)>;
1251 def : MipsPat<(add GPR32:$hi, (MipsLo tconstpool:$lo)),
1252 (ADDiu GPR32:$hi, tconstpool:$lo)>;
1253 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaltlsaddr:$lo)),
1254 (ADDiu GPR32:$hi, tglobaltlsaddr:$lo)>;
1257 def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
1258 (ADDiu GPR32:$gp, tglobaladdr:$in)>;
1259 def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
1260 (ADDiu GPR32:$gp, tconstpool:$in)>;
1263 class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
1264 MipsPat<(MipsWrapper RC:$gp, node:$in),
1265 (ADDiuOp RC:$gp, node:$in)>;
1267 def : WrapperPat<tglobaladdr, ADDiu, GPR32>;
1268 def : WrapperPat<tconstpool, ADDiu, GPR32>;
1269 def : WrapperPat<texternalsym, ADDiu, GPR32>;
1270 def : WrapperPat<tblockaddress, ADDiu, GPR32>;
1271 def : WrapperPat<tjumptable, ADDiu, GPR32>;
1272 def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>;
1274 // Mips does not have "not", so we expand our way
1275 def : MipsPat<(not GPR32:$in),
1276 (NOR GPR32Opnd:$in, ZERO)>;
1279 let Predicates = [NotN64, HasStdEnc] in {
1280 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>;
1281 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>;
1282 def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
1284 let Predicates = [IsN64, HasStdEnc] in {
1285 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu_P8 addr:$src)>;
1286 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu_P8 addr:$src)>;
1287 def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu_P8 addr:$src)>;
1291 let Predicates = [NotN64, HasStdEnc] in {
1292 def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>;
1294 let Predicates = [IsN64, HasStdEnc] in {
1295 def : MipsPat<(store (i32 0), addr:$dst), (SW_P8 ZERO, addr:$dst)>;
1299 multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BNEOp,
1300 Instruction SLTOp, Instruction SLTuOp, Instruction SLTiOp,
1301 Instruction SLTiuOp, Register ZEROReg> {
1302 def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
1303 (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
1304 def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
1305 (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
1307 def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
1308 (BEQ (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
1309 def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
1310 (BEQ (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
1311 def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
1312 (BEQ (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
1313 def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
1314 (BEQ (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
1315 def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
1316 (BEQ (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
1317 def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
1318 (BEQ (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
1320 def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
1321 (BEQ (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
1322 def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
1323 (BEQ (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
1325 def : MipsPat<(brcond RC:$cond, bb:$dst),
1326 (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
1329 defm : BrcondPats<GPR32, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>;
1331 def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
1332 (BLEZ i32:$lhs, bb:$dst)>;
1333 def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
1334 (BGEZ i32:$lhs, bb:$dst)>;
1337 multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp,
1338 Instruction SLTuOp, Register ZEROReg> {
1339 def : MipsPat<(seteq RC:$lhs, 0),
1340 (SLTiuOp RC:$lhs, 1)>;
1341 def : MipsPat<(setne RC:$lhs, 0),
1342 (SLTuOp ZEROReg, RC:$lhs)>;
1343 def : MipsPat<(seteq RC:$lhs, RC:$rhs),
1344 (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>;
1345 def : MipsPat<(setne RC:$lhs, RC:$rhs),
1346 (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
1349 multiclass SetlePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1350 def : MipsPat<(setle RC:$lhs, RC:$rhs),
1351 (XORi (SLTOp RC:$rhs, RC:$lhs), 1)>;
1352 def : MipsPat<(setule RC:$lhs, RC:$rhs),
1353 (XORi (SLTuOp RC:$rhs, RC:$lhs), 1)>;
1356 multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1357 def : MipsPat<(setgt RC:$lhs, RC:$rhs),
1358 (SLTOp RC:$rhs, RC:$lhs)>;
1359 def : MipsPat<(setugt RC:$lhs, RC:$rhs),
1360 (SLTuOp RC:$rhs, RC:$lhs)>;
1363 multiclass SetgePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1364 def : MipsPat<(setge RC:$lhs, RC:$rhs),
1365 (XORi (SLTOp RC:$lhs, RC:$rhs), 1)>;
1366 def : MipsPat<(setuge RC:$lhs, RC:$rhs),
1367 (XORi (SLTuOp RC:$lhs, RC:$rhs), 1)>;
1370 multiclass SetgeImmPats<RegisterClass RC, Instruction SLTiOp,
1371 Instruction SLTiuOp> {
1372 def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
1373 (XORi (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
1374 def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
1375 (XORi (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
1378 defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>;
1379 defm : SetlePats<GPR32, SLT, SLTu>;
1380 defm : SetgtPats<GPR32, SLT, SLTu>;
1381 defm : SetgePats<GPR32, SLT, SLTu>;
1382 defm : SetgeImmPats<GPR32, SLTi, SLTiu>;
1385 def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>;
1387 // mflo/hi patterns.
1388 def : MipsPat<(i32 (ExtractLOHI ACC64:$ac, imm:$lohi_idx)),
1389 (EXTRACT_SUBREG ACC64:$ac, imm:$lohi_idx)>;
1391 // Load halfword/word patterns.
1392 let AddedComplexity = 40 in {
1393 let Predicates = [NotN64, HasStdEnc] in {
1394 def : LoadRegImmPat<LBu, i32, zextloadi8>;
1395 def : LoadRegImmPat<LH, i32, sextloadi16>;
1396 def : LoadRegImmPat<LW, i32, load>;
1398 let Predicates = [IsN64, HasStdEnc] in {
1399 def : LoadRegImmPat<LBu_P8, i32, zextloadi8>;
1400 def : LoadRegImmPat<LH_P8, i32, sextloadi16>;
1401 def : LoadRegImmPat<LW_P8, i32, load>;
1405 //===----------------------------------------------------------------------===//
1406 // Floating Point Support
1407 //===----------------------------------------------------------------------===//
1409 include "MipsInstrFPU.td"
1410 include "Mips64InstrInfo.td"
1411 include "MipsCondMov.td"
1416 include "Mips16InstrFormats.td"
1417 include "Mips16InstrInfo.td"
1420 include "MipsDSPInstrFormats.td"
1421 include "MipsDSPInstrInfo.td"
1424 include "MipsMSAInstrFormats.td"
1425 include "MipsMSAInstrInfo.td"
1428 include "MicroMipsInstrFormats.td"
1429 include "MicroMipsInstrInfo.td"