mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 20:29:48 +00:00
add support for global address, including PIC support.
This REALLY should be lowered by the legalizer! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22941 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9b78db7f16
commit
4416f1a0a5
@ -15,10 +15,14 @@
|
|||||||
#include "PowerPC.h"
|
#include "PowerPC.h"
|
||||||
#include "PPC32TargetMachine.h"
|
#include "PPC32TargetMachine.h"
|
||||||
#include "PPC32ISelLowering.h"
|
#include "PPC32ISelLowering.h"
|
||||||
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||||
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
|
#include "llvm/CodeGen/SSARegMap.h"
|
||||||
#include "llvm/CodeGen/SelectionDAG.h"
|
#include "llvm/CodeGen/SelectionDAG.h"
|
||||||
#include "llvm/CodeGen/SelectionDAGISel.h"
|
#include "llvm/CodeGen/SelectionDAGISel.h"
|
||||||
#include "llvm/Target/TargetOptions.h"
|
#include "llvm/Target/TargetOptions.h"
|
||||||
#include "llvm/ADT/Statistic.h"
|
#include "llvm/ADT/Statistic.h"
|
||||||
|
#include "llvm/GlobalValue.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Support/MathExtras.h"
|
#include "llvm/Support/MathExtras.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
@ -34,16 +38,26 @@ namespace {
|
|||||||
///
|
///
|
||||||
class PPC32DAGToDAGISel : public SelectionDAGISel {
|
class PPC32DAGToDAGISel : public SelectionDAGISel {
|
||||||
PPC32TargetLowering PPC32Lowering;
|
PPC32TargetLowering PPC32Lowering;
|
||||||
|
unsigned GlobalBaseReg;
|
||||||
public:
|
public:
|
||||||
PPC32DAGToDAGISel(TargetMachine &TM)
|
PPC32DAGToDAGISel(TargetMachine &TM)
|
||||||
: SelectionDAGISel(PPC32Lowering), PPC32Lowering(TM) {}
|
: SelectionDAGISel(PPC32Lowering), PPC32Lowering(TM) {}
|
||||||
|
|
||||||
|
virtual bool runOnFunction(Function &Fn) {
|
||||||
|
// Make sure we re-emit a set of the global base reg if necessary
|
||||||
|
GlobalBaseReg = 0;
|
||||||
|
return SelectionDAGISel::runOnFunction(Fn);
|
||||||
|
}
|
||||||
|
|
||||||
/// getI32Imm - Return a target constant with the specified value, of type
|
/// getI32Imm - Return a target constant with the specified value, of type
|
||||||
/// i32.
|
/// i32.
|
||||||
inline SDOperand getI32Imm(unsigned Imm) {
|
inline SDOperand getI32Imm(unsigned Imm) {
|
||||||
return CurDAG->getTargetConstant(Imm, MVT::i32);
|
return CurDAG->getTargetConstant(Imm, MVT::i32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// getGlobalBaseReg - insert code into the entry mbb to materialize the PIC
|
||||||
|
/// base register. Return the virtual register that holds this value.
|
||||||
|
unsigned getGlobalBaseReg();
|
||||||
|
|
||||||
// Select - Convert the specified operand from a target-independent to a
|
// Select - Convert the specified operand from a target-independent to a
|
||||||
// target-specific node if it hasn't already been changed.
|
// target-specific node if it hasn't already been changed.
|
||||||
@ -73,6 +87,23 @@ namespace {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// getGlobalBaseReg - Output the instructions required to put the
|
||||||
|
/// base address to use for accessing globals into a register.
|
||||||
|
///
|
||||||
|
unsigned PPC32DAGToDAGISel::getGlobalBaseReg() {
|
||||||
|
if (!GlobalBaseReg) {
|
||||||
|
// Insert the set of GlobalBaseReg into the first MBB of the function
|
||||||
|
MachineBasicBlock &FirstMBB = BB->getParent()->front();
|
||||||
|
MachineBasicBlock::iterator MBBI = FirstMBB.begin();
|
||||||
|
SSARegMap *RegMap = BB->getParent()->getSSARegMap();
|
||||||
|
GlobalBaseReg = RegMap->createVirtualRegister(PPC32::GPRCRegisterClass);
|
||||||
|
BuildMI(FirstMBB, MBBI, PPC::MovePCtoLR, 0, PPC::LR);
|
||||||
|
BuildMI(FirstMBB, MBBI, PPC::MFLR, 1, GlobalBaseReg);
|
||||||
|
}
|
||||||
|
return GlobalBaseReg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// isIntImmediate - This method tests to see if a constant operand.
|
// isIntImmediate - This method tests to see if a constant operand.
|
||||||
// If so Imm will receive the 32 bit value.
|
// If so Imm will receive the 32 bit value.
|
||||||
static bool isIntImmediate(SDNode *N, unsigned& Imm) {
|
static bool isIntImmediate(SDNode *N, unsigned& Imm) {
|
||||||
@ -392,6 +423,22 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ISD::GlobalAddress: {
|
||||||
|
GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal();
|
||||||
|
SDOperand Tmp;
|
||||||
|
SDOperand GA = CurDAG->getTargetGlobalAddress(GV, MVT::i32);
|
||||||
|
if (PICEnabled) {
|
||||||
|
SDOperand PICBaseReg = CurDAG->getRegister(getGlobalBaseReg(), MVT::i32);
|
||||||
|
Tmp = CurDAG->getTargetNode(PPC::ADDIS, MVT::i32, PICBaseReg, GA);
|
||||||
|
} else {
|
||||||
|
Tmp = CurDAG->getTargetNode(PPC::LIS, MVT::i32, GA);
|
||||||
|
}
|
||||||
|
if (GV->hasWeakLinkage() || GV->isExternal())
|
||||||
|
CurDAG->SelectNodeTo(N, MVT::i32, PPC::LWZ, GA, Tmp);
|
||||||
|
else
|
||||||
|
CurDAG->SelectNodeTo(N, MVT::i32, PPC::LA, Tmp, GA);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ISD::SIGN_EXTEND_INREG:
|
case ISD::SIGN_EXTEND_INREG:
|
||||||
switch(cast<VTSDNode>(N->getOperand(1))->getVT()) {
|
switch(cast<VTSDNode>(N->getOperand(1))->getVT()) {
|
||||||
default: assert(0 && "Illegal type in SIGN_EXTEND_INREG"); break;
|
default: assert(0 && "Illegal type in SIGN_EXTEND_INREG"); break;
|
||||||
|
Loading…
Reference in New Issue
Block a user