diff options
Diffstat (limited to 'lib/Target/Mips/MipsInstrInfo.td')
-rw-r--r-- | lib/Target/Mips/MipsInstrInfo.td | 168 |
1 files changed, 118 insertions, 50 deletions
diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index 89a5854bede0..e0d818b749df 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -208,10 +208,10 @@ def NotMips64r6 : Predicate<"!Subtarget->hasMips64r6()">, AssemblerPredicate<"!FeatureMips64r6">; def HasMicroMips32r6 : Predicate<"Subtarget->inMicroMips32r6Mode()">, AssemblerPredicate<"FeatureMicroMips,FeatureMips32r6">; -def HasMicroMips64r6 : Predicate<"Subtarget->inMicroMips64r6Mode()">, - AssemblerPredicate<"FeatureMicroMips,FeatureMips64r6">; def InMips16Mode : Predicate<"Subtarget->inMips16Mode()">, AssemblerPredicate<"FeatureMips16">; +def NotInMips16Mode : Predicate<"!Subtarget->inMips16Mode()">, + AssemblerPredicate<"!FeatureMips16">; def HasCnMips : Predicate<"Subtarget->hasCnMips()">, AssemblerPredicate<"FeatureCnMips">; def NotCnMips : Predicate<"!Subtarget->hasCnMips()">, @@ -220,6 +220,8 @@ def IsSym32 : Predicate<"Subtarget->HasSym32()">, AssemblerPredicate<"FeatureSym32">; def IsSym64 : Predicate<"!Subtarget->HasSym32()">, AssemblerPredicate<"!FeatureSym32">; +def IsN64 : Predicate<"Subtarget->isABI_N64()">; +def IsNotN64 : Predicate<"!Subtarget->isABI_N64()">; def RelocNotPIC : Predicate<"!TM.isPositionIndependent()">; def RelocPIC : Predicate<"TM.isPositionIndependent()">; def NoNaNsFPMath : Predicate<"TM.Options.NoNaNsFPMath">; @@ -309,9 +311,6 @@ class ISA_MICROMIPS { list<Predicate> InsnPredicates = [InMicroMips]; } class ISA_MICROMIPS32R6 { list<Predicate> InsnPredicates = [HasMicroMips32r6]; } -class ISA_MICROMIPS64R6 { - list<Predicate> InsnPredicates = [HasMicroMips64r6]; -} class ISA_MICROMIPS32_NOT_MIPS32R6 { list<Predicate> InsnPredicates = [InMicroMips, NotMips32r6]; } @@ -389,8 +388,8 @@ class ASE_MT { // Class used for separating microMIPSr6 and microMIPS (r3) instruction. // It can be used only on instructions that doesn't inherit PredicateControl. -class ISA_MICROMIPS_NOT_32R6_64R6 : PredicateControl { - let InsnPredicates = [InMicroMips, NotMips32r6, NotMips64r6]; +class ISA_MICROMIPS_NOT_32R6 : PredicateControl { + let InsnPredicates = [InMicroMips, NotMips32r6]; } class ASE_NOT_DSP { @@ -401,6 +400,16 @@ class MADD4 { list<Predicate> AdditionalPredicates = [HasMadd4]; } +// Classses used for separating expansions that differ based on the ABI in +// use. +class ABI_N64 { + list<Predicate> AdditionalPredicates = [IsN64]; +} + +class ABI_NOT_N64 { + list<Predicate> AdditionalPredicates = [IsNotN64]; +} + //===----------------------------------------------------------------------===// class MipsPat<dag pattern, dag result> : Pat<pattern, result>, PredicateControl { @@ -678,9 +687,14 @@ def ConstantUImm5Plus32NormalizeAsmOperandClass // We must also subtract 32 when we render the operand. let RenderMethod = "addConstantUImmOperands<5, 32, -32>"; } +def ConstantUImm5Plus1ReportUImm6AsmOperandClass + : ConstantUImmAsmOperandClass< + 5, [ConstantUImm5Plus32NormalizeAsmOperandClass], 1>{ + let Name = "ConstantUImm5_Plus1_Report_UImm6"; +} def ConstantUImm5Plus1AsmOperandClass : ConstantUImmAsmOperandClass< - 5, [ConstantUImm5Plus32NormalizeAsmOperandClass], 1>; + 5, [ConstantUImm5Plus1ReportUImm6AsmOperandClass], 1>; def ConstantUImm5AsmOperandClass : ConstantUImmAsmOperandClass<5, [ConstantUImm5Plus1AsmOperandClass]>; def ConstantSImm5AsmOperandClass @@ -787,6 +801,13 @@ def uimm5_plus1 : Operand<i32> { let ParserMatchClass = ConstantUImm5Plus1AsmOperandClass; } +def uimm5_plus1_report_uimm6 : Operand<i32> { + let PrintMethod = "printUImm<6, 1>"; + let EncoderMethod = "getUImmWithOffsetEncoding<5, 1>"; + let DecoderMethod = "DecodeUImmWithOffset<5, 1>"; + let ParserMatchClass = ConstantUImm5Plus1ReportUImm6AsmOperandClass; +} + def uimm5_plus32 : Operand<i32> { let PrintMethod = "printUImm<5, 32>"; let ParserMatchClass = ConstantUImm5Plus32AsmOperandClass; @@ -871,7 +892,7 @@ def uimm16_altrelaxed : Operand<i32> { // Like uimm5 but reports a less confusing error for 32-63 when // an instruction alias permits that. def uimm5_report_uimm6 : Operand<i32> { - let PrintMethod = "printUImm<5>"; + let PrintMethod = "printUImm<6>"; let ParserMatchClass = ConstantUImm5ReportUImm6AsmOperandClass; } @@ -1193,6 +1214,25 @@ def immSExt16Plus1 : PatLeaf<(imm), [{ return isInt<17>(N->getSExtValue()) && isInt<16>(N->getSExtValue() + 1); }]>; +def immZExtRange2To64 : PatLeaf<(imm), [{ + return isUInt<7>(N->getZExtValue()) && (N->getZExtValue() >= 2) && + (N->getZExtValue() <= 64); +}]>; + +def ORiPred : PatLeaf<(imm), [{ + return isUInt<16>(N->getZExtValue()) && !isInt<16>(N->getSExtValue()); +}], LO16>; + +def LUiPred : PatLeaf<(imm), [{ + int64_t Val = N->getSExtValue(); + return !isInt<16>(Val) && isInt<32>(Val) && !(Val & 0xffff); +}]>; + +def LUiORiPred : PatLeaf<(imm), [{ + int64_t SVal = N->getSExtValue(); + return isInt<32>(SVal) && (SVal & 0xffff); +}]>; + // Mips Address Mode! SDNode frameindex could possibily be a match // since load and store instructions from stack used it. def addr : @@ -1370,27 +1410,47 @@ class SW_FT3<string opstr, RegisterOperand RC, InstrItinClass Itin, // Conditional Branch class CBranch<string opstr, DAGOperand opnd, PatFrag cond_op, - RegisterOperand RO, bit DelaySlot = 1> : + RegisterOperand RO> : InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset), !strconcat(opstr, "\t$rs, $rt, $offset"), [(brcond (i32 (cond_op RO:$rs, RO:$rt)), bb:$offset)], II_BCC, FrmI, opstr> { let isBranch = 1; let isTerminator = 1; - let hasDelaySlot = DelaySlot; + let hasDelaySlot = 1; + let Defs = [AT]; + bit isCTI = 1; +} + +class CBranchLikely<string opstr, DAGOperand opnd, RegisterOperand RO> : + InstSE<(outs), (ins RO:$rs, RO:$rt, opnd:$offset), + !strconcat(opstr, "\t$rs, $rt, $offset"), [], II_BCC, FrmI, opstr> { + let isBranch = 1; + let isTerminator = 1; + let hasDelaySlot = 1; let Defs = [AT]; bit isCTI = 1; } class CBranchZero<string opstr, DAGOperand opnd, PatFrag cond_op, - RegisterOperand RO, bit DelaySlot = 1> : + RegisterOperand RO> : InstSE<(outs), (ins RO:$rs, opnd:$offset), !strconcat(opstr, "\t$rs, $offset"), [(brcond (i32 (cond_op RO:$rs, 0)), bb:$offset)], II_BCCZ, FrmI, opstr> { let isBranch = 1; let isTerminator = 1; - let hasDelaySlot = DelaySlot; + let hasDelaySlot = 1; + let Defs = [AT]; + bit isCTI = 1; +} + +class CBranchZeroLikely<string opstr, DAGOperand opnd, RegisterOperand RO> : + InstSE<(outs), (ins RO:$rs, opnd:$offset), + !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZ, FrmI, opstr> { + let isBranch = 1; + let isTerminator = 1; + let hasDelaySlot = 1; let Defs = [AT]; bit isCTI = 1; } @@ -1423,9 +1483,9 @@ class JumpFJ<DAGOperand opnd, string opstr, SDPatternOperator operator, } // Unconditional branch -class UncondBranch<Instruction BEQInst> : +class UncondBranch<Instruction BEQInst, DAGOperand opnd> : PseudoSE<(outs), (ins brtarget:$offset), [(br bb:$offset)], II_B>, - PseudoInstExpansion<(BEQInst ZERO, ZERO, brtarget:$offset)> { + PseudoInstExpansion<(BEQInst ZERO, ZERO, opnd:$offset)> { let isBranch = 1; let isTerminator = 1; let isBarrier = 1; @@ -1466,10 +1526,10 @@ let isCall=1, hasDelaySlot=1, isCTI=1, Defs = [RA] in { [], II_JALR, FrmR, opstr>; class BGEZAL_FT<string opstr, DAGOperand opnd, - RegisterOperand RO, bit DelaySlot = 1> : + RegisterOperand RO> : InstSE<(outs), (ins RO:$rs, opnd:$offset), !strconcat(opstr, "\t$rs, $offset"), [], II_BCCZAL, FrmI, opstr> { - let hasDelaySlot = DelaySlot; + let hasDelaySlot = 1; } } @@ -1481,7 +1541,7 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1, PseudoInstExpansion<(JumpInst Opnd:$target)>; class TailCallReg<RegisterOperand RO> : - MipsPseudo<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>; + PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>; } class BAL_BR_Pseudo<Instruction RealInst> : @@ -1659,15 +1719,17 @@ class ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd, Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm, SDPatternOperator Op = null_frag> : InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size), - !strconcat(opstr, " $rt, $rs, $pos, $size"), + !strconcat(opstr, "\t$rt, $rs, $pos, $size"), [(set RO:$rt, (Op RO:$rs, PosImm:$pos, SizeImm:$size))], II_EXT, FrmR, opstr>, ISA_MIPS32R2; +// 'ins' and its' 64 bit variants are matched by C++ code. class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd, - Operand SizeOpnd, SDPatternOperator Op = null_frag>: + Operand SizeOpnd, PatFrag PosImm, PatFrag SizeImm>: InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, SizeOpnd:$size, RO:$src), - !strconcat(opstr, " $rt, $rs, $pos, $size"), - [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size, RO:$src))], + !strconcat(opstr, "\t$rt, $rs, $pos, $size"), + [(set RO:$rt, (null_frag RO:$rs, PosImm:$pos, SizeImm:$size, + RO:$src))], II_INS, FrmR, opstr>, ISA_MIPS32R2 { let Constraints = "$src = $rt"; } @@ -1978,31 +2040,32 @@ def SC : SCBase<"sc", GPR32Opnd>, LW_FM<0x38>, PTR_32, ISA_MIPS2_NOT_32R6_64R6; /// Jump and Branch Instructions def J : MMRel, JumpFJ<jmptarget, "j", br, bb, "j">, FJ<2>, - AdditionalRequires<[RelocNotPIC]>, IsBranch; + AdditionalRequires<[RelocNotPIC, NotInMicroMips]>, IsBranch; def JR : MMRel, IndirectBranch<"jr", GPR32Opnd>, MTLO_FM<8>, ISA_MIPS1_NOT_32R6_64R6; def BEQ : MMRel, CBranch<"beq", brtarget, seteq, GPR32Opnd>, BEQ_FM<4>; -def BEQL : MMRel, CBranch<"beql", brtarget, seteq, GPR32Opnd, 0>, +def BEQL : MMRel, CBranchLikely<"beql", brtarget, GPR32Opnd>, BEQ_FM<20>, ISA_MIPS2_NOT_32R6_64R6; def BNE : MMRel, CBranch<"bne", brtarget, setne, GPR32Opnd>, BEQ_FM<5>; -def BNEL : MMRel, CBranch<"bnel", brtarget, setne, GPR32Opnd, 0>, +def BNEL : MMRel, CBranchLikely<"bnel", brtarget, GPR32Opnd>, BEQ_FM<21>, ISA_MIPS2_NOT_32R6_64R6; def BGEZ : MMRel, CBranchZero<"bgez", brtarget, setge, GPR32Opnd>, BGEZ_FM<1, 1>; -def BGEZL : MMRel, CBranchZero<"bgezl", brtarget, setge, GPR32Opnd, 0>, +def BGEZL : MMRel, CBranchZeroLikely<"bgezl", brtarget, GPR32Opnd>, BGEZ_FM<1, 3>, ISA_MIPS2_NOT_32R6_64R6; def BGTZ : MMRel, CBranchZero<"bgtz", brtarget, setgt, GPR32Opnd>, BGEZ_FM<7, 0>; -def BGTZL : MMRel, CBranchZero<"bgtzl", brtarget, setgt, GPR32Opnd, 0>, +def BGTZL : MMRel, CBranchZeroLikely<"bgtzl", brtarget, GPR32Opnd>, BGEZ_FM<23, 0>, ISA_MIPS2_NOT_32R6_64R6; def BLEZ : MMRel, CBranchZero<"blez", brtarget, setle, GPR32Opnd>, BGEZ_FM<6, 0>; -def BLEZL : MMRel, CBranchZero<"blezl", brtarget, setle, GPR32Opnd, 0>, +def BLEZL : MMRel, CBranchZeroLikely<"blezl", brtarget, GPR32Opnd>, BGEZ_FM<22, 0>, ISA_MIPS2_NOT_32R6_64R6; def BLTZ : MMRel, CBranchZero<"bltz", brtarget, setlt, GPR32Opnd>, BGEZ_FM<1, 0>; -def BLTZL : MMRel, CBranchZero<"bltzl", brtarget, setlt, GPR32Opnd, 0>, +def BLTZL : MMRel, CBranchZeroLikely<"bltzl", brtarget, GPR32Opnd>, BGEZ_FM<1, 2>, ISA_MIPS2_NOT_32R6_64R6; -def B : UncondBranch<BEQ>; +def B : UncondBranch<BEQ, brtarget>, + AdditionalRequires<[NotInMicroMips]>; def JAL : MMRel, JumpLink<"jal", calltarget>, FJ<3>; let AdditionalPredicates = [NotInMicroMips] in { @@ -2014,15 +2077,15 @@ def JALX : MMRel, JumpLink<"jalx", calltarget>, FJ<0x1D>, ISA_MIPS32_NOT_32R6_64R6; def BGEZAL : MMRel, BGEZAL_FT<"bgezal", brtarget, GPR32Opnd>, BGEZAL_FM<0x11>, ISA_MIPS1_NOT_32R6_64R6; -def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd, 0>, +def BGEZALL : MMRel, BGEZAL_FT<"bgezall", brtarget, GPR32Opnd>, BGEZAL_FM<0x13>, ISA_MIPS2_NOT_32R6_64R6; def BLTZAL : MMRel, BGEZAL_FT<"bltzal", brtarget, GPR32Opnd>, BGEZAL_FM<0x10>, ISA_MIPS1_NOT_32R6_64R6; -def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd, 0>, +def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd>, BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6; def BAL_BR : BAL_BR_Pseudo<BGEZAL>; -let Predicates = [NotInMicroMips] in { +let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips] in { def TAILCALL : TailCall<J, jmptarget>; } @@ -2039,6 +2102,7 @@ class PseudoIndirectBranchBase<RegisterOperand RO> : let isBranch = 1; let isIndirectBranch = 1; bit isCTI = 1; + let Predicates = [NotInMips16Mode]; } def PseudoIndirectBranch : PseudoIndirectBranchBase<GPR32Opnd>; @@ -2171,7 +2235,8 @@ let AdditionalPredicates = [NotInMicroMips] in { immZExt5, immZExt5Plus1, MipsExt>, EXT_FM<0>; def INS : MMRel, StdMMR6Rel, InsBase<"ins", GPR32Opnd, uimm5, - uimm5_inssize_plus1, MipsIns>, + uimm5_inssize_plus1, immZExt5, + immZExt5Plus1>, EXT_FM<4>; } /// Move Control Registers From/To CPU Registers @@ -2665,15 +2730,20 @@ multiclass MaterializeImms<ValueType VT, Register ZEROReg, Instruction ADDiuOp, Instruction LUiOp, Instruction ORiOp> { -// Small immediates -def : MipsPat<(VT immSExt16:$imm), (ADDiuOp ZEROReg, imm:$imm)>; -def : MipsPat<(VT immZExt16:$imm), (ORiOp ZEROReg, imm:$imm)>; +// Constant synthesis previously relied on the ordering of the patterns below. +// By making the predicates they use non-overlapping, the patterns were +// reordered so that the effect of the newly introduced predicates can be +// observed. + +// Arbitrary immediates +def : MipsPat<(VT LUiORiPred:$imm), (ORiOp (LUiOp (HI16 imm:$imm)), (LO16 imm:$imm))>; // Bits 32-16 set, sign/zero extended. -def : MipsPat<(VT immSExt32Low16Zero:$imm), (LUiOp (HI16 imm:$imm))>; +def : MipsPat<(VT LUiPred:$imm), (LUiOp (HI16 imm:$imm))>; -// Arbitrary immediates -def : MipsPat<(VT immSExt32:$imm), (ORiOp (LUiOp (HI16 imm:$imm)), (LO16 imm:$imm))>; +// Small immediates +def : MipsPat<(VT ORiPred:$imm), (ORiOp ZEROReg, imm:$imm)>; +def : MipsPat<(VT immSExt16:$imm), (ADDiuOp ZEROReg, imm:$imm)>; } let AdditionalPredicates = [NotInMicroMips] in @@ -2706,10 +2776,12 @@ def : MipsPat<(MipsJmpLink (i32 texternalsym:$dst)), // (JALR GPR32:$dst)>; // Tail call -def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)), - (TAILCALL tglobaladdr:$dst)>; -def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)), - (TAILCALL texternalsym:$dst)>; +let AdditionalPredicates = [NotInMicroMips] in { + def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)), + (TAILCALL tglobaladdr:$dst)>; + def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)), + (TAILCALL texternalsym:$dst)>; +} // hi/lo relocs multiclass MipsHiLoRelocs<Instruction Lui, Instruction Addiu, Register ZeroReg, RegisterOperand GPROpnd> { @@ -2748,9 +2820,9 @@ def : MipsPat<(MipsGotHi texternalsym:$in), (LUi texternalsym:$in)>; // gp_rel relocs def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)), - (ADDiu GPR32:$gp, tglobaladdr:$in)>; + (ADDiu GPR32:$gp, tglobaladdr:$in)>, ABI_NOT_N64; def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)), - (ADDiu GPR32:$gp, tconstpool:$in)>; + (ADDiu GPR32:$gp, tconstpool:$in)>, ABI_NOT_N64; // wrapper_pic class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>: @@ -2937,10 +3009,6 @@ include "MicroMipsInstrFPU.td" include "MicroMips32r6InstrFormats.td" include "MicroMips32r6InstrInfo.td" -// Micromips64 r6 -include "MicroMips64r6InstrFormats.td" -include "MicroMips64r6InstrInfo.td" - // Micromips DSP include "MicroMipsDSPInstrFormats.td" include "MicroMipsDSPInstrInfo.td" |