mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-19 02:25:01 +00:00
Support global addresses and fix call returns. Varargs still aren't
handled correctly for floating point arguments, or more than 8 arguemnts. This does however, allow hello world to run. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@20832 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -229,6 +229,7 @@ PPC32TargetLowering::LowerCallTo(SDOperand Chain,
|
|||||||
Args[i].first = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first);
|
Args[i].first = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first);
|
||||||
break;
|
break;
|
||||||
case MVT::i32:
|
case MVT::i32:
|
||||||
|
case MVT::i64:
|
||||||
case MVT::f32:
|
case MVT::f32:
|
||||||
case MVT::f64:
|
case MVT::f64:
|
||||||
break;
|
break;
|
||||||
@@ -259,7 +260,23 @@ PPC32TargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) {
|
|||||||
std::pair<SDOperand,SDOperand> PPC32TargetLowering::
|
std::pair<SDOperand,SDOperand> PPC32TargetLowering::
|
||||||
LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
|
LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
|
||||||
const Type *ArgTy, SelectionDAG &DAG) {
|
const Type *ArgTy, SelectionDAG &DAG) {
|
||||||
abort();
|
MVT::ValueType ArgVT = getValueType(ArgTy);
|
||||||
|
SDOperand Result;
|
||||||
|
if (!isVANext) {
|
||||||
|
Result = DAG.getLoad(ArgVT, DAG.getEntryNode(), VAList);
|
||||||
|
} else {
|
||||||
|
unsigned Amt;
|
||||||
|
if (ArgVT == MVT::i32 || ArgVT == MVT::f32)
|
||||||
|
Amt = 4;
|
||||||
|
else {
|
||||||
|
assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) &&
|
||||||
|
"Other types should have been promoted for varargs!");
|
||||||
|
Amt = 8;
|
||||||
|
}
|
||||||
|
Result = DAG.getNode(ISD::ADD, VAList.getValueType(), VAList,
|
||||||
|
DAG.getConstant(Amt, VAList.getValueType()));
|
||||||
|
}
|
||||||
|
return std::make_pair(Result, Chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -284,11 +301,22 @@ class ISel : public SelectionDAGISel {
|
|||||||
/// vreg the value is produced in, so we only emit one copy of each compiled
|
/// vreg the value is produced in, so we only emit one copy of each compiled
|
||||||
/// tree.
|
/// tree.
|
||||||
std::map<SDOperand, unsigned> ExprMap;
|
std::map<SDOperand, unsigned> ExprMap;
|
||||||
|
|
||||||
|
unsigned GlobalBaseReg;
|
||||||
|
bool GlobalBaseInitialized;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ISel(TargetMachine &TM) : SelectionDAGISel(PPC32Lowering), PPC32Lowering(TM)
|
ISel(TargetMachine &TM) : SelectionDAGISel(PPC32Lowering), PPC32Lowering(TM)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
/// runOnFunction - Override this function in order to reset our per-function
|
||||||
|
/// variables.
|
||||||
|
virtual bool runOnFunction(Function &Fn) {
|
||||||
|
// Make sure we re-emit a set of the global base reg if necessary
|
||||||
|
GlobalBaseInitialized = false;
|
||||||
|
return SelectionDAGISel::runOnFunction(Fn);
|
||||||
|
}
|
||||||
|
|
||||||
/// InstructionSelectBasicBlock - This callback is invoked by
|
/// InstructionSelectBasicBlock - This callback is invoked by
|
||||||
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
|
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
|
||||||
virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
||||||
@@ -300,6 +328,7 @@ public:
|
|||||||
ExprMap.clear();
|
ExprMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned ISel::getGlobalBaseReg();
|
||||||
unsigned SelectExpr(SDOperand N);
|
unsigned SelectExpr(SDOperand N);
|
||||||
unsigned SelectExprFP(SDOperand N, unsigned Result);
|
unsigned SelectExprFP(SDOperand N, unsigned Result);
|
||||||
void Select(SDOperand N);
|
void Select(SDOperand N);
|
||||||
@@ -340,6 +369,22 @@ static unsigned canUseAsImmediateForOpcode(SDOperand N, unsigned Opcode,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// getGlobalBaseReg - Output the instructions required to put the
|
||||||
|
/// base address to use for accessing globals into a register.
|
||||||
|
///
|
||||||
|
unsigned ISel::getGlobalBaseReg() {
|
||||||
|
if (!GlobalBaseInitialized) {
|
||||||
|
// Insert the set of GlobalBaseReg into the first MBB of the function
|
||||||
|
MachineBasicBlock &FirstMBB = BB->getParent()->front();
|
||||||
|
MachineBasicBlock::iterator MBBI = FirstMBB.begin();
|
||||||
|
GlobalBaseReg = MakeReg(MVT::i32);
|
||||||
|
BuildMI(FirstMBB, MBBI, PPC::MovePCtoLR, 0, PPC::LR);
|
||||||
|
BuildMI(FirstMBB, MBBI, PPC::MFLR, 1, GlobalBaseReg).addReg(PPC::LR);
|
||||||
|
GlobalBaseInitialized = true;
|
||||||
|
}
|
||||||
|
return GlobalBaseReg;
|
||||||
|
}
|
||||||
|
|
||||||
//Check to see if the load is a constant offset from a base register
|
//Check to see if the load is a constant offset from a base register
|
||||||
void ISel::SelectAddr(SDOperand N, unsigned& Reg, int& offset)
|
void ISel::SelectAddr(SDOperand N, unsigned& Reg, int& offset)
|
||||||
{
|
{
|
||||||
@@ -510,9 +555,8 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
|||||||
case ISD::GlobalAddress: {
|
case ISD::GlobalAddress: {
|
||||||
GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal();
|
GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal();
|
||||||
unsigned Tmp1 = MakeReg(MVT::i32);
|
unsigned Tmp1 = MakeReg(MVT::i32);
|
||||||
// FIXME: R1 is incorrect, we need the getGlobalBaseReg() functionality
|
BuildMI(BB, PPC::LOADHiAddr, 2, Tmp1).addReg(getGlobalBaseReg())
|
||||||
// from the simple isel
|
.addGlobalAddress(GV);
|
||||||
BuildMI(BB, PPC::LOADHiAddr, 2, Tmp1).addReg(PPC::R1).addGlobalAddress(GV);
|
|
||||||
if (GV->hasWeakLinkage() || GV->isExternal()) {
|
if (GV->hasWeakLinkage() || GV->isExternal()) {
|
||||||
BuildMI(BB, PPC::LWZ, 2, Result).addGlobalAddress(GV).addReg(Tmp1);
|
BuildMI(BB, PPC::LWZ, 2, Result).addGlobalAddress(GV).addReg(Tmp1);
|
||||||
} else {
|
} else {
|
||||||
@@ -631,9 +675,9 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
|||||||
case MVT::i8:
|
case MVT::i8:
|
||||||
case MVT::i16:
|
case MVT::i16:
|
||||||
case MVT::i32:
|
case MVT::i32:
|
||||||
BuildMI(BB, PPC::OR, 2, Result).addReg(PPC::R3);
|
BuildMI(BB, PPC::OR, 2, Result).addReg(PPC::R3).addReg(PPC::R3);
|
||||||
if (Node->getValueType(1) == MVT::i32)
|
if (Node->getValueType(1) == MVT::i32)
|
||||||
BuildMI(BB, PPC::OR, 2, Result+1).addReg(PPC::R4);
|
BuildMI(BB, PPC::OR, 2, Result+1).addReg(PPC::R4).addReg(PPC::R4);
|
||||||
break;
|
break;
|
||||||
case MVT::f32:
|
case MVT::f32:
|
||||||
case MVT::f64:
|
case MVT::f64:
|
||||||
|
Reference in New Issue
Block a user