Index: lib/Target/Mips/MicroMips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/MicroMips32r6InstrInfo.td +++ 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>; Index: lib/Target/Mips/Mips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips32r6InstrInfo.td +++ lib/Target/Mips/Mips32r6InstrInfo.td @@ -578,11 +578,26 @@ 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; +def SDT_MipsFSelect : SDTypeProfile<1, 3, [SDTCisFP<1>, + SDTCisSameAs<0,2>, + SDTCisSameAs<2,3>]>; + +def MipsFSelect : SDNode<"MipsISD::FSELECT", SDT_MipsFSelect>; + +class COP1_SEL_D_DESC_BASE { + 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 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">; Index: lib/Target/Mips/MipsCondMov.td =================================================================== --- lib/Target/Mips/MipsCondMov.td +++ lib/Target/Mips/MipsCondMov.td @@ -270,13 +270,13 @@ ISA_MIPS1_NOT_4_32; class SelectFP_Pseudo_T : - 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 : - 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; } Index: lib/Target/Mips/MipsISelLowering.h =================================================================== --- lib/Target/Mips/MipsISelLowering.h +++ lib/Target/Mips/MipsISelLowering.h @@ -66,6 +66,10 @@ // Floating Point Compare FPCmp, + // Floating point select + FSELECT, + MTC1_D64, + // Floating Point Conditional Moves CMovFP_T, CMovFP_F, Index: lib/Target/Mips/MipsISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsISelLowering.cpp +++ 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"; @@ -1401,9 +1403,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: @@ -1963,32 +1962,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. Index: lib/Target/Mips/MipsInstrFPU.td =================================================================== --- lib/Target/Mips/MipsInstrFPU.td +++ lib/Target/Mips/MipsInstrFPU.td @@ -39,6 +39,9 @@ SDTCisVT<1, f64>, SDTCisVT<2, i32>]>; +def SDT_MipsMTC1_D64 : SDTypeProfile<1, 1, [SDTCisVT<1, i32>, + SDTCisVT<0, f64>]>; + 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; @@ -811,6 +816,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), Index: lib/Target/Mips/MipsSEISelLowering.h =================================================================== --- lib/Target/Mips/MipsSEISelLowering.h +++ 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; Index: lib/Target/Mips/MipsSEISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsSEISelLowering.cpp +++ 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,19 @@ } } +SDValue MipsSETargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const { + + if(!Subtarget.hasMips32r6() && !Subtarget.hasMips64r6()) + return MipsTargetLowering::LowerOperation(Op, DAG); + + EVT ResTy = Op->getValueType(0); + SDLoc DL(Op); + + 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 +427,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); Index: test/CodeGen/Mips/llvm-ir/select-dbl.ll =================================================================== --- test/CodeGen/Mips/llvm-ir/select-dbl.ll +++ test/CodeGen/Mips/llvm-ir/select-dbl.ll @@ -1,32 +1,32 @@ -; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \ +; RUN: llc < %s -march=mips -mcpu=mips2 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,M2,M2-M3 -; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \ +; RUN: llc < %s -march=mips -mcpu=mips32 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,CMOV,CMOV-32,CMOV-32R1 -; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \ +; RUN: llc < %s -march=mips -mcpu=mips32r2 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,CMOV,CMOV-32,CMOV-32R2-R5 -; RUN: llc < %s -march=mips -mcpu=mips32r3 | FileCheck %s \ +; RUN: llc < %s -march=mips -mcpu=mips32r3 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,CMOV,CMOV-32,CMOV-32R2-R5 -; RUN: llc < %s -march=mips -mcpu=mips32r5 | FileCheck %s \ +; RUN: llc < %s -march=mips -mcpu=mips32r5 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,CMOV,CMOV-32,CMOV-32R2-R5 -; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \ +; RUN: llc < %s -march=mips -mcpu=mips32r6 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,SEL-32,32R6 -; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \ +; RUN: llc < %s -march=mips64 -mcpu=mips3 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,M3,M2-M3 -; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \ +; RUN: llc < %s -march=mips64 -mcpu=mips4 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,CMOV,CMOV-64 -; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \ +; RUN: llc < %s -march=mips64 -mcpu=mips64 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,CMOV,CMOV-64 -; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \ +; RUN: llc < %s -march=mips64 -mcpu=mips64r2 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,CMOV,CMOV-64 -; RUN: llc < %s -march=mips64 -mcpu=mips64r3 | FileCheck %s \ +; RUN: llc < %s -march=mips64 -mcpu=mips64r3 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,CMOV,CMOV-64 -; RUN: llc < %s -march=mips64 -mcpu=mips64r5 | FileCheck %s \ +; RUN: llc < %s -march=mips64 -mcpu=mips64r5 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,CMOV,CMOV-64 -; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \ +; RUN: llc < %s -march=mips64 -mcpu=mips64r6 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,SEL-64,64R6 -; RUN: llc < %s -march=mips -mcpu=mips32r3 -mattr=+micromips | FileCheck %s \ +; RUN: llc < %s -march=mips -mcpu=mips32r3 -mattr=+micromips -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,MM32R3 -; RUN: llc < %s -march=mips -mcpu=mips32r6 -mattr=+micromips | FileCheck %s \ +; RUN: llc < %s -march=mips -mcpu=mips32r6 -mattr=+micromips -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,MM32R6,SEL-32 define double @tst_select_i1_double(i1 signext %s, double %x, double %y) { @@ -53,8 +53,8 @@ ; SEL-32: mtc1 $7, $[[F0:f[0-9]+]] ; SEL-32: mthc1 $6, $[[F0]] - ; SEL-32: ldc1 $[[F1:f[0-9]+]], 16($sp) ; SEL-32: mtc1 $4, $f0 + ; SEL-32: ldc1 $[[F1:f[0-9]+]], 16($sp) ; SEL-32: sel.d $f0, $[[F1]], $[[F0]] ; M3: andi $[[T0:[0-9]+]], $4, 1 Index: test/CodeGen/Mips/llvm-ir/select-flt.ll =================================================================== --- test/CodeGen/Mips/llvm-ir/select-flt.ll +++ test/CodeGen/Mips/llvm-ir/select-flt.ll @@ -1,32 +1,32 @@ -; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \ +; RUN: llc < %s -march=mips -mcpu=mips2 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,M2,M2-M3 -; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \ +; RUN: llc < %s -march=mips -mcpu=mips32 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,CMOV,CMOV-32,CMOV-32R1 -; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \ +; RUN: llc < %s -march=mips -mcpu=mips32r2 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,CMOV,CMOV-32,CMOV-32R2-R5 -; RUN: llc < %s -march=mips -mcpu=mips32r3 | FileCheck %s \ +; RUN: llc < %s -march=mips -mcpu=mips32r3 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,CMOV,CMOV-32,CMOV-32R2-R5 -; RUN: llc < %s -march=mips -mcpu=mips32r5 | FileCheck %s \ +; RUN: llc < %s -march=mips -mcpu=mips32r5 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,CMOV,CMOV-32,CMOV-32R2-R5 -; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \ +; RUN: llc < %s -march=mips -mcpu=mips32r6 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,SEL-32,32R6 -; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \ +; RUN: llc < %s -march=mips64 -mcpu=mips3 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,M3,M2-M3 -; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \ +; RUN: llc < %s -march=mips64 -mcpu=mips4 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,CMOV,CMOV-64 -; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \ +; RUN: llc < %s -march=mips64 -mcpu=mips64 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,CMOV,CMOV-64 -; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \ +; RUN: llc < %s -march=mips64 -mcpu=mips64r2 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,CMOV,CMOV-64 -; RUN: llc < %s -march=mips64 -mcpu=mips64r3 | FileCheck %s \ +; RUN: llc < %s -march=mips64 -mcpu=mips64r3 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,CMOV,CMOV-64 -; RUN: llc < %s -march=mips64 -mcpu=mips64r5 | FileCheck %s \ +; RUN: llc < %s -march=mips64 -mcpu=mips64r5 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,CMOV,CMOV-64 -; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \ +; RUN: llc < %s -march=mips64 -mcpu=mips64r6 -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,SEL-64,64R6 -; RUN: llc < %s -march=mips -mcpu=mips32r3 -mattr=+micromips | FileCheck %s \ +; RUN: llc < %s -march=mips -mcpu=mips32r3 -mattr=+micromips -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,MM32R3 -; RUN: llc < %s -march=mips -mcpu=mips32r6 -mattr=+micromips | FileCheck %s \ +; RUN: llc < %s -march=mips -mcpu=mips32r6 -mattr=+micromips -verify-machineinstrs | FileCheck %s \ ; RUN: -check-prefixes=ALL,MM32R6,SEL-32 define float @tst_select_i1_float(i1 signext %s, float %x, float %y) { Index: test/CodeGen/Mips/select.ll =================================================================== --- test/CodeGen/Mips/select.ll +++ test/CodeGen/Mips/select.ll @@ -1,9 +1,9 @@ -; RUN: llc < %s -march=mipsel -mcpu=mips32 -relocation-model=pic | FileCheck %s -check-prefixes=ALL,32 -; RUN: llc < %s -march=mipsel -mcpu=mips32r2 -relocation-model=pic | FileCheck %s -check-prefixes=ALL,32R2 -; RUN: llc < %s -march=mipsel -mcpu=mips32r6 -relocation-model=pic | FileCheck %s -check-prefixes=ALL,32R6 -; RUN: llc < %s -march=mips64el -mcpu=mips64 -relocation-model=pic | FileCheck %s -check-prefixes=ALL,64 -; RUN: llc < %s -march=mips64el -mcpu=mips64r2 -relocation-model=pic | FileCheck %s -check-prefixes=ALL,64R2 -; RUN: llc < %s -march=mips64el -mcpu=mips64r6 -relocation-model=pic | FileCheck %s -check-prefixes=ALL,64R6 +; RUN: llc < %s -march=mipsel -mcpu=mips32 -relocation-model=pic -verify-machineinstrs | FileCheck %s -check-prefixes=ALL,32 +; RUN: llc < %s -march=mipsel -mcpu=mips32r2 -relocation-model=pic -verify-machineinstrs | FileCheck %s -check-prefixes=ALL,32R2 +; RUN: llc < %s -march=mipsel -mcpu=mips32r6 -relocation-model=pic -verify-machineinstrs | FileCheck %s -check-prefixes=ALL,32R6 +; RUN: llc < %s -march=mips64el -mcpu=mips64 -relocation-model=pic -verify-machineinstrs | FileCheck %s -check-prefixes=ALL,64 +; RUN: llc < %s -march=mips64el -mcpu=mips64r2 -relocation-model=pic -verify-machineinstrs | FileCheck %s -check-prefixes=ALL,64R2 +; RUN: llc < %s -march=mips64el -mcpu=mips64r6 -relocation-model=pic -verify-machineinstrs | FileCheck %s -check-prefixes=ALL,64R6 @d2 = external global double @d3 = external global double