refactor the LowerOperation code out to individual functions for

each lowering, which is 'best practice'.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48441 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner
2008-03-17 02:52:07 +00:00
parent fdd3ade005
commit 601fe38b1e

View File

@ -106,6 +106,8 @@ namespace {
SparcTargetLowering(TargetMachine &TM); SparcTargetLowering(TargetMachine &TM);
virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
int getVarArgsFrameOffset() const { return VarArgsFrameOffset; }
/// computeMaskedBitsForTargetNode - Determine which of the bits specified /// computeMaskedBitsForTargetNode - Determine which of the bits specified
/// in Mask are known to be either zero or one and return them in the /// in Mask are known to be either zero or one and return them in the
/// KnownZero/KnownOne bitsets. /// KnownZero/KnownOne bitsets.
@ -719,40 +721,38 @@ static void LookThroughSetCC(SDOperand &LHS, SDOperand &RHS,
} }
} }
static SDOperand LowerGLOBALADDRESS(SDOperand Op, SelectionDAG &DAG) {
SDOperand SparcTargetLowering::
LowerOperation(SDOperand Op, SelectionDAG &DAG) {
switch (Op.getOpcode()) {
default: assert(0 && "Should not custom lower this!");
case ISD::GlobalTLSAddress:
assert(0 && "TLS not implemented for Sparc.");
case ISD::GlobalAddress: {
GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32); SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32);
SDOperand Hi = DAG.getNode(SPISD::Hi, MVT::i32, GA); SDOperand Hi = DAG.getNode(SPISD::Hi, MVT::i32, GA);
SDOperand Lo = DAG.getNode(SPISD::Lo, MVT::i32, GA); SDOperand Lo = DAG.getNode(SPISD::Lo, MVT::i32, GA);
return DAG.getNode(ISD::ADD, MVT::i32, Lo, Hi); return DAG.getNode(ISD::ADD, MVT::i32, Lo, Hi);
} }
case ISD::ConstantPool: {
Constant *C = cast<ConstantPoolSDNode>(Op)->getConstVal(); static SDOperand LowerCONSTANTPOOL(SDOperand Op, SelectionDAG &DAG) {
SDOperand CP = DAG.getTargetConstantPool(C, MVT::i32, ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
cast<ConstantPoolSDNode>(Op)->getAlignment()); Constant *C = N->getConstVal();
SDOperand CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment());
SDOperand Hi = DAG.getNode(SPISD::Hi, MVT::i32, CP); SDOperand Hi = DAG.getNode(SPISD::Hi, MVT::i32, CP);
SDOperand Lo = DAG.getNode(SPISD::Lo, MVT::i32, CP); SDOperand Lo = DAG.getNode(SPISD::Lo, MVT::i32, CP);
return DAG.getNode(ISD::ADD, MVT::i32, Lo, Hi); return DAG.getNode(ISD::ADD, MVT::i32, Lo, Hi);
} }
case ISD::FP_TO_SINT:
static SDOperand LowerFP_TO_SINT(SDOperand Op, SelectionDAG &DAG) {
// Convert the fp value to integer in an FP register. // Convert the fp value to integer in an FP register.
assert(Op.getValueType() == MVT::i32); assert(Op.getValueType() == MVT::i32);
Op = DAG.getNode(SPISD::FTOI, MVT::f32, Op.getOperand(0)); Op = DAG.getNode(SPISD::FTOI, MVT::f32, Op.getOperand(0));
return DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Op); return DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Op);
case ISD::SINT_TO_FP: { }
static SDOperand LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
assert(Op.getOperand(0).getValueType() == MVT::i32); assert(Op.getOperand(0).getValueType() == MVT::i32);
SDOperand Tmp = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, Op.getOperand(0)); SDOperand Tmp = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, Op.getOperand(0));
// Convert the int value to FP in an FP register. // Convert the int value to FP in an FP register.
return DAG.getNode(SPISD::ITOF, Op.getValueType(), Tmp); return DAG.getNode(SPISD::ITOF, Op.getValueType(), Tmp);
} }
case ISD::BR_CC: {
static SDOperand LowerBR_CC(SDOperand Op, SelectionDAG &DAG) {
SDOperand Chain = Op.getOperand(0); SDOperand Chain = Op.getOperand(0);
ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
SDOperand LHS = Op.getOperand(2); SDOperand LHS = Op.getOperand(2);
@ -781,8 +781,9 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
} }
return DAG.getNode(Opc, MVT::Other, Chain, Dest, return DAG.getNode(Opc, MVT::Other, Chain, Dest,
DAG.getConstant(SPCC, MVT::i32), CompareFlag); DAG.getConstant(SPCC, MVT::i32), CompareFlag);
} }
case ISD::SELECT_CC: {
static SDOperand LowerSELECT_CC(SDOperand Op, SelectionDAG &DAG) {
SDOperand LHS = Op.getOperand(0); SDOperand LHS = Op.getOperand(0);
SDOperand RHS = Op.getOperand(1); SDOperand RHS = Op.getOperand(1);
ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
@ -810,47 +811,52 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
} }
return DAG.getNode(Opc, TrueVal.getValueType(), TrueVal, FalseVal, return DAG.getNode(Opc, TrueVal.getValueType(), TrueVal, FalseVal,
DAG.getConstant(SPCC, MVT::i32), CompareFlag); DAG.getConstant(SPCC, MVT::i32), CompareFlag);
} }
case ISD::VASTART: {
static SDOperand LowerVASTART(SDOperand Op, SelectionDAG &DAG,
SparcTargetLowering &TLI) {
// vastart just stores the address of the VarArgsFrameIndex slot into the // vastart just stores the address of the VarArgsFrameIndex slot into the
// memory location argument. // memory location argument.
SDOperand Offset = DAG.getNode(ISD::ADD, MVT::i32, SDOperand Offset = DAG.getNode(ISD::ADD, MVT::i32,
DAG.getRegister(SP::I6, MVT::i32), DAG.getRegister(SP::I6, MVT::i32),
DAG.getConstant(VarArgsFrameOffset, MVT::i32)); DAG.getConstant(TLI.getVarArgsFrameOffset(),
MVT::i32));
const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
return DAG.getStore(Op.getOperand(0), Offset, Op.getOperand(1), SV, 0); return DAG.getStore(Op.getOperand(0), Offset, Op.getOperand(1), SV, 0);
} }
case ISD::VAARG: {
static SDOperand LowerVAARG(SDOperand Op, SelectionDAG &DAG) {
SDNode *Node = Op.Val; SDNode *Node = Op.Val;
MVT::ValueType VT = Node->getValueType(0); MVT::ValueType VT = Node->getValueType(0);
SDOperand InChain = Node->getOperand(0); SDOperand InChain = Node->getOperand(0);
SDOperand VAListPtr = Node->getOperand(1); SDOperand VAListPtr = Node->getOperand(1);
const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue(); const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
SDOperand VAList = DAG.getLoad(getPointerTy(), InChain, VAListPtr, SV, 0); SDOperand VAList = DAG.getLoad(MVT::i32, InChain, VAListPtr, SV, 0);
// Increment the pointer, VAList, to the next vaarg // Increment the pointer, VAList, to the next vaarg
SDOperand NextPtr = DAG.getNode(ISD::ADD, getPointerTy(), VAList, SDOperand NextPtr = DAG.getNode(ISD::ADD, MVT::i32, VAList,
DAG.getConstant(MVT::getSizeInBits(VT)/8, DAG.getConstant(MVT::getSizeInBits(VT)/8,
getPointerTy())); MVT::i32));
// Store the incremented VAList to the legalized pointer // Store the incremented VAList to the legalized pointer
InChain = DAG.getStore(VAList.getValue(1), NextPtr, InChain = DAG.getStore(VAList.getValue(1), NextPtr,
VAListPtr, SV, 0); VAListPtr, SV, 0);
// Load the actual argument out of the pointer VAList, unless this is an // Load the actual argument out of the pointer VAList, unless this is an
// f64 load. // f64 load.
if (VT != MVT::f64) { if (VT != MVT::f64)
return DAG.getLoad(VT, InChain, VAList, NULL, 0); return DAG.getLoad(VT, InChain, VAList, NULL, 0);
} else {
// Otherwise, load it as i64, then do a bitconvert. // Otherwise, load it as i64, then do a bitconvert.
SDOperand V = DAG.getLoad(MVT::i64, InChain, VAList, NULL, 0); SDOperand V = DAG.getLoad(MVT::i64, InChain, VAList, NULL, 0);
std::vector<MVT::ValueType> Tys;
Tys.push_back(MVT::f64);
Tys.push_back(MVT::Other);
// Bit-Convert the value to f64. // Bit-Convert the value to f64.
SDOperand Ops[2] = { DAG.getNode(ISD::BIT_CONVERT, MVT::f64, V), SDOperand Ops[2] = {
V.getValue(1) }; DAG.getNode(ISD::BIT_CONVERT, MVT::f64, V),
return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops, 2); V.getValue(1)
} };
} return DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(MVT::f64, MVT::Other),
case ISD::DYNAMIC_STACKALLOC: { Ops, 2);
}
static SDOperand LowerDYNAMIC_STACKALLOC(SDOperand Op, SelectionDAG &DAG) {
SDOperand Chain = Op.getOperand(0); // Legalize the chain. SDOperand Chain = Op.getOperand(0); // Legalize the chain.
SDOperand Size = Op.getOperand(1); // Legalize the size. SDOperand Size = Op.getOperand(1); // Legalize the size.
@ -868,8 +874,9 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
Tys.push_back(MVT::Other); Tys.push_back(MVT::Other);
SDOperand Ops[2] = { NewVal, Chain }; SDOperand Ops[2] = { NewVal, Chain };
return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops, 2); return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops, 2);
} }
case ISD::RET: {
static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) {
SDOperand Copy; SDOperand Copy;
switch(Op.getNumOperands()) { switch(Op.getNumOperands()) {
@ -897,12 +904,29 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
break; break;
} }
return DAG.getNode(SPISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1)); return DAG.getNode(SPISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1));
} }
SDOperand SparcTargetLowering::
LowerOperation(SDOperand Op, SelectionDAG &DAG) {
switch (Op.getOpcode()) {
default: assert(0 && "Should not custom lower this!");
// Frame & Return address. Currently unimplemented // Frame & Return address. Currently unimplemented
case ISD::RETURNADDR: break; case ISD::RETURNADDR: return SDOperand();
case ISD::FRAMEADDR: break; case ISD::FRAMEADDR: return SDOperand();
case ISD::GlobalTLSAddress:
assert(0 && "TLS not implemented for Sparc.");
case ISD::GlobalAddress: return LowerGLOBALADDRESS(Op, DAG);
case ISD::ConstantPool: return LowerCONSTANTPOOL(Op, DAG);
case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG);
case ISD::SINT_TO_FP: return LowerSINT_TO_FP(Op, DAG);
case ISD::BR_CC: return LowerBR_CC(Op, DAG);
case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
case ISD::VASTART: return LowerVASTART(Op, DAG, *this);
case ISD::VAARG: return LowerVAARG(Op, DAG);
case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
case ISD::RET: return LowerRET(Op, DAG);
} }
return SDOperand();
} }
MachineBasicBlock * MachineBasicBlock *