aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/Mips
diff options
context:
space:
mode:
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>2008-07-29 19:05:28 +0000
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>2008-07-29 19:05:28 +0000
commit6d399bdea269658a03b63de850595fbfdd487098 (patch)
treec5a011a2718ca5a48fb0344aca8f1fec3bc07ecb /lib/Target/Mips
parentc73738b3eca2d0b8ac6c66b294a49d4355026bd7 (diff)
downloadexternal_llvm-6d399bdea269658a03b63de850595fbfdd487098.zip
external_llvm-6d399bdea269658a03b63de850595fbfdd487098.tar.gz
external_llvm-6d399bdea269658a03b63de850595fbfdd487098.tar.bz2
Added floating point lowering for select.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@54167 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Mips')
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp215
-rw-r--r--lib/Target/Mips/MipsISelLowering.h4
-rw-r--r--lib/Target/Mips/MipsInstrFPU.td39
-rw-r--r--lib/Target/Mips/MipsInstrInfo.td13
4 files changed, 185 insertions, 86 deletions
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp
index 0a48632..f1b3c90 100644
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -41,15 +41,16 @@ getTargetNodeName(unsigned Opcode) const
{
switch (Opcode)
{
- case MipsISD::JmpLink : return "MipsISD::JmpLink";
- case MipsISD::Hi : return "MipsISD::Hi";
- case MipsISD::Lo : return "MipsISD::Lo";
- case MipsISD::GPRel : return "MipsISD::GPRel";
- case MipsISD::Ret : return "MipsISD::Ret";
- case MipsISD::SelectCC : return "MipsISD::SelectCC";
- case MipsISD::FPBrcond : return "MipsISD::FPBrcond";
- case MipsISD::FPCmp : return "MipsISD::FPCmp";
- default : return NULL;
+ case MipsISD::JmpLink : return "MipsISD::JmpLink";
+ case MipsISD::Hi : return "MipsISD::Hi";
+ case MipsISD::Lo : return "MipsISD::Lo";
+ case MipsISD::GPRel : return "MipsISD::GPRel";
+ case MipsISD::Ret : return "MipsISD::Ret";
+ case MipsISD::SelectCC : return "MipsISD::SelectCC";
+ case MipsISD::FPSelectCC : return "MipsISD::FPSelectCC";
+ case MipsISD::FPBrcond : return "MipsISD::FPBrcond";
+ case MipsISD::FPCmp : return "MipsISD::FPCmp";
+ default : return NULL;
}
}
@@ -87,8 +88,9 @@ MipsTargetLowering(MipsTargetMachine &TM): TargetLowering(TM)
setOperationAction(ISD::RET, MVT::Other, Custom);
setOperationAction(ISD::JumpTable, MVT::i32, Custom);
setOperationAction(ISD::ConstantPool, MVT::i32, Custom);
+ setOperationAction(ISD::SELECT, MVT::f32, Custom);
+ setOperationAction(ISD::SELECT, MVT::i32, Custom);
setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
- setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
setOperationAction(ISD::SETCC, MVT::f32, Custom);
setOperationAction(ISD::BRCOND, MVT::Other, Custom);
@@ -96,7 +98,6 @@ MipsTargetLowering(MipsTargetMachine &TM): TargetLowering(TM)
setOperationAction(ISD::BR_JT, MVT::Other, Expand);
setOperationAction(ISD::BR_CC, MVT::Other, Expand);
setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
- setOperationAction(ISD::SELECT, MVT::i32, Expand);
setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);
setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
@@ -151,6 +152,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG)
case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
case ISD::JumpTable: return LowerJumpTable(Op, DAG);
case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
+ case ISD::SELECT: return LowerSELECT(Op, DAG);
case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
case ISD::SETCC: return LowerSETCC(Op, DAG);
case ISD::BRCOND: return LowerBRCOND(Op, DAG);
@@ -158,70 +160,6 @@ LowerOperation(SDValue Op, SelectionDAG &DAG)
return SDValue();
}
-MachineBasicBlock *
-MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
- MachineBasicBlock *BB)
-{
- const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
- switch (MI->getOpcode()) {
- default: assert(false && "Unexpected instr type to insert");
- case Mips::Select_CC: {
- // To "insert" a SELECT_CC instruction, we actually have to insert the
- // diamond control-flow pattern. The incoming instruction knows the
- // destination vreg to set, the condition code register to branch on, the
- // true/false values to select between, and a branch opcode to use.
- const BasicBlock *LLVM_BB = BB->getBasicBlock();
- MachineFunction::iterator It = BB;
- ++It;
-
- // thisMBB:
- // ...
- // TrueVal = ...
- // setcc r1, r2, r3
- // bNE r1, r0, copy1MBB
- // fallthrough --> copy0MBB
- MachineBasicBlock *thisMBB = BB;
- MachineFunction *F = BB->getParent();
- MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
- MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
- BuildMI(BB, TII->get(Mips::BNE)).addReg(MI->getOperand(1).getReg())
- .addReg(Mips::ZERO).addMBB(sinkMBB);
- F->insert(It, copy0MBB);
- F->insert(It, sinkMBB);
- // Update machine-CFG edges by first adding all successors of the current
- // block to the new block which will contain the Phi node for the select.
- for(MachineBasicBlock::succ_iterator i = BB->succ_begin(),
- e = BB->succ_end(); i != e; ++i)
- sinkMBB->addSuccessor(*i);
- // Next, remove all successors of the current block, and add the true
- // and fallthrough blocks as its successors.
- while(!BB->succ_empty())
- BB->removeSuccessor(BB->succ_begin());
- BB->addSuccessor(copy0MBB);
- BB->addSuccessor(sinkMBB);
-
- // copy0MBB:
- // %FalseValue = ...
- // # fallthrough to sinkMBB
- BB = copy0MBB;
-
- // Update machine-CFG edges
- BB->addSuccessor(sinkMBB);
-
- // sinkMBB:
- // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
- // ...
- BB = sinkMBB;
- BuildMI(BB, TII->get(Mips::PHI), MI->getOperand(0).getReg())
- .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB)
- .addReg(MI->getOperand(3).getReg()).addMBB(thisMBB);
-
- F->DeleteMachineInstr(MI); // The pseudo instruction is gone now.
- return BB;
- }
- }
-}
-
//===----------------------------------------------------------------------===//
// Lower helper functions
//===----------------------------------------------------------------------===//
@@ -280,6 +218,16 @@ static Mips::FPBranchCode GetFPBranchCodeFromCond(Mips::CondCode CC) {
return Mips::BRANCH_INVALID;
}
+static unsigned FPBranchCodeToOpc(Mips::FPBranchCode BC) {
+ switch(BC) {
+ default:
+ assert(0 && "Unknown branch code");
+ case Mips::BRANCH_T : return Mips::BC1T;
+ case Mips::BRANCH_F : return Mips::BC1F;
+ case Mips::BRANCH_TL : return Mips::BC1TL;
+ case Mips::BRANCH_FL : return Mips::BC1FL;
+ }
+}
static Mips::CondCode FPCondCCodeToFCC(ISD::CondCode CC) {
switch (CC) {
@@ -307,6 +255,90 @@ static Mips::CondCode FPCondCCodeToFCC(ISD::CondCode CC) {
}
}
+MachineBasicBlock *
+MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
+ MachineBasicBlock *BB)
+{
+ const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
+ bool isFPCmp = false;
+
+ switch (MI->getOpcode()) {
+ default: assert(false && "Unexpected instr type to insert");
+ case Mips::Select_FCC:
+ case Mips::Select_FCC_SO32:
+ case Mips::Select_FCC_AS32:
+ case Mips::Select_FCC_D32:
+ isFPCmp = true; // FALL THROUGH
+ case Mips::Select_CC:
+ case Mips::Select_CC_SO32:
+ case Mips::Select_CC_AS32:
+ case Mips::Select_CC_D32: {
+ // To "insert" a SELECT_CC instruction, we actually have to insert the
+ // diamond control-flow pattern. The incoming instruction knows the
+ // destination vreg to set, the condition code register to branch on, the
+ // true/false values to select between, and a branch opcode to use.
+ const BasicBlock *LLVM_BB = BB->getBasicBlock();
+ MachineFunction::iterator It = BB;
+ ++It;
+
+ // thisMBB:
+ // ...
+ // TrueVal = ...
+ // setcc r1, r2, r3
+ // bNE r1, r0, copy1MBB
+ // fallthrough --> copy0MBB
+ MachineBasicBlock *thisMBB = BB;
+ MachineFunction *F = BB->getParent();
+ MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
+ MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
+
+ // Emit the right instruction according to the type of the operands compared
+ if (isFPCmp) {
+ // Find the condiction code present in the setcc operation.
+ Mips::CondCode CC = (Mips::CondCode)MI->getOperand(4).getImm();
+ // Get the branch opcode from the branch code.
+ unsigned Opc = FPBranchCodeToOpc(GetFPBranchCodeFromCond(CC));
+ BuildMI(BB, TII->get(Opc)).addMBB(sinkMBB);
+ } else
+ BuildMI(BB, TII->get(Mips::BNE)).addReg(MI->getOperand(1).getReg())
+ .addReg(Mips::ZERO).addMBB(sinkMBB);
+
+ F->insert(It, copy0MBB);
+ F->insert(It, sinkMBB);
+ // Update machine-CFG edges by first adding all successors of the current
+ // block to the new block which will contain the Phi node for the select.
+ for(MachineBasicBlock::succ_iterator i = BB->succ_begin(),
+ e = BB->succ_end(); i != e; ++i)
+ sinkMBB->addSuccessor(*i);
+ // Next, remove all successors of the current block, and add the true
+ // and fallthrough blocks as its successors.
+ while(!BB->succ_empty())
+ BB->removeSuccessor(BB->succ_begin());
+ BB->addSuccessor(copy0MBB);
+ BB->addSuccessor(sinkMBB);
+
+ // copy0MBB:
+ // %FalseValue = ...
+ // # fallthrough to sinkMBB
+ BB = copy0MBB;
+
+ // Update machine-CFG edges
+ BB->addSuccessor(sinkMBB);
+
+ // sinkMBB:
+ // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
+ // ...
+ BB = sinkMBB;
+ BuildMI(BB, TII->get(Mips::PHI), MI->getOperand(0).getReg())
+ .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB)
+ .addReg(MI->getOperand(3).getReg()).addMBB(thisMBB);
+
+ F->DeleteMachineInstr(MI); // The pseudo instruction is gone now.
+ return BB;
+ }
+ }
+}
+
//===----------------------------------------------------------------------===//
// Misc Lower Operation implementation
//===----------------------------------------------------------------------===//
@@ -392,6 +424,34 @@ LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG)
}
SDValue MipsTargetLowering::
+LowerSELECT(SDValue Op, SelectionDAG &DAG)
+{
+ SDValue Cond = Op.getOperand(0);
+ SDValue True = Op.getOperand(1);
+ SDValue False = Op.getOperand(2);
+
+ // this can be a fp select but with a setcc comming from a
+ // integer compare.
+ if (Cond.getOpcode() == ISD::SETCC)
+ if (Cond.getOperand(0).getValueType().isInteger())
+ return DAG.getNode(MipsISD::SelectCC, True.getValueType(),
+ Cond, True, False);
+
+ // Otherwise we're dealing with floating point compare.
+ SDValue CondRes;
+ if (Cond.getOpcode() == ISD::AND)
+ CondRes = Cond.getOperand(0);
+ else if (Cond.getOpcode() == MipsISD::FPCmp)
+ CondRes = Cond;
+ else
+ assert(0 && "Incoming condition flag unknown");
+
+ SDValue CCNode = CondRes.getOperand(2);
+ return DAG.getNode(MipsISD::FPSelectCC, True.getValueType(),
+ CondRes, True, False, CCNode);
+}
+
+SDValue MipsTargetLowering::
LowerSELECT_CC(SDValue Op, SelectionDAG &DAG)
{
SDValue LHS = Op.getOperand(0);
@@ -400,10 +460,7 @@ LowerSELECT_CC(SDValue Op, SelectionDAG &DAG)
SDValue False = Op.getOperand(3);
SDValue CC = Op.getOperand(4);
- const MVT *VTs = DAG.getNodeValueTypes(MVT::i32);
- SDValue Ops[] = { LHS, RHS, CC };
- SDValue SetCCRes = DAG.getNode(ISD::SETCC, VTs, 1, Ops, 3);
-
+ SDValue SetCCRes = DAG.getNode(ISD::SETCC, LHS.getValueType(), LHS, RHS, CC);
return DAG.getNode(MipsISD::SelectCC, True.getValueType(),
SetCCRes, True, False);
}
diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h
index 136b230..ee0df3d 100644
--- a/lib/Target/Mips/MipsISelLowering.h
+++ b/lib/Target/Mips/MipsISelLowering.h
@@ -43,6 +43,9 @@ namespace llvm {
// Select CC Pseudo Instruction
SelectCC,
+ // Floating Point Select CC Pseudo Instruction
+ FPSelectCC,
+
// Floating Point Branch Conditional
FPBrcond,
@@ -95,6 +98,7 @@ namespace llvm {
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG);
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG);
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG);
+ SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG);
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG);
SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG);
SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG);
diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td
index 550c835..b459815 100644
--- a/lib/Target/Mips/MipsInstrFPU.td
+++ b/lib/Target/Mips/MipsInstrFPU.td
@@ -28,9 +28,12 @@ def SDT_MipsFPBrcond : SDTypeProfile<0, 3, [SDTCisSameAs<0, 2>, SDTCisInt<0>,
SDTCisVT<1, OtherVT>]>;
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 MipsFPBrcond : SDNode<"MipsISD::FPBrcond", SDT_MipsFPBrcond,
[SDNPHasChain]>;
-def MipsFPCmp : SDNode<"MipsISD::FPCmp", SDT_MipsFPCmp>;
+def MipsFPCmp : SDNode<"MipsISD::FPCmp", SDT_MipsFPCmp>;
+def MipsFPSelectCC : SDNode<"MipsISD::FPSelectCC", SDT_MipsFPSelectCC>;
// Operand for printing out a condition code.
let PrintMethod = "printFCCOperand" in
@@ -285,6 +288,40 @@ let hasDelaySlot = 1, Defs=[FCR31] in {
}
//===----------------------------------------------------------------------===//
+// Floating Point Pseudo-Instructions
+//===----------------------------------------------------------------------===//
+
+// For some explanation, see Select_CC at MipsInstrInfo.td. We also embedd a
+// condiciton code to enable easy handling by the Custom Inserter.
+let usesCustomDAGSchedInserter = 1, Uses=[FCR31] in {
+ class PseudoFPSelCC<RegisterClass RC, string asmstr> :
+ MipsPseudo<(outs RC:$dst),
+ (ins CPURegs:$CmpRes, RC:$T, RC:$F, condcode:$cc), asmstr,
+ [(set RC:$dst, (MipsFPSelectCC CPURegs:$CmpRes, RC:$T, RC:$F,
+ imm:$cc))]>;
+}
+
+// The values to be selected are fp but the condition test is with integers.
+def Select_CC_SO32 : PseudoSelCC<FGR32, "# MipsSelect_CC_SO32_f32">,
+ Requires<[IsSingleFloat]>;
+def Select_CC_AS32 : PseudoSelCC<AFGR32, "# MipsSelect_CC_AS32_f32">,
+ Requires<[In32BitMode]>;
+def Select_CC_D32 : PseudoSelCC<AFGR64, "# MipsSelect_CC_D32_f32">,
+ Requires<[In32BitMode]>;
+
+// The values to be selected are int but the condition test is done with fp.
+def Select_FCC : PseudoFPSelCC<CPURegs, "# MipsSelect_FCC">;
+
+// The values to be selected and the condition test is done with fp.
+def Select_FCC_SO32 : PseudoFPSelCC<FGR32, "# MipsSelect_FCC_SO32_f32">,
+ Requires<[IsSingleFloat]>;
+def Select_FCC_AS32 : PseudoFPSelCC<AFGR32, "# MipsSelect_FCC_AS32_f32">,
+ Requires<[In32BitMode]>;
+def Select_FCC_D32 : PseudoFPSelCC<AFGR64, "# MipsSelect_FCC_D32_f32">,
+ Requires<[In32BitMode]>;
+
+
+//===----------------------------------------------------------------------===//
// Floating Point Patterns
//===----------------------------------------------------------------------===//
def : Pat<(f32 (sint_to_fp CPURegs:$src)), (CVTS_W32 (MTC1 CPURegs:$src))>;
diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td
index b129b90..61626bd 100644
--- a/lib/Target/Mips/MipsInstrInfo.td
+++ b/lib/Target/Mips/MipsInstrInfo.td
@@ -19,8 +19,8 @@ include "MipsInstrFormats.td"
def SDT_MipsRet : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
def SDT_MipsJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
-def SDT_MipsSelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>,
- SDTCisSameAs<1, 2>, SDTCisInt<3>]>;
+def SDT_MipsSelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 2>,
+ SDTCisSameAs<2, 3>, SDTCisInt<1>]>;
def SDT_MipsCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>;
def SDT_MipsCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
@@ -383,12 +383,13 @@ def CPRESTORE : MipsPseudo<(outs), (ins uimm16:$loc), ".cprestore\t$loc\n", []>;
// (MipsSelectCC), use LowerSELECT_CC to generate this instruction and finally
// replace it for real supported nodes into EmitInstrWithCustomInserter
let usesCustomDAGSchedInserter = 1 in {
- def Select_CC : MipsPseudo<(outs CPURegs:$dst),
- (ins CPURegs:$CmpRes, CPURegs:$T, CPURegs:$F), "# MipsSelect_CC",
- [(set CPURegs:$dst, (MipsSelectCC CPURegs:$CmpRes,
- CPURegs:$T, CPURegs:$F))]>;
+ class PseudoSelCC<RegisterClass RC, string asmstr>:
+ MipsPseudo<(outs RC:$dst), (ins CPURegs:$CmpRes, RC:$T, RC:$F), asmstr,
+ [(set RC:$dst, (MipsSelectCC CPURegs:$CmpRes, RC:$T, RC:$F))]>;
}
+def Select_CC : PseudoSelCC<CPURegs, "# MipsSelect_CC_i32">;
+
//===----------------------------------------------------------------------===//
// Instruction definition
//===----------------------------------------------------------------------===//