Alpha JIT (beta)
authorAndrew Lenharth <andrewl@lenharth.org>
Fri, 22 Jul 2005 20:52:16 +0000 (20:52 +0000)
committerAndrew Lenharth <andrewl@lenharth.org>
Fri, 22 Jul 2005 20:52:16 +0000 (20:52 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22500 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Alpha/Alpha.h
lib/Target/Alpha/AlphaAsmPrinter.cpp
lib/Target/Alpha/AlphaCodeEmitter.cpp [new file with mode: 0644]
lib/Target/Alpha/AlphaJITInfo.cpp [new file with mode: 0644]
lib/Target/Alpha/AlphaJITInfo.h [new file with mode: 0644]
lib/Target/Alpha/AlphaRegisterInfo.cpp
lib/Target/Alpha/AlphaRelocations.h [new file with mode: 0644]
lib/Target/Alpha/AlphaTargetMachine.cpp
lib/Target/Alpha/AlphaTargetMachine.h

index 08b16cee0c1389bf493986bf07b7f7385fddf432..1b369066212c1637c2926575d3c868738e86779b 100644 (file)
@@ -21,12 +21,13 @@ namespace llvm {
 
   class FunctionPass;
   class TargetMachine;
+  class MachineCodeEmitter;
 
   FunctionPass *createAlphaSimpleInstructionSelector(TargetMachine &TM);
   FunctionPass *createAlphaCodePrinterPass(std::ostream &OS,
                                              TargetMachine &TM);
   FunctionPass *createAlphaPatternInstructionSelector(TargetMachine &TM);
-
+  FunctionPass *createAlphaCodeEmitterPass(MachineCodeEmitter &MCE);
 } // end namespace llvm;
 
 // Defines symbolic names for Alpha registers.  This defines a mapping from
index 5caa5d9f7726d8371f7fae7b19af60e656505694..19db81935a5053f749315f32e467e7194b271d9b 100644 (file)
@@ -239,6 +239,7 @@ bool AlphaAsmPrinter::doInitialization(Module &M)
     O << "\t.arch ev6\n";
   else
     O << "\t.arch ev56\n";
+  O << "\t.set noat\n";
   return false;
 }
 
diff --git a/lib/Target/Alpha/AlphaCodeEmitter.cpp b/lib/Target/Alpha/AlphaCodeEmitter.cpp
new file mode 100644 (file)
index 0000000..f198883
--- /dev/null
@@ -0,0 +1,231 @@
+//===-- Alpha/AlphaCodeEmitter.cpp - Convert Alpha code to machine code ---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the pass that transforms the Alpha machine instructions
+// into relocatable machine code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AlphaTargetMachine.h"
+#include "AlphaRelocations.h"
+#include "Alpha.h"
+#include "llvm/PassManager.h"
+#include "llvm/CodeGen/MachineCodeEmitter.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/Function.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/ADT/Statistic.h"
+using namespace llvm;
+
+namespace {
+  Statistic<>
+  NumEmitted("alpha-emitter", "Number of machine instructions emitted");
+}
+
+namespace {
+  class AlphaCodeEmitter : public MachineFunctionPass {
+    const AlphaInstrInfo  *II;
+    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) {}
+
+    bool runOnMachineFunction(MachineFunction &MF);
+
+    virtual const char *getPassName() const {
+      return "Alpha Machine Code Emitter";
+    }
+
+    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.
+    ///
+    unsigned getBinaryCodeForInstr(MachineInstr &MI);
+
+  private:
+    void emitBasicBlock(MachineBasicBlock &MBB);
+
+  };
+}
+
+/// createAlphaCodeEmitterPass - Return a pass that emits the collected Alpha code
+/// to the specified MCE object.
+FunctionPass *llvm::createAlphaCodeEmitterPass(MachineCodeEmitter &MCE) {
+  return new AlphaCodeEmitter(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();
+
+  return false;
+}
+
+void AlphaCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
+  uint64_t Addr = MCE.getCurrentPCValue();
+  BasicBlockAddrs[&MBB] = (unsigned*)Addr;
+
+  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));
+      break;
+    case Alpha::ALTENT:
+    case Alpha::PCLABEL:
+    case Alpha::MEMLABEL:
+      break; //skip these
+    }
+  }
+}
+
+static unsigned getAlphaRegNumber(unsigned Reg) {
+  switch (Reg) {
+  case Alpha::R0  : case Alpha::F0  : return 0;
+  case Alpha::R1  : case Alpha::F1  : return 1;
+  case Alpha::R2  : case Alpha::F2  : return 2;
+  case Alpha::R3  : case Alpha::F3  : return 3;
+  case Alpha::R4  : case Alpha::F4  : return 4;
+  case Alpha::R5  : case Alpha::F5  : return 5;
+  case Alpha::R6  : case Alpha::F6  : return 6;
+  case Alpha::R7  : case Alpha::F7  : return 7;
+  case Alpha::R8  : case Alpha::F8  : return 8;
+  case Alpha::R9  : case Alpha::F9  : return 9;
+  case Alpha::R10 : case Alpha::F10 : return 10;
+  case Alpha::R11 : case Alpha::F11 : return 11;
+  case Alpha::R12 : case Alpha::F12 : return 12;
+  case Alpha::R13 : case Alpha::F13 : return 13;
+  case Alpha::R14 : case Alpha::F14 : return 14;
+  case Alpha::R15 : case Alpha::F15 : return 15;
+  case Alpha::R16 : case Alpha::F16 : return 16;
+  case Alpha::R17 : case Alpha::F17 : return 17;
+  case Alpha::R18 : case Alpha::F18 : return 18;
+  case Alpha::R19 : case Alpha::F19 : return 19;
+  case Alpha::R20 : case Alpha::F20 : return 20;
+  case Alpha::R21 : case Alpha::F21 : return 21;
+  case Alpha::R22 : case Alpha::F22 : return 22;
+  case Alpha::R23 : case Alpha::F23 : return 23;
+  case Alpha::R24 : case Alpha::F24 : return 24;
+  case Alpha::R25 : case Alpha::F25 : return 25;
+  case Alpha::R26 : case Alpha::F26 : return 26;
+  case Alpha::R27 : case Alpha::F27 : return 27;
+  case Alpha::R28 : case Alpha::F28 : return 28;
+  case Alpha::R29 : case Alpha::F29 : return 29;
+  case Alpha::R30 : case Alpha::F30 : return 30;
+  case Alpha::R31 : case Alpha::F31 : return 31;
+  default:
+    assert(0 && "Unhandled reg");
+    abort();
+  }
+}
+
+int AlphaCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) {
+
+  int rv = 0; // Return value; defaults to 0 for unhandled cases
+              // or things that get fixed up later by the JIT.
+
+  if (MO.isRegister()) {
+    rv = getAlphaRegNumber(MO.getReg());
+  } else if (MO.isImmediate()) {
+    rv = MO.getImmedValue();
+  } 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() && 
+       ( MO.getGlobal()->hasWeakLinkage() ||
+         MO.getGlobal()->isExternal()) );
+    unsigned Reloc = 0;
+    int Offset = 0;
+    switch (MI.getOpcode()) {
+    case Alpha::LDLr:
+    case Alpha::LDQr:
+    case Alpha::LDBUr:
+    case Alpha::LDWUr:
+    case Alpha::LDSr:
+    case Alpha::LDTr:
+    case Alpha::LDAr:
+      Reloc = Alpha::reloc_gprellow;
+      break;
+    case Alpha::LDAHr:
+      Reloc = Alpha::reloc_gprelhigh;
+      break;
+    case Alpha::LDQl:
+      Reloc = Alpha::reloc_literal;
+      break;
+    case Alpha::LDAg:
+    case Alpha::LDAHg:
+      Reloc = Alpha::reloc_gpdist;
+      Offset = MI.getOperand(3).getImmedValue();
+      break;
+    default:
+      assert(0 && "unknown relocatable instruction");
+      abort();
+    }
+    if (MO.isGlobalAddress())
+      MCE.addRelocation(MachineRelocation((unsigned)MCE.getCurrentPCOffset(),
+                                          Reloc, MO.getGlobal(), Offset,
+                                          true, true));
+    else if (MO.isExternalSymbol())
+      MCE.addRelocation(MachineRelocation((unsigned)MCE.getCurrentPCOffset(),
+                                          Reloc, MO.getSymbolName(), Offset,
+                                          true));
+    else
+      MCE.addRelocation(MachineRelocation((unsigned)MCE.getCurrentPCOffset(),
+                                          Reloc, MO.getConstantPoolIndex(), 
+                                          Offset));
+  } else if (MO.isMachineBasicBlock()) {
+    unsigned* CurrPC = (unsigned*)MCE.getCurrentPCValue();
+    BBRefs.push_back(std::make_pair(MO.getMachineBasicBlock(), CurrPC));
+  }else {
+    std::cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n";
+    abort();
+  }
+
+  return rv;
+}
+
+
+#include "AlphaGenCodeEmitter.inc"
+
diff --git a/lib/Target/Alpha/AlphaJITInfo.cpp b/lib/Target/Alpha/AlphaJITInfo.cpp
new file mode 100644 (file)
index 0000000..ff09f09
--- /dev/null
@@ -0,0 +1,273 @@
+//===-- AlphaJITInfo.cpp - Implement the JIT interfaces for the Alpha ---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the JIT interfaces for the Alpha target.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "jit"
+#include "AlphaJITInfo.h"
+#include "AlphaRelocations.h"
+#include "llvm/CodeGen/MachineCodeEmitter.h"
+#include "llvm/Config/alloca.h"
+#include "llvm/Support/Debug.h"
+#include <cstdlib>
+#include <iostream>
+#include <map>
+using namespace std;
+using namespace llvm;
+
+#define BUILD_LDA(RD, RS, IMM16) \
+  ((0x08 << 26) | ((RD) << 21) | ((RS) << 16) | ((IMM16) & 65535))
+#define BUILD_LDAH(RD, RS, IMM16) \
+  ((0x09 << 26) | ((RD) << 21) | ((RS) << 16) | ((IMM16) & 65535))
+
+#define MERGE_PARTS(HH, HL, LH, LL) \
+  (((HH * 65536 + HL) << 32) + (LH * 65536 + LL))
+
+#define BUILD_LDQ(RD, RS, IMM16) \
+  ((0x29 << 26) | ((RD) << 21) | ((RS) << 16) | ((IMM16) & 0xFFFF))
+
+#define BUILD_JMP(RD, RS, IMM16) \
+  ((0x1A << 26) | ((RD) << 21) | ((RS) << 16) | ((IMM16) & 0xFFFF))
+
+static void EmitBranchToAt(void *At, void *To, bool isCall) {
+  //FIXME
+  assert(0);
+}
+
+void AlphaJITInfo::replaceMachineCodeForFunction(void *Old, void *New) {
+  //FIXME
+  assert(0);
+}
+
+static TargetJITInfo::JITCompilerFn JITCompilerFunction;
+//static AlphaJITInfo* AlphaJTI;
+
+extern "C" {
+#if 0
+
+  void AlphaCompilationCallbackC(long* oldsp)
+  {
+    void* CameFromStub = (void*)*(oldsp - 1);
+    void* CameFromOrig = (void*)*(oldsp - 2);
+
+    void* Target = JITCompilerFunction(CameFromStub);
+    
+    //rewrite the stub to an unconditional branch
+    EmitBranchToAt(CameFromStub, Target, false);
+
+    //Change pv to new Target
+    *(oldsp - 1) = (long)Target;
+
+    //special epilog
+    register long* RSP asm ("$0") = oldsp;
+    __asm__ __volatile__ (
+      "ldq $16,   0($0)\n"
+      "ldq $17,   8($0)\n"
+      "ldq $18,  16($0)\n"
+      "ldq $19,  24($0)\n"
+      "ldq $20,  32($0)\n"
+      "ldq $21,  40($0)\n"
+      "ldt $f16, 48($0)\n"
+      "ldt $f17, 56($0)\n"
+      "ldt $f18, 64($0)\n"
+      "ldt $f19, 72($0)\n"
+      "ldt $f20, 80($0)\n"
+      "ldt $f21, 88($0)\n"
+      "ldq $9,   96($0)\n"
+      "ldq $10, 104($0)\n"
+      "ldq $11, 112($0)\n"
+      "ldq $12, 120($0)\n"
+      "ldq $13, 128($0)\n"
+      "ldq $14, 136($0)\n"
+      "ldt $f2, 144($0)\n"
+      "ldt $f3, 152($0)\n"
+      "ldt $f4, 160($0)\n"
+      "ldt $f5, 168($0)\n"
+      "ldt $f6, 176($0)\n"
+      "ldt $f7, 184($0)\n"
+      "ldt $f8, 192($0)\n"
+      "ldt $f9, 200($0)\n"
+      "ldq $15, 208($0)\n"
+      "ldq $26, 216($0)\n"
+      "ldq $27, 224($0)\n"
+      "bis $30, $0, $0\n" //restore sp
+      "jmp $31, ($27)\n" //jump to the new function
+      "and $0, $31, $31\n" //dummy use of r0
+    );
+  }
+
+  void AlphaCompilationCallback(void);
+
+  asm(
+      ".text\n"
+      ".globl AlphaComilationCallbackC\n"
+      ".align 4\n"
+      ".globl AlphaCompilationCallback\n"
+      ".ent AlphaCompilationCallback\n"
+"AlphaCompilationCallback:\n"
+      //      //get JIT's GOT
+      //      "ldgp\n"
+      //Save args, callee saved, and perhaps others?
+      //args: $16-$21 $f16-$f21     (12)
+      //callee: $9-$14 $f2-$f9      (14)
+      //others: fp:$15 ra:$26 pv:$27 (3)
+      "bis $0, $30, $30\n" //0 = sp
+      "lda $30, -232($30)\n"
+      "stq $16,   0($30)\n"
+      "stq $17,   8($30)\n"
+      "stq $18,  16($30)\n"
+      "stq $19,  24($30)\n"
+      "stq $20,  32($30)\n"
+      "stq $21,  40($30)\n"
+      "stt $f16, 48($30)\n"
+      "stt $f17, 56($30)\n"
+      "stt $f18, 64($30)\n"
+      "stt $f19, 72($30)\n"
+      "stt $f20, 80($30)\n"
+      "stt $f21, 88($30)\n"
+      "stq $9,   96($30)\n"
+      "stq $10, 104($30)\n"
+      "stq $11, 112($30)\n"
+      "stq $12, 120($30)\n"
+      "stq $13, 128($30)\n"
+      "stq $14, 136($30)\n"
+      "stt $f2, 144($30)\n"
+      "stt $f3, 152($30)\n"
+      "stt $f4, 160($30)\n"
+      "stt $f5, 168($30)\n"
+      "stt $f6, 176($30)\n"
+      "stt $f7, 184($30)\n"
+      "stt $f8, 192($30)\n"
+      "stt $f9, 200($30)\n"
+      "stq $15, 208($30)\n"
+      "stq $26, 216($30)\n"
+      "stq $27, 224($30)\n"
+      "bis $16, $0, $0\n" //pass the old sp as the first arg
+      "bsr $31, AlphaCompilationCallbackC\n"
+      ".end AlphaCompilationCallback\n"
+      );
+#else
+  void AlphaCompilationCallback() {
+    std::cerr << "Cannot call AlphaCompilationCallback() on a non-Alpha arch!\n";
+    abort();
+  }
+#endif
+}
+
+void *AlphaJITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) {
+//   // If this is just a call to an external function, emit a branch instead of a
+//   // call.  This means looking up Fn and storing that in R27 so as to appear to
+//   // have called there originally
+//   if (Fn != AlphaCompilationCallback) {
+//     int idx = AlphaJTI->getNewGOTEntry(Fn);
+//     //R27 = ldq idx(R29)
+//     //R31 = JMP R27, 0
+//     MCE.startFunctionStub(2*4);
+//     void *Addr = (void*)(intptr_t)MCE.getCurrentPCValue();
+//     MCE.emitWord(BUILD_LDQ(27, 29, idx << 3));
+//     MCE.emitWord(BUILD_JMP(31, 27, 0));
+//     return MCE.finishFunctionStub(0);
+//   }
+
+  assert(0 && "Need to be able to jump to this guy too");
+}
+
+TargetJITInfo::LazyResolverFn
+AlphaJITInfo::getLazyResolverFunction(JITCompilerFn F) {
+  JITCompilerFunction = F;
+  //  setZerothGOTEntry((void*)AlphaCompilationCallback);
+  return AlphaCompilationCallback;
+}
+
+//These describe LDAx
+static const int IMM_LOW  = -32768;
+static const int IMM_HIGH = 32767;
+static const int IMM_MULT = 65536;
+
+static long getUpper16(long l)
+{
+  long y = l / IMM_MULT;
+  if (l % IMM_MULT > IMM_HIGH)
+    ++y;
+  if (l % IMM_MULT < IMM_LOW)
+    --y;
+  assert((short)y == y && "displacement out of range");
+  return y;
+}
+
+static long getLower16(long l)
+{
+  long h = getUpper16(l);
+  long y = l - h * IMM_MULT;
+  assert(y == (short)y && "Displacement out of range");
+  return y;
+}
+
+void AlphaJITInfo::relocate(void *Function, MachineRelocation *MR,
+                            unsigned NumRelocs, unsigned char* GOTBase) {
+  //because gpdist are paired and relative to the pc of the first inst,
+  //we need to have some state
+
+  static map<pair<void*, int>, void*> gpdistmap;
+
+  for (unsigned i = 0; i != NumRelocs; ++i, ++MR) {
+    unsigned *RelocPos = (unsigned*)Function + MR->getMachineCodeOffset()/4;
+    long idx = 0;
+    switch ((Alpha::RelocationType)MR->getRelocationType()) {
+    default: assert(0 && "Unknown relocation type!");
+    case Alpha::reloc_literal:
+      //This is a LDQl
+      idx = MR->getGOTIndex();
+      DEBUG(std::cerr << "Literal relocation to slot " << idx);
+      idx = (idx - GOToffset) * 8;
+      DEBUG(std::cerr << " offset " << idx << "\n");
+      break;
+    case Alpha::reloc_gprellow:
+      idx = (unsigned char*)MR->getResultPointer() - &GOTBase[GOToffset * 8];
+      idx = getLower16(idx);
+      DEBUG(std::cerr << "gprellow relocation offset " << idx << "\n");
+      DEBUG(std::cerr << " Pointer is " << (void*)MR->getResultPointer()
+            << " GOT is " << (void*)&GOTBase[GOToffset * 8] << "\n");
+      break;
+    case Alpha::reloc_gprelhigh:
+      idx = (unsigned char*)MR->getResultPointer() - &GOTBase[GOToffset * 8];
+      idx = getUpper16(idx);
+      DEBUG(std::cerr << "gprelhigh relocation offset " << idx << "\n");
+      DEBUG(std::cerr << " Pointer is " << (void*)MR->getResultPointer()
+            << " GOT is " << (void*)&GOTBase[GOToffset * 8] << "\n");
+      break;
+    case Alpha::reloc_gpdist:
+      switch (*RelocPos >> 26) {
+      case 0x09: //LDAH
+        idx = &GOTBase[GOToffset * 8] - (unsigned char*)RelocPos;
+        idx = getUpper16(idx);
+        DEBUG(std::cerr << "LDAH: " << idx << "\n");
+        //add the relocation to the map
+        gpdistmap[make_pair(Function, MR->getConstantVal())] = RelocPos;
+        break;
+      case 0x08: //LDA
+        assert(gpdistmap[make_pair(Function, MR->getConstantVal())] &&
+               "LDAg without seeing LDAHg");
+        idx = &GOTBase[GOToffset * 8] - 
+          (unsigned char*)gpdistmap[make_pair(Function, MR->getConstantVal())];
+        idx = getLower16(idx);
+        DEBUG(std::cerr << "LDA: " << idx << "\n");
+        break;
+      default:
+        assert(0 && "Cannot handle gpdist yet");
+      }
+      break;
+    }
+    short x = (short)idx;
+    assert(x == idx);
+    *(short*)RelocPos = x;
+  }
+}
diff --git a/lib/Target/Alpha/AlphaJITInfo.h b/lib/Target/Alpha/AlphaJITInfo.h
new file mode 100644 (file)
index 0000000..252b05c
--- /dev/null
@@ -0,0 +1,56 @@
+//===- AlphaJITInfo.h - Alpha impl. of the JIT interface ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the Alpha implementation of the TargetJITInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ALPHA_JITINFO_H
+#define ALPHA_JITINFO_H
+
+#include "llvm/Target/TargetJITInfo.h"
+#include "llvm/GlobalValue.h"
+#include <string>
+#include <map>
+
+namespace llvm {
+  class TargetMachine;
+
+  class AlphaJITInfo : public TargetJITInfo {
+  protected:
+    TargetMachine &TM;
+  public:
+    AlphaJITInfo(TargetMachine &tm) : TM(tm)
+    { useGOT = true; }
+
+    /// addPassesToJITCompile - Add passes to the specified pass manager to
+    /// implement a fast dynamic compiler for this target.  Return true if this
+    /// is not supported for this target.
+    ///
+    virtual void addPassesToJITCompile(FunctionPassManager &PM);
+
+    virtual void *emitFunctionStub(void *Fn, MachineCodeEmitter &MCE);
+    virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn);
+    virtual void relocate(void *Function, MachineRelocation *MR,
+                          unsigned NumRelocs, unsigned char* GOTBase);
+
+    /// replaceMachineCodeForFunction - Make it so that calling the function
+    /// whose machine code is at OLD turns into a call to NEW, perhaps by
+    /// overwriting OLD with a branch to NEW.  This is used for self-modifying
+    /// code.
+    ///
+    virtual void replaceMachineCodeForFunction(void *Old, void *New);
+
+  private:
+    static const unsigned GOToffset = 4096;
+
+  };
+}
+
+#endif
index 4f0e1d2c884f18dd08d0d37022ce05b6f058f213..f7c3e5402cb1bc906dcc867b78c016304d28c3c0 100644 (file)
@@ -226,8 +226,16 @@ void AlphaRegisterInfo::emitPrologue(MachineFunction &MF) const {
   MachineFrameInfo *MFI = MF.getFrameInfo();
   bool FP = hasFP(MF);
 
+  static int curgpdist = 0;
+
   //handle GOP offset
-  BuildMI(MBB, MBBI, Alpha::LDGP, 0);
+  BuildMI(MBB, MBBI, Alpha::LDAHg, 3, Alpha::R29)
+    .addGlobalAddress(const_cast<Function*>(MF.getFunction()))
+    .addReg(Alpha::R27).addImm(++curgpdist);
+  BuildMI(MBB, MBBI, Alpha::LDAg, 3, Alpha::R29)
+    .addGlobalAddress(const_cast<Function*>(MF.getFunction()))
+    .addReg(Alpha::R29).addImm(curgpdist);
+
   //evil const_cast until MO stuff setup to handle const
   BuildMI(MBB, MBBI, Alpha::ALTENT, 1).addGlobalAddress(const_cast<Function*>(MF.getFunction()), true);
 
diff --git a/lib/Target/Alpha/AlphaRelocations.h b/lib/Target/Alpha/AlphaRelocations.h
new file mode 100644 (file)
index 0000000..f913c9b
--- /dev/null
@@ -0,0 +1,30 @@
+//===- AlphaRelocations.h - Alpha Code Relocations --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Alpha target-specific relocation types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ALPHARELOCATIONS_H
+#define ALPHARELOCATIONS_H
+
+#include "llvm/CodeGen/MachineRelocation.h"
+
+namespace llvm {
+  namespace Alpha {
+    enum RelocationType {
+      reloc_literal,
+      reloc_gprellow,
+      reloc_gprelhigh,
+      reloc_gpdist,
+    };
+  }
+}
+
+#endif
index 2c3be3dbcd656ade01cc2df6ae5056695679fe90..16f8899818aab8c016e8da57bd71e99b003a4a19 100644 (file)
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "Alpha.h"
+#include "AlphaJITInfo.h"
 #include "AlphaTargetMachine.h"
 #include "llvm/Module.h"
 #include "llvm/CodeGen/Passes.h"
@@ -49,9 +50,18 @@ unsigned AlphaTargetMachine::getModuleMatchQuality(const Module &M) {
   return 0;
 }
 
+unsigned AlphaTargetMachine::getJITMatchQuality() {
+#if 0
+  return 10;
+#else
+  return 0;
+#endif
+}
+
 AlphaTargetMachine::AlphaTargetMachine( const Module &M, IntrinsicLowering *IL)
   : TargetMachine("alpha", IL, true),
-    FrameInfo(TargetFrameInfo::StackGrowsDown, 8, 0) //TODO: check these
+    FrameInfo(TargetFrameInfo::StackGrowsDown, 8, 0), //TODO: check these
+    JITInfo(*this)
 {}
 
 /// addPassesToEmitFile - Add passes to the specified pass manager to implement
@@ -99,3 +109,47 @@ bool AlphaTargetMachine::addPassesToEmitFile(PassManager &PM,
   PM.add(createMachineCodeDeleter());
   return false;
 }
+
+void AlphaJITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
+
+  if (EnableAlphaLSR) {
+    PM.add(createLoopStrengthReducePass());
+    PM.add(createCFGSimplificationPass());
+  }
+
+  // FIXME: Implement efficient support for garbage collection intrinsics.
+  PM.add(createLowerGCPass());
+
+  // FIXME: Implement the invoke/unwind instructions!
+  PM.add(createLowerInvokePass());
+
+  // FIXME: Implement the switch instruction in the instruction selector!
+  PM.add(createLowerSwitchPass());
+
+  // Make sure that no unreachable blocks are instruction selected.
+  PM.add(createUnreachableBlockEliminationPass());
+
+  PM.add(createAlphaPatternInstructionSelector(TM));
+
+  if (PrintMachineCode)
+    PM.add(createMachineFunctionPrinterPass(&std::cerr));
+
+  PM.add(createRegisterAllocator());
+
+  if (PrintMachineCode)
+    PM.add(createMachineFunctionPrinterPass(&std::cerr));
+
+  PM.add(createPrologEpilogCodeInserter());
+
+  // Must run branch selection immediately preceding the asm printer
+  //PM.add(createAlphaBranchSelectionPass());
+
+}
+
+bool AlphaTargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
+                                                    MachineCodeEmitter &MCE) {
+  PM.add(createAlphaCodeEmitterPass(MCE));
+  // Delete machine code for this function
+  PM.add(createMachineCodeDeleter());
+  return false;
+}
index 9ff9ecdab669020770cbc67ba89afe40a7eb4ad8..b7f824e20e85540fd5c2cdf7f6fc72a206d4574d 100644 (file)
@@ -18,6 +18,7 @@
 #include "llvm/Target/TargetFrameInfo.h"
 #include "llvm/PassManager.h"
 #include "AlphaInstrInfo.h"
+#include "AlphaJITInfo.h"
 
 namespace llvm {
 
@@ -27,6 +28,7 @@ class IntrinsicLowering;
 class AlphaTargetMachine : public TargetMachine {
   AlphaInstrInfo InstrInfo;
   TargetFrameInfo FrameInfo;
+  AlphaJITInfo JITInfo;
 
 public:
   AlphaTargetMachine(const Module &M, IntrinsicLowering *IL);
@@ -36,6 +38,20 @@ public:
   virtual const MRegisterInfo *getRegisterInfo() const {
     return &InstrInfo.getRegisterInfo();
   }
+  virtual TargetJITInfo* getJITInfo() {
+    return &JITInfo;
+  }
+
+  static unsigned getJITMatchQuality();
+
+  /// addPassesToEmitMachineCode - Add passes to the specified pass manager to
+  /// get machine code emitted.  This uses a MachineCodeEmitter object to handle
+  /// actually outputting the machine code and resolving things like the address
+  /// of functions.  This method should returns true if machine code emission is
+  /// not supported.
+  ///
+  virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
+                                          MachineCodeEmitter &MCE);
 
   virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
                                    CodeGenFileType FileType);