aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/Target/Mips/Mips.td8
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp37
-rw-r--r--lib/Target/Mips/MipsISelLowering.h4
-rw-r--r--lib/Target/Mips/MipsInstrFPU.td26
-rw-r--r--lib/Target/Mips/MipsInstrInfo.cpp25
-rw-r--r--lib/Target/Mips/MipsInstrInfo.td4
-rw-r--r--lib/Target/Mips/MipsRegisterInfo.td12
-rw-r--r--lib/Target/Mips/MipsSubtarget.cpp1
-rw-r--r--lib/Target/Mips/MipsSubtarget.h2
9 files changed, 90 insertions, 29 deletions
diff --git a/lib/Target/Mips/Mips.td b/lib/Target/Mips/Mips.td
index 79ae5d2..79a78d8 100644
--- a/lib/Target/Mips/Mips.td
+++ b/lib/Target/Mips/Mips.td
@@ -39,6 +39,8 @@ def FeatureFP64Bit : SubtargetFeature<"fp64", "IsFP64bit", "true",
"Support 64-bit FP registers.">;
def FeatureSingleFloat : SubtargetFeature<"single-float", "IsSingleFloat",
"true", "Only supports single precision float">;
+def FeatureMips1 : SubtargetFeature<"mips1", "MipsArchVersion", "Mips1",
+ "Mips1 ISA Support">;
def FeatureMips2 : SubtargetFeature<"mips2", "MipsArchVersion", "Mips2",
"Mips2 ISA Support">;
def FeatureO32 : SubtargetFeature<"o32", "MipsABI", "O32",
@@ -67,9 +69,9 @@ def FeatureBitCount : SubtargetFeature<"bitcount", "HasBitCount", "true",
class Proc<string Name, list<SubtargetFeature> Features>
: Processor<Name, MipsGenericItineraries, Features>;
-def : Proc<"mips1", []>;
-def : Proc<"r2000", []>;
-def : Proc<"r3000", []>;
+def : Proc<"mips1", [FeatureMips1]>;
+def : Proc<"r2000", [FeatureMips1]>;
+def : Proc<"r3000", [FeatureMips1]>;
def : Proc<"mips2", [FeatureMips2]>;
def : Proc<"r6000", [FeatureMips2]>;
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp
index a0e5f30..9281940 100644
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -48,6 +48,7 @@ getTargetNodeName(unsigned Opcode) const
case MipsISD::FPSelectCC : return "MipsISD::FPSelectCC";
case MipsISD::FPBrcond : return "MipsISD::FPBrcond";
case MipsISD::FPCmp : return "MipsISD::FPCmp";
+ case MipsISD::FPRound : return "MipsISD::FPRound";
default : return NULL;
}
}
@@ -96,8 +97,10 @@ MipsTargetLowering(MipsTargetMachine &TM): TargetLowering(TM)
setOperationAction(ISD::SELECT, MVT::f32, Custom);
setOperationAction(ISD::SELECT, MVT::i32, Custom);
setOperationAction(ISD::SETCC, MVT::f32, Custom);
+ setOperationAction(ISD::SETCC, MVT::f64, Custom);
setOperationAction(ISD::BRCOND, MVT::Other, Custom);
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Custom);
+ setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
// We custom lower AND/OR to handle the case where the DAG contain 'ands/ors'
// with operands comming from setcc fp comparions. This is necessary since
@@ -166,6 +169,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG)
case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG);
+ case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG);
case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
case ISD::JumpTable: return LowerJumpTable(Op, DAG);
@@ -359,6 +363,39 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
//===----------------------------------------------------------------------===//
SDValue MipsTargetLowering::
+LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG)
+{
+ if (!Subtarget->isMips1())
+ return Op;
+
+ MachineFunction &MF = DAG.getMachineFunction();
+ unsigned CCReg = AddLiveIn(MF, Mips::FCR31, Mips::CCRRegisterClass);
+
+ SDValue Chain = DAG.getEntryNode();
+ DebugLoc dl = Op.getDebugLoc();
+ SDValue Src = Op.getOperand(0);
+
+ // Set the condition register
+ SDValue CondReg = DAG.getCopyFromReg(Chain, dl, CCReg, MVT::i32);
+ CondReg = DAG.getCopyToReg(Chain, dl, Mips::AT, CondReg);
+ CondReg = DAG.getCopyFromReg(CondReg, dl, Mips::AT, MVT::i32);
+
+ SDValue Cst = DAG.getConstant(3, MVT::i32);
+ SDValue Or = DAG.getNode(ISD::OR, dl, MVT::i32, CondReg, Cst);
+ Cst = DAG.getConstant(2, MVT::i32);
+ SDValue Xor = DAG.getNode(ISD::XOR, dl, MVT::i32, Or, Cst);
+
+ SDValue InFlag(0, 0);
+ CondReg = DAG.getCopyToReg(Chain, dl, Mips::FCR31, Xor, InFlag);
+
+ // Emit the round instruction and bit convert to integer
+ SDValue Trunc = DAG.getNode(MipsISD::FPRound, dl, MVT::f32,
+ Src, CondReg.getValue(1));
+ SDValue BitCvt = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Trunc);
+ return BitCvt;
+}
+
+SDValue MipsTargetLowering::
LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG)
{
SDValue Chain = Op.getOperand(0);
diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h
index 1128982..55cd6ea 100644
--- a/lib/Target/Mips/MipsISelLowering.h
+++ b/lib/Target/Mips/MipsISelLowering.h
@@ -55,6 +55,9 @@ namespace llvm {
// Floating Point Compare
FPCmp,
+ // Floating Point Rounding
+ FPRound,
+
// Return
Ret
};
@@ -98,6 +101,7 @@ namespace llvm {
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG);
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG);
SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG);
+ SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG);
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG);
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG);
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG);
diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td
index b734a7c..b6a6d2f 100644
--- a/lib/Target/Mips/MipsInstrFPU.td
+++ b/lib/Target/Mips/MipsInstrFPU.td
@@ -30,6 +30,8 @@ def SDT_MipsFPCmp : SDTypeProfile<0, 3, [SDTCisSameAs<0, 1>, SDTCisFP<0>,
SDTCisInt<2>]>;
def SDT_MipsFPSelectCC : SDTypeProfile<1, 4, [SDTCisInt<1>, SDTCisInt<4>,
SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>]>;
+
+def MipsFPRound : SDNode<"MipsISD::FPRound", SDTFPRoundOp, [SDNPOptInFlag]>;
def MipsFPBrcond : SDNode<"MipsISD::FPBrcond", SDT_MipsFPBrcond,
[SDNPHasChain]>;
def MipsFPCmp : SDNode<"MipsISD::FPCmp", SDT_MipsFPCmp>;
@@ -66,7 +68,7 @@ multiclass FFR1_1<bits<6> funct, string asmstr>
def _S32 : FFR<0x11, funct, 0x0, (outs FGR32:$fd), (ins FGR32:$fs),
!strconcat(asmstr, ".s $fd, $fs"), []>;
- def _D32 : FFR<0x11, funct, 0x1, (outs AFGR64:$fd), (ins AFGR64:$fs),
+ def _D32 : FFR<0x11, funct, 0x1, (outs FGR32:$fd), (ins AFGR64:$fs),
!strconcat(asmstr, ".d $fd, $fs"), []>, Requires<[In32BitMode]>;
}
@@ -157,12 +159,12 @@ let ft = 0 in {
// regardless of register aliasing.
let fd = 0 in {
/// Move Control Registers From/To CPU Registers
- ///def CFC1 : FFR<0x11, 0x0, 0x2, (outs CPURegs:$rt), (ins FGR32:$fs),
- /// "cfc1 $rt, $fs", []>;
+ def CFC1 : FFR<0x11, 0x0, 0x2, (outs CPURegs:$rt), (ins CCR:$fs),
+ "cfc1 $rt, $fs", []>;
- ///def CTC1 : FFR<0x11, 0x0, 0x6, (outs CPURegs:$rt), (ins FGR32:$fs),
- /// "ctc1 $rt, $fs", []>;
- ///
+ def CTC1 : FFR<0x11, 0x0, 0x6, (outs CCR:$rt), (ins CPURegs:$fs),
+ "ctc1 $fs, $rt", []>;
+
def MFC1 : FFR<0x11, 0x00, 0x00, (outs CPURegs:$rt), (ins FGR32:$fs),
"mfc1 $rt, $fs", []>;
@@ -272,6 +274,9 @@ def Select_FCC_S32 : PseudoFPSelCC<FGR32, "# MipsSelect_FCC_S32_f32">;
def Select_FCC_D32 : PseudoFPSelCC<AFGR64, "# MipsSelect_FCC_D32_f32">,
Requires<[In32BitMode]>;
+def MOVCCRToCCR : MipsPseudo<(outs CCR:$dst), (ins CCR:$src),
+ "# MOVCCRToCCR", []>;
+
//===----------------------------------------------------------------------===//
// Floating Point Patterns
//===----------------------------------------------------------------------===//
@@ -288,3 +293,12 @@ def : Pat<(i32 (fp_to_sint FGR32:$src)), (MFC1 (TRUNC_W_S32 FGR32:$src))>;
def : Pat<(i32 (bitconvert FGR32:$src)), (MFC1 FGR32:$src)>;
def : Pat<(f32 (bitconvert CPURegs:$src)), (MTC1 CPURegs:$src)>;
+
+let Predicates = [In32BitMode] in {
+ def : Pat<(f32 (fround AFGR64:$src)), (CVTS_D32 AFGR64:$src)>;
+ def : Pat<(f64 (fextend FGR32:$src)), (CVTD_S32 FGR32:$src)>;
+}
+
+// MipsFPRound is only emitted for MipsI targets.
+def : Pat<(f32 (MipsFPRound AFGR64:$src)), (CVTW_D32 AFGR64:$src)>;
+
diff --git a/lib/Target/Mips/MipsInstrInfo.cpp b/lib/Target/Mips/MipsInstrInfo.cpp
index 2ccbe89..6225fa9 100644
--- a/lib/Target/Mips/MipsInstrInfo.cpp
+++ b/lib/Target/Mips/MipsInstrInfo.cpp
@@ -55,7 +55,8 @@ isMoveInstr(const MachineInstr &MI, unsigned &SrcReg, unsigned &DstReg,
if (MI.getOpcode() == Mips::FMOV_S32 ||
MI.getOpcode() == Mips::FMOV_D32 ||
MI.getOpcode() == Mips::MFC1 ||
- MI.getOpcode() == Mips::MTC1 ) {
+ MI.getOpcode() == Mips::MTC1 ||
+ MI.getOpcode() == Mips::MOVCCRToCCR) {
DstReg = MI.getOperand(0).getReg();
SrcReg = MI.getOperand(1).getReg();
return true;
@@ -69,6 +70,7 @@ isMoveInstr(const MachineInstr &MI, unsigned &SrcReg, unsigned &DstReg,
return true;
}
}
+
return false;
}
@@ -132,22 +134,23 @@ copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
if (I != MBB.end()) DL = I->getDebugLoc();
if (DestRC != SrcRC) {
- // Moves between coprocessors and cpu
+
+ // Copy to/from FCR31 condition register
if ((DestRC == Mips::CPURegsRegisterClass) &&
+ (SrcRC == Mips::CCRRegisterClass))
+ BuildMI(MBB, I, DL, get(Mips::CFC1), DestReg).addReg(SrcReg);
+ else if ((DestRC == Mips::CCRRegisterClass) &&
+ (SrcRC == Mips::CPURegsRegisterClass))
+ BuildMI(MBB, I, DL, get(Mips::CTC1), DestReg).addReg(SrcReg);
+
+ // Moves between coprocessors and cpu
+ else if ((DestRC == Mips::CPURegsRegisterClass) &&
(SrcRC == Mips::FGR32RegisterClass))
BuildMI(MBB, I, DL, get(Mips::MFC1), DestReg).addReg(SrcReg);
else if ((DestRC == Mips::FGR32RegisterClass) &&
(SrcRC == Mips::CPURegsRegisterClass))
BuildMI(MBB, I, DL, get(Mips::MTC1), DestReg).addReg(SrcReg);
- // Condition registers
- else if ((SrcRC == Mips::CCRRegisterClass) &&
- (SrcReg == Mips::FCR31))
- return true; // This register is used implicitly, no copy needed.
- else if ((DestRC == Mips::CCRRegisterClass) &&
- (DestReg == Mips::FCR31))
- return true; // This register is used implicitly, no copy needed.
-
// Move from/to Hi/Lo registers
else if ((DestRC == Mips::HILORegisterClass) &&
(SrcRC == Mips::CPURegsRegisterClass)) {
@@ -172,6 +175,8 @@ copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
BuildMI(MBB, I, DL, get(Mips::FMOV_S32), DestReg).addReg(SrcReg);
else if (DestRC == Mips::AFGR64RegisterClass)
BuildMI(MBB, I, DL, get(Mips::FMOV_D32), DestReg).addReg(SrcReg);
+ else if (DestRC == Mips::CCRRegisterClass)
+ BuildMI(MBB, I, DL, get(Mips::MOVCCRToCCR), DestReg).addReg(SrcReg);
else
// Can't copy this register
return false;
diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td
index e30dfbf..b9276fe 100644
--- a/lib/Target/Mips/MipsInstrInfo.td
+++ b/lib/Target/Mips/MipsInstrInfo.td
@@ -518,10 +518,10 @@ let Uses = [LO] in
/// Sign Ext In Register Instructions.
let Predicates = [HasSEInReg] in {
- let shamt = 0x10, rs = 0 in
+ let shamt = 0x10, rs = 0 in
def SEB : SignExtInReg<0x21, "seb", i8>;
- let shamt = 0x18, rs = 0 in
+ let shamt = 0x18, rs = 0 in
def SEH : SignExtInReg<0x20, "seh", i16>;
}
diff --git a/lib/Target/Mips/MipsRegisterInfo.td b/lib/Target/Mips/MipsRegisterInfo.td
index aa94269..bbb275c 100644
--- a/lib/Target/Mips/MipsRegisterInfo.td
+++ b/lib/Target/Mips/MipsRegisterInfo.td
@@ -131,7 +131,7 @@ let Namespace = "Mips" in {
def LO : Register<"lo">, DwarfRegNum<[65]>;
// Status flags register
- def FCR31 : Register<"FCR31">;
+ def FCR31 : Register<"31">;
}
//===----------------------------------------------------------------------===//
@@ -244,11 +244,9 @@ def AFGR64 : RegisterClass<"Mips", [f64], 64,
}];
}
-def CCR : RegisterClass<"Mips", [i32], 32, [FCR31]> {
- let CopyCost = -1; // Don't allow copying of status registers.
-}
+// Condition Register for floating point operations
+def CCR : RegisterClass<"Mips", [i32], 32, [FCR31]>;
-def HILO : RegisterClass<"Mips", [i32], 32, [HI, LO]> {
- //let CopyCost = -1; // Don't allow copying of hi/lo registers.
-}
+// Hi/Lo Registers
+def HILO : RegisterClass<"Mips", [i32], 32, [HI, LO]>;
diff --git a/lib/Target/Mips/MipsSubtarget.cpp b/lib/Target/Mips/MipsSubtarget.cpp
index 48f58a5..4245f27 100644
--- a/lib/Target/Mips/MipsSubtarget.cpp
+++ b/lib/Target/Mips/MipsSubtarget.cpp
@@ -37,6 +37,7 @@ MipsSubtarget::MipsSubtarget(const TargetMachine &TM, const Module &M,
HasMulDivAdd(false), HasMinMax(false), HasSwap(false), HasBitCount(false)
{
std::string CPU = "mips1";
+ MipsArchVersion = Mips1;
// Parse features string.
ParseSubtargetFeatures(FS, CPU);
diff --git a/lib/Target/Mips/MipsSubtarget.h b/lib/Target/Mips/MipsSubtarget.h
index 62d5e96..61c37c1 100644
--- a/lib/Target/Mips/MipsSubtarget.h
+++ b/lib/Target/Mips/MipsSubtarget.h
@@ -112,7 +112,7 @@ public:
std::string ParseSubtargetFeatures(const std::string &FS,
const std::string &CPU);
- bool hasMips2Ops() const { return MipsArchVersion >= Mips2; }
+ bool isMips1() const { return MipsArchVersion == Mips1; }
bool isLittle() const { return IsLittle; }
bool isFP64bit() const { return IsFP64bit; };