Reland r308585
Builder clang-x86_64-linux-abi-test apparently failed due
to a spurious error unrelated to the changes r308585
introduced.
llvm-svn: 308612
diff --git a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td
index fd04f80..45c1709 100644
--- a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td
+++ b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td
@@ -1124,10 +1124,7 @@
FGR64Opnd, II_ROUND>;
class SEL_S_MMR6_DESC : COP1_SEL_DESC_BASE<"sel.s", FGR32Opnd, II_SEL_S>;
-class SEL_D_MMR6_DESC : COP1_SEL_DESC_BASE<"sel.d", FGR64Opnd, II_SEL_D> {
- // We must insert a SUBREG_TO_REG around $fd_in
- bit usesCustomInserter = 1;
-}
+class SEL_D_MMR6_DESC : COP1_SEL_D_DESC_BASE<"sel.d", FGR64Opnd, II_SEL_D>;
class SELEQZ_S_MMR6_DESC : SELEQNEZ_DESC_BASE<"seleqz.s", FGR32Opnd,
II_SELCCZ_S>;
diff --git a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td
index 7daea16..001d9c1 100644
--- a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td
+++ b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td
@@ -13,6 +13,24 @@
include "Mips32r6InstrFormats.td"
+//===----------------------------------------------------------------------===//
+//
+// Mips profiles and nodes
+//
+//===----------------------------------------------------------------------===//
+
+def SDT_MipsFSelect : SDTypeProfile<1, 3, [SDTCisFP<1>,
+ SDTCisSameAs<0,2>,
+ SDTCisSameAs<2,3>]>;
+
+def MipsFSelect : SDNode<"MipsISD::FSELECT", SDT_MipsFSelect>;
+
+//===----------------------------------------------------------------------===//
+//
+// Mips Operands
+//
+//===----------------------------------------------------------------------===//
+
// Notes about removals/changes from MIPS32r6:
// Reencoded: jr -> jalr
// Reencoded: jr.hb -> jalr.hb
@@ -578,11 +596,20 @@
InstrItinClass Itinerary = itin;
}
-class SEL_D_DESC : COP1_SEL_DESC_BASE<"sel.d", FGR64Opnd, II_SEL_D>,
- MipsR6Arch<"sel.d"> {
- // We must insert a SUBREG_TO_REG around $fd_in
- bit usesCustomInserter = 1;
+class COP1_SEL_D_DESC_BASE<string instr_asm, RegisterOperand FGROpnd,
+ InstrItinClass itin> {
+ dag OutOperandList = (outs FGROpnd:$fd);
+ dag InOperandList = (ins FGROpnd:$fd_in, FGROpnd:$fs, FGROpnd:$ft);
+ string AsmString = !strconcat(instr_asm, "\t$fd, $fs, $ft");
+ list<dag> Pattern = [(set FGROpnd:$fd, (MipsFSelect FGROpnd:$fd_in,
+ FGROpnd:$ft,
+ FGROpnd:$fs))];
+ string Constraints = "$fd_in = $fd";
+ InstrItinClass Itinerary = itin;
}
+
+class SEL_D_DESC : COP1_SEL_D_DESC_BASE<"sel.d", FGR64Opnd, II_SEL_D>,
+ MipsR6Arch<"sel.d">;
class SEL_S_DESC : COP1_SEL_DESC_BASE<"sel.s", FGR32Opnd, II_SEL_S>,
MipsR6Arch<"sel.s">;
diff --git a/llvm/lib/Target/Mips/MipsCondMov.td b/llvm/lib/Target/Mips/MipsCondMov.td
index fd4517f..69bb374 100644
--- a/llvm/lib/Target/Mips/MipsCondMov.td
+++ b/llvm/lib/Target/Mips/MipsCondMov.td
@@ -270,13 +270,13 @@
ISA_MIPS1_NOT_4_32;
class SelectFP_Pseudo_T<RegisterOperand RC> :
- PseudoSE<(outs RC:$dst), (ins GPR32Opnd:$cond, RC:$T, RC:$F),
- [(set RC:$dst, (MipsCMovFP_T RC:$T, GPR32Opnd:$cond, RC:$F))]>,
+ PseudoSE<(outs RC:$dst), (ins FCCRegsOpnd:$cond, RC:$T, RC:$F),
+ [(set RC:$dst, (MipsCMovFP_T RC:$T, FCCRegsOpnd:$cond, RC:$F))]>,
ISA_MIPS1_NOT_4_32;
class SelectFP_Pseudo_F<RegisterOperand RC> :
- PseudoSE<(outs RC:$dst), (ins GPR32Opnd:$cond, RC:$T, RC:$F),
- [(set RC:$dst, (MipsCMovFP_F RC:$T, GPR32Opnd:$cond, RC:$F))]>,
+ PseudoSE<(outs RC:$dst), (ins FCCRegsOpnd:$cond, RC:$T, RC:$F),
+ [(set RC:$dst, (MipsCMovFP_F RC:$T, FCCRegsOpnd:$cond, RC:$F))]>,
ISA_MIPS1_NOT_4_32;
}
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index dd41fef..8e66a59 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -166,6 +166,8 @@
case MipsISD::EH_RETURN: return "MipsISD::EH_RETURN";
case MipsISD::FPBrcond: return "MipsISD::FPBrcond";
case MipsISD::FPCmp: return "MipsISD::FPCmp";
+ case MipsISD::FSELECT: return "MipsISD::FSELECT";
+ case MipsISD::MTC1_D64: return "MipsISD::MTC1_D64";
case MipsISD::CMovFP_T: return "MipsISD::CMovFP_T";
case MipsISD::CMovFP_F: return "MipsISD::CMovFP_F";
case MipsISD::TruncIntFP: return "MipsISD::TruncIntFP";
@@ -1398,9 +1400,6 @@
case Mips::DMOD_MM64R6:
case Mips::DMODU_MM64R6:
return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), true, true);
- case Mips::SEL_D:
- case Mips::SEL_D_MMR6:
- return emitSEL_D(MI, BB);
case Mips::PseudoSELECT_I:
case Mips::PseudoSELECT_I64:
@@ -1960,32 +1959,6 @@
return exitMBB;
}
-MachineBasicBlock *MipsTargetLowering::emitSEL_D(MachineInstr &MI,
- MachineBasicBlock *BB) const {
- MachineFunction *MF = BB->getParent();
- const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
- const TargetInstrInfo *TII = Subtarget.getInstrInfo();
- MachineRegisterInfo &RegInfo = MF->getRegInfo();
- DebugLoc DL = MI.getDebugLoc();
- MachineBasicBlock::iterator II(MI);
-
- unsigned Fc = MI.getOperand(1).getReg();
- const auto &FGR64RegClass = TRI->getRegClass(Mips::FGR64RegClassID);
-
- unsigned Fc2 = RegInfo.createVirtualRegister(FGR64RegClass);
-
- BuildMI(*BB, II, DL, TII->get(Mips::SUBREG_TO_REG), Fc2)
- .addImm(0)
- .addReg(Fc)
- .addImm(Mips::sub_lo);
-
- // We don't erase the original instruction, we just replace the condition
- // register with the 64-bit super-register.
- MI.getOperand(1).setReg(Fc2);
-
- return BB;
-}
-
SDValue MipsTargetLowering::lowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
// The first operand is the chain, the second is the condition, the third is
// the block to branch to if the condition is true.
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h
index 0e47ed3..7566e1d 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.h
+++ b/llvm/lib/Target/Mips/MipsISelLowering.h
@@ -66,6 +66,12 @@
// Floating Point Compare
FPCmp,
+ // Floating point select
+ FSELECT,
+
+ // Node used to generate an MTC1 i32 to f64 instruction
+ MTC1_D64,
+
// Floating Point Conditional Moves
CMovFP_T,
CMovFP_F,
diff --git a/llvm/lib/Target/Mips/MipsInstrFPU.td b/llvm/lib/Target/Mips/MipsInstrFPU.td
index 0333fe6..115494d 100644
--- a/llvm/lib/Target/Mips/MipsInstrFPU.td
+++ b/llvm/lib/Target/Mips/MipsInstrFPU.td
@@ -39,6 +39,9 @@
SDTCisVT<1, f64>,
SDTCisVT<2, i32>]>;
+def SDT_MipsMTC1_D64 : SDTypeProfile<1, 1, [SDTCisVT<0, f64>,
+ SDTCisVT<1, i32>]>;
+
def MipsFPCmp : SDNode<"MipsISD::FPCmp", SDT_MipsFPCmp, [SDNPOutGlue]>;
def MipsCMovFP_T : SDNode<"MipsISD::CMovFP_T", SDT_MipsCMovFP, [SDNPInGlue]>;
def MipsCMovFP_F : SDNode<"MipsISD::CMovFP_F", SDT_MipsCMovFP, [SDNPInGlue]>;
@@ -49,6 +52,8 @@
def MipsExtractElementF64 : SDNode<"MipsISD::ExtractElementF64",
SDT_MipsExtractElementF64>;
+def MipsMTC1_D64 : SDNode<"MipsISD::MTC1_D64", SDT_MipsMTC1_D64>;
+
// Operand for printing out a condition code.
let PrintMethod = "printFCCOperand", DecoderMethod = "DecodeCondCode" in
def condcode : Operand<i32>;
@@ -820,6 +825,9 @@
def : MipsPat<(MipsTruncIntFP FGR32Opnd:$src),
(TRUNC_W_S FGR32Opnd:$src)>;
+def : MipsPat<(MipsMTC1_D64 GPR32Opnd:$src),
+ (MTC1_D64 GPR32Opnd:$src)>, FGR_64;
+
def : MipsPat<(f64 (sint_to_fp GPR32Opnd:$src)),
(PseudoCVT_D32_W GPR32Opnd:$src)>, FGR_32;
def : MipsPat<(MipsTruncIntFP AFGR64Opnd:$src),
diff --git a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
index 72b2738..1948b86 100644
--- a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
@@ -220,7 +220,7 @@
assert(Subtarget.isFP64bit() && "FR=1 is required for MIPS32r6");
setOperationAction(ISD::SETCC, MVT::f64, Legal);
- setOperationAction(ISD::SELECT, MVT::f64, Legal);
+ setOperationAction(ISD::SELECT, MVT::f64, Custom);
setOperationAction(ISD::SELECT_CC, MVT::f64, Expand);
setOperationAction(ISD::BRCOND, MVT::Other, Legal);
@@ -367,6 +367,22 @@
}
}
+SDValue MipsSETargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
+
+ if(!Subtarget.hasMips32r6())
+ return MipsTargetLowering::LowerOperation(Op, DAG);
+
+ EVT ResTy = Op->getValueType(0);
+ SDLoc DL(Op);
+
+ // Although MTC1_D64 takes an i32 and writes an f64, the upper 32 bits of the
+ // floating point register are undefined. Not really an issue as sel.d, which
+ // is produced from an FSELECT node, only looks at bit 0.
+ SDValue Tmp = DAG.getNode(MipsISD::MTC1_D64, DL, MVT::f64, Op->getOperand(0));
+ return DAG.getNode(MipsISD::FSELECT, DL, ResTy, Tmp, Op->getOperand(1),
+ Op->getOperand(2));
+}
+
bool
MipsSETargetLowering::allowsMisalignedMemoryAccesses(EVT VT,
unsigned,
@@ -414,6 +430,7 @@
case ISD::EXTRACT_VECTOR_ELT: return lowerEXTRACT_VECTOR_ELT(Op, DAG);
case ISD::BUILD_VECTOR: return lowerBUILD_VECTOR(Op, DAG);
case ISD::VECTOR_SHUFFLE: return lowerVECTOR_SHUFFLE(Op, DAG);
+ case ISD::SELECT: return lowerSELECT(Op, DAG);
}
return MipsTargetLowering::LowerOperation(Op, DAG);
diff --git a/llvm/lib/Target/Mips/MipsSEISelLowering.h b/llvm/lib/Target/Mips/MipsSEISelLowering.h
index 0abb9b3..15b474e 100644
--- a/llvm/lib/Target/Mips/MipsSEISelLowering.h
+++ b/llvm/lib/Target/Mips/MipsSEISelLowering.h
@@ -76,6 +76,7 @@
/// \brief Lower VECTOR_SHUFFLE into one of a number of instructions
/// depending on the indices in the shuffle.
SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;
+ SDValue lowerSELECT(SDValue Op, SelectionDAG &DAG) const;
MachineBasicBlock *emitBPOSGE32(MachineInstr &MI,
MachineBasicBlock *BB) const;