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 HasSEInReg : Predicate<"Subtarget.hasSEInReg()">,
150 AssemblerPredicate<"FeatureSEInReg">;
151 def HasBitCount : Predicate<"Subtarget.hasBitCount()">,
152 AssemblerPredicate<"FeatureBitCount">;
153 def HasSwap : Predicate<"Subtarget.hasSwap()">,
154 AssemblerPredicate<"FeatureSwap">;
155 def HasCondMov : Predicate<"Subtarget.hasCondMov()">,
156 AssemblerPredicate<"FeatureCondMov">;
157 def HasFPIdx : Predicate<"Subtarget.hasFPIdx()">,
158 AssemblerPredicate<"FeatureFPIdx">;
159 def HasMips32 : Predicate<"Subtarget.hasMips32()">,
160 AssemblerPredicate<"FeatureMips32">;
161 def HasMips32r2 : Predicate<"Subtarget.hasMips32r2()">,
162 AssemblerPredicate<"FeatureMips32r2">;
163 def HasMips64 : Predicate<"Subtarget.hasMips64()">,
164 AssemblerPredicate<"FeatureMips64">;
165 def NotMips64 : Predicate<"!Subtarget.hasMips64()">,
166 AssemblerPredicate<"!FeatureMips64">;
167 def HasMips64r2 : Predicate<"Subtarget.hasMips64r2()">,
168 AssemblerPredicate<"FeatureMips64r2">;
169 def IsN64 : Predicate<"Subtarget.isABI_N64()">,
170 AssemblerPredicate<"FeatureN64">;
171 def InMips16Mode : Predicate<"Subtarget.inMips16Mode()">,
172 AssemblerPredicate<"FeatureMips16">;
173 def HasCnMips : Predicate<"Subtarget.hasCnMips()">,
174 AssemblerPredicate<"FeatureCnMips">;
175 def RelocStatic : Predicate<"TM.getRelocationModel() == Reloc::Static">,
176 AssemblerPredicate<"FeatureMips32">;
177 def RelocPIC : Predicate<"TM.getRelocationModel() == Reloc::PIC_">,
178 AssemblerPredicate<"FeatureMips32">;
179 def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">,
180 AssemblerPredicate<"FeatureMips32">;
181 def HasStdEnc : Predicate<"Subtarget.hasStandardEncoding()">,
182 AssemblerPredicate<"!FeatureMips16">;
183 def NotDSP : Predicate<"!Subtarget.hasDSP()">;
184 def InMicroMips : Predicate<"Subtarget.inMicroMipsMode()">,
185 AssemblerPredicate<"FeatureMicroMips">;
186 def NotInMicroMips : Predicate<"!Subtarget.inMicroMipsMode()">,
187 AssemblerPredicate<"!FeatureMicroMips">;
188 def IsLE : Predicate<"Subtarget.isLittle()">;
189 def IsBE : Predicate<"!Subtarget.isLittle()">;
190 def IsNotNaCl : Predicate<"!Subtarget.isTargetNaCl()">;
192 class MipsPat<dag pattern, dag result> : Pat<pattern, result> {
193 let Predicates = [HasStdEnc];
197 bit isCommutable = 1;
214 bit isTerminator = 1;
217 bit hasExtraSrcRegAllocReq = 1;
218 bit isCodeGenOnly = 1;
221 class IsAsCheapAsAMove {
222 bit isAsCheapAsAMove = 1;
225 class NeverHasSideEffects {
226 bit neverHasSideEffects = 1;
229 //===----------------------------------------------------------------------===//
230 // Instruction format superclass
231 //===----------------------------------------------------------------------===//
233 include "MipsInstrFormats.td"
235 //===----------------------------------------------------------------------===//
236 // Mips Operand, Complex Patterns and Transformations Definitions.
237 //===----------------------------------------------------------------------===//
239 def MipsJumpTargetAsmOperand : AsmOperandClass {
240 let Name = "JumpTarget";
241 let ParserMethod = "ParseJumpTarget";
242 let PredicateMethod = "isImm";
243 let RenderMethod = "addImmOperands";
246 // Instruction operand types
247 def jmptarget : Operand<OtherVT> {
248 let EncoderMethod = "getJumpTargetOpValue";
249 let ParserMatchClass = MipsJumpTargetAsmOperand;
251 def brtarget : Operand<OtherVT> {
252 let EncoderMethod = "getBranchTargetOpValue";
253 let OperandType = "OPERAND_PCREL";
254 let DecoderMethod = "DecodeBranchTarget";
255 let ParserMatchClass = MipsJumpTargetAsmOperand;
257 def calltarget : Operand<iPTR> {
258 let EncoderMethod = "getJumpTargetOpValue";
259 let ParserMatchClass = MipsJumpTargetAsmOperand;
262 def simm10 : Operand<i32>;
264 def simm16 : Operand<i32> {
265 let DecoderMethod= "DecodeSimm16";
268 def simm20 : Operand<i32> {
271 def uimm20 : Operand<i32> {
274 def uimm10 : Operand<i32> {
277 def simm16_64 : Operand<i64> {
278 let DecoderMethod = "DecodeSimm16";
282 def uimmz : Operand<i32> {
283 let PrintMethod = "printUnsignedImm";
287 def uimm5 : Operand<i32> {
288 let PrintMethod = "printUnsignedImm";
291 def uimm6 : Operand<i32> {
292 let PrintMethod = "printUnsignedImm";
295 def uimm16 : Operand<i32> {
296 let PrintMethod = "printUnsignedImm";
299 def pcrel16 : Operand<i32> {
302 def MipsMemAsmOperand : AsmOperandClass {
304 let ParserMethod = "parseMemOperand";
307 def MipsInvertedImmoperand : AsmOperandClass {
309 let RenderMethod = "addImmOperands";
310 let ParserMethod = "parseInvNum";
313 def InvertedImOperand : Operand<i32> {
314 let ParserMatchClass = MipsInvertedImmoperand;
317 class mem_generic : Operand<iPTR> {
318 let PrintMethod = "printMemOperand";
319 let MIOperandInfo = (ops ptr_rc, simm16);
320 let EncoderMethod = "getMemEncoding";
321 let ParserMatchClass = MipsMemAsmOperand;
322 let OperandType = "OPERAND_MEMORY";
326 def mem : mem_generic;
328 // MSA specific address operand
329 def mem_msa : mem_generic {
330 let MIOperandInfo = (ops ptr_rc, simm10);
331 let EncoderMethod = "getMSAMemEncoding";
334 def mem_ea : Operand<iPTR> {
335 let PrintMethod = "printMemOperandEA";
336 let MIOperandInfo = (ops ptr_rc, simm16);
337 let EncoderMethod = "getMemEncoding";
338 let OperandType = "OPERAND_MEMORY";
341 def PtrRC : Operand<iPTR> {
342 let MIOperandInfo = (ops ptr_rc);
343 let DecoderMethod = "DecodePtrRegisterClass";
344 let ParserMatchClass = GPR32AsmOperand;
347 // size operand of ext instruction
348 def size_ext : Operand<i32> {
349 let EncoderMethod = "getSizeExtEncoding";
350 let DecoderMethod = "DecodeExtSize";
353 // size operand of ins instruction
354 def size_ins : Operand<i32> {
355 let EncoderMethod = "getSizeInsEncoding";
356 let DecoderMethod = "DecodeInsSize";
359 // Transformation Function - get the lower 16 bits.
360 def LO16 : SDNodeXForm<imm, [{
361 return getImm(N, N->getZExtValue() & 0xFFFF);
364 // Transformation Function - get the higher 16 bits.
365 def HI16 : SDNodeXForm<imm, [{
366 return getImm(N, (N->getZExtValue() >> 16) & 0xFFFF);
370 def Plus1 : SDNodeXForm<imm, [{ return getImm(N, N->getSExtValue() + 1); }]>;
372 // Node immediate is zero (e.g. insve.d)
373 def immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>;
375 // Node immediate fits as 16-bit sign extended on target immediate.
377 def immSExt8 : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;
379 // Node immediate fits as 16-bit sign extended on target immediate.
381 def immSExt16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;
383 // Node immediate fits as 15-bit sign extended on target immediate.
385 def immSExt15 : PatLeaf<(imm), [{ return isInt<15>(N->getSExtValue()); }]>;
387 // Node immediate fits as 16-bit zero extended on target immediate.
388 // The LO16 param means that only the lower 16 bits of the node
389 // immediate are caught.
391 def immZExt16 : PatLeaf<(imm), [{
392 if (N->getValueType(0) == MVT::i32)
393 return (uint32_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
395 return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
398 // Immediate can be loaded with LUi (32-bit int with lower 16-bit cleared).
399 def immLow16Zero : PatLeaf<(imm), [{
400 int64_t Val = N->getSExtValue();
401 return isInt<32>(Val) && !(Val & 0xffff);
404 // shamt field must fit in 5 bits.
405 def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>;
407 // True if (N + 1) fits in 16-bit field.
408 def immSExt16Plus1 : PatLeaf<(imm), [{
409 return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1);
412 // Mips Address Mode! SDNode frameindex could possibily be a match
413 // since load and store instructions from stack used it.
415 ComplexPattern<iPTR, 2, "selectIntAddr", [frameindex]>;
418 ComplexPattern<iPTR, 2, "selectAddrRegImm", [frameindex]>;
421 ComplexPattern<iPTR, 2, "selectAddrRegReg", [frameindex]>;
424 ComplexPattern<iPTR, 2, "selectAddrDefault", [frameindex]>;
426 def addrimm10 : ComplexPattern<iPTR, 2, "selectIntAddrMSA", [frameindex]>;
428 //===----------------------------------------------------------------------===//
429 // Instructions specific format
430 //===----------------------------------------------------------------------===//
432 // Arithmetic and logical instructions with 3 register operands.
433 class ArithLogicR<string opstr, RegisterOperand RO, bit isComm = 0,
434 InstrItinClass Itin = NoItinerary,
435 SDPatternOperator OpNode = null_frag>:
436 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
437 !strconcat(opstr, "\t$rd, $rs, $rt"),
438 [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR, opstr> {
439 let isCommutable = isComm;
440 let isReMaterializable = 1;
441 let TwoOperandAliasConstraint = "$rd = $rs";
444 // Arithmetic and logical instructions with 2 register operands.
445 class ArithLogicI<string opstr, Operand Od, RegisterOperand RO,
446 InstrItinClass Itin = NoItinerary,
447 SDPatternOperator imm_type = null_frag,
448 SDPatternOperator OpNode = null_frag> :
449 InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16),
450 !strconcat(opstr, "\t$rt, $rs, $imm16"),
451 [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))],
453 let isReMaterializable = 1;
454 let TwoOperandAliasConstraint = "$rs = $rt";
457 // Arithmetic Multiply ADD/SUB
458 class MArithR<string opstr, InstrItinClass itin, bit isComm = 0> :
459 InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt),
460 !strconcat(opstr, "\t$rs, $rt"), [], itin, FrmR, opstr> {
461 let Defs = [HI0, LO0];
462 let Uses = [HI0, LO0];
463 let isCommutable = isComm;
467 class LogicNOR<string opstr, RegisterOperand RO>:
468 InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt),
469 !strconcat(opstr, "\t$rd, $rs, $rt"),
470 [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], II_NOR, FrmR, opstr> {
471 let isCommutable = 1;
475 class shift_rotate_imm<string opstr, Operand ImmOpnd,
476 RegisterOperand RO, InstrItinClass itin,
477 SDPatternOperator OpNode = null_frag,
478 SDPatternOperator PF = null_frag> :
479 InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt),
480 !strconcat(opstr, "\t$rd, $rt, $shamt"),
481 [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], itin, FrmR, opstr>;
483 class shift_rotate_reg<string opstr, RegisterOperand RO, InstrItinClass itin,
484 SDPatternOperator OpNode = null_frag>:
485 InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs),
486 !strconcat(opstr, "\t$rd, $rt, $rs"),
487 [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], itin, FrmR,
490 // Load Upper Imediate
491 class LoadUpper<string opstr, RegisterOperand RO, Operand Imm>:
492 InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"),
493 [], II_LUI, FrmI, opstr>, IsAsCheapAsAMove {
494 let neverHasSideEffects = 1;
495 let isReMaterializable = 1;
499 class Load<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
500 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
501 InstSE<(outs RO:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
502 [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> {
503 let DecoderMethod = "DecodeMem";
504 let canFoldAsLoad = 1;
508 class Store<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
509 InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
510 InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
511 [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> {
512 let DecoderMethod = "DecodeMem";
516 // Load/Store Left/Right
517 let canFoldAsLoad = 1 in
518 class LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
519 InstrItinClass Itin> :
520 InstSE<(outs RO:$rt), (ins mem:$addr, RO:$src),
521 !strconcat(opstr, "\t$rt, $addr"),
522 [(set RO:$rt, (OpNode addr:$addr, RO:$src))], Itin, FrmI> {
523 let DecoderMethod = "DecodeMem";
524 string Constraints = "$src = $rt";
527 class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
528 InstrItinClass Itin> :
529 InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
530 [(OpNode RO:$rt, addr:$addr)], Itin, FrmI> {
531 let DecoderMethod = "DecodeMem";
534 // Conditional Branch
535 class CBranch<string opstr, DAGOperand opnd, PatFrag cond_op,
536 RegisterOperand RO> :
537 InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset),
538 !strconcat(opstr, "\t$rs, $rt, $offset"),
539 [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], IIBranch,
542 let isTerminator = 1;
543 let hasDelaySlot = 1;
547 class CBranchZero<string opstr, DAGOperand opnd, PatFrag cond_op,
548 RegisterOperand RO> :
549 InstSE<(outs), (ins RO:$rs, opnd:$offset),
550 !strconcat(opstr, "\t$rs, $offset"),
551 [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], IIBranch,
554 let isTerminator = 1;
555 let hasDelaySlot = 1;
560 class SetCC_R<string opstr, PatFrag cond_op, RegisterOperand RO> :
561 InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt),
562 !strconcat(opstr, "\t$rd, $rs, $rt"),
563 [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))],
564 II_SLT_SLTU, FrmR, opstr>;
566 class SetCC_I<string opstr, PatFrag cond_op, Operand Od, PatLeaf imm_type,
568 InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16),
569 !strconcat(opstr, "\t$rt, $rs, $imm16"),
570 [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))],
571 II_SLTI_SLTIU, FrmI, opstr>;
574 class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator,
575 SDPatternOperator targetoperator, string bopstr> :
576 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
577 [(operator targetoperator:$target)], IIBranch, FrmJ, bopstr> {
580 let hasDelaySlot = 1;
581 let DecoderMethod = "DecodeJumpTarget";
585 // Unconditional branch
586 class UncondBranch<Instruction BEQInst> :
587 PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], IIBranch>,
588 PseudoInstExpansion<(BEQInst ZERO, ZERO, brtarget:$offset)> {
590 let isTerminator = 1;
592 let hasDelaySlot = 1;
593 let Predicates = [RelocPIC, HasStdEnc];
597 // Base class for indirect branch and return instruction classes.
598 let isTerminator=1, isBarrier=1, hasDelaySlot = 1 in
599 class JumpFR<string opstr, RegisterOperand RO,
600 SDPatternOperator operator = null_frag>:
601 InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], IIBranch,
605 class IndirectBranch<string opstr, RegisterOperand RO> :
606 JumpFR<opstr, RO, brind> {
608 let isIndirectBranch = 1;
611 // Return instruction
612 class RetBase<string opstr, RegisterOperand RO>: JumpFR<opstr, RO> {
614 let isCodeGenOnly = 1;
616 let hasExtraSrcRegAllocReq = 1;
619 // Jump and Link (Call)
620 let isCall=1, hasDelaySlot=1, Defs = [RA] in {
621 class JumpLink<string opstr, DAGOperand opnd> :
622 InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"),
623 [(MipsJmpLink imm:$target)], IIBranch, FrmJ, opstr> {
624 let DecoderMethod = "DecodeJumpTarget";
627 class JumpLinkRegPseudo<RegisterOperand RO, Instruction JALRInst,
628 Register RetReg, RegisterOperand ResRO = RO>:
629 PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], IIBranch>,
630 PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)>;
632 class JumpLinkReg<string opstr, RegisterOperand RO>:
633 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
636 class BGEZAL_FT<string opstr, DAGOperand opnd, RegisterOperand RO> :
637 InstSE<(outs), (ins RO:$rs, opnd:$offset),
638 !strconcat(opstr, "\t$rs, $offset"), [], IIBranch, FrmI, opstr>;
642 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
643 hasExtraSrcRegAllocReq = 1, Defs = [AT] in {
644 class TailCall<Instruction JumpInst> :
645 PseudoSE<(outs), (ins calltarget:$target), [], IIBranch>,
646 PseudoInstExpansion<(JumpInst jmptarget:$target)>;
648 class TailCallReg<RegisterOperand RO, Instruction JRInst,
649 RegisterOperand ResRO = RO> :
650 PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], IIBranch>,
651 PseudoInstExpansion<(JRInst ResRO:$rs)>;
654 class BAL_BR_Pseudo<Instruction RealInst> :
655 PseudoSE<(outs), (ins brtarget:$offset), [], IIBranch>,
656 PseudoInstExpansion<(RealInst ZERO, brtarget:$offset)> {
658 let isTerminator = 1;
660 let hasDelaySlot = 1;
665 class SYS_FT<string opstr> :
666 InstSE<(outs), (ins uimm20:$code_),
667 !strconcat(opstr, "\t$code_"), [], NoItinerary, FrmI, opstr>;
669 class BRK_FT<string opstr> :
670 InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
671 !strconcat(opstr, "\t$code_1, $code_2"), [], NoItinerary,
675 class ER_FT<string opstr> :
676 InstSE<(outs), (ins),
677 opstr, [], NoItinerary, FrmOther, opstr>;
680 class DEI_FT<string opstr, RegisterOperand RO> :
681 InstSE<(outs RO:$rt), (ins),
682 !strconcat(opstr, "\t$rt"), [], NoItinerary, FrmOther, opstr>;
685 class WAIT_FT<string opstr> :
686 InstSE<(outs), (ins), opstr, [], NoItinerary, FrmOther, opstr>;
689 let hasSideEffects = 1 in
690 class SYNC_FT<string opstr> :
691 InstSE<(outs), (ins i32imm:$stype), "sync $stype", [(MipsSync imm:$stype)],
692 NoItinerary, FrmOther, opstr>;
694 let hasSideEffects = 1 in
695 class TEQ_FT<string opstr, RegisterOperand RO> :
696 InstSE<(outs), (ins RO:$rs, RO:$rt, uimm16:$code_),
697 !strconcat(opstr, "\t$rs, $rt, $code_"), [], NoItinerary,
700 class TEQI_FT<string opstr, RegisterOperand RO> :
701 InstSE<(outs), (ins RO:$rs, uimm16:$imm16),
702 !strconcat(opstr, "\t$rs, $imm16"), [], NoItinerary, FrmOther, opstr>;
704 class Mult<string opstr, InstrItinClass itin, RegisterOperand RO,
705 list<Register> DefRegs> :
706 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rs, $rt"), [],
708 let isCommutable = 1;
710 let neverHasSideEffects = 1;
713 // Pseudo multiply/divide instruction with explicit accumulator register
715 class MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1,
716 SDPatternOperator OpNode, InstrItinClass Itin,
717 bit IsComm = 1, bit HasSideEffects = 0,
718 bit UsesCustomInserter = 0> :
719 PseudoSE<(outs R0:$ac), (ins R1:$rs, R1:$rt),
720 [(set R0:$ac, (OpNode R1:$rs, R1:$rt))], Itin>,
721 PseudoInstExpansion<(RealInst R1:$rs, R1:$rt)> {
722 let isCommutable = IsComm;
723 let hasSideEffects = HasSideEffects;
724 let usesCustomInserter = UsesCustomInserter;
727 // Pseudo multiply add/sub instruction with explicit accumulator register
729 class MAddSubPseudo<Instruction RealInst, SDPatternOperator OpNode,
731 : PseudoSE<(outs ACC64:$ac),
732 (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin),
734 (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))],
736 PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> {
737 string Constraints = "$acin = $ac";
740 class Div<string opstr, InstrItinClass itin, RegisterOperand RO,
741 list<Register> DefRegs> :
742 InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$$zero, $rs, $rt"),
743 [], itin, FrmR, opstr> {
748 class PseudoMFLOHI<RegisterClass DstRC, RegisterClass SrcRC, SDNode OpNode>
749 : PseudoSE<(outs DstRC:$rd), (ins SrcRC:$hilo),
750 [(set DstRC:$rd, (OpNode SrcRC:$hilo))], II_MFHI_MFLO>;
752 class MoveFromLOHI<string opstr, RegisterOperand RO, Register UseReg>:
753 InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO,
756 let neverHasSideEffects = 1;
759 class PseudoMTLOHI<RegisterClass DstRC, RegisterClass SrcRC>
760 : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi),
761 [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))],
764 class MoveToLOHI<string opstr, RegisterOperand RO, list<Register> DefRegs>:
765 InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO,
768 let neverHasSideEffects = 1;
771 class EffectiveAddress<string opstr, RegisterOperand RO> :
772 InstSE<(outs RO:$rt), (ins mem_ea:$addr), !strconcat(opstr, "\t$rt, $addr"),
773 [(set RO:$rt, addr:$addr)], NoItinerary, FrmI,
774 !strconcat(opstr, "_lea")> {
775 let isCodeGenOnly = 1;
776 let DecoderMethod = "DecodeMem";
779 // Count Leading Ones/Zeros in Word
780 class CountLeading0<string opstr, RegisterOperand RO>:
781 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
782 [(set RO:$rd, (ctlz RO:$rs))], II_CLZ, FrmR, opstr>,
783 Requires<[HasBitCount, HasStdEnc]>;
785 class CountLeading1<string opstr, RegisterOperand RO>:
786 InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
787 [(set RO:$rd, (ctlz (not RO:$rs)))], II_CLO, FrmR, opstr>,
788 Requires<[HasBitCount, HasStdEnc]>;
790 // Sign Extend in Register.
791 class SignExtInReg<string opstr, ValueType vt, RegisterOperand RO,
792 InstrItinClass itin> :
793 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"),
794 [(set RO:$rd, (sext_inreg RO:$rt, vt))], itin, FrmR, opstr> {
795 let Predicates = [HasSEInReg, HasStdEnc];
799 class SubwordSwap<string opstr, RegisterOperand RO>:
800 InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [],
801 NoItinerary, FrmR, opstr> {
802 let Predicates = [HasSwap, HasStdEnc];
803 let neverHasSideEffects = 1;
807 class ReadHardware<RegisterOperand CPURegOperand, RegisterOperand RO> :
808 InstSE<(outs CPURegOperand:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [],
812 class ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd,
813 SDPatternOperator Op = null_frag>:
814 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, size_ext:$size),
815 !strconcat(opstr, " $rt, $rs, $pos, $size"),
816 [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size))], NoItinerary,
818 let Predicates = [HasMips32r2, HasStdEnc];
821 class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd,
822 SDPatternOperator Op = null_frag>:
823 InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, size_ins:$size, RO:$src),
824 !strconcat(opstr, " $rt, $rs, $pos, $size"),
825 [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size, RO:$src))],
826 NoItinerary, FrmR, opstr> {
827 let Predicates = [HasMips32r2, HasStdEnc];
828 let Constraints = "$src = $rt";
831 // Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*).
832 class Atomic2Ops<PatFrag Op, RegisterClass DRC> :
833 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr),
834 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]>;
836 // Atomic Compare & Swap.
837 class AtomicCmpSwap<PatFrag Op, RegisterClass DRC> :
838 PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap),
839 [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]>;
841 class LLBase<string opstr, RegisterOperand RO> :
842 InstSE<(outs RO:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
843 [], NoItinerary, FrmI> {
844 let DecoderMethod = "DecodeMem";
848 class SCBase<string opstr, RegisterOperand RO> :
849 InstSE<(outs RO:$dst), (ins RO:$rt, mem:$addr),
850 !strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> {
851 let DecoderMethod = "DecodeMem";
853 let Constraints = "$rt = $dst";
856 class MFC3OP<string asmstr, RegisterOperand RO> :
857 InstSE<(outs RO:$rt, RO:$rd, uimm16:$sel), (ins),
858 !strconcat(asmstr, "\t$rt, $rd, $sel"), [], NoItinerary, FrmFR>;
860 class TrapBase<Instruction RealInst>
861 : PseudoSE<(outs), (ins), [(trap)], NoItinerary>,
862 PseudoInstExpansion<(RealInst 0, 0)> {
864 let isTerminator = 1;
865 let isCodeGenOnly = 1;
868 //===----------------------------------------------------------------------===//
869 // Pseudo instructions
870 //===----------------------------------------------------------------------===//
873 let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1 in
874 def RetRA : PseudoSE<(outs), (ins), [(MipsRet)]>;
876 let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
877 def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins i32imm:$amt),
878 [(callseq_start timm:$amt)]>;
879 def ADJCALLSTACKUP : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
880 [(callseq_end timm:$amt1, timm:$amt2)]>;
883 let usesCustomInserter = 1 in {
884 def ATOMIC_LOAD_ADD_I8 : Atomic2Ops<atomic_load_add_8, GPR32>;
885 def ATOMIC_LOAD_ADD_I16 : Atomic2Ops<atomic_load_add_16, GPR32>;
886 def ATOMIC_LOAD_ADD_I32 : Atomic2Ops<atomic_load_add_32, GPR32>;
887 def ATOMIC_LOAD_SUB_I8 : Atomic2Ops<atomic_load_sub_8, GPR32>;
888 def ATOMIC_LOAD_SUB_I16 : Atomic2Ops<atomic_load_sub_16, GPR32>;
889 def ATOMIC_LOAD_SUB_I32 : Atomic2Ops<atomic_load_sub_32, GPR32>;
890 def ATOMIC_LOAD_AND_I8 : Atomic2Ops<atomic_load_and_8, GPR32>;
891 def ATOMIC_LOAD_AND_I16 : Atomic2Ops<atomic_load_and_16, GPR32>;
892 def ATOMIC_LOAD_AND_I32 : Atomic2Ops<atomic_load_and_32, GPR32>;
893 def ATOMIC_LOAD_OR_I8 : Atomic2Ops<atomic_load_or_8, GPR32>;
894 def ATOMIC_LOAD_OR_I16 : Atomic2Ops<atomic_load_or_16, GPR32>;
895 def ATOMIC_LOAD_OR_I32 : Atomic2Ops<atomic_load_or_32, GPR32>;
896 def ATOMIC_LOAD_XOR_I8 : Atomic2Ops<atomic_load_xor_8, GPR32>;
897 def ATOMIC_LOAD_XOR_I16 : Atomic2Ops<atomic_load_xor_16, GPR32>;
898 def ATOMIC_LOAD_XOR_I32 : Atomic2Ops<atomic_load_xor_32, GPR32>;
899 def ATOMIC_LOAD_NAND_I8 : Atomic2Ops<atomic_load_nand_8, GPR32>;
900 def ATOMIC_LOAD_NAND_I16 : Atomic2Ops<atomic_load_nand_16, GPR32>;
901 def ATOMIC_LOAD_NAND_I32 : Atomic2Ops<atomic_load_nand_32, GPR32>;
903 def ATOMIC_SWAP_I8 : Atomic2Ops<atomic_swap_8, GPR32>;
904 def ATOMIC_SWAP_I16 : Atomic2Ops<atomic_swap_16, GPR32>;
905 def ATOMIC_SWAP_I32 : Atomic2Ops<atomic_swap_32, GPR32>;
907 def ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap<atomic_cmp_swap_8, GPR32>;
908 def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap<atomic_cmp_swap_16, GPR32>;
909 def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap<atomic_cmp_swap_32, GPR32>;
912 /// Pseudo instructions for loading and storing accumulator registers.
913 let isPseudo = 1, isCodeGenOnly = 1 in {
914 def LOAD_ACC64 : Load<"", ACC64>;
915 def STORE_ACC64 : Store<"", ACC64>;
918 //===----------------------------------------------------------------------===//
919 // Instruction definition
920 //===----------------------------------------------------------------------===//
921 //===----------------------------------------------------------------------===//
922 // MipsI Instructions
923 //===----------------------------------------------------------------------===//
925 /// Arithmetic Instructions (ALU Immediate)
926 def ADDiu : MMRel, ArithLogicI<"addiu", simm16, GPR32Opnd, II_ADDIU, immSExt16,
928 ADDI_FM<0x9>, IsAsCheapAsAMove;
929 def ADDi : MMRel, ArithLogicI<"addi", simm16, GPR32Opnd>, ADDI_FM<0x8>;
930 def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>,
932 def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>,
934 def ANDi : MMRel, ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16,
937 def ORi : MMRel, ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16,
940 def XORi : MMRel, ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16,
943 def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16>, LUI_FM;
945 /// Arithmetic Instructions (3-Operand, R-Type)
946 def ADDu : MMRel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>,
948 def SUBu : MMRel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>,
950 let Defs = [HI0, LO0] in
951 def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>,
953 def ADD : MMRel, ArithLogicR<"add", GPR32Opnd>, ADD_FM<0, 0x20>;
954 def SUB : MMRel, ArithLogicR<"sub", GPR32Opnd>, ADD_FM<0, 0x22>;
955 def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>;
956 def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>;
957 def AND : MMRel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>,
959 def OR : MMRel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>,
961 def XOR : MMRel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>,
963 def NOR : MMRel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>;
965 /// Shift Instructions
966 def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl,
967 immZExt5>, SRA_FM<0, 0>;
968 def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl,
969 immZExt5>, SRA_FM<2, 0>;
970 def SRA : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, sra,
971 immZExt5>, SRA_FM<3, 0>;
972 def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, shl>,
974 def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, srl>,
976 def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, sra>,
979 // Rotate Instructions
980 let Predicates = [HasMips32r2, HasStdEnc] in {
981 def ROTR : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr,
982 immZExt5>, SRA_FM<2, 1>;
983 def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>,
987 /// Load and Store Instructions
989 def LB : Load<"lb", GPR32Opnd, sextloadi8, II_LB>, MMRel, LW_FM<0x20>;
990 def LBu : Load<"lbu", GPR32Opnd, zextloadi8, II_LBU, addrDefault>, MMRel,
992 def LH : Load<"lh", GPR32Opnd, sextloadi16, II_LH, addrDefault>, MMRel,
994 def LHu : Load<"lhu", GPR32Opnd, zextloadi16, II_LHU>, MMRel, LW_FM<0x25>;
995 def LW : Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel,
997 def SB : Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel, LW_FM<0x28>;
998 def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>;
999 def SW : Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>;
1001 /// load/store left/right
1002 let Predicates = [NotInMicroMips] in {
1003 def LWL : LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>;
1004 def LWR : LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>;
1005 def SWL : StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>;
1006 def SWR : StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>;
1009 def SYNC : MMRel, SYNC_FT<"sync">, SYNC_FM;
1010 def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM<0x34>;
1011 def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM<0x30>;
1012 def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd>, TEQ_FM<0x31>;
1013 def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd>, TEQ_FM<0x32>;
1014 def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd>, TEQ_FM<0x33>;
1015 def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd>, TEQ_FM<0x36>;
1017 def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd>, TEQI_FM<0xc>;
1018 def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd>, TEQI_FM<0x8>;
1019 def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd>, TEQI_FM<0x9>;
1020 def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd>, TEQI_FM<0xa>;
1021 def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd>, TEQI_FM<0xb>;
1022 def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd>, TEQI_FM<0xe>;
1024 def BREAK : MMRel, BRK_FT<"break">, BRK_FM<0xd>;
1025 def SYSCALL : MMRel, SYS_FT<"syscall">, SYS_FM<0xc>;
1026 def TRAP : TrapBase<BREAK>;
1028 def ERET : MMRel, ER_FT<"eret">, ER_FM<0x18>;
1029 def DERET : MMRel, ER_FT<"deret">, ER_FM<0x1f>;
1031 def EI : MMRel, DEI_FT<"ei", GPR32Opnd>, EI_FM<1>;
1032 def DI : MMRel, DEI_FT<"di", GPR32Opnd>, EI_FM<0>;
1034 let Predicates = [NotInMicroMips] in {
1035 def WAIT : WAIT_FT<"wait">, WAIT_FM;
1037 /// Load-linked, Store-conditional
1038 def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>;
1039 def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>;
1042 /// Jump and Branch Instructions
1043 def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>,
1044 Requires<[RelocStatic, HasStdEnc]>, IsBranch;
1045 def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>;
1046 def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>;
1047 def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>;
1048 def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>,
1050 def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>,
1052 def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>,
1054 def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>,
1056 def B : UncondBranch<BEQ>;
1058 def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>;
1059 let Predicates = [NotInMicroMips, HasStdEnc] in {
1060 def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM;
1061 def JALRPseudo : JumpLinkRegPseudo<GPR32Opnd, JALR, RA>;
1063 def JALX : JumpLink<"jalx", calltarget>, FJ<0x1D>;
1064 def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>;
1065 def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>;
1066 def BAL_BR : BAL_BR_Pseudo<BGEZAL>;
1067 def TAILCALL : TailCall<J>;
1068 def TAILCALL_R : TailCallReg<GPR32Opnd, JR>;
1070 def RET : MMRel, RetBase<"ret", GPR32Opnd>, MTLO_FM<8>;
1072 // Exception handling related node and instructions.
1073 // The conversion sequence is:
1074 // ISD::EH_RETURN -> MipsISD::EH_RETURN ->
1075 // MIPSeh_return -> (stack change + indirect branch)
1077 // MIPSeh_return takes the place of regular return instruction
1078 // but takes two arguments (V1, V0) which are used for storing
1079 // the offset and return address respectively.
1080 def SDT_MipsEHRET : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
1082 def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET,
1083 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
1085 let Uses = [V0, V1], isTerminator = 1, isReturn = 1, isBarrier = 1 in {
1086 def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst),
1087 [(MIPSehret GPR32:$spoff, GPR32:$dst)]>;
1088 def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff,
1090 [(MIPSehret GPR64:$spoff, GPR64:$dst)]>;
1093 /// Multiply and Divide Instructions.
1094 def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>,
1096 def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>,
1098 def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>,
1100 def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>,
1103 def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>;
1104 def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>;
1105 def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>;
1106 def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>;
1108 /// Sign Ext In Register Instructions.
1109 def SEB : MMRel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>, SEB_FM<0x10, 0x20>;
1110 def SEH : MMRel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>, SEB_FM<0x18, 0x20>;
1113 def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd>, CLO_FM<0x20>;
1114 def CLO : MMRel, CountLeading1<"clo", GPR32Opnd>, CLO_FM<0x21>;
1116 /// Word Swap Bytes Within Halfwords
1117 def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd>, SEB_FM<2, 0x20>;
1120 def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>;
1122 // FrameIndexes are legalized when they are operands from load/store
1123 // instructions. The same not happens for stack address copies, so an
1124 // add op with mem ComplexPattern is used and the stack address copy
1125 // can be matched. It's similar to Sparc LEA_ADDRi
1126 def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>;
1129 def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>;
1130 def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>;
1131 def MSUB : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>;
1132 def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>;
1134 let Predicates = [HasStdEnc, NotDSP] in {
1135 def PseudoMULT : MultDivPseudo<MULT, ACC64, GPR32Opnd, MipsMult, II_MULT>;
1136 def PseudoMULTu : MultDivPseudo<MULTu, ACC64, GPR32Opnd, MipsMultu, II_MULTU>;
1137 def PseudoMFHI : PseudoMFLOHI<GPR32, ACC64, MipsMFHI>;
1138 def PseudoMFLO : PseudoMFLOHI<GPR32, ACC64, MipsMFLO>;
1139 def PseudoMTLOHI : PseudoMTLOHI<ACC64, GPR32>;
1140 def PseudoMADD : MAddSubPseudo<MADD, MipsMAdd, II_MADD>;
1141 def PseudoMADDU : MAddSubPseudo<MADDU, MipsMAddu, II_MADDU>;
1142 def PseudoMSUB : MAddSubPseudo<MSUB, MipsMSub, II_MSUB>;
1143 def PseudoMSUBU : MAddSubPseudo<MSUBU, MipsMSubu, II_MSUBU>;
1146 def PseudoSDIV : MultDivPseudo<SDIV, ACC64, GPR32Opnd, MipsDivRem, II_DIV,
1148 def PseudoUDIV : MultDivPseudo<UDIV, ACC64, GPR32Opnd, MipsDivRemU, II_DIVU,
1151 def RDHWR : ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM;
1153 def EXT : MMRel, ExtBase<"ext", GPR32Opnd, uimm5, MipsExt>, EXT_FM<0>;
1154 def INS : MMRel, InsBase<"ins", GPR32Opnd, uimm5, MipsIns>, EXT_FM<4>;
1156 /// Move Control Registers From/To CPU Registers
1157 def MFC0 : MFC3OP<"mfc0", GPR32Opnd>, MFC3OP_FM<0x10, 0>;
1158 def MTC0 : MFC3OP<"mtc0", GPR32Opnd>, MFC3OP_FM<0x10, 4>;
1159 def MFC2 : MFC3OP<"mfc2", GPR32Opnd>, MFC3OP_FM<0x12, 0>;
1160 def MTC2 : MFC3OP<"mtc2", GPR32Opnd>, MFC3OP_FM<0x12, 4>;
1162 //===----------------------------------------------------------------------===//
1163 // Instruction aliases
1164 //===----------------------------------------------------------------------===//
1165 def : InstAlias<"move $dst, $src",
1166 (ADDu GPR32Opnd:$dst, GPR32Opnd:$src,ZERO), 1>,
1167 Requires<[NotMips64, NotInMicroMips]>;
1168 def : InstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>;
1169 def : InstAlias<"addu $rs, $rt, $imm",
1170 (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1171 def : InstAlias<"add $rs, $rt, $imm",
1172 (ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1173 def : InstAlias<"and $rs, $rt, $imm",
1174 (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1175 def : InstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>;
1176 let Predicates = [NotInMicroMips] in {
1177 def : InstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
1179 def : InstAlias<"jal $rs", (JALR RA, GPR32Opnd:$rs), 0>;
1180 def : InstAlias<"jal $rd,$rs", (JALR GPR32Opnd:$rd, GPR32Opnd:$rs), 0>;
1181 def : InstAlias<"not $rt, $rs",
1182 (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>;
1183 def : InstAlias<"neg $rt, $rs",
1184 (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
1185 def : InstAlias<"negu $rt, $rs",
1186 (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
1187 def : InstAlias<"slt $rs, $rt, $imm",
1188 (SLTi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>;
1189 def : InstAlias<"xor $rs, $rt, $imm",
1190 (XORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
1191 def : InstAlias<"or $rs, $rt, $imm",
1192 (ORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>;
1193 def : InstAlias<"nop", (SLL ZERO, ZERO, 0), 1>;
1194 def : InstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>;
1195 def : InstAlias<"mtc0 $rt, $rd", (MTC0 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>;
1196 def : InstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>;
1197 def : InstAlias<"mtc2 $rt, $rd", (MTC2 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>;
1198 def : InstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>;
1199 def : InstAlias<"bnez $rs,$offset",
1200 (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1201 def : InstAlias<"beqz $rs,$offset",
1202 (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>;
1203 def : InstAlias<"syscall", (SYSCALL 0), 1>;
1205 def : InstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>;
1206 def : InstAlias<"break", (BREAK 0, 0), 1>;
1207 def : InstAlias<"ei", (EI ZERO), 1>;
1208 def : InstAlias<"di", (DI ZERO), 1>;
1210 def : InstAlias<"teq $rs, $rt", (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>;
1211 def : InstAlias<"tge $rs, $rt", (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>;
1212 def : InstAlias<"tgeu $rs, $rt", (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>;
1213 def : InstAlias<"tlt $rs, $rt", (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>;
1214 def : InstAlias<"tltu $rs, $rt", (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>;
1215 def : InstAlias<"tne $rs, $rt", (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>;
1216 def : InstAlias<"sub, $rd, $rs, $imm",
1217 (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs, InvertedImOperand:$imm)>;
1218 def : InstAlias<"subu, $rd, $rs, $imm",
1219 (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs, InvertedImOperand:$imm)>;
1221 //===----------------------------------------------------------------------===//
1222 // Assembler Pseudo Instructions
1223 //===----------------------------------------------------------------------===//
1225 class LoadImm32< string instr_asm, Operand Od, RegisterOperand RO> :
1226 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
1227 !strconcat(instr_asm, "\t$rt, $imm32")> ;
1228 def LoadImm32Reg : LoadImm32<"li", uimm5, GPR32Opnd>;
1230 class LoadAddress<string instr_asm, Operand MemOpnd, RegisterOperand RO> :
1231 MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr),
1232 !strconcat(instr_asm, "\t$rt, $addr")> ;
1233 def LoadAddr32Reg : LoadAddress<"la", mem, GPR32Opnd>;
1235 class LoadAddressImm<string instr_asm, Operand Od, RegisterOperand RO> :
1236 MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
1237 !strconcat(instr_asm, "\t$rt, $imm32")> ;
1238 def LoadAddr32Imm : LoadAddressImm<"la", uimm5, GPR32Opnd>;
1240 //===----------------------------------------------------------------------===//
1241 // Arbitrary patterns that map to one or more instructions
1242 //===----------------------------------------------------------------------===//
1244 // Load/store pattern templates.
1245 class LoadRegImmPat<Instruction LoadInst, ValueType ValTy, PatFrag Node> :
1246 MipsPat<(ValTy (Node addrRegImm:$a)), (LoadInst addrRegImm:$a)>;
1248 class StoreRegImmPat<Instruction StoreInst, ValueType ValTy> :
1249 MipsPat<(store ValTy:$v, addrRegImm:$a), (StoreInst ValTy:$v, addrRegImm:$a)>;
1252 def : MipsPat<(i32 immSExt16:$in),
1253 (ADDiu ZERO, imm:$in)>;
1254 def : MipsPat<(i32 immZExt16:$in),
1255 (ORi ZERO, imm:$in)>;
1256 def : MipsPat<(i32 immLow16Zero:$in),
1257 (LUi (HI16 imm:$in))>;
1259 // Arbitrary immediates
1260 def : MipsPat<(i32 imm:$imm),
1261 (ORi (LUi (HI16 imm:$imm)), (LO16 imm:$imm))>;
1263 // Carry MipsPatterns
1264 def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
1265 (SUBu GPR32:$lhs, GPR32:$rhs)>;
1266 let Predicates = [HasStdEnc, NotDSP] in {
1267 def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs),
1268 (ADDu GPR32:$lhs, GPR32:$rhs)>;
1269 def : MipsPat<(addc GPR32:$src, immSExt16:$imm),
1270 (ADDiu GPR32:$src, imm:$imm)>;
1274 def : MipsPat<(MipsJmpLink (i32 tglobaladdr:$dst)),
1275 (JAL tglobaladdr:$dst)>;
1276 def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)),
1277 (JAL texternalsym:$dst)>;
1278 //def : MipsPat<(MipsJmpLink GPR32:$dst),
1279 // (JALR GPR32:$dst)>;
1282 def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
1283 (TAILCALL tglobaladdr:$dst)>;
1284 def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
1285 (TAILCALL texternalsym:$dst)>;
1287 def : MipsPat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
1288 def : MipsPat<(MipsHi tblockaddress:$in), (LUi tblockaddress:$in)>;
1289 def : MipsPat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>;
1290 def : MipsPat<(MipsHi tconstpool:$in), (LUi tconstpool:$in)>;
1291 def : MipsPat<(MipsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>;
1292 def : MipsPat<(MipsHi texternalsym:$in), (LUi texternalsym:$in)>;
1294 def : MipsPat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
1295 def : MipsPat<(MipsLo tblockaddress:$in), (ADDiu ZERO, tblockaddress:$in)>;
1296 def : MipsPat<(MipsLo tjumptable:$in), (ADDiu ZERO, tjumptable:$in)>;
1297 def : MipsPat<(MipsLo tconstpool:$in), (ADDiu ZERO, tconstpool:$in)>;
1298 def : MipsPat<(MipsLo tglobaltlsaddr:$in), (ADDiu ZERO, tglobaltlsaddr:$in)>;
1299 def : MipsPat<(MipsLo texternalsym:$in), (ADDiu ZERO, texternalsym:$in)>;
1301 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaladdr:$lo)),
1302 (ADDiu GPR32:$hi, tglobaladdr:$lo)>;
1303 def : MipsPat<(add GPR32:$hi, (MipsLo tblockaddress:$lo)),
1304 (ADDiu GPR32:$hi, tblockaddress:$lo)>;
1305 def : MipsPat<(add GPR32:$hi, (MipsLo tjumptable:$lo)),
1306 (ADDiu GPR32:$hi, tjumptable:$lo)>;
1307 def : MipsPat<(add GPR32:$hi, (MipsLo tconstpool:$lo)),
1308 (ADDiu GPR32:$hi, tconstpool:$lo)>;
1309 def : MipsPat<(add GPR32:$hi, (MipsLo tglobaltlsaddr:$lo)),
1310 (ADDiu GPR32:$hi, tglobaltlsaddr:$lo)>;
1313 def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
1314 (ADDiu GPR32:$gp, tglobaladdr:$in)>;
1315 def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
1316 (ADDiu GPR32:$gp, tconstpool:$in)>;
1319 class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
1320 MipsPat<(MipsWrapper RC:$gp, node:$in),
1321 (ADDiuOp RC:$gp, node:$in)>;
1323 def : WrapperPat<tglobaladdr, ADDiu, GPR32>;
1324 def : WrapperPat<tconstpool, ADDiu, GPR32>;
1325 def : WrapperPat<texternalsym, ADDiu, GPR32>;
1326 def : WrapperPat<tblockaddress, ADDiu, GPR32>;
1327 def : WrapperPat<tjumptable, ADDiu, GPR32>;
1328 def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>;
1330 // Mips does not have "not", so we expand our way
1331 def : MipsPat<(not GPR32:$in),
1332 (NOR GPR32Opnd:$in, ZERO)>;
1335 let Predicates = [HasStdEnc] in {
1336 def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>;
1337 def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>;
1338 def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
1342 let Predicates = [HasStdEnc] in
1343 def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>;
1346 multiclass BrcondPats<RegisterClass RC, Instruction BEQOp, Instruction BNEOp,
1347 Instruction SLTOp, Instruction SLTuOp, Instruction SLTiOp,
1348 Instruction SLTiuOp, Register ZEROReg> {
1349 def : MipsPat<(brcond (i32 (setne RC:$lhs, 0)), bb:$dst),
1350 (BNEOp RC:$lhs, ZEROReg, bb:$dst)>;
1351 def : MipsPat<(brcond (i32 (seteq RC:$lhs, 0)), bb:$dst),
1352 (BEQOp RC:$lhs, ZEROReg, bb:$dst)>;
1354 def : MipsPat<(brcond (i32 (setge RC:$lhs, RC:$rhs)), bb:$dst),
1355 (BEQ (SLTOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
1356 def : MipsPat<(brcond (i32 (setuge RC:$lhs, RC:$rhs)), bb:$dst),
1357 (BEQ (SLTuOp RC:$lhs, RC:$rhs), ZERO, bb:$dst)>;
1358 def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst),
1359 (BEQ (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
1360 def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst),
1361 (BEQ (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
1362 def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
1363 (BEQ (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
1364 def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst),
1365 (BEQ (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>;
1367 def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst),
1368 (BEQ (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
1369 def : MipsPat<(brcond (i32 (setule RC:$lhs, RC:$rhs)), bb:$dst),
1370 (BEQ (SLTuOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>;
1372 def : MipsPat<(brcond RC:$cond, bb:$dst),
1373 (BNEOp RC:$cond, ZEROReg, bb:$dst)>;
1376 defm : BrcondPats<GPR32, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>;
1378 def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst),
1379 (BLEZ i32:$lhs, bb:$dst)>;
1380 def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst),
1381 (BGEZ i32:$lhs, bb:$dst)>;
1384 multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp,
1385 Instruction SLTuOp, Register ZEROReg> {
1386 def : MipsPat<(seteq RC:$lhs, 0),
1387 (SLTiuOp RC:$lhs, 1)>;
1388 def : MipsPat<(setne RC:$lhs, 0),
1389 (SLTuOp ZEROReg, RC:$lhs)>;
1390 def : MipsPat<(seteq RC:$lhs, RC:$rhs),
1391 (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>;
1392 def : MipsPat<(setne RC:$lhs, RC:$rhs),
1393 (SLTuOp ZEROReg, (XOROp RC:$lhs, RC:$rhs))>;
1396 multiclass SetlePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1397 def : MipsPat<(setle RC:$lhs, RC:$rhs),
1398 (XORi (SLTOp RC:$rhs, RC:$lhs), 1)>;
1399 def : MipsPat<(setule RC:$lhs, RC:$rhs),
1400 (XORi (SLTuOp RC:$rhs, RC:$lhs), 1)>;
1403 multiclass SetgtPats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1404 def : MipsPat<(setgt RC:$lhs, RC:$rhs),
1405 (SLTOp RC:$rhs, RC:$lhs)>;
1406 def : MipsPat<(setugt RC:$lhs, RC:$rhs),
1407 (SLTuOp RC:$rhs, RC:$lhs)>;
1410 multiclass SetgePats<RegisterClass RC, Instruction SLTOp, Instruction SLTuOp> {
1411 def : MipsPat<(setge RC:$lhs, RC:$rhs),
1412 (XORi (SLTOp RC:$lhs, RC:$rhs), 1)>;
1413 def : MipsPat<(setuge RC:$lhs, RC:$rhs),
1414 (XORi (SLTuOp RC:$lhs, RC:$rhs), 1)>;
1417 multiclass SetgeImmPats<RegisterClass RC, Instruction SLTiOp,
1418 Instruction SLTiuOp> {
1419 def : MipsPat<(setge RC:$lhs, immSExt16:$rhs),
1420 (XORi (SLTiOp RC:$lhs, immSExt16:$rhs), 1)>;
1421 def : MipsPat<(setuge RC:$lhs, immSExt16:$rhs),
1422 (XORi (SLTiuOp RC:$lhs, immSExt16:$rhs), 1)>;
1425 defm : SeteqPats<GPR32, SLTiu, XOR, SLTu, ZERO>;
1426 defm : SetlePats<GPR32, SLT, SLTu>;
1427 defm : SetgtPats<GPR32, SLT, SLTu>;
1428 defm : SetgePats<GPR32, SLT, SLTu>;
1429 defm : SetgeImmPats<GPR32, SLTi, SLTiu>;
1432 def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>;
1434 // Load halfword/word patterns.
1435 let AddedComplexity = 40 in {
1436 let Predicates = [HasStdEnc] in {
1437 def : LoadRegImmPat<LBu, i32, zextloadi8>;
1438 def : LoadRegImmPat<LH, i32, sextloadi16>;
1439 def : LoadRegImmPat<LW, i32, load>;
1443 //===----------------------------------------------------------------------===//
1444 // Floating Point Support
1445 //===----------------------------------------------------------------------===//
1447 include "MipsInstrFPU.td"
1448 include "Mips64InstrInfo.td"
1449 include "MipsCondMov.td"
1454 include "Mips16InstrFormats.td"
1455 include "Mips16InstrInfo.td"
1458 include "MipsDSPInstrFormats.td"
1459 include "MipsDSPInstrInfo.td"
1462 include "MipsMSAInstrFormats.td"
1463 include "MipsMSAInstrInfo.td"
1466 include "MicroMipsInstrFormats.td"
1467 include "MicroMipsInstrInfo.td"
1468 include "MicroMipsInstrFPU.td"