mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-22 13:29:44 +00:00
Add -arm-long-calls option to force calls to be indirect. This makes the
kernel linker happier when dealing with kexts. Radar 7805069 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@101303 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
070c07f2c8
commit
e7b52526d3
@ -40,12 +40,18 @@
|
|||||||
#include "llvm/MC/MCSectionMachO.h"
|
#include "llvm/MC/MCSectionMachO.h"
|
||||||
#include "llvm/Target/TargetOptions.h"
|
#include "llvm/Target/TargetOptions.h"
|
||||||
#include "llvm/ADT/VectorExtras.h"
|
#include "llvm/ADT/VectorExtras.h"
|
||||||
|
#include "llvm/Support/CommandLine.h"
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include "llvm/Support/MathExtras.h"
|
#include "llvm/Support/MathExtras.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
static cl::opt<bool>
|
||||||
|
EnableARMLongCalls("arm-long-calls", cl::Hidden,
|
||||||
|
cl::desc("Generate calls via indirect call instructions."),
|
||||||
|
cl::init(false));
|
||||||
|
|
||||||
static bool CC_ARM_APCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT,
|
static bool CC_ARM_APCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT,
|
||||||
CCValAssign::LocInfo &LocInfo,
|
CCValAssign::LocInfo &LocInfo,
|
||||||
ISD::ArgFlagsTy &ArgFlags,
|
ISD::ArgFlagsTy &ArgFlags,
|
||||||
@ -1027,7 +1033,43 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
|
|||||||
bool isLocalARMFunc = false;
|
bool isLocalARMFunc = false;
|
||||||
MachineFunction &MF = DAG.getMachineFunction();
|
MachineFunction &MF = DAG.getMachineFunction();
|
||||||
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
|
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
|
||||||
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
|
|
||||||
|
if (EnableARMLongCalls) {
|
||||||
|
assert (getTargetMachine().getRelocationModel() == Reloc::Static
|
||||||
|
&& "long-calls with non-static relocation model!");
|
||||||
|
// Handle a global address or an external symbol. If it's not one of
|
||||||
|
// those, the target's already in a register, so we don't need to do
|
||||||
|
// anything extra.
|
||||||
|
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
|
||||||
|
GlobalValue *GV = G->getGlobal();
|
||||||
|
// Create a constant pool entry for the callee address
|
||||||
|
unsigned ARMPCLabelIndex = AFI->createConstPoolEntryUId();
|
||||||
|
ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV,
|
||||||
|
ARMPCLabelIndex,
|
||||||
|
ARMCP::CPValue, 0);
|
||||||
|
// Get the address of the callee into a register
|
||||||
|
SDValue CPAddr = DAG.getTargetConstantPool(CPV, getPointerTy(), 4);
|
||||||
|
CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
|
||||||
|
Callee = DAG.getLoad(getPointerTy(), dl,
|
||||||
|
DAG.getEntryNode(), CPAddr,
|
||||||
|
PseudoSourceValue::getConstantPool(), 0,
|
||||||
|
false, false, 0);
|
||||||
|
} else if (ExternalSymbolSDNode *S=dyn_cast<ExternalSymbolSDNode>(Callee)) {
|
||||||
|
const char *Sym = S->getSymbol();
|
||||||
|
|
||||||
|
// Create a constant pool entry for the callee address
|
||||||
|
unsigned ARMPCLabelIndex = AFI->createConstPoolEntryUId();
|
||||||
|
ARMConstantPoolValue *CPV = new ARMConstantPoolValue(*DAG.getContext(),
|
||||||
|
Sym, ARMPCLabelIndex, 0);
|
||||||
|
// Get the address of the callee into a register
|
||||||
|
SDValue CPAddr = DAG.getTargetConstantPool(CPV, getPointerTy(), 4);
|
||||||
|
CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
|
||||||
|
Callee = DAG.getLoad(getPointerTy(), dl,
|
||||||
|
DAG.getEntryNode(), CPAddr,
|
||||||
|
PseudoSourceValue::getConstantPool(), 0,
|
||||||
|
false, false, 0);
|
||||||
|
}
|
||||||
|
} else if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
|
||||||
GlobalValue *GV = G->getGlobal();
|
GlobalValue *GV = G->getGlobal();
|
||||||
isDirect = true;
|
isDirect = true;
|
||||||
bool isExt = GV->isDeclaration() || GV->isWeakForLinker();
|
bool isExt = GV->isDeclaration() || GV->isWeakForLinker();
|
||||||
@ -1051,7 +1093,7 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
|
|||||||
SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32);
|
SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32);
|
||||||
Callee = DAG.getNode(ARMISD::PIC_ADD, dl,
|
Callee = DAG.getNode(ARMISD::PIC_ADD, dl,
|
||||||
getPointerTy(), Callee, PICLabel);
|
getPointerTy(), Callee, PICLabel);
|
||||||
} else
|
} else
|
||||||
Callee = DAG.getTargetGlobalAddress(GV, getPointerTy());
|
Callee = DAG.getTargetGlobalAddress(GV, getPointerTy());
|
||||||
} else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
|
} else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
|
||||||
isDirect = true;
|
isDirect = true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user