diff options
author | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2008-07-29 19:05:28 +0000 |
---|---|---|
committer | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2008-07-29 19:05:28 +0000 |
commit | 6d399bdea269658a03b63de850595fbfdd487098 (patch) | |
tree | c5a011a2718ca5a48fb0344aca8f1fec3bc07ecb /lib/Target/Mips | |
parent | c73738b3eca2d0b8ac6c66b294a49d4355026bd7 (diff) | |
download | external_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.cpp | 215 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.h | 4 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrFPU.td | 39 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrInfo.td | 13 |
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 //===----------------------------------------------------------------------===// |