Tailcalls require stubs to be emitted. Otherwise, the compilation callback
authorChris Lattner <sabre@nondot.org>
Thu, 19 May 2005 05:54:33 +0000 (05:54 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 19 May 2005 05:54:33 +0000 (05:54 +0000)
doesn't know who 'called' it.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22136 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86CodeEmitter.cpp
lib/Target/X86/X86ISelPattern.cpp

index 3e8c79a971396dccc01236e4a584bfdbe7af4ea4..d55edc5841c472e165b6a2a18dffe871e54bfa81 100644 (file)
@@ -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));
       }
index 1d30608d34c8b4d0e2fe0ddc3708da43f971d23c..c3b0e5a61150426a5cea8e837f1ab6c9d5f0c34f 100644 (file)
@@ -3918,7 +3918,7 @@ void ISel::EmitFastCCToFastCCTailCall(SDNode *TailCallNode) {
   if (!isDirect) {
     BuildMI(BB, X86::TAILJMPr, 1).addReg(CalleeReg);
   } 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 {
     ExternalSymbolSDNode *ESSDN = cast<ExternalSymbolSDNode>(Callee);
     BuildMI(BB, X86::TAILJMPd, 1).addExternalSymbol(ESSDN->getSymbol(), true);