X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FMips%2FMipsInstrInfo.td;h=71d0a18d48c97cbc86fa21f52a0868855edc3613;hb=8f7dc89e2126f8c66cc0dbb0e27c7ed6be9d6b8c;hp=86ec72982b33d2ca6571cfb998c8726d51ba64de;hpb=c147c1b994e1187cb471cdb7ee05f5f875eff4e0;p=oota-llvm.git diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index 86ec72982b3..71d0a18d48c 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -23,10 +23,9 @@ def SDT_MipsCMov : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, SDTCisInt<4>]>; def SDT_MipsCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>; def SDT_MipsCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; -def SDT_ExtractLOHI : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisVT<1, untyped>, - SDTCisVT<2, i32>]>; -def SDT_InsertLOHI : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>, - SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>; +def SDT_MFLOHI : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisVT<1, untyped>]>; +def SDT_MTLOHI : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>, + SDTCisInt<1>, SDTCisSameAs<1, 2>]>; def SDT_MipsMultDiv : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>, SDTCisInt<1>, SDTCisSameAs<1, 2>]>; def SDT_MipsMAddMSub : SDTypeProfile<1, 3, @@ -85,11 +84,12 @@ def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeqEnd, [SDNPHasChain, SDNPSideEffect, SDNPOptInGlue, SDNPOutGlue]>; -// Node used to extract integer from LO/HI register. -def ExtractLOHI : SDNode<"MipsISD::ExtractLOHI", SDT_ExtractLOHI>; +// Nodes used to extract LO/HI registers. +def MipsMFHI : SDNode<"MipsISD::MFHI", SDT_MFLOHI>; +def MipsMFLO : SDNode<"MipsISD::MFLO", SDT_MFLOHI>; // Node used to insert 32-bit integers to LOHI register pair. -def InsertLOHI : SDNode<"MipsISD::InsertLOHI", SDT_InsertLOHI>; +def MipsMTLOHI : SDNode<"MipsISD::MTLOHI", SDT_MTLOHI>; // Mult nodes. def MipsMult : SDNode<"MipsISD::Mult", SDT_MipsMultDiv>; @@ -104,7 +104,8 @@ def MipsMSubu : SDNode<"MipsISD::MSubu", SDT_MipsMAddMSub>; // DivRem(u) nodes def MipsDivRem : SDNode<"MipsISD::DivRem", SDT_MipsMultDiv>; def MipsDivRemU : SDNode<"MipsISD::DivRemU", SDT_MipsMultDiv>; -def MipsDivRem16 : SDNode<"MipsISD::DivRem16", SDT_MipsDivRem16, [SDNPOutGlue]>; +def MipsDivRem16 : SDNode<"MipsISD::DivRem16", SDT_MipsDivRem16, + [SDNPOutGlue]>; def MipsDivRemU16 : SDNode<"MipsISD::DivRemU16", SDT_MipsDivRem16, [SDNPOutGlue]>; @@ -113,7 +114,7 @@ def MipsDivRemU16 : SDNode<"MipsISD::DivRemU16", SDT_MipsDivRem16, // Wrapper node patterns give the instruction selector a chance to replace // target constant nodes that would otherwise remain unchanged with ADDiu // nodes. Without these wrapper node patterns, the following conditional move -// instrucion is emitted when function cmov2 in test/CodeGen/Mips/cmov.ll is +// instruction is emitted when function cmov2 in test/CodeGen/Mips/cmov.ll is // compiled: // movn %got(d)($gp), %got(c)($gp), $4 // This instruction is illegal since movn can take only register operands. @@ -167,10 +168,10 @@ def HasMips64r2 : Predicate<"Subtarget.hasMips64r2()">, AssemblerPredicate<"FeatureMips64r2">; def IsN64 : Predicate<"Subtarget.isABI_N64()">, AssemblerPredicate<"FeatureN64">; -def NotN64 : Predicate<"!Subtarget.isABI_N64()">, - AssemblerPredicate<"!FeatureN64">; def InMips16Mode : Predicate<"Subtarget.inMips16Mode()">, AssemblerPredicate<"FeatureMips16">; +def HasCnMips : Predicate<"Subtarget.hasCnMips()">, + AssemblerPredicate<"FeatureCnMips">; def RelocStatic : Predicate<"TM.getRelocationModel() == Reloc::Static">, AssemblerPredicate<"FeatureMips32">; def RelocPIC : Predicate<"TM.getRelocationModel() == Reloc::PIC_">, @@ -180,6 +181,13 @@ def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">, def HasStdEnc : Predicate<"Subtarget.hasStandardEncoding()">, AssemblerPredicate<"!FeatureMips16">; def NotDSP : Predicate<"!Subtarget.hasDSP()">; +def InMicroMips : Predicate<"Subtarget.inMicroMipsMode()">, + AssemblerPredicate<"FeatureMicroMips">; +def NotInMicroMips : Predicate<"!Subtarget.inMicroMipsMode()">, + AssemblerPredicate<"!FeatureMicroMips">; +def IsLE : Predicate<"Subtarget.isLittle()">; +def IsBE : Predicate<"!Subtarget.isLittle()">; +def IsNotNaCl : Predicate<"!Subtarget.isTargetNaCl()">; class MipsPat : Pat { let Predicates = [HasStdEnc]; @@ -228,19 +236,31 @@ include "MipsInstrFormats.td" // Mips Operand, Complex Patterns and Transformations Definitions. //===----------------------------------------------------------------------===// +def MipsJumpTargetAsmOperand : AsmOperandClass { + let Name = "JumpTarget"; + let ParserMethod = "ParseJumpTarget"; + let PredicateMethod = "isImm"; + let RenderMethod = "addImmOperands"; +} + // Instruction operand types def jmptarget : Operand { let EncoderMethod = "getJumpTargetOpValue"; + let ParserMatchClass = MipsJumpTargetAsmOperand; } def brtarget : Operand { let EncoderMethod = "getBranchTargetOpValue"; let OperandType = "OPERAND_PCREL"; let DecoderMethod = "DecodeBranchTarget"; + let ParserMatchClass = MipsJumpTargetAsmOperand; } def calltarget : Operand { let EncoderMethod = "getJumpTargetOpValue"; + let ParserMatchClass = MipsJumpTargetAsmOperand; } -def calltarget64: Operand; + +def simm10 : Operand; + def simm16 : Operand { let DecoderMethod= "DecodeSimm16"; } @@ -248,50 +268,82 @@ def simm16 : Operand { def simm20 : Operand { } -def simm16_64 : Operand; -def shamt : Operand; +def uimm20 : Operand { +} + +def uimm10 : Operand { +} + +def simm16_64 : Operand { + let DecoderMethod = "DecodeSimm16"; +} + +// Zero +def uimmz : Operand { + let PrintMethod = "printUnsignedImm"; +} // Unsigned Operand +def uimm5 : Operand { + let PrintMethod = "printUnsignedImm"; +} + +def uimm6 : Operand { + let PrintMethod = "printUnsignedImm"; +} + def uimm16 : Operand { let PrintMethod = "printUnsignedImm"; } +def pcrel16 : Operand { +} + def MipsMemAsmOperand : AsmOperandClass { let Name = "Mem"; let ParserMethod = "parseMemOperand"; } -// Address operand -def mem : Operand { - let PrintMethod = "printMemOperand"; - let MIOperandInfo = (ops CPURegs, simm16); - let EncoderMethod = "getMemEncoding"; - let ParserMatchClass = MipsMemAsmOperand; - let OperandType = "OPERAND_MEMORY"; +def MipsInvertedImmoperand : AsmOperandClass { + let Name = "InvNum"; + let RenderMethod = "addImmOperands"; + let ParserMethod = "parseInvNum"; +} + +def InvertedImOperand : Operand { + let ParserMatchClass = MipsInvertedImmoperand; } -def mem64 : Operand { +class mem_generic : Operand { let PrintMethod = "printMemOperand"; - let MIOperandInfo = (ops CPU64Regs, simm16_64); + let MIOperandInfo = (ops ptr_rc, simm16); let EncoderMethod = "getMemEncoding"; let ParserMatchClass = MipsMemAsmOperand; let OperandType = "OPERAND_MEMORY"; } -def mem_ea : Operand { - let PrintMethod = "printMemOperandEA"; - let MIOperandInfo = (ops CPURegs, simm16); - let EncoderMethod = "getMemEncoding"; - let OperandType = "OPERAND_MEMORY"; +// Address operand +def mem : mem_generic; + +// MSA specific address operand +def mem_msa : mem_generic { + let MIOperandInfo = (ops ptr_rc, simm10); + let EncoderMethod = "getMSAMemEncoding"; } -def mem_ea_64 : Operand { +def mem_ea : Operand { let PrintMethod = "printMemOperandEA"; - let MIOperandInfo = (ops CPU64Regs, simm16_64); + let MIOperandInfo = (ops ptr_rc, simm16); let EncoderMethod = "getMemEncoding"; let OperandType = "OPERAND_MEMORY"; } +def PtrRC : Operand { + let MIOperandInfo = (ops ptr_rc); + let DecoderMethod = "DecodePtrRegisterClass"; + let ParserMatchClass = GPR32AsmOperand; +} + // size operand of ext instruction def size_ext : Operand { let EncoderMethod = "getSizeExtEncoding"; @@ -317,6 +369,9 @@ def HI16 : SDNodeXFormgetSExtValue() + 1); }]>; +// Node immediate is zero (e.g. insve.d) +def immz : PatLeaf<(imm), [{ return N->getSExtValue() == 0; }]>; + // Node immediate fits as 16-bit sign extended on target immediate. // e.g. addi, andi def immSExt8 : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>; @@ -362,9 +417,14 @@ def addr : def addrRegImm : ComplexPattern; +def addrRegReg : + ComplexPattern; + def addrDefault : ComplexPattern; +def addrimm10 : ComplexPattern; + //===----------------------------------------------------------------------===// // Instructions specific format //===----------------------------------------------------------------------===// @@ -378,164 +438,118 @@ class ArithLogicR { let isCommutable = isComm; let isReMaterializable = 1; + let TwoOperandAliasConstraint = "$rd = $rs"; } // Arithmetic and logical instructions with 2 register operands. class ArithLogicI : InstSE<(outs RO:$rt), (ins RO:$rs, Od:$imm16), !strconcat(opstr, "\t$rt, $rs, $imm16"), [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))], - IIAlu, FrmI, opstr> { + Itin, FrmI, opstr> { let isReMaterializable = 1; + let TwoOperandAliasConstraint = "$rs = $rt"; } // Arithmetic Multiply ADD/SUB -class MArithR : - InstSE<(outs), (ins CPURegsOpnd:$rs, CPURegsOpnd:$rt), - !strconcat(opstr, "\t$rs, $rt"), [], IIImul, FrmR> { - let Defs = [HI, LO]; - let Uses = [HI, LO]; +class MArithR : + InstSE<(outs), (ins GPR32Opnd:$rs, GPR32Opnd:$rt), + !strconcat(opstr, "\t$rs, $rt"), [], itin, FrmR, opstr> { + let Defs = [HI0, LO0]; + let Uses = [HI0, LO0]; let isCommutable = isComm; } // Logical -class LogicNOR: - InstSE<(outs RC:$rd), (ins RC:$rs, RC:$rt), +class LogicNOR: + InstSE<(outs RO:$rd), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rd, $rs, $rt"), - [(set RC:$rd, (not (or RC:$rs, RC:$rt)))], IIAlu, FrmR, opstr> { + [(set RO:$rd, (not (or RO:$rs, RO:$rt)))], II_NOR, FrmR, opstr> { let isCommutable = 1; } // Shifts class shift_rotate_imm : - InstSE<(outs RC:$rd), (ins RC:$rt, ImmOpnd:$shamt), + InstSE<(outs RO:$rd), (ins RO:$rt, ImmOpnd:$shamt), !strconcat(opstr, "\t$rd, $rt, $shamt"), - [(set RC:$rd, (OpNode RC:$rt, PF:$shamt))], IIAlu, FrmR, opstr>; + [(set RO:$rd, (OpNode RO:$rt, PF:$shamt))], itin, FrmR, opstr>; -class shift_rotate_reg: - InstSE<(outs RC:$rd), (ins CPURegsOpnd:$rs, RC:$rt), + InstSE<(outs RO:$rd), (ins RO:$rt, GPR32Opnd:$rs), !strconcat(opstr, "\t$rd, $rt, $rs"), - [(set RC:$rd, (OpNode RC:$rt, CPURegsOpnd:$rs))], IIAlu, FrmR, opstr>; + [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))], itin, FrmR, + opstr>; // Load Upper Imediate -class LoadUpper: - InstSE<(outs RC:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"), - [], IIAlu, FrmI>, IsAsCheapAsAMove { +class LoadUpper: + InstSE<(outs RO:$rt), (ins Imm:$imm16), !strconcat(opstr, "\t$rt, $imm16"), + [], II_LUI, FrmI, opstr>, IsAsCheapAsAMove { let neverHasSideEffects = 1; let isReMaterializable = 1; } -class FMem op, dag outs, dag ins, string asmstr, list pattern, - InstrItinClass itin>: FFI { - bits<21> addr; - let Inst{25-21} = addr{20-16}; - let Inst{15-0} = addr{15-0}; - let DecoderMethod = "DecodeMem"; -} - // Memory Load/Store -class Load : - InstSE<(outs RC:$rt), (ins MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"), - [(set RC:$rt, (OpNode Addr:$addr))], NoItinerary, FrmI, - !strconcat(opstr, ofsuffix)> { +class Load : + InstSE<(outs RO:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(set RO:$rt, (OpNode Addr:$addr))], Itin, FrmI, opstr> { let DecoderMethod = "DecodeMem"; let canFoldAsLoad = 1; let mayLoad = 1; } -class Store : - InstSE<(outs), (ins RC:$rt, MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"), - [(OpNode RC:$rt, Addr:$addr)], NoItinerary, FrmI, - !strconcat(opstr, ofsuffix)> { +class Store : + InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> { let DecoderMethod = "DecodeMem"; let mayStore = 1; } -multiclass LoadM { - def NAME : Load, - Requires<[NotN64, HasStdEnc]>; - def _P8 : Load, - Requires<[IsN64, HasStdEnc]> { - let DecoderNamespace = "Mips64"; - let isCodeGenOnly = 1; - } -} - -multiclass StoreM { - def NAME : Store, - Requires<[NotN64, HasStdEnc]>; - def _P8 : Store, - Requires<[IsN64, HasStdEnc]> { - let DecoderNamespace = "Mips64"; - let isCodeGenOnly = 1; - } -} - // Load/Store Left/Right let canFoldAsLoad = 1 in -class LoadLeftRight : - InstSE<(outs RC:$rt), (ins MemOpnd:$addr, RC:$src), +class LoadLeftRight : + InstSE<(outs RO:$rt), (ins mem:$addr, RO:$src), !strconcat(opstr, "\t$rt, $addr"), - [(set RC:$rt, (OpNode addr:$addr, RC:$src))], NoItinerary, FrmI> { + [(set RO:$rt, (OpNode addr:$addr, RO:$src))], Itin, FrmI> { let DecoderMethod = "DecodeMem"; string Constraints = "$src = $rt"; } -class StoreLeftRight: - InstSE<(outs), (ins RC:$rt, MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"), - [(OpNode RC:$rt, addr:$addr)], NoItinerary, FrmI> { +class StoreLeftRight : + InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(OpNode RO:$rt, addr:$addr)], Itin, FrmI> { let DecoderMethod = "DecodeMem"; } -multiclass LoadLeftRightM { - def NAME : LoadLeftRight, - Requires<[NotN64, HasStdEnc]>; - def _P8 : LoadLeftRight, - Requires<[IsN64, HasStdEnc]> { - let DecoderNamespace = "Mips64"; - let isCodeGenOnly = 1; - } -} - -multiclass StoreLeftRightM { - def NAME : StoreLeftRight, - Requires<[NotN64, HasStdEnc]>; - def _P8 : StoreLeftRight, - Requires<[IsN64, HasStdEnc]> { - let DecoderNamespace = "Mips64"; - let isCodeGenOnly = 1; - } -} - // Conditional Branch -class CBranch : - InstSE<(outs), (ins RC:$rs, RC:$rt, brtarget:$offset), +class CBranch : + InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset), !strconcat(opstr, "\t$rs, $rt, $offset"), - [(brcond (i32 (cond_op RC:$rs, RC:$rt)), bb:$offset)], IIBranch, - FrmI> { + [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], IIBranch, + FrmI, opstr> { let isBranch = 1; let isTerminator = 1; let hasDelaySlot = 1; let Defs = [AT]; } -class CBranchZero : - InstSE<(outs), (ins RC:$rs, brtarget:$offset), +class CBranchZero : + InstSE<(outs), (ins RO:$rs, opnd:$offset), !strconcat(opstr, "\t$rs, $offset"), - [(brcond (i32 (cond_op RC:$rs, 0)), bb:$offset)], IIBranch, FrmI> { + [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], IIBranch, + FrmI, opstr> { let isBranch = 1; let isTerminator = 1; let hasDelaySlot = 1; @@ -543,24 +557,24 @@ class CBranchZero : } // SetCC -class SetCC_R : - InstSE<(outs CPURegsOpnd:$rd), (ins RC:$rs, RC:$rt), +class SetCC_R : + InstSE<(outs GPR32Opnd:$rd), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$rd, $rs, $rt"), - [(set CPURegsOpnd:$rd, (cond_op RC:$rs, RC:$rt))], - IIAlu, FrmR, opstr>; + [(set GPR32Opnd:$rd, (cond_op RO:$rs, RO:$rt))], + II_SLT_SLTU, FrmR, opstr>; class SetCC_I: - InstSE<(outs CPURegsOpnd:$rt), (ins RC:$rs, Od:$imm16), + RegisterOperand RO>: + InstSE<(outs GPR32Opnd:$rt), (ins RO:$rs, Od:$imm16), !strconcat(opstr, "\t$rt, $rs, $imm16"), - [(set CPURegsOpnd:$rt, (cond_op RC:$rs, imm_type:$imm16))], - IIAlu, FrmI, opstr>; + [(set GPR32Opnd:$rt, (cond_op RO:$rs, imm_type:$imm16))], + II_SLTI_SLTIU, FrmI, opstr>; // Jump class JumpFJ : + SDPatternOperator targetoperator, string bopstr> : InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"), - [(operator targetoperator:$target)], IIBranch, FrmJ> { + [(operator targetoperator:$target)], IIBranch, FrmJ, bopstr> { let isTerminator=1; let isBarrier=1; let hasDelaySlot = 1; @@ -569,9 +583,9 @@ class JumpFJ : - InstSE<(outs), (ins brtarget:$offset), !strconcat(opstr, "\t$offset"), - [(br bb:$offset)], IIBranch, FrmI> { +class UncondBranch : + PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], IIBranch>, + PseudoInstExpansion<(BEQInst ZERO, ZERO, brtarget:$offset)> { let isBranch = 1; let isTerminator = 1; let isBarrier = 1; @@ -582,17 +596,20 @@ class UncondBranch : // Base class for indirect branch and return instruction classes. let isTerminator=1, isBarrier=1, hasDelaySlot = 1 in -class JumpFR: - InstSE<(outs), (ins RC:$rs), "jr\t$rs", [(operator RC:$rs)], IIBranch, FrmR>; +class JumpFR: + InstSE<(outs), (ins RO:$rs), "jr\t$rs", [(operator RO:$rs)], IIBranch, + FrmR, opstr>; // Indirect branch -class IndirectBranch: JumpFR { +class IndirectBranch : + JumpFR { let isBranch = 1; let isIndirectBranch = 1; } // Return instruction -class RetBase: JumpFR { +class RetBase: JumpFR { let isReturn = 1; let isCodeGenOnly = 1; let hasCtrlDep = 1; @@ -601,29 +618,42 @@ class RetBase: JumpFR { // Jump and Link (Call) let isCall=1, hasDelaySlot=1, Defs = [RA] in { - class JumpLink : - InstSE<(outs), (ins calltarget:$target), !strconcat(opstr, "\t$target"), - [(MipsJmpLink imm:$target)], IIBranch, FrmJ> { + class JumpLink : + InstSE<(outs), (ins opnd:$target), !strconcat(opstr, "\t$target"), + [(MipsJmpLink imm:$target)], IIBranch, FrmJ, opstr> { let DecoderMethod = "DecodeJumpTarget"; } - class JumpLinkRegPseudo: - PseudoSE<(outs), (ins RC:$rs), [(MipsJmpLink RC:$rs)], IIBranch>, - PseudoInstExpansion<(JALRInst RetReg, RC:$rs)>; + class JumpLinkRegPseudo: + PseudoSE<(outs), (ins RO:$rs), [(MipsJmpLink RO:$rs)], IIBranch>, + PseudoInstExpansion<(JALRInst RetReg, ResRO:$rs)>; - class JumpLinkReg: - InstSE<(outs RC:$rd), (ins RC:$rs), !strconcat(opstr, "\t$rd, $rs"), + class JumpLinkReg: + InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), [], IIBranch, FrmR>; - class BGEZAL_FT : - InstSE<(outs), (ins RO:$rs, brtarget:$offset), - !strconcat(opstr, "\t$rs, $offset"), [], IIBranch, FrmI>; + class BGEZAL_FT : + InstSE<(outs), (ins RO:$rs, opnd:$offset), + !strconcat(opstr, "\t$rs, $offset"), [], IIBranch, FrmI, opstr>; } -class BAL_FT : - InstSE<(outs), (ins brtarget:$offset), "bal\t$offset", [], IIBranch, FrmI> { +let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1, + hasExtraSrcRegAllocReq = 1, Defs = [AT] in { + class TailCall : + PseudoSE<(outs), (ins calltarget:$target), [], IIBranch>, + PseudoInstExpansion<(JumpInst jmptarget:$target)>; + + class TailCallReg : + PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], IIBranch>, + PseudoInstExpansion<(JRInst ResRO:$rs)>; +} + +class BAL_BR_Pseudo : + PseudoSE<(outs), (ins brtarget:$offset), [], IIBranch>, + PseudoInstExpansion<(RealInst ZERO, brtarget:$offset)> { let isBranch = 1; let isTerminator = 1; let isBarrier = 1; @@ -631,12 +661,45 @@ class BAL_FT : let Defs = [RA]; } +// Syscall +class SYS_FT : + InstSE<(outs), (ins uimm20:$code_), + !strconcat(opstr, "\t$code_"), [], NoItinerary, FrmI, opstr>; +// Break +class BRK_FT : + InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2), + !strconcat(opstr, "\t$code_1, $code_2"), [], NoItinerary, + FrmOther, opstr>; + +// (D)Eret +class ER_FT : + InstSE<(outs), (ins), + opstr, [], NoItinerary, FrmOther, opstr>; + +// Interrupts +class DEI_FT : + InstSE<(outs RO:$rt), (ins), + !strconcat(opstr, "\t$rt"), [], NoItinerary, FrmOther, opstr>; + +// Wait +class WAIT_FT : + InstSE<(outs), (ins), opstr, [], NoItinerary, FrmOther, opstr>; + // Sync let hasSideEffects = 1 in -class SYNC_FT : +class SYNC_FT : InstSE<(outs), (ins i32imm:$stype), "sync $stype", [(MipsSync imm:$stype)], - NoItinerary, FrmOther>; + NoItinerary, FrmOther, opstr>; +let hasSideEffects = 1 in +class TEQ_FT : + InstSE<(outs), (ins RO:$rs, RO:$rt, uimm16:$code_), + !strconcat(opstr, "\t$rs, $rt, $code_"), [], NoItinerary, + FrmI, opstr>; + +class TEQI_FT : + InstSE<(outs), (ins RO:$rs, uimm16:$imm16), + !strconcat(opstr, "\t$rs, $imm16"), [], NoItinerary, FrmOther, opstr>; // Mul, Div class Mult DefRegs> : @@ -651,49 +714,64 @@ class Mult : + bit IsComm = 1, bit HasSideEffects = 0, + bit UsesCustomInserter = 0> : PseudoSE<(outs R0:$ac), (ins R1:$rs, R1:$rt), [(set R0:$ac, (OpNode R1:$rs, R1:$rt))], Itin>, PseudoInstExpansion<(RealInst R1:$rs, R1:$rt)> { let isCommutable = IsComm; let hasSideEffects = HasSideEffects; + let usesCustomInserter = UsesCustomInserter; } // Pseudo multiply add/sub instruction with explicit accumulator register // operands. -class MAddSubPseudo - : PseudoSE<(outs ACRegs:$ac), - (ins CPURegsOpnd:$rs, CPURegsOpnd:$rt, ACRegs:$acin), - [(set ACRegs:$ac, - (OpNode CPURegsOpnd:$rs, CPURegsOpnd:$rt, ACRegs:$acin))], - IIImul>, - PseudoInstExpansion<(RealInst CPURegsOpnd:$rs, CPURegsOpnd:$rt)> { +class MAddSubPseudo + : PseudoSE<(outs ACC64:$ac), + (ins GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin), + [(set ACC64:$ac, + (OpNode GPR32Opnd:$rs, GPR32Opnd:$rt, ACC64:$acin))], + itin>, + PseudoInstExpansion<(RealInst GPR32Opnd:$rs, GPR32Opnd:$rt)> { string Constraints = "$acin = $ac"; } class Div DefRegs> : InstSE<(outs), (ins RO:$rs, RO:$rt), !strconcat(opstr, "\t$$zero, $rs, $rt"), - [], itin, FrmR> { + [], itin, FrmR, opstr> { let Defs = DefRegs; } // Move from Hi/Lo -class MoveFromLOHI UseRegs>: - InstSE<(outs RC:$rd), (ins), !strconcat(opstr, "\t$rd"), [], IIHiLo, FrmR> { - let Uses = UseRegs; +class PseudoMFLOHI + : PseudoSE<(outs DstRC:$rd), (ins SrcRC:$hilo), + [(set DstRC:$rd, (OpNode SrcRC:$hilo))], II_MFHI_MFLO>; + +class MoveFromLOHI: + InstSE<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO, + FrmR, opstr> { + let Uses = [UseReg]; let neverHasSideEffects = 1; } -class MoveToLOHI DefRegs>: - InstSE<(outs), (ins RC:$rs), !strconcat(opstr, "\t$rs"), [], IIHiLo, FrmR> { +class PseudoMTLOHI + : PseudoSE<(outs DstRC:$lohi), (ins SrcRC:$lo, SrcRC:$hi), + [(set DstRC:$lohi, (MipsMTLOHI SrcRC:$lo, SrcRC:$hi))], + II_MTHI_MTLO>; + +class MoveToLOHI DefRegs>: + InstSE<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), [], II_MTHI_MTLO, + FrmR, opstr> { let Defs = DefRegs; let neverHasSideEffects = 1; } -class EffectiveAddress : - InstSE<(outs RC:$rt), (ins Mem:$addr), !strconcat(opstr, "\t$rt, $addr"), - [(set RC:$rt, addr:$addr)], NoItinerary, FrmI> { +class EffectiveAddress : + InstSE<(outs RO:$rt), (ins mem_ea:$addr), !strconcat(opstr, "\t$rt, $addr"), + [(set RO:$rt, addr:$addr)], NoItinerary, FrmI, + !strconcat(opstr, "_lea")> { let isCodeGenOnly = 1; let DecoderMethod = "DecodeMem"; } @@ -701,97 +779,91 @@ class EffectiveAddress : // Count Leading Ones/Zeros in Word class CountLeading0: InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), - [(set RO:$rd, (ctlz RO:$rs))], IIAlu, FrmR>, + [(set RO:$rd, (ctlz RO:$rs))], II_CLZ, FrmR, opstr>, Requires<[HasBitCount, HasStdEnc]>; class CountLeading1: InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), - [(set RO:$rd, (ctlz (not RO:$rs)))], IIAlu, FrmR>, + [(set RO:$rd, (ctlz (not RO:$rs)))], II_CLO, FrmR, opstr>, Requires<[HasBitCount, HasStdEnc]>; - // Sign Extend in Register. -class SignExtInReg : - InstSE<(outs RC:$rd), (ins RC:$rt), !strconcat(opstr, "\t$rd, $rt"), - [(set RC:$rd, (sext_inreg RC:$rt, vt))], NoItinerary, FrmR> { +class SignExtInReg : + InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), + [(set RO:$rd, (sext_inreg RO:$rt, vt))], itin, FrmR, opstr> { let Predicates = [HasSEInReg, HasStdEnc]; } // Subword Swap class SubwordSwap: InstSE<(outs RO:$rd), (ins RO:$rt), !strconcat(opstr, "\t$rd, $rt"), [], - NoItinerary, FrmR> { + NoItinerary, FrmR, opstr> { let Predicates = [HasSwap, HasStdEnc]; let neverHasSideEffects = 1; } // Read Hardware -class ReadHardware : - InstSE<(outs CPURegClass:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [], - IIAlu, FrmR>; +class ReadHardware : + InstSE<(outs CPURegOperand:$rt), (ins RO:$rd), "rdhwr\t$rt, $rd", [], + II_RDHWR, FrmR>; // Ext and Ins -class ExtBase: - InstSE<(outs RO:$rt), (ins RO:$rs, uimm16:$pos, size_ext:$size), +class ExtBase: + InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, size_ext:$size), !strconcat(opstr, " $rt, $rs, $pos, $size"), - [(set RO:$rt, (MipsExt RO:$rs, imm:$pos, imm:$size))], NoItinerary, - FrmR> { + [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size))], NoItinerary, + FrmR, opstr> { let Predicates = [HasMips32r2, HasStdEnc]; } -class InsBase: - InstSE<(outs RO:$rt), (ins RO:$rs, uimm16:$pos, size_ins:$size, RO:$src), +class InsBase: + InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, size_ins:$size, RO:$src), !strconcat(opstr, " $rt, $rs, $pos, $size"), - [(set RO:$rt, (MipsIns RO:$rs, imm:$pos, imm:$size, RO:$src))], - NoItinerary, FrmR> { + [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size, RO:$src))], + NoItinerary, FrmR, opstr> { let Predicates = [HasMips32r2, HasStdEnc]; let Constraints = "$src = $rt"; } // Atomic instructions with 2 source operands (ATOMIC_SWAP & ATOMIC_LOAD_*). -class Atomic2Ops : - PseudoSE<(outs DRC:$dst), (ins PRC:$ptr, DRC:$incr), - [(set DRC:$dst, (Op PRC:$ptr, DRC:$incr))]>; - -multiclass Atomic2Ops32 { - def NAME : Atomic2Ops, Requires<[NotN64, HasStdEnc]>; - def _P8 : Atomic2Ops, - Requires<[IsN64, HasStdEnc]> { - let DecoderNamespace = "Mips64"; - } -} +class Atomic2Ops : + PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$incr), + [(set DRC:$dst, (Op iPTR:$ptr, DRC:$incr))]>; // Atomic Compare & Swap. -class AtomicCmpSwap : - PseudoSE<(outs DRC:$dst), (ins PRC:$ptr, DRC:$cmp, DRC:$swap), - [(set DRC:$dst, (Op PRC:$ptr, DRC:$cmp, DRC:$swap))]>; - -multiclass AtomicCmpSwap32 { - def NAME : AtomicCmpSwap, - Requires<[NotN64, HasStdEnc]>; - def _P8 : AtomicCmpSwap, - Requires<[IsN64, HasStdEnc]> { - let DecoderNamespace = "Mips64"; - } -} +class AtomicCmpSwap : + PseudoSE<(outs DRC:$dst), (ins PtrRC:$ptr, DRC:$cmp, DRC:$swap), + [(set DRC:$dst, (Op iPTR:$ptr, DRC:$cmp, DRC:$swap))]>; -class LLBase : - InstSE<(outs RO:$rt), (ins Mem:$addr), !strconcat(opstr, "\t$rt, $addr"), +class LLBase : + InstSE<(outs RO:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> { let DecoderMethod = "DecodeMem"; let mayLoad = 1; } -class SCBase : - InstSE<(outs RO:$dst), (ins RO:$rt, Mem:$addr), +class SCBase : + InstSE<(outs RO:$dst), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"), [], NoItinerary, FrmI> { let DecoderMethod = "DecodeMem"; let mayStore = 1; let Constraints = "$rt = $dst"; } -class MFC3OP : - InstSE; +class MFC3OP : + InstSE<(outs RO:$rt, RO:$rd, uimm16:$sel), (ins), + !strconcat(asmstr, "\t$rt, $rd, $sel"), [], NoItinerary, FrmFR>; + +class TrapBase + : PseudoSE<(outs), (ins), [(trap)], NoItinerary>, + PseudoInstExpansion<(RealInst 0, 0)> { + let isBarrier = 1; + let isTerminator = 1; + let isCodeGenOnly = 1; +} //===----------------------------------------------------------------------===// // Pseudo instructions @@ -809,38 +881,38 @@ def ADJCALLSTACKUP : MipsPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), } let usesCustomInserter = 1 in { - defm ATOMIC_LOAD_ADD_I8 : Atomic2Ops32; - defm ATOMIC_LOAD_ADD_I16 : Atomic2Ops32; - defm ATOMIC_LOAD_ADD_I32 : Atomic2Ops32; - defm ATOMIC_LOAD_SUB_I8 : Atomic2Ops32; - defm ATOMIC_LOAD_SUB_I16 : Atomic2Ops32; - defm ATOMIC_LOAD_SUB_I32 : Atomic2Ops32; - defm ATOMIC_LOAD_AND_I8 : Atomic2Ops32; - defm ATOMIC_LOAD_AND_I16 : Atomic2Ops32; - defm ATOMIC_LOAD_AND_I32 : Atomic2Ops32; - defm ATOMIC_LOAD_OR_I8 : Atomic2Ops32; - defm ATOMIC_LOAD_OR_I16 : Atomic2Ops32; - defm ATOMIC_LOAD_OR_I32 : Atomic2Ops32; - defm ATOMIC_LOAD_XOR_I8 : Atomic2Ops32; - defm ATOMIC_LOAD_XOR_I16 : Atomic2Ops32; - defm ATOMIC_LOAD_XOR_I32 : Atomic2Ops32; - defm ATOMIC_LOAD_NAND_I8 : Atomic2Ops32; - defm ATOMIC_LOAD_NAND_I16 : Atomic2Ops32; - defm ATOMIC_LOAD_NAND_I32 : Atomic2Ops32; - - defm ATOMIC_SWAP_I8 : Atomic2Ops32; - defm ATOMIC_SWAP_I16 : Atomic2Ops32; - defm ATOMIC_SWAP_I32 : Atomic2Ops32; - - defm ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap32; - defm ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap32; - defm ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap32; + def ATOMIC_LOAD_ADD_I8 : Atomic2Ops; + def ATOMIC_LOAD_ADD_I16 : Atomic2Ops; + def ATOMIC_LOAD_ADD_I32 : Atomic2Ops; + def ATOMIC_LOAD_SUB_I8 : Atomic2Ops; + def ATOMIC_LOAD_SUB_I16 : Atomic2Ops; + def ATOMIC_LOAD_SUB_I32 : Atomic2Ops; + def ATOMIC_LOAD_AND_I8 : Atomic2Ops; + def ATOMIC_LOAD_AND_I16 : Atomic2Ops; + def ATOMIC_LOAD_AND_I32 : Atomic2Ops; + def ATOMIC_LOAD_OR_I8 : Atomic2Ops; + def ATOMIC_LOAD_OR_I16 : Atomic2Ops; + def ATOMIC_LOAD_OR_I32 : Atomic2Ops; + def ATOMIC_LOAD_XOR_I8 : Atomic2Ops; + def ATOMIC_LOAD_XOR_I16 : Atomic2Ops; + def ATOMIC_LOAD_XOR_I32 : Atomic2Ops; + def ATOMIC_LOAD_NAND_I8 : Atomic2Ops; + def ATOMIC_LOAD_NAND_I16 : Atomic2Ops; + def ATOMIC_LOAD_NAND_I32 : Atomic2Ops; + + def ATOMIC_SWAP_I8 : Atomic2Ops; + def ATOMIC_SWAP_I16 : Atomic2Ops; + def ATOMIC_SWAP_I32 : Atomic2Ops; + + def ATOMIC_CMP_SWAP_I8 : AtomicCmpSwap; + def ATOMIC_CMP_SWAP_I16 : AtomicCmpSwap; + def ATOMIC_CMP_SWAP_I32 : AtomicCmpSwap; } /// Pseudo instructions for loading and storing accumulator registers. -let isPseudo = 1 in { - defm LOAD_AC64 : LoadM<"load_ac64", ACRegs>; - defm STORE_AC64 : StoreM<"store_ac64", ACRegs>; +let isPseudo = 1, isCodeGenOnly = 1 in { + def LOAD_ACC64 : Load<"", ACC64>; + def STORE_ACC64 : Store<"", ACC64>; } //===----------------------------------------------------------------------===// @@ -851,113 +923,151 @@ let isPseudo = 1 in { //===----------------------------------------------------------------------===// /// Arithmetic Instructions (ALU Immediate) -def ADDiu : MMRel, ArithLogicI<"addiu", simm16, CPURegsOpnd, immSExt16, add>, +def ADDiu : MMRel, ArithLogicI<"addiu", simm16, GPR32Opnd, II_ADDIU, immSExt16, + add>, ADDI_FM<0x9>, IsAsCheapAsAMove; -def ADDi : MMRel, ArithLogicI<"addi", simm16, CPURegsOpnd>, ADDI_FM<0x8>; -def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, CPURegs>, +def ADDi : MMRel, ArithLogicI<"addi", simm16, GPR32Opnd>, ADDI_FM<0x8>; +def SLTi : MMRel, SetCC_I<"slti", setlt, simm16, immSExt16, GPR32Opnd>, SLTI_FM<0xa>; -def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, CPURegs>, +def SLTiu : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, GPR32Opnd>, SLTI_FM<0xb>; -def ANDi : MMRel, ArithLogicI<"andi", uimm16, CPURegsOpnd, immZExt16, and>, +def ANDi : MMRel, ArithLogicI<"andi", uimm16, GPR32Opnd, II_ANDI, immZExt16, + and>, ADDI_FM<0xc>; -def ORi : MMRel, ArithLogicI<"ori", uimm16, CPURegsOpnd, immZExt16, or>, +def ORi : MMRel, ArithLogicI<"ori", uimm16, GPR32Opnd, II_ORI, immZExt16, + or>, ADDI_FM<0xd>; -def XORi : MMRel, ArithLogicI<"xori", uimm16, CPURegsOpnd, immZExt16, xor>, +def XORi : MMRel, ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16, + xor>, ADDI_FM<0xe>; -def LUi : MMRel, LoadUpper<"lui", CPURegs, uimm16>, LUI_FM; +def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16>, LUI_FM; /// Arithmetic Instructions (3-Operand, R-Type) -def ADDu : MMRel, ArithLogicR<"addu", CPURegsOpnd, 1, IIAlu, add>, +def ADDu : MMRel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>, ADD_FM<0, 0x21>; -def SUBu : MMRel, ArithLogicR<"subu", CPURegsOpnd, 0, IIAlu, sub>, +def SUBu : MMRel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>, ADD_FM<0, 0x23>; -def MUL : MMRel, ArithLogicR<"mul", CPURegsOpnd, 1, IIImul, mul>, +let Defs = [HI0, LO0] in +def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>, ADD_FM<0x1c, 2>; -def ADD : MMRel, ArithLogicR<"add", CPURegsOpnd>, ADD_FM<0, 0x20>; -def SUB : MMRel, ArithLogicR<"sub", CPURegsOpnd>, ADD_FM<0, 0x22>; -def SLT : MMRel, SetCC_R<"slt", setlt, CPURegs>, ADD_FM<0, 0x2a>; -def SLTu : MMRel, SetCC_R<"sltu", setult, CPURegs>, ADD_FM<0, 0x2b>; -def AND : MMRel, ArithLogicR<"and", CPURegsOpnd, 1, IIAlu, and>, +def ADD : MMRel, ArithLogicR<"add", GPR32Opnd>, ADD_FM<0, 0x20>; +def SUB : MMRel, ArithLogicR<"sub", GPR32Opnd>, ADD_FM<0, 0x22>; +def SLT : MMRel, SetCC_R<"slt", setlt, GPR32Opnd>, ADD_FM<0, 0x2a>; +def SLTu : MMRel, SetCC_R<"sltu", setult, GPR32Opnd>, ADD_FM<0, 0x2b>; +def AND : MMRel, ArithLogicR<"and", GPR32Opnd, 1, II_AND, and>, ADD_FM<0, 0x24>; -def OR : MMRel, ArithLogicR<"or", CPURegsOpnd, 1, IIAlu, or>, +def OR : MMRel, ArithLogicR<"or", GPR32Opnd, 1, II_OR, or>, ADD_FM<0, 0x25>; -def XOR : MMRel, ArithLogicR<"xor", CPURegsOpnd, 1, IIAlu, xor>, +def XOR : MMRel, ArithLogicR<"xor", GPR32Opnd, 1, II_XOR, xor>, ADD_FM<0, 0x26>; -def NOR : MMRel, LogicNOR<"nor", CPURegsOpnd>, ADD_FM<0, 0x27>; +def NOR : MMRel, LogicNOR<"nor", GPR32Opnd>, ADD_FM<0, 0x27>; /// Shift Instructions -def SLL : MMRel, shift_rotate_imm<"sll", shamt, CPURegsOpnd, shl, immZExt5>, - SRA_FM<0, 0>; -def SRL : MMRel, shift_rotate_imm<"srl", shamt, CPURegsOpnd, srl, immZExt5>, - SRA_FM<2, 0>; -def SRA : MMRel, shift_rotate_imm<"sra", shamt, CPURegsOpnd, sra, immZExt5>, - SRA_FM<3, 0>; -def SLLV : MMRel, shift_rotate_reg<"sllv", CPURegsOpnd, shl>, SRLV_FM<4, 0>; -def SRLV : MMRel, shift_rotate_reg<"srlv", CPURegsOpnd, srl>, SRLV_FM<6, 0>; -def SRAV : MMRel, shift_rotate_reg<"srav", CPURegsOpnd, sra>, SRLV_FM<7, 0>; +def SLL : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL, shl, + immZExt5>, SRA_FM<0, 0>; +def SRL : MMRel, shift_rotate_imm<"srl", uimm5, GPR32Opnd, II_SRL, srl, + immZExt5>, SRA_FM<2, 0>; +def SRA : MMRel, shift_rotate_imm<"sra", uimm5, GPR32Opnd, II_SRA, sra, + immZExt5>, SRA_FM<3, 0>; +def SLLV : MMRel, shift_rotate_reg<"sllv", GPR32Opnd, II_SLLV, shl>, + SRLV_FM<4, 0>; +def SRLV : MMRel, shift_rotate_reg<"srlv", GPR32Opnd, II_SRLV, srl>, + SRLV_FM<6, 0>; +def SRAV : MMRel, shift_rotate_reg<"srav", GPR32Opnd, II_SRAV, sra>, + SRLV_FM<7, 0>; // Rotate Instructions let Predicates = [HasMips32r2, HasStdEnc] in { - def ROTR : MMRel, shift_rotate_imm<"rotr", shamt, CPURegsOpnd, rotr, - immZExt5>, - SRA_FM<2, 1>; - def ROTRV : MMRel, shift_rotate_reg<"rotrv", CPURegsOpnd, rotr>, + def ROTR : MMRel, shift_rotate_imm<"rotr", uimm5, GPR32Opnd, II_ROTR, rotr, + immZExt5>, SRA_FM<2, 1>; + def ROTRV : MMRel, shift_rotate_reg<"rotrv", GPR32Opnd, II_ROTRV, rotr>, SRLV_FM<6, 1>; } /// Load and Store Instructions /// aligned -defm LB : LoadM<"lb", CPURegs, sextloadi8>, MMRel, LW_FM<0x20>; -defm LBu : LoadM<"lbu", CPURegs, zextloadi8, addrDefault>, MMRel, LW_FM<0x24>; -defm LH : LoadM<"lh", CPURegs, sextloadi16, addrDefault>, MMRel, LW_FM<0x21>; -defm LHu : LoadM<"lhu", CPURegs, zextloadi16>, MMRel, LW_FM<0x25>; -defm LW : LoadM<"lw", CPURegs, load, addrDefault>, MMRel, LW_FM<0x23>; -defm SB : StoreM<"sb", CPURegs, truncstorei8>, MMRel, LW_FM<0x28>; -defm SH : StoreM<"sh", CPURegs, truncstorei16>, MMRel, LW_FM<0x29>; -defm SW : StoreM<"sw", CPURegs, store>, MMRel, LW_FM<0x2b>; +def LB : Load<"lb", GPR32Opnd, sextloadi8, II_LB>, MMRel, LW_FM<0x20>; +def LBu : Load<"lbu", GPR32Opnd, zextloadi8, II_LBU, addrDefault>, MMRel, + LW_FM<0x24>; +def LH : Load<"lh", GPR32Opnd, sextloadi16, II_LH, addrDefault>, MMRel, + LW_FM<0x21>; +def LHu : Load<"lhu", GPR32Opnd, zextloadi16, II_LHU>, MMRel, LW_FM<0x25>; +def LW : Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel, + LW_FM<0x23>; +def SB : Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel, LW_FM<0x28>; +def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>; +def SW : Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>; /// load/store left/right -defm LWL : LoadLeftRightM<"lwl", MipsLWL, CPURegs>, LW_FM<0x22>; -defm LWR : LoadLeftRightM<"lwr", MipsLWR, CPURegs>, LW_FM<0x26>; -defm SWL : StoreLeftRightM<"swl", MipsSWL, CPURegs>, LW_FM<0x2a>; -defm SWR : StoreLeftRightM<"swr", MipsSWR, CPURegs>, LW_FM<0x2e>; +let Predicates = [NotInMicroMips] in { +def LWL : LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>; +def LWR : LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>; +def SWL : StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>; +def SWR : StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>; +} -def SYNC : SYNC_FT, SYNC_FM; +def SYNC : MMRel, SYNC_FT<"sync">, SYNC_FM; +def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM<0x34>; +def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM<0x30>; +def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd>, TEQ_FM<0x31>; +def TLT : MMRel, TEQ_FT<"tlt", GPR32Opnd>, TEQ_FM<0x32>; +def TLTU : MMRel, TEQ_FT<"tltu", GPR32Opnd>, TEQ_FM<0x33>; +def TNE : MMRel, TEQ_FT<"tne", GPR32Opnd>, TEQ_FM<0x36>; -/// Load-linked, Store-conditional -let Predicates = [NotN64, HasStdEnc] in { - def LL : LLBase<"ll", CPURegsOpnd, mem>, LW_FM<0x30>; - def SC : SCBase<"sc", CPURegsOpnd, mem>, LW_FM<0x38>; -} +def TEQI : MMRel, TEQI_FT<"teqi", GPR32Opnd>, TEQI_FM<0xc>; +def TGEI : MMRel, TEQI_FT<"tgei", GPR32Opnd>, TEQI_FM<0x8>; +def TGEIU : MMRel, TEQI_FT<"tgeiu", GPR32Opnd>, TEQI_FM<0x9>; +def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd>, TEQI_FM<0xa>; +def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd>, TEQI_FM<0xb>; +def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd>, TEQI_FM<0xe>; + +def BREAK : MMRel, BRK_FT<"break">, BRK_FM<0xd>; +def SYSCALL : MMRel, SYS_FT<"syscall">, SYS_FM<0xc>; +def TRAP : TrapBase; + +def ERET : MMRel, ER_FT<"eret">, ER_FM<0x18>; +def DERET : MMRel, ER_FT<"deret">, ER_FM<0x1f>; + +def EI : MMRel, DEI_FT<"ei", GPR32Opnd>, EI_FM<1>; +def DI : MMRel, DEI_FT<"di", GPR32Opnd>, EI_FM<0>; + +let Predicates = [NotInMicroMips] in { +def WAIT : WAIT_FT<"wait">, WAIT_FM; -let Predicates = [IsN64, HasStdEnc], DecoderNamespace = "Mips64" in { - def LL_P8 : LLBase<"ll", CPURegsOpnd, mem64>, LW_FM<0x30>; - def SC_P8 : SCBase<"sc", CPURegsOpnd, mem64>, LW_FM<0x38>; +/// Load-linked, Store-conditional +def LL : LLBase<"ll", GPR32Opnd>, LW_FM<0x30>; +def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>; } /// Jump and Branch Instructions -def J : JumpFJ, FJ<2>, +def J : MMRel, JumpFJ, FJ<2>, Requires<[RelocStatic, HasStdEnc]>, IsBranch; -def JR : IndirectBranch, MTLO_FM<8>; -def B : UncondBranch<"b">, B_FM; -def BEQ : CBranch<"beq", seteq, CPURegs>, BEQ_FM<4>; -def BNE : CBranch<"bne", setne, CPURegs>, BEQ_FM<5>; -def BGEZ : CBranchZero<"bgez", setge, CPURegs>, BGEZ_FM<1, 1>; -def BGTZ : CBranchZero<"bgtz", setgt, CPURegs>, BGEZ_FM<7, 0>; -def BLEZ : CBranchZero<"blez", setle, CPURegs>, BGEZ_FM<6, 0>; -def BLTZ : CBranchZero<"bltz", setlt, CPURegs>, BGEZ_FM<1, 0>; - -def BAL_BR: BAL_FT, BAL_FM; - -def JAL : JumpLink<"jal">, FJ<3>; -def JALR : JumpLinkReg<"jalr", CPURegs>, JALR_FM; -def JALRPseudo : JumpLinkRegPseudo; -def BGEZAL : BGEZAL_FT<"bgezal", CPURegsOpnd>, BGEZAL_FM<0x11>; -def BLTZAL : BGEZAL_FT<"bltzal", CPURegsOpnd>, BGEZAL_FM<0x10>; -def TAILCALL : JumpFJ, FJ<2>, IsTailCall; -def TAILCALL_R : JumpFR, MTLO_FM<8>, IsTailCall; - -def RET : RetBase, MTLO_FM<8>; +def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>; +def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>; +def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>; +def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>, + BGEZ_FM<1, 1>; +def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>, + BGEZ_FM<7, 0>; +def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>, + BGEZ_FM<6, 0>; +def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>, + BGEZ_FM<1, 0>; +def B : UncondBranch; + +def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>; +let Predicates = [NotInMicroMips, HasStdEnc] in { +def JALR : JumpLinkReg<"jalr", GPR32Opnd>, JALR_FM; +def JALRPseudo : JumpLinkRegPseudo; +} +def JALX : JumpLink<"jalx", calltarget>, FJ<0x1D>; +def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>; +def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>; +def BAL_BR : BAL_BR_Pseudo; +def TAILCALL : TailCall; +def TAILCALL_R : TailCallReg; + +def RET : MMRel, RetBase<"ret", GPR32Opnd>, MTLO_FM<8>; // Exception handling related node and instructions. // The conversion sequence is: @@ -973,41 +1083,38 @@ def MIPSehret : SDNode<"MipsISD::EH_RETURN", SDT_MipsEHRET, [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; let Uses = [V0, V1], isTerminator = 1, isReturn = 1, isBarrier = 1 in { - def MIPSeh_return32 : MipsPseudo<(outs), (ins CPURegs:$spoff, CPURegs:$dst), - [(MIPSehret CPURegs:$spoff, CPURegs:$dst)]>; - def MIPSeh_return64 : MipsPseudo<(outs), (ins CPU64Regs:$spoff, - CPU64Regs:$dst), - [(MIPSehret CPU64Regs:$spoff, CPU64Regs:$dst)]>; + def MIPSeh_return32 : MipsPseudo<(outs), (ins GPR32:$spoff, GPR32:$dst), + [(MIPSehret GPR32:$spoff, GPR32:$dst)]>; + def MIPSeh_return64 : MipsPseudo<(outs), (ins GPR64:$spoff, + GPR64:$dst), + [(MIPSehret GPR64:$spoff, GPR64:$dst)]>; } /// Multiply and Divide Instructions. -def MULT : MMRel, Mult<"mult", IIImul, CPURegsOpnd, [HI, LO]>, +def MULT : MMRel, Mult<"mult", II_MULT, GPR32Opnd, [HI0, LO0]>, MULT_FM<0, 0x18>; -def MULTu : MMRel, Mult<"multu", IIImul, CPURegsOpnd, [HI, LO]>, +def MULTu : MMRel, Mult<"multu", II_MULTU, GPR32Opnd, [HI0, LO0]>, MULT_FM<0, 0x19>; -def PseudoMULT : MultDivPseudo; -def PseudoMULTu : MultDivPseudo; -def SDIV : Div<"div", IIIdiv, CPURegsOpnd, [HI, LO]>, MULT_FM<0, 0x1a>; -def UDIV : Div<"divu", IIIdiv, CPURegsOpnd, [HI, LO]>, MULT_FM<0, 0x1b>; -def PseudoSDIV : MultDivPseudo; -def PseudoUDIV : MultDivPseudo; - -def MTHI : MoveToLOHI<"mthi", CPURegs, [HI]>, MTLO_FM<0x11>; -def MTLO : MoveToLOHI<"mtlo", CPURegs, [LO]>, MTLO_FM<0x13>; -def MFHI : MoveFromLOHI<"mfhi", CPURegs, [HI]>, MFLO_FM<0x10>; -def MFLO : MoveFromLOHI<"mflo", CPURegs, [LO]>, MFLO_FM<0x12>; +def SDIV : MMRel, Div<"div", II_DIV, GPR32Opnd, [HI0, LO0]>, + MULT_FM<0, 0x1a>; +def UDIV : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>, + MULT_FM<0, 0x1b>; + +def MTHI : MMRel, MoveToLOHI<"mthi", GPR32Opnd, [HI0]>, MTLO_FM<0x11>; +def MTLO : MMRel, MoveToLOHI<"mtlo", GPR32Opnd, [LO0]>, MTLO_FM<0x13>; +def MFHI : MMRel, MoveFromLOHI<"mfhi", GPR32Opnd, AC0>, MFLO_FM<0x10>; +def MFLO : MMRel, MoveFromLOHI<"mflo", GPR32Opnd, AC0>, MFLO_FM<0x12>; /// Sign Ext In Register Instructions. -def SEB : SignExtInReg<"seb", i8, CPURegs>, SEB_FM<0x10, 0x20>; -def SEH : SignExtInReg<"seh", i16, CPURegs>, SEB_FM<0x18, 0x20>; +def SEB : MMRel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>, SEB_FM<0x10, 0x20>; +def SEH : MMRel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>, SEB_FM<0x18, 0x20>; /// Count Leading -def CLZ : CountLeading0<"clz", CPURegsOpnd>, CLO_FM<0x20>; -def CLO : CountLeading1<"clo", CPURegsOpnd>, CLO_FM<0x21>; +def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd>, CLO_FM<0x20>; +def CLO : MMRel, CountLeading1<"clo", GPR32Opnd>, CLO_FM<0x21>; /// Word Swap Bytes Within Halfwords -def WSBH : SubwordSwap<"wsbh", CPURegsOpnd>, SEB_FM<2, 0x20>; +def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd>, SEB_FM<2, 0x20>; /// No operation. def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>; @@ -1016,85 +1123,100 @@ def NOP : PseudoSE<(outs), (ins), []>, PseudoInstExpansion<(SLL ZERO, ZERO, 0)>; // instructions. The same not happens for stack address copies, so an // add op with mem ComplexPattern is used and the stack address copy // can be matched. It's similar to Sparc LEA_ADDRi -def LEA_ADDiu : EffectiveAddress<"addiu", CPURegs, mem_ea>, LW_FM<9>; +def LEA_ADDiu : MMRel, EffectiveAddress<"addiu", GPR32Opnd>, LW_FM<9>; // MADD*/MSUB* -def MADD : MArithR<"madd", 1>, MULT_FM<0x1c, 0>; -def MADDU : MArithR<"maddu", 1>, MULT_FM<0x1c, 1>; -def MSUB : MArithR<"msub">, MULT_FM<0x1c, 4>; -def MSUBU : MArithR<"msubu">, MULT_FM<0x1c, 5>; -def PseudoMADD : MAddSubPseudo; -def PseudoMADDU : MAddSubPseudo; -def PseudoMSUB : MAddSubPseudo; -def PseudoMSUBU : MAddSubPseudo; - -def RDHWR : ReadHardware, RDHWR_FM; +def MADD : MMRel, MArithR<"madd", II_MADD, 1>, MULT_FM<0x1c, 0>; +def MADDU : MMRel, MArithR<"maddu", II_MADDU, 1>, MULT_FM<0x1c, 1>; +def MSUB : MMRel, MArithR<"msub", II_MSUB>, MULT_FM<0x1c, 4>; +def MSUBU : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM<0x1c, 5>; -def EXT : ExtBase<"ext", CPURegsOpnd>, EXT_FM<0>; -def INS : InsBase<"ins", CPURegsOpnd>, EXT_FM<4>; +let Predicates = [HasStdEnc, NotDSP] in { +def PseudoMULT : MultDivPseudo; +def PseudoMULTu : MultDivPseudo; +def PseudoMFHI : PseudoMFLOHI; +def PseudoMFLO : PseudoMFLOHI; +def PseudoMTLOHI : PseudoMTLOHI; +def PseudoMADD : MAddSubPseudo; +def PseudoMADDU : MAddSubPseudo; +def PseudoMSUB : MAddSubPseudo; +def PseudoMSUBU : MAddSubPseudo; +} -/// Move Control Registers From/To CPU Registers -def MFC0_3OP : MFC3OP<(outs CPURegsOpnd:$rt), - (ins CPURegsOpnd:$rd, uimm16:$sel), - "mfc0\t$rt, $rd, $sel">, MFC3OP_FM<0x10, 0>; +def PseudoSDIV : MultDivPseudo; +def PseudoUDIV : MultDivPseudo; -def MTC0_3OP : MFC3OP<(outs CPURegsOpnd:$rd, uimm16:$sel), - (ins CPURegsOpnd:$rt), - "mtc0\t$rt, $rd, $sel">, MFC3OP_FM<0x10, 4>; +def RDHWR : ReadHardware, RDHWR_FM; -def MFC2_3OP : MFC3OP<(outs CPURegsOpnd:$rt), - (ins CPURegsOpnd:$rd, uimm16:$sel), - "mfc2\t$rt, $rd, $sel">, MFC3OP_FM<0x12, 0>; +def EXT : MMRel, ExtBase<"ext", GPR32Opnd, uimm5, MipsExt>, EXT_FM<0>; +def INS : MMRel, InsBase<"ins", GPR32Opnd, uimm5, MipsIns>, EXT_FM<4>; -def MTC2_3OP : MFC3OP<(outs CPURegsOpnd:$rd, uimm16:$sel), - (ins CPURegsOpnd:$rt), - "mtc2\t$rt, $rd, $sel">, MFC3OP_FM<0x12, 4>; +/// Move Control Registers From/To CPU Registers +def MFC0 : MFC3OP<"mfc0", GPR32Opnd>, MFC3OP_FM<0x10, 0>; +def MTC0 : MFC3OP<"mtc0", GPR32Opnd>, MFC3OP_FM<0x10, 4>; +def MFC2 : MFC3OP<"mfc2", GPR32Opnd>, MFC3OP_FM<0x12, 0>; +def MTC2 : MFC3OP<"mtc2", GPR32Opnd>, MFC3OP_FM<0x12, 4>; //===----------------------------------------------------------------------===// // Instruction aliases //===----------------------------------------------------------------------===// def : InstAlias<"move $dst, $src", - (ADDu CPURegsOpnd:$dst, CPURegsOpnd:$src,ZERO), 1>, - Requires<[NotMips64]>; -def : InstAlias<"move $dst, $src", - (OR CPURegsOpnd:$dst, CPURegsOpnd:$src,ZERO), 1>, - Requires<[NotMips64]>; -def : InstAlias<"bal $offset", (BGEZAL RA, brtarget:$offset), 1>; + (ADDu GPR32Opnd:$dst, GPR32Opnd:$src,ZERO), 1>, + Requires<[NotMips64, NotInMicroMips]>; +def : InstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>; def : InstAlias<"addu $rs, $rt, $imm", - (ADDiu CPURegsOpnd:$rs, CPURegsOpnd:$rt, simm16:$imm), 0>; + (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>; def : InstAlias<"add $rs, $rt, $imm", - (ADDi CPURegsOpnd:$rs, CPURegsOpnd:$rt, simm16:$imm), 0>; + (ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>; def : InstAlias<"and $rs, $rt, $imm", - (ANDi CPURegsOpnd:$rs, CPURegsOpnd:$rt, simm16:$imm), 0>; -def : InstAlias<"j $rs", (JR CPURegs:$rs), 0>, - Requires<[NotMips64]>; -def : InstAlias<"jalr $rs", (JALR RA, CPURegs:$rs)>, Requires<[NotMips64]>; -def : InstAlias<"jal $rs", (JALR RA, CPURegs:$rs), 0>, Requires<[NotMips64]>; -def : InstAlias<"jal $rd,$rs", (JALR CPURegs:$rd, CPURegs:$rs), 0>, - Requires<[NotMips64]>; + (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>; +def : InstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>; +let Predicates = [NotInMicroMips] in { +def : InstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>; +} +def : InstAlias<"jal $rs", (JALR RA, GPR32Opnd:$rs), 0>; +def : InstAlias<"jal $rd,$rs", (JALR GPR32Opnd:$rd, GPR32Opnd:$rs), 0>; def : InstAlias<"not $rt, $rs", - (NOR CPURegsOpnd:$rt, CPURegsOpnd:$rs, ZERO), 1>; + (NOR GPR32Opnd:$rt, GPR32Opnd:$rs, ZERO), 0>; def : InstAlias<"neg $rt, $rs", - (SUB CPURegsOpnd:$rt, ZERO, CPURegsOpnd:$rs), 1>; + (SUB GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>; def : InstAlias<"negu $rt, $rs", - (SUBu CPURegsOpnd:$rt, ZERO, CPURegsOpnd:$rs), 1>; + (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>; def : InstAlias<"slt $rs, $rt, $imm", - (SLTi CPURegsOpnd:$rs, CPURegs:$rt, simm16:$imm), 0>; + (SLTi GPR32Opnd:$rs, GPR32Opnd:$rt, simm16:$imm), 0>; def : InstAlias<"xor $rs, $rt, $imm", - (XORi CPURegsOpnd:$rs, CPURegsOpnd:$rt, uimm16:$imm), 1>, - Requires<[NotMips64]>; + (XORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>; def : InstAlias<"or $rs, $rt, $imm", - (ORi CPURegsOpnd:$rs, CPURegsOpnd:$rt, uimm16:$imm), 1>, - Requires<[NotMips64]>; + (ORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>; def : InstAlias<"nop", (SLL ZERO, ZERO, 0), 1>; -def : InstAlias<"mfc0 $rt, $rd", - (MFC0_3OP CPURegsOpnd:$rt, CPURegsOpnd:$rd, 0), 0>; -def : InstAlias<"mtc0 $rt, $rd", - (MTC0_3OP CPURegsOpnd:$rd, 0, CPURegsOpnd:$rt), 0>; -def : InstAlias<"mfc2 $rt, $rd", - (MFC2_3OP CPURegsOpnd:$rt, CPURegsOpnd:$rd, 0), 0>; -def : InstAlias<"mtc2 $rt, $rd", - (MTC2_3OP CPURegsOpnd:$rd, 0, CPURegsOpnd:$rt), 0>; +def : InstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>; +def : InstAlias<"mtc0 $rt, $rd", (MTC0 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>; +def : InstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>; +def : InstAlias<"mtc2 $rt, $rd", (MTC2 GPR32Opnd:$rt, GPR32Opnd:$rd, 0), 0>; +def : InstAlias<"b $offset", (BEQ ZERO, ZERO, brtarget:$offset), 0>; +def : InstAlias<"bnez $rs,$offset", + (BNE GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>; +def : InstAlias<"beqz $rs,$offset", + (BEQ GPR32Opnd:$rs, ZERO, brtarget:$offset), 0>; +def : InstAlias<"syscall", (SYSCALL 0), 1>; + +def : InstAlias<"break $imm", (BREAK uimm10:$imm, 0), 1>; +def : InstAlias<"break", (BREAK 0, 0), 1>; +def : InstAlias<"ei", (EI ZERO), 1>; +def : InstAlias<"di", (DI ZERO), 1>; + +def : InstAlias<"teq $rs, $rt", (TEQ GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>; +def : InstAlias<"tge $rs, $rt", (TGE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>; +def : InstAlias<"tgeu $rs, $rt", (TGEU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>; +def : InstAlias<"tlt $rs, $rt", (TLT GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>; +def : InstAlias<"tltu $rs, $rt", (TLTU GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>; +def : InstAlias<"tne $rs, $rt", (TNE GPR32Opnd:$rs, GPR32Opnd:$rt, 0), 1>; +def : InstAlias<"sub, $rd, $rs, $imm", + (ADDi GPR32Opnd:$rd, GPR32Opnd:$rs, InvertedImOperand:$imm)>; +def : InstAlias<"subu, $rd, $rs, $imm", + (ADDiu GPR32Opnd:$rd, GPR32Opnd:$rs, InvertedImOperand:$imm)>; //===----------------------------------------------------------------------===// // Assembler Pseudo Instructions @@ -1103,19 +1225,17 @@ def : InstAlias<"mtc2 $rt, $rd", class LoadImm32< string instr_asm, Operand Od, RegisterOperand RO> : MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32), !strconcat(instr_asm, "\t$rt, $imm32")> ; -def LoadImm32Reg : LoadImm32<"li", shamt,CPURegsOpnd>; +def LoadImm32Reg : LoadImm32<"li", uimm5, GPR32Opnd>; class LoadAddress : MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr), !strconcat(instr_asm, "\t$rt, $addr")> ; -def LoadAddr32Reg : LoadAddress<"la", mem, CPURegsOpnd>; +def LoadAddr32Reg : LoadAddress<"la", mem, GPR32Opnd>; class LoadAddressImm : MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32), !strconcat(instr_asm, "\t$rt, $imm32")> ; -def LoadAddr32Imm : LoadAddressImm<"la", shamt,CPURegsOpnd>; - - +def LoadAddr32Imm : LoadAddressImm<"la", uimm5, GPR32Opnd>; //===----------------------------------------------------------------------===// // Arbitrary patterns that map to one or more instructions @@ -1141,13 +1261,13 @@ def : MipsPat<(i32 imm:$imm), (ORi (LUi (HI16 imm:$imm)), (LO16 imm:$imm))>; // Carry MipsPatterns -def : MipsPat<(subc CPURegs:$lhs, CPURegs:$rhs), - (SUBu CPURegs:$lhs, CPURegs:$rhs)>; +def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs), + (SUBu GPR32:$lhs, GPR32:$rhs)>; let Predicates = [HasStdEnc, NotDSP] in { - def : MipsPat<(addc CPURegs:$lhs, CPURegs:$rhs), - (ADDu CPURegs:$lhs, CPURegs:$rhs)>; - def : MipsPat<(addc CPURegs:$src, immSExt16:$imm), - (ADDiu CPURegs:$src, imm:$imm)>; + def : MipsPat<(addc GPR32:$lhs, GPR32:$rhs), + (ADDu GPR32:$lhs, GPR32:$rhs)>; + def : MipsPat<(addc GPR32:$src, immSExt16:$imm), + (ADDiu GPR32:$src, imm:$imm)>; } // Call @@ -1155,8 +1275,8 @@ def : MipsPat<(MipsJmpLink (i32 tglobaladdr:$dst)), (JAL tglobaladdr:$dst)>; def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)), (JAL texternalsym:$dst)>; -//def : MipsPat<(MipsJmpLink CPURegs:$dst), -// (JALR CPURegs:$dst)>; +//def : MipsPat<(MipsJmpLink GPR32:$dst), +// (JALR GPR32:$dst)>; // Tail call def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)), @@ -1178,58 +1298,49 @@ def : MipsPat<(MipsLo tconstpool:$in), (ADDiu ZERO, tconstpool:$in)>; def : MipsPat<(MipsLo tglobaltlsaddr:$in), (ADDiu ZERO, tglobaltlsaddr:$in)>; def : MipsPat<(MipsLo texternalsym:$in), (ADDiu ZERO, texternalsym:$in)>; -def : MipsPat<(add CPURegs:$hi, (MipsLo tglobaladdr:$lo)), - (ADDiu CPURegs:$hi, tglobaladdr:$lo)>; -def : MipsPat<(add CPURegs:$hi, (MipsLo tblockaddress:$lo)), - (ADDiu CPURegs:$hi, tblockaddress:$lo)>; -def : MipsPat<(add CPURegs:$hi, (MipsLo tjumptable:$lo)), - (ADDiu CPURegs:$hi, tjumptable:$lo)>; -def : MipsPat<(add CPURegs:$hi, (MipsLo tconstpool:$lo)), - (ADDiu CPURegs:$hi, tconstpool:$lo)>; -def : MipsPat<(add CPURegs:$hi, (MipsLo tglobaltlsaddr:$lo)), - (ADDiu CPURegs:$hi, tglobaltlsaddr:$lo)>; +def : MipsPat<(add GPR32:$hi, (MipsLo tglobaladdr:$lo)), + (ADDiu GPR32:$hi, tglobaladdr:$lo)>; +def : MipsPat<(add GPR32:$hi, (MipsLo tblockaddress:$lo)), + (ADDiu GPR32:$hi, tblockaddress:$lo)>; +def : MipsPat<(add GPR32:$hi, (MipsLo tjumptable:$lo)), + (ADDiu GPR32:$hi, tjumptable:$lo)>; +def : MipsPat<(add GPR32:$hi, (MipsLo tconstpool:$lo)), + (ADDiu GPR32:$hi, tconstpool:$lo)>; +def : MipsPat<(add GPR32:$hi, (MipsLo tglobaltlsaddr:$lo)), + (ADDiu GPR32:$hi, tglobaltlsaddr:$lo)>; // gp_rel relocs -def : MipsPat<(add CPURegs:$gp, (MipsGPRel tglobaladdr:$in)), - (ADDiu CPURegs:$gp, tglobaladdr:$in)>; -def : MipsPat<(add CPURegs:$gp, (MipsGPRel tconstpool:$in)), - (ADDiu CPURegs:$gp, tconstpool:$in)>; +def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)), + (ADDiu GPR32:$gp, tglobaladdr:$in)>; +def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)), + (ADDiu GPR32:$gp, tconstpool:$in)>; // wrapper_pic class WrapperPat: MipsPat<(MipsWrapper RC:$gp, node:$in), (ADDiuOp RC:$gp, node:$in)>; -def : WrapperPat; -def : WrapperPat; -def : WrapperPat; -def : WrapperPat; -def : WrapperPat; -def : WrapperPat; +def : WrapperPat; +def : WrapperPat; +def : WrapperPat; +def : WrapperPat; +def : WrapperPat; +def : WrapperPat; // Mips does not have "not", so we expand our way -def : MipsPat<(not CPURegs:$in), - (NOR CPURegsOpnd:$in, ZERO)>; +def : MipsPat<(not GPR32:$in), + (NOR GPR32Opnd:$in, ZERO)>; // extended loads -let Predicates = [NotN64, HasStdEnc] in { +let Predicates = [HasStdEnc] in { def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>; def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>; def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>; } -let Predicates = [IsN64, HasStdEnc] in { - def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu_P8 addr:$src)>; - def : MipsPat<(i32 (extloadi8 addr:$src)), (LBu_P8 addr:$src)>; - def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu_P8 addr:$src)>; -} // peepholes -let Predicates = [NotN64, HasStdEnc] in { - def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>; -} -let Predicates = [IsN64, HasStdEnc] in { - def : MipsPat<(store (i32 0), addr:$dst), (SW_P8 ZERO, addr:$dst)>; -} +let Predicates = [HasStdEnc] in +def : MipsPat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>; // brcond patterns multiclass BrcondPats; def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst), (BEQ (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>; +def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst), + (BEQ (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>; +def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst), + (BEQ (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>; def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst), (BEQ (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>; @@ -1258,11 +1373,20 @@ def : MipsPat<(brcond RC:$cond, bb:$dst), (BNEOp RC:$cond, ZEROReg, bb:$dst)>; } -defm : BrcondPats; +defm : BrcondPats; + +def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst), + (BLEZ i32:$lhs, bb:$dst)>; +def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst), + (BGEZ i32:$lhs, bb:$dst)>; // setcc patterns multiclass SeteqPats { + def : MipsPat<(seteq RC:$lhs, 0), + (SLTiuOp RC:$lhs, 1)>; + def : MipsPat<(setne RC:$lhs, 0), + (SLTuOp ZEROReg, RC:$lhs)>; def : MipsPat<(seteq RC:$lhs, RC:$rhs), (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>; def : MipsPat<(setne RC:$lhs, RC:$rhs), @@ -1298,31 +1422,22 @@ multiclass SetgeImmPats; } -defm : SeteqPats; -defm : SetlePats; -defm : SetgtPats; -defm : SetgePats; -defm : SetgeImmPats; +defm : SeteqPats; +defm : SetlePats; +defm : SetgtPats; +defm : SetgePats; +defm : SetgeImmPats; // bswap pattern -def : MipsPat<(bswap CPURegs:$rt), (ROTR (WSBH CPURegs:$rt), 16)>; - -// mflo/hi patterns. -def : MipsPat<(i32 (ExtractLOHI ACRegs:$ac, imm:$lohi_idx)), - (EXTRACT_SUBREG ACRegs:$ac, imm:$lohi_idx)>; +def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>; // Load halfword/word patterns. let AddedComplexity = 40 in { - let Predicates = [NotN64, HasStdEnc] in { + let Predicates = [HasStdEnc] in { def : LoadRegImmPat; def : LoadRegImmPat; def : LoadRegImmPat; } - let Predicates = [IsN64, HasStdEnc] in { - def : LoadRegImmPat; - def : LoadRegImmPat; - def : LoadRegImmPat; - } } //===----------------------------------------------------------------------===// @@ -1343,6 +1458,11 @@ include "Mips16InstrInfo.td" include "MipsDSPInstrFormats.td" include "MipsDSPInstrInfo.td" +// MSA +include "MipsMSAInstrFormats.td" +include "MipsMSAInstrInfo.td" + // Micromips include "MicroMipsInstrFormats.td" include "MicroMipsInstrInfo.td" +include "MicroMipsInstrFPU.td"