summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/X86/X86CodeEmitter.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-05-19 05:54:33 +0000
committerChris Lattner <sabre@nondot.org>2005-05-19 05:54:33 +0000
commit57279597ab1e68870454efd38d53b5c7ced20914 (patch)
tree56a53341cb5944555d13d60e630cff017412c2e0 /llvm/lib/Target/X86/X86CodeEmitter.cpp
parente4925ca229fa65c9dc5b07c69ea8bd1191edd4b1 (diff)
downloadbcm5719-llvm-57279597ab1e68870454efd38d53b5c7ced20914.tar.gz
bcm5719-llvm-57279597ab1e68870454efd38d53b5c7ced20914.zip
Tailcalls require stubs to be emitted. Otherwise, the compilation callback
doesn't know who 'called' it. llvm-svn: 22136
Diffstat (limited to 'llvm/lib/Target/X86/X86CodeEmitter.cpp')
-rw-r--r--llvm/lib/Target/X86/X86CodeEmitter.cpp23
1 files changed, 15 insertions, 8 deletions
diff --git a/llvm/lib/Target/X86/X86CodeEmitter.cpp b/llvm/lib/Target/X86/X86CodeEmitter.cpp
index 3e8c79a9713..d55edc5841c 100644
--- a/llvm/lib/Target/X86/X86CodeEmitter.cpp
+++ b/llvm/lib/Target/X86/X86CodeEmitter.cpp
@@ -53,9 +53,10 @@ namespace {
void emitPCRelativeBlockAddress(const MachineBasicBlock *BB);
void emitPCRelativeValue(unsigned Address);
- void emitGlobalAddressForCall(GlobalValue *GV);
+ void emitGlobalAddressForCall(GlobalValue *GV, bool isTailCall);
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 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
/// 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(),
- X86::reloc_pcrel_word, GV, 0, true));
+ X86::reloc_pcrel_word, GV, 0,
+ !isTailCall /*Doesn'tNeedStub*/));
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
/// be emitted to the current location in the function, and allow it to be PC
/// relative.
-void Emitter::emitExternalSymbolAddress(const char *ES, bool isPCRelative) {
+void Emitter::emitExternalSymbolAddress(const char *ES, bool isPCRelative,
+ bool isTailCall) {
MCE.addRelocation(MachineRelocation(MCE.getCurrentPCOffset(),
isPCRelative ? X86::reloc_pcrel_word : X86::reloc_absolute_word, ES));
MCE.emitWord(0);
@@ -394,9 +397,13 @@ void Emitter::emitInstruction(const MachineInstr &MI) {
emitPCRelativeBlockAddress(MO.getMachineBasicBlock());
} else if (MO.isGlobalAddress()) {
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()) {
- emitExternalSymbolAddress(MO.getSymbolName(), true);
+ bool isTailCall = Opcode == X86::TAILJMPd ||
+ Opcode == X86::TAILJMPr || Opcode == X86::TAILJMPm;
+ emitExternalSymbolAddress(MO.getSymbolName(), true, isTailCall);
} else if (MO.isImmediate()) {
emitConstant(MO.getImmedValue(), sizeOfImm(Desc));
} else {
@@ -421,7 +428,7 @@ void Emitter::emitInstruction(const MachineInstr &MI) {
} else if (MO1.isExternalSymbol()) {
assert(sizeOfImm(Desc) == 4 &&
"Don't know how to emit non-pointer values!");
- emitExternalSymbolAddress(MO1.getSymbolName(), false);
+ emitExternalSymbolAddress(MO1.getSymbolName(), false, false);
} else {
emitConstant(MO1.getImmedValue(), sizeOfImm(Desc));
}
OpenPOWER on IntegriCloud