Resolve BB references with relocation.
[oota-llvm.git] / lib / Target / Alpha / AlphaCodeEmitter.cpp
index 92e38b93cd36dd3f52c3fabe9c82781f3acaad38..82f31da00783dd86686d2ee4a12228374d51dfe2 100644 (file)
@@ -23,6 +23,7 @@
 #include "llvm/Function.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/ADT/Statistic.h"
+#include <iostream>
 using namespace llvm;
 
 namespace {
@@ -33,18 +34,19 @@ namespace {
 namespace {
   class AlphaCodeEmitter : public MachineFunctionPass {
     const AlphaInstrInfo  *II;
+    TargetMachine &TM;
     MachineCodeEmitter  &MCE;
-    std::map<const MachineBasicBlock*, unsigned*> BasicBlockAddrs;
-    std::vector<std::pair<const MachineBasicBlock *, unsigned*> > BBRefs;
 
     /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr
     ///
     int getMachineOpValue(MachineInstr &MI, MachineOperand &MO);
 
   public:
-    explicit AlphaCodeEmitter(MachineCodeEmitter &mce) : II(0), MCE(mce) {}
-    AlphaCodeEmitter(MachineCodeEmitter &mce, const AlphaInstrInfo& ii)
-        : II(&ii), MCE(mce) {}
+    explicit AlphaCodeEmitter(TargetMachine &tm, MachineCodeEmitter &mce)
+      : II(0), TM(tm), MCE(mce) {}
+    AlphaCodeEmitter(TargetMachine &tm, MachineCodeEmitter &mce,
+                     const AlphaInstrInfo& ii)
+      : II(&ii), TM(tm), MCE(mce) {}
 
     bool runOnMachineFunction(MachineFunction &MF);
 
@@ -54,10 +56,6 @@ namespace {
 
     void emitInstruction(const MachineInstr &MI);
 
-    /// emitWord - write a 32-bit word to memory at the current PC
-    ///
-    void emitWord(unsigned w) { MCE.emitWord(w); }
-
     /// getBinaryCodeForInstr - This function, generated by the
     /// CodeEmitterGenerator using TableGen, produces the binary encoding for
     /// machine instructions.
@@ -72,49 +70,39 @@ namespace {
 
 /// createAlphaCodeEmitterPass - Return a pass that emits the collected Alpha code
 /// to the specified MCE object.
-FunctionPass *llvm::createAlphaCodeEmitterPass(MachineCodeEmitter &MCE) {
-  return new AlphaCodeEmitter(MCE);
+FunctionPass *llvm::createAlphaCodeEmitterPass(AlphaTargetMachine &TM,
+                                               MachineCodeEmitter &MCE) {
+  return new AlphaCodeEmitter(TM, MCE);
 }
 
 bool AlphaCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
   II = ((AlphaTargetMachine&)MF.getTarget()).getInstrInfo();
 
-  MCE.startFunction(MF);
-  MCE.emitConstantPool(MF.getConstantPool());
-  for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I)
-    emitBasicBlock(*I);
-  MCE.finishFunction(MF);
-
-  // Resolve all forward branches now...
-  for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) {
-    unsigned* Location = (unsigned*)BasicBlockAddrs[BBRefs[i].first];
-    unsigned* Ref = (unsigned*)BBRefs[i].second;
-    intptr_t BranchTargetDisp = (((unsigned char*)Location  - (unsigned char*)Ref) >> 2) - 1;
-    DEBUG(std::cerr << "Fixup @ " << (void*)Ref << " to " << (void*)Location
-          << " Disp " << BranchTargetDisp << " using " <<  (BranchTargetDisp & ((1 << 22)-1)) << "\n");
-    *Ref |= (BranchTargetDisp & ((1 << 21)-1));
-  }
-  BBRefs.clear();
-  BasicBlockAddrs.clear();
+  do {
+    MCE.startFunction(MF);
+    for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I)
+      emitBasicBlock(*I);
+  } while (MCE.finishFunction(MF));
 
   return false;
 }
 
 void AlphaCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
-  uintptr_t Addr = MCE.getCurrentPCValue();
-  BasicBlockAddrs[&MBB] = (unsigned*)Addr;
-
+  MCE.StartMachineBasicBlock(&MBB);
   for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
        I != E; ++I) {
     MachineInstr &MI = *I;
     unsigned Opcode = MI.getOpcode();
     switch(MI.getOpcode()) {
     default:
-      emitWord(getBinaryCodeForInstr(*I));
+      MCE.emitWordLE(getBinaryCodeForInstr(*I));
       break;
     case Alpha::ALTENT:
     case Alpha::PCLABEL:
     case Alpha::MEMLABEL:
+    case Alpha::IDEF_I:
+    case Alpha::IDEF_F32:
+    case Alpha::IDEF_F64:
       break; //skip these
     }
   }
@@ -169,16 +157,20 @@ int AlphaCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) {
     rv = getAlphaRegNumber(MO.getReg());
   } else if (MO.isImmediate()) {
     rv = MO.getImmedValue();
-  } else if (MO.isGlobalAddress() || MO.isExternalSymbol() 
+  } else if (MO.isGlobalAddress() || MO.isExternalSymbol()
              || MO.isConstantPoolIndex()) {
     DEBUG(std::cerr << MO << " is a relocated op for " << MI << "\n";);
-    bool isExternal = MO.isExternalSymbol() || 
-      (MO.isGlobalAddress() && 
+    bool isExternal = MO.isExternalSymbol() ||
+      (MO.isGlobalAddress() &&
        ( MO.getGlobal()->hasWeakLinkage() ||
          MO.getGlobal()->isExternal()) );
     unsigned Reloc = 0;
     int Offset = 0;
+    bool useGOT = false;
     switch (MI.getOpcode()) {
+    case Alpha::BSR:
+      Reloc = Alpha::reloc_bsr;
+      break;
     case Alpha::LDLr:
     case Alpha::LDQr:
     case Alpha::LDBUr:
@@ -186,6 +178,12 @@ int AlphaCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) {
     case Alpha::LDSr:
     case Alpha::LDTr:
     case Alpha::LDAr:
+    case Alpha::STQr:
+    case Alpha::STLr:
+    case Alpha::STWr:
+    case Alpha::STBr:
+    case Alpha::STSr:
+    case Alpha::STTr:
       Reloc = Alpha::reloc_gprellow;
       break;
     case Alpha::LDAHr:
@@ -193,6 +191,7 @@ int AlphaCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) {
       break;
     case Alpha::LDQl:
       Reloc = Alpha::reloc_literal;
+      useGOT = true;
       break;
     case Alpha::LDAg:
     case Alpha::LDAHg:
@@ -204,20 +203,21 @@ int AlphaCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) {
       abort();
     }
     if (MO.isGlobalAddress())
-      MCE.addRelocation(MachineRelocation((unsigned)MCE.getCurrentPCOffset(),
+      MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(),
                                           Reloc, MO.getGlobal(), Offset,
-                                          true, true));
+                                          false, useGOT));
     else if (MO.isExternalSymbol())
-      MCE.addRelocation(MachineRelocation((unsigned)MCE.getCurrentPCOffset(),
+      MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
                                           Reloc, MO.getSymbolName(), Offset,
                                           true));
     else
-      MCE.addRelocation(MachineRelocation((unsigned)MCE.getCurrentPCOffset(),
-                                          Reloc, MO.getConstantPoolIndex(), 
+    MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
+                                          Reloc, MO.getConstantPoolIndex(),
                                           Offset));
   } else if (MO.isMachineBasicBlock()) {
-    unsigned* CurrPC = (unsigned*)(intptr_t)MCE.getCurrentPCValue();
-    BBRefs.push_back(std::make_pair(MO.getMachineBasicBlock(), CurrPC));
+    MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(),
+                                               Alpha::reloc_bsr,
+                                               MO.getMachineBasicBlock()));
   }else {
     std::cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n";
     abort();