aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/Mips/MipsInstrInfo.td
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/Mips/MipsInstrInfo.td')
-rw-r--r--lib/Target/Mips/MipsInstrInfo.td168
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"