Resolve BB references with relocation.
[oota-llvm.git] / lib / Target / Alpha / AlphaCodeEmitter.cpp
index f5d517fadd49d634280ca828329b39184c8b40b9..82f31da00783dd86686d2ee4a12228374d51dfe2 100644 (file)
@@ -34,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);
 
@@ -55,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.
@@ -73,47 +70,32 @@ 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:
@@ -221,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,
                                           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(),
+    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();