mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-29 07:53:33 +00:00
implement SELECT_CC fully for the DAG->DAG isel!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23101 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
050967c4d1
commit
8a2d3ca7df
@ -1400,8 +1400,17 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
|
||||
Tmp.getValue(1));
|
||||
break;
|
||||
}
|
||||
|
||||
assert(0 && "Select_cc not implemented yet!");
|
||||
|
||||
SDOperand CCReg = SelectCC(Select(N->getOperand(0)),
|
||||
Select(N->getOperand(1)), CC);
|
||||
unsigned BROpc = getBCCForSetCC(CC);
|
||||
|
||||
bool isFP = MVT::isFloatingPoint(N->getValueType(0));
|
||||
unsigned SelectCCOp = isFP ? PPC::SELECT_CC_FP : PPC::SELECT_CC_Int;
|
||||
CurDAG->SelectNodeTo(N, SelectCCOp, N->getValueType(0), CCReg,
|
||||
Select(N->getOperand(2)), Select(N->getOperand(3)),
|
||||
getI32Imm(BROpc));
|
||||
break;
|
||||
}
|
||||
|
||||
case ISD::CALLSEQ_START:
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "PPC32TargetMachine.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/SelectionDAG.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/Function.h"
|
||||
@ -553,3 +554,57 @@ LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
|
||||
assert(0 && "LowerFrameReturnAddress unimplemented");
|
||||
abort();
|
||||
}
|
||||
|
||||
MachineBasicBlock *
|
||||
PPC32TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
|
||||
MachineBasicBlock *BB) {
|
||||
assert((MI->getOpcode() == PPC::SELECT_CC_Int ||
|
||||
MI->getOpcode() == PPC::SELECT_CC_FP) &&
|
||||
"Unexpected instr type to insert");
|
||||
|
||||
// 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();
|
||||
ilist<MachineBasicBlock>::iterator It = BB;
|
||||
++It;
|
||||
|
||||
// thisMBB:
|
||||
// ...
|
||||
// TrueVal = ...
|
||||
// cmpTY ccX, r1, r2
|
||||
// bCC copy1MBB
|
||||
// fallthrough --> copy0MBB
|
||||
MachineBasicBlock *thisMBB = BB;
|
||||
MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
|
||||
MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
|
||||
BuildMI(BB, MI->getOperand(4).getImmedValue(), 2)
|
||||
.addReg(MI->getOperand(1).getReg()).addMBB(sinkMBB);
|
||||
MachineFunction *F = BB->getParent();
|
||||
F->getBasicBlockList().insert(It, copy0MBB);
|
||||
F->getBasicBlockList().insert(It, sinkMBB);
|
||||
// Update machine-CFG edges
|
||||
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, PPC::PHI, 4, MI->getOperand(0).getReg())
|
||||
.addReg(MI->getOperand(3).getReg()).addMBB(copy0MBB)
|
||||
.addReg(MI->getOperand(2).getReg()).addMBB(thisMBB);
|
||||
|
||||
delete MI; // The pseudo instruction is gone now.
|
||||
return BB;
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,9 @@ namespace llvm {
|
||||
virtual std::pair<SDOperand, SDOperand>
|
||||
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
|
||||
SelectionDAG &DAG);
|
||||
|
||||
virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI,
|
||||
MachineBasicBlock *MBB);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -67,6 +67,16 @@ def ADJCALLSTACKUP : Pseudo<(ops u16imm), "; ADJCALLSTACKUP">;
|
||||
def IMPLICIT_DEF_GPR : Pseudo<(ops GPRC:$rD), "; $rD = IMPLICIT_DEF_GPRC">;
|
||||
def IMPLICIT_DEF_FP : Pseudo<(ops FPRC:$rD), "; %rD = IMPLICIT_DEF_FP">;
|
||||
|
||||
// SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded by the
|
||||
// scheduler into a branch sequence.
|
||||
let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler.
|
||||
def SELECT_CC_Int : Pseudo<(ops GPRC:$dst, CRRC:$cond, GPRC:$T, GPRC:$F,
|
||||
i32imm:$BROPC), "; SELECT_CC PSEUDO!">;
|
||||
def SELECT_CC_FP : Pseudo<(ops FPRC:$dst, CRRC:$cond, FPRC:$T, FPRC:$F,
|
||||
i32imm:$BROPC), "; SELECT_CC PSEUDO!">;
|
||||
}
|
||||
|
||||
|
||||
let Defs = [LR] in
|
||||
def MovePCtoLR : Pseudo<(ops piclabel:$label), "bl $label">;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user