mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-08 19:25:47 +00:00
Tailcalls require stubs to be emitted. Otherwise, the compilation callback
doesn't know who 'called' it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22136 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -53,9 +53,10 @@ namespace {
|
|||||||
|
|
||||||
void emitPCRelativeBlockAddress(const MachineBasicBlock *BB);
|
void emitPCRelativeBlockAddress(const MachineBasicBlock *BB);
|
||||||
void emitPCRelativeValue(unsigned Address);
|
void emitPCRelativeValue(unsigned Address);
|
||||||
void emitGlobalAddressForCall(GlobalValue *GV);
|
void emitGlobalAddressForCall(GlobalValue *GV, bool isTailCall);
|
||||||
void emitGlobalAddressForPtr(GlobalValue *GV, int Disp = 0);
|
void emitGlobalAddressForPtr(GlobalValue *GV, int Disp = 0);
|
||||||
void emitExternalSymbolAddress(const char *ES, bool isPCRelative);
|
void emitExternalSymbolAddress(const char *ES, bool isPCRelative,
|
||||||
|
bool isTailCall);
|
||||||
|
|
||||||
void emitRegModRMByte(unsigned ModRMReg, unsigned RegOpcodeField);
|
void emitRegModRMByte(unsigned ModRMReg, unsigned RegOpcodeField);
|
||||||
void emitSIBByte(unsigned SS, unsigned Index, unsigned Base);
|
void emitSIBByte(unsigned SS, unsigned Index, unsigned Base);
|
||||||
@@ -139,9 +140,10 @@ void Emitter::emitPCRelativeBlockAddress(const MachineBasicBlock *MBB) {
|
|||||||
/// emitGlobalAddressForCall - Emit the specified address to the code stream
|
/// emitGlobalAddressForCall - Emit the specified address to the code stream
|
||||||
/// assuming this is part of a function call, which is PC relative.
|
/// assuming this is part of a function call, which is PC relative.
|
||||||
///
|
///
|
||||||
void Emitter::emitGlobalAddressForCall(GlobalValue *GV) {
|
void Emitter::emitGlobalAddressForCall(GlobalValue *GV, bool isTailCall) {
|
||||||
MCE.addRelocation(MachineRelocation(MCE.getCurrentPCOffset(),
|
MCE.addRelocation(MachineRelocation(MCE.getCurrentPCOffset(),
|
||||||
X86::reloc_pcrel_word, GV, 0, true));
|
X86::reloc_pcrel_word, GV, 0,
|
||||||
|
!isTailCall /*Doesn'tNeedStub*/));
|
||||||
MCE.emitWord(0);
|
MCE.emitWord(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +160,8 @@ void Emitter::emitGlobalAddressForPtr(GlobalValue *GV, int Disp /* = 0 */) {
|
|||||||
/// emitExternalSymbolAddress - Arrange for the address of an external symbol to
|
/// emitExternalSymbolAddress - Arrange for the address of an external symbol to
|
||||||
/// be emitted to the current location in the function, and allow it to be PC
|
/// be emitted to the current location in the function, and allow it to be PC
|
||||||
/// relative.
|
/// relative.
|
||||||
void Emitter::emitExternalSymbolAddress(const char *ES, bool isPCRelative) {
|
void Emitter::emitExternalSymbolAddress(const char *ES, bool isPCRelative,
|
||||||
|
bool isTailCall) {
|
||||||
MCE.addRelocation(MachineRelocation(MCE.getCurrentPCOffset(),
|
MCE.addRelocation(MachineRelocation(MCE.getCurrentPCOffset(),
|
||||||
isPCRelative ? X86::reloc_pcrel_word : X86::reloc_absolute_word, ES));
|
isPCRelative ? X86::reloc_pcrel_word : X86::reloc_absolute_word, ES));
|
||||||
MCE.emitWord(0);
|
MCE.emitWord(0);
|
||||||
@@ -394,9 +397,13 @@ void Emitter::emitInstruction(const MachineInstr &MI) {
|
|||||||
emitPCRelativeBlockAddress(MO.getMachineBasicBlock());
|
emitPCRelativeBlockAddress(MO.getMachineBasicBlock());
|
||||||
} else if (MO.isGlobalAddress()) {
|
} else if (MO.isGlobalAddress()) {
|
||||||
assert(MO.isPCRelative() && "Call target is not PC Relative?");
|
assert(MO.isPCRelative() && "Call target is not PC Relative?");
|
||||||
emitGlobalAddressForCall(MO.getGlobal());
|
bool isTailCall = Opcode == X86::TAILJMPd ||
|
||||||
|
Opcode == X86::TAILJMPr || Opcode == X86::TAILJMPm;
|
||||||
|
emitGlobalAddressForCall(MO.getGlobal(), isTailCall);
|
||||||
} else if (MO.isExternalSymbol()) {
|
} else if (MO.isExternalSymbol()) {
|
||||||
emitExternalSymbolAddress(MO.getSymbolName(), true);
|
bool isTailCall = Opcode == X86::TAILJMPd ||
|
||||||
|
Opcode == X86::TAILJMPr || Opcode == X86::TAILJMPm;
|
||||||
|
emitExternalSymbolAddress(MO.getSymbolName(), true, isTailCall);
|
||||||
} else if (MO.isImmediate()) {
|
} else if (MO.isImmediate()) {
|
||||||
emitConstant(MO.getImmedValue(), sizeOfImm(Desc));
|
emitConstant(MO.getImmedValue(), sizeOfImm(Desc));
|
||||||
} else {
|
} else {
|
||||||
@@ -421,7 +428,7 @@ void Emitter::emitInstruction(const MachineInstr &MI) {
|
|||||||
} else if (MO1.isExternalSymbol()) {
|
} else if (MO1.isExternalSymbol()) {
|
||||||
assert(sizeOfImm(Desc) == 4 &&
|
assert(sizeOfImm(Desc) == 4 &&
|
||||||
"Don't know how to emit non-pointer values!");
|
"Don't know how to emit non-pointer values!");
|
||||||
emitExternalSymbolAddress(MO1.getSymbolName(), false);
|
emitExternalSymbolAddress(MO1.getSymbolName(), false, false);
|
||||||
} else {
|
} else {
|
||||||
emitConstant(MO1.getImmedValue(), sizeOfImm(Desc));
|
emitConstant(MO1.getImmedValue(), sizeOfImm(Desc));
|
||||||
}
|
}
|
||||||
|
@@ -3918,7 +3918,7 @@ void ISel::EmitFastCCToFastCCTailCall(SDNode *TailCallNode) {
|
|||||||
if (!isDirect) {
|
if (!isDirect) {
|
||||||
BuildMI(BB, X86::TAILJMPr, 1).addReg(CalleeReg);
|
BuildMI(BB, X86::TAILJMPr, 1).addReg(CalleeReg);
|
||||||
} else if (GlobalAddressSDNode *GASD = dyn_cast<GlobalAddressSDNode>(Callee)){
|
} else if (GlobalAddressSDNode *GASD = dyn_cast<GlobalAddressSDNode>(Callee)){
|
||||||
BuildMI(BB, X86::TAILJMPd, 1).addGlobalAddress(GASD->getGlobal(),true);
|
BuildMI(BB, X86::TAILJMPd, 1).addGlobalAddress(GASD->getGlobal(), true);
|
||||||
} else {
|
} else {
|
||||||
ExternalSymbolSDNode *ESSDN = cast<ExternalSymbolSDNode>(Callee);
|
ExternalSymbolSDNode *ESSDN = cast<ExternalSymbolSDNode>(Callee);
|
||||||
BuildMI(BB, X86::TAILJMPd, 1).addExternalSymbol(ESSDN->getSymbol(), true);
|
BuildMI(BB, X86::TAILJMPd, 1).addExternalSymbol(ESSDN->getSymbol(), true);
|
||||||
|
Reference in New Issue
Block a user