Correct way to handle CONSTPOOL_ENTRY instructions.
authorEvan Cheng <evan.cheng@apple.com>
Wed, 29 Oct 2008 23:55:43 +0000 (23:55 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Wed, 29 Oct 2008 23:55:43 +0000 (23:55 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58409 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMCodeEmitter.cpp
lib/Target/ARM/ARMJITInfo.cpp
lib/Target/ARM/ARMJITInfo.h
lib/Target/ARM/ARMRelocations.h

index 641e1a1205f19bd8af254ef75c33c5da2c0eae81..b6a57e533094c6123bc546ca5f70c8e13a84f615 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "arm-emitter"
+#define DEBUG_TYPE "jit"
 #include "ARM.h"
 #include "ARMAddressingModes.h"
+#include "ARMConstantPoolValue.h"
 #include "ARMInstrInfo.h"
 #include "ARMRelocations.h"
 #include "ARMSubtarget.h"
@@ -192,7 +193,7 @@ unsigned ARMCodeEmitter::getMachineOpValue(const MachineInstr &MI,
   else if (MO.isSymbol())
     emitExternalSymbolAddress(MO.getSymbolName(), ARM::reloc_arm_relative);
   else if (MO.isCPI())
-    emitConstPoolAddress(MO.getIndex(), ARM::reloc_arm_relative);
+    emitConstPoolAddress(MO.getIndex(), ARM::reloc_arm_cp_entry);
   else if (MO.isJTI())
     emitJumpTableAddress(MO.getIndex(), ARM::reloc_arm_relative);
   else if (MO.isMBB())
@@ -226,8 +227,9 @@ void ARMCodeEmitter::emitExternalSymbolAddress(const char *ES, unsigned Reloc) {
 void ARMCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc,
                                           int Disp /* = 0 */,
                                           unsigned PCAdj /* = 0 */) {
+  // Tell JIT emitter we'll resolve the address.
   MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
-                                                    Reloc, CPI, PCAdj));
+                                                    Reloc, CPI, PCAdj, true));
 }
 
 /// emitJumpTableAddress - Arrange for the address of a jump table to
@@ -246,7 +248,7 @@ void ARMCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB) {
 }
 
 void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
-  DOUT << MI;
+  DOUT << "JIT: " << "0x" << MCE.getCurrentPCValue() << ":\t" << MI;
 
   NumEmitted++;  // Keep track of the # of mi's emitted
   if ((MI.getDesc().TSFlags & ARMII::FormMask) == ARMII::Pseudo)
@@ -360,29 +362,47 @@ unsigned ARMCodeEmitter::getAddrMode1SBit(const MachineInstr &MI,
 }
 
 void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) {
-  unsigned CPID = MI.getOperand(0).getImm();
+  unsigned CPI = MI.getOperand(0).getImm();
   unsigned CPIndex = MI.getOperand(1).getIndex();
   const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIndex];
   
-  //FIXME: Can we get these here?
-  assert (!MCPE.isMachineConstantPoolEntry());
-
-  const Constant *CV = MCPE.Val.ConstVal;  
-  // FIXME: We can get other types here. Need to handle them.
-  // According to the constant island pass, everything is multiples,
-  // of 4-bytes in size, though, so that helps.
-  assert (CV->getType()->isInteger());
-  assert (cast<IntegerType>(CV->getType())->getBitWidth() == 32);
-
-  const ConstantInt *CI = dyn_cast<ConstantInt>(CV);
-  uint32_t Val = *(uint32_t*)CI->getValue().getRawData();
-
-  DOUT << "Constant pool #" << CPID << ", value '" << Val << "' @ " << 
-    (void*)MCE.getCurrentPCValue() << "\n";
-
-  if (JTI)
-    JTI->mapCPIDtoAddress(CPID, MCE.getCurrentPCValue());
-  MCE.emitWordLE(Val);
+  // Remember the CONSTPOOL_ENTRY address for later relocation.
+  JTI->addConstantPoolEntryAddr(CPI, MCE.getCurrentPCValue());
+
+  // Emit constpool island entry. In most cases, the actual values will be
+  // resolved and relocated after code emission.
+  if (MCPE.isMachineConstantPoolEntry()) {
+    ARMConstantPoolValue *ACPV =
+      static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal);
+
+    DOUT << "\t** ARM constant pool #" << CPI << ", ' @ "
+         << (void*)MCE.getCurrentPCValue() << *ACPV << '\n';
+
+    GlobalValue *GV = ACPV->getGV();
+    if (GV) {
+      assert(!ACPV->isStub() && "Don't know how to deal this yet!");
+      emitGlobalAddress(GV, ARM::reloc_arm_absolute, false);
+    } else  {
+      assert(!ACPV->isNonLazyPointer() && "Don't know how to deal this yet!");
+      emitExternalSymbolAddress(ACPV->getSymbol(), ARM::reloc_arm_absolute);
+    }
+    MCE.emitWordLE(0);
+  } else {
+    Constant *CV = MCPE.Val.ConstVal;
+
+    DOUT << "\t** Constant pool #" << CPI << ", ' @ "
+         << (void*)MCE.getCurrentPCValue() << *CV << '\n';
+
+    if (GlobalValue *GV = dyn_cast<GlobalValue>(CV)) {
+      emitGlobalAddress(GV, ARM::reloc_arm_absolute, false);
+      MCE.emitWordLE(0);
+    } else {
+      abort(); // FIXME: Is this right?
+      const ConstantInt *CI = dyn_cast<ConstantInt>(CV);
+      uint32_t Val = *(uint32_t*)CI->getValue().getRawData();
+      MCE.emitWordLE(Val);
+    }
+  }
 }
 
 void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
index 3c50caaf6d0b002ecc9820a7874207c47d80a4db..6a2c253ff112852a088ca9ac7ece353b62fc2676 100644 (file)
@@ -174,8 +174,14 @@ void ARMJITInfo::relocate(void *Function, MachineRelocation *MR,
                           unsigned NumRelocs, unsigned char* GOTBase) {
   for (unsigned i = 0; i != NumRelocs; ++i, ++MR) {
     void *RelocPos = (char*)Function + MR->getMachineCodeOffset();
-    intptr_t ResultPtr = (intptr_t)MR->getResultPointer();
+    ARM::RelocationType RT = (ARM::RelocationType)MR->getRelocationType();
+    // If this is a constpool relocation, get the address of the
+    // constpool_entry instruction.
+    intptr_t ResultPtr = (RT == ARM::reloc_arm_cp_entry)
+      ? getConstantPoolEntryAddr(MR->getConstantPoolIndex())
+      : (intptr_t)MR->getResultPointer();
     switch ((ARM::RelocationType)MR->getRelocationType()) {
+    case ARM::reloc_arm_cp_entry:
     case ARM::reloc_arm_relative: {
       // It is necessary to calculate the correct PC relative value. We
       // subtract the base addr from the target addr to form a byte offset.
@@ -195,6 +201,10 @@ void ARMJITInfo::relocate(void *Function, MachineRelocation *MR,
       *((unsigned*)RelocPos) |= 0xF << 16;
       break;
     }
+    case ARM::reloc_arm_absolute: {
+      *((unsigned*)RelocPos) += (unsigned)ResultPtr;
+      break;
+    }
     case ARM::reloc_arm_branch: {
       // It is necessary to calculate the correct value of signed_immed_24
       // field. We subtract the base addr from the target addr to form a
index 62b83030106b229ec3e4b49a213181d52aa4cebb..f16e54205a5a28bd630a99fa48b89886f6f133cb 100644 (file)
@@ -22,7 +22,11 @@ namespace llvm {
 
   class ARMJITInfo : public TargetJITInfo {
     ARMTargetMachine &TM;
-    std::map<unsigned, intptr_t> CPIDtoAddressMap;
+
+    // ConstPoolId2AddrMap - A map from constant pool ids to the corresponding
+    // CONSTPOOL_ENTRY addresses.
+    std::map<unsigned, intptr_t> ConstPoolId2AddrMap;
+
   public:
     explicit ARMJITInfo(ARMTargetMachine &tm) : TM(tm) { useGOT = false; }
 
@@ -52,22 +56,22 @@ namespace llvm {
     /// pool address resolution is handled by the target.
     virtual bool hasCustomConstantPool() const { return true; }
 
-    /// getCustomConstantPoolEntryAddress - The ARM target puts all constant
+    /// getConstantPoolEntryAddr - The ARM target puts all constant
     /// pool entries into constant islands. Resolve the constant pool index
     /// into the address where the constant is stored.
-    virtual intptr_t getCustomConstantPoolEntryAddress(unsigned CPID) const
-      {
-        std::map<unsigned, intptr_t>::const_iterator elem;
-        elem = CPIDtoAddressMap.find(CPID);
-        assert (elem != CPIDtoAddressMap.end());
-        return elem->second;
-      }
+    virtual intptr_t getConstantPoolEntryAddr(unsigned CPID) const {
+      std::map<unsigned, intptr_t>::const_iterator I
+        = ConstPoolId2AddrMap.find(CPID);
+      assert(I != ConstPoolId2AddrMap.end() && "Missing constpool_entry?");
+      return I->second;
+    }
 
-    /// mapCPIDtoAddress - Map a Constant Pool Index (CPID) to the address
+    /// addConstantPoolEntryAddr - Map a Constant Pool Index (CPID) to the address
     /// where its associated value is stored. When relocations are processed,
     /// this value will be used to resolve references to the constant.
-    void mapCPIDtoAddress(unsigned CPID, intptr_t address)
-      { CPIDtoAddressMap[CPID] = address; }
+    void addConstantPoolEntryAddr(unsigned CPID, intptr_t Addr) {
+      ConstPoolId2AddrMap[CPID] = Addr;
+    }
   };
 }
 
index 6963980bc2e235f5a1b6781d5a3704efe17b76b4..93101a61797bbd173bfc555d7c3af5262d2d8a64 100644 (file)
 namespace llvm {
   namespace ARM {
     enum RelocationType {
+      // reloc_arm_absolute - Absolute relocation, just add the relocated value
+      // to the value already in memory.
+      reloc_arm_absolute,
+
+      // reloc_arm_relative - PC relative relocation, add the relocated value to
+      // the value already in memory, after we adjust it for where the PC is.
       reloc_arm_relative,
 
+      // reloc_arm_cp_entry - PC relative relocation for constpool_entry's whose
+      // addresses are kept locally in a map.
+      reloc_arm_cp_entry,
+
+      // reloc_arm_branch - Branch address relocation.
       reloc_arm_branch
     };
   }