mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 15:11:24 +00:00
Added the infrastructute necessary for MIPS JIT support. Patch by Vladimir
Stefanovic. I removed the part that actually emits the instructions cause I want that to get in better shape first and in incremental steps. This also makes it easier to review the upcoming parts. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135678 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4b5e207bf2
commit
dca6cdd6a1
@ -82,7 +82,7 @@ set(LLVM_ALL_TARGETS
|
|||||||
)
|
)
|
||||||
|
|
||||||
# List of targets with JIT support:
|
# List of targets with JIT support:
|
||||||
set(LLVM_TARGETS_WITH_JIT X86 PowerPC ARM)
|
set(LLVM_TARGETS_WITH_JIT X86 PowerPC ARM Mips)
|
||||||
|
|
||||||
if( MSVC )
|
if( MSVC )
|
||||||
set(LLVM_TARGETS_TO_BUILD X86
|
set(LLVM_TARGETS_TO_BUILD X86
|
||||||
|
@ -484,7 +484,7 @@ else
|
|||||||
x86_64) AC_SUBST(TARGET_HAS_JIT,1) ;;
|
x86_64) AC_SUBST(TARGET_HAS_JIT,1) ;;
|
||||||
Alpha) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
Alpha) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||||
ARM) AC_SUBST(TARGET_HAS_JIT,1) ;;
|
ARM) AC_SUBST(TARGET_HAS_JIT,1) ;;
|
||||||
Mips) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
Mips) AC_SUBST(TARGET_HAS_JIT,1) ;;
|
||||||
XCore) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
XCore) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||||
MSP430) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
MSP430) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||||
SystemZ) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
SystemZ) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||||
|
2
configure
vendored
2
configure
vendored
@ -4865,7 +4865,7 @@ else
|
|||||||
;;
|
;;
|
||||||
ARM) TARGET_HAS_JIT=1
|
ARM) TARGET_HAS_JIT=1
|
||||||
;;
|
;;
|
||||||
Mips) TARGET_HAS_JIT=0
|
Mips) TARGET_HAS_JIT=1
|
||||||
;;
|
;;
|
||||||
XCore) TARGET_HAS_JIT=0
|
XCore) TARGET_HAS_JIT=0
|
||||||
;;
|
;;
|
||||||
|
@ -9,6 +9,7 @@ tablegen(MipsGenSubtargetInfo.inc -gen-subtarget)
|
|||||||
|
|
||||||
add_llvm_target(MipsCodeGen
|
add_llvm_target(MipsCodeGen
|
||||||
MipsAsmPrinter.cpp
|
MipsAsmPrinter.cpp
|
||||||
|
MipsCodeEmitter.cpp
|
||||||
MipsDelaySlotFiller.cpp
|
MipsDelaySlotFiller.cpp
|
||||||
MipsEmitGPRestore.cpp
|
MipsEmitGPRestore.cpp
|
||||||
MipsExpandPseudo.cpp
|
MipsExpandPseudo.cpp
|
||||||
|
@ -29,6 +29,9 @@ namespace llvm {
|
|||||||
FunctionPass *createMipsExpandPseudoPass(MipsTargetMachine &TM);
|
FunctionPass *createMipsExpandPseudoPass(MipsTargetMachine &TM);
|
||||||
FunctionPass *createMipsEmitGPRestorePass(MipsTargetMachine &TM);
|
FunctionPass *createMipsEmitGPRestorePass(MipsTargetMachine &TM);
|
||||||
|
|
||||||
|
FunctionPass *createMipsJITCodeEmitterPass(MipsTargetMachine &TM,
|
||||||
|
JITCodeEmitter &JCE);
|
||||||
|
|
||||||
} // end namespace llvm;
|
} // end namespace llvm;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
193
lib/Target/Mips/MipsCodeEmitter.cpp
Normal file
193
lib/Target/Mips/MipsCodeEmitter.cpp
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
//===-- Mips/MipsCodeEmitter.cpp - Convert Mips code to machine code -----===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===---------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file contains the pass that transforms the Mips machine instructions
|
||||||
|
// into relocatable machine code.
|
||||||
|
//
|
||||||
|
//===---------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#define DEBUG_TYPE "jit"
|
||||||
|
#include "Mips.h"
|
||||||
|
#include "MipsInstrInfo.h"
|
||||||
|
#include "MipsRelocations.h"
|
||||||
|
#include "MipsSubtarget.h"
|
||||||
|
#include "MipsTargetMachine.h"
|
||||||
|
#include "llvm/Constants.h"
|
||||||
|
#include "llvm/DerivedTypes.h"
|
||||||
|
#include "llvm/Function.h"
|
||||||
|
#include "llvm/PassManager.h"
|
||||||
|
#include "llvm/CodeGen/JITCodeEmitter.h"
|
||||||
|
#include "llvm/CodeGen/MachineConstantPool.h"
|
||||||
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||||
|
#include "llvm/CodeGen/MachineInstr.h"
|
||||||
|
#include "llvm/CodeGen/MachineJumpTableInfo.h"
|
||||||
|
#include "llvm/CodeGen/MachineModuleInfo.h"
|
||||||
|
#include "llvm/CodeGen/Passes.h"
|
||||||
|
#include "llvm/ADT/Statistic.h"
|
||||||
|
#include "llvm/Support/Debug.h"
|
||||||
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
#ifndef NDEBUG
|
||||||
|
#include <iomanip>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "llvm/CodeGen/MachineOperand.h"
|
||||||
|
|
||||||
|
using namespace llvm;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class MipsCodeEmitter : public MachineFunctionPass {
|
||||||
|
MipsJITInfo *JTI;
|
||||||
|
const MipsInstrInfo *II;
|
||||||
|
const TargetData *TD;
|
||||||
|
const MipsSubtarget *Subtarget;
|
||||||
|
TargetMachine &TM;
|
||||||
|
JITCodeEmitter &MCE;
|
||||||
|
const std::vector<MachineConstantPoolEntry> *MCPEs;
|
||||||
|
const std::vector<MachineJumpTableEntry> *MJTEs;
|
||||||
|
bool IsPIC;
|
||||||
|
|
||||||
|
void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
|
AU.addRequired<MachineModuleInfo> ();
|
||||||
|
MachineFunctionPass::getAnalysisUsage(AU);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char ID;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MipsCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce) :
|
||||||
|
MachineFunctionPass(ID), JTI(0),
|
||||||
|
II((const MipsInstrInfo *) tm.getInstrInfo()),
|
||||||
|
TD(tm.getTargetData()), TM(tm), MCE(mce), MCPEs(0), MJTEs(0),
|
||||||
|
IsPIC(TM.getRelocationModel() == Reloc::PIC_) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool runOnMachineFunction(MachineFunction &MF);
|
||||||
|
|
||||||
|
virtual const char *getPassName() const {
|
||||||
|
return "Mips Machine Code Emitter";
|
||||||
|
}
|
||||||
|
|
||||||
|
void emitInstruction(const MachineInstr &MI);
|
||||||
|
|
||||||
|
unsigned getOperandValue(const MachineOperand &MO,
|
||||||
|
unsigned relocType = -1);
|
||||||
|
|
||||||
|
void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
|
||||||
|
bool MayNeedFarStub = true);
|
||||||
|
|
||||||
|
void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc,
|
||||||
|
intptr_t JTBase = 0);
|
||||||
|
|
||||||
|
void emitExternalSymbolAddress(const char *ES, unsigned Reloc);
|
||||||
|
void emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const;
|
||||||
|
void emitConstPoolAddress(unsigned CPI, unsigned Reloc);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void MipsCodeEmitter::emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
|
||||||
|
bool mayNeedFarStub) {
|
||||||
|
MachineRelocation MR = MachineRelocation::getGV(MCE.getCurrentPCOffset(),
|
||||||
|
Reloc, const_cast<GlobalValue *> (GV), 0, mayNeedFarStub);
|
||||||
|
MCE.addRelocation(MR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// emitMachineBasicBlock - Emit the specified address basic block.
|
||||||
|
void MipsCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB,
|
||||||
|
unsigned Reloc, intptr_t JTBase) {
|
||||||
|
MCE.addRelocation(
|
||||||
|
MachineRelocation::getBB(MCE.getCurrentPCOffset(), Reloc, BB, JTBase));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MipsCodeEmitter::emitExternalSymbolAddress(const char *ES,
|
||||||
|
unsigned Reloc) {
|
||||||
|
MCE.addRelocation(
|
||||||
|
MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), Reloc, ES, 0, 0,
|
||||||
|
false));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MipsCodeEmitter::emitJumpTableAddress(unsigned JTIndex, unsigned Reloc)
|
||||||
|
const {
|
||||||
|
MCE.addRelocation(
|
||||||
|
MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(), Reloc, JTIndex,
|
||||||
|
0, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MipsCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc) {
|
||||||
|
MCE.addRelocation(
|
||||||
|
MachineRelocation::getConstPool
|
||||||
|
(MCE.getCurrentPCOffset(), Reloc, CPI, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// createMipsJITCodeEmitterPass - Return a pass that emits the collected Mips
|
||||||
|
/// code to the specified MCE object.
|
||||||
|
FunctionPass *llvm::createMipsJITCodeEmitterPass(MipsTargetMachine &TM,
|
||||||
|
JITCodeEmitter &JCE) {
|
||||||
|
return new MipsCodeEmitter(TM, JCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
char MipsCodeEmitter::ID = 10;
|
||||||
|
|
||||||
|
bool MipsCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
|
||||||
|
JTI = ((MipsTargetMachine&) MF.getTarget()).getJITInfo();
|
||||||
|
II = ((const MipsTargetMachine&) MF.getTarget()).getInstrInfo();
|
||||||
|
TD = ((const MipsTargetMachine&) MF.getTarget()).getTargetData();
|
||||||
|
Subtarget = &TM.getSubtarget<MipsSubtarget> ();
|
||||||
|
MCPEs = &MF.getConstantPool()->getConstants();
|
||||||
|
MJTEs = 0;
|
||||||
|
if (MF.getJumpTableInfo()) MJTEs = &MF.getJumpTableInfo()->getJumpTables();
|
||||||
|
JTI->Initialize(MF, IsPIC);
|
||||||
|
MCE.setModuleInfo(&getAnalysis<MachineModuleInfo> ());
|
||||||
|
|
||||||
|
do {
|
||||||
|
DEBUG(errs() << "JITTing function '"
|
||||||
|
<< MF.getFunction()->getName() << "'\n");
|
||||||
|
MCE.startFunction(MF);
|
||||||
|
|
||||||
|
for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
|
||||||
|
MBB != E; ++MBB){
|
||||||
|
MCE.StartMachineBasicBlock(MBB);
|
||||||
|
for (MachineBasicBlock::const_iterator I = MBB->begin(), E = MBB->end();
|
||||||
|
I != E; ++I)
|
||||||
|
emitInstruction(*I);
|
||||||
|
}
|
||||||
|
} while (MCE.finishFunction(MF));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MipsCodeEmitter::emitInstruction(const MachineInstr &MI) {}
|
||||||
|
|
||||||
|
unsigned MipsCodeEmitter::getOperandValue(const MachineOperand &MO,
|
||||||
|
unsigned relocType) {
|
||||||
|
switch (MO.getType()) {
|
||||||
|
case MachineOperand::MO_Immediate:
|
||||||
|
return MO.getImm();
|
||||||
|
case MachineOperand::MO_GlobalAddress:
|
||||||
|
emitGlobalAddress(MO.getGlobal(), relocType, false);
|
||||||
|
return 0;
|
||||||
|
case MachineOperand::MO_ExternalSymbol:
|
||||||
|
emitExternalSymbolAddress(MO.getSymbolName(), relocType);
|
||||||
|
return 0;
|
||||||
|
case MachineOperand::MO_MachineBasicBlock:
|
||||||
|
emitMachineBasicBlock(MO.getMBB(), relocType, MCE.getCurrentPCValue());
|
||||||
|
return 0;
|
||||||
|
case MachineOperand::MO_Register:
|
||||||
|
return MipsRegisterInfo::getRegisterNumbering(MO.getReg());
|
||||||
|
case MachineOperand::MO_JumpTableIndex:
|
||||||
|
emitJumpTableAddress(MO.getIndex(), relocType);
|
||||||
|
return 0;
|
||||||
|
case MachineOperand::MO_ConstantPoolIndex:
|
||||||
|
emitConstPoolAddress(MO.getIndex(), relocType);
|
||||||
|
return 0;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
195
lib/Target/Mips/MipsJITInfo.cpp
Normal file
195
lib/Target/Mips/MipsJITInfo.cpp
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
//===- MipsJITInfo.cpp - Implement the JIT interfaces for the Mips target -===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file implements the JIT interfaces for the Mips target.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#define DEBUG_TYPE "jit"
|
||||||
|
#include "MipsJITInfo.h"
|
||||||
|
#include "MipsInstrInfo.h"
|
||||||
|
#include "MipsRelocations.h"
|
||||||
|
#include "MipsSubtarget.h"
|
||||||
|
#include "llvm/Function.h"
|
||||||
|
#include "llvm/CodeGen/JITCodeEmitter.h"
|
||||||
|
#include "llvm/Support/Debug.h"
|
||||||
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
#include "llvm/Support/Memory.h"
|
||||||
|
#include <cstdlib>
|
||||||
|
using namespace llvm;
|
||||||
|
|
||||||
|
|
||||||
|
void MipsJITInfo::replaceMachineCodeForFunction(void *Old, void *New) {
|
||||||
|
report_fatal_error("MipsJITInfo::replaceMachineCodeForFunction");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// JITCompilerFunction - This contains the address of the JIT function used to
|
||||||
|
/// compile a function lazily.
|
||||||
|
static TargetJITInfo::JITCompilerFn JITCompilerFunction;
|
||||||
|
|
||||||
|
// Get the ASMPREFIX for the current host. This is often '_'.
|
||||||
|
#ifndef __USER_LABEL_PREFIX__
|
||||||
|
#define __USER_LABEL_PREFIX__
|
||||||
|
#endif
|
||||||
|
#define GETASMPREFIX2(X) #X
|
||||||
|
#define GETASMPREFIX(X) GETASMPREFIX2(X)
|
||||||
|
#define ASMPREFIX GETASMPREFIX(__USER_LABEL_PREFIX__)
|
||||||
|
|
||||||
|
// save registers, call MipsCompilationCallbackC, restore registers
|
||||||
|
extern "C" {
|
||||||
|
#if defined (__mips__)
|
||||||
|
void MipsCompilationCallback();
|
||||||
|
|
||||||
|
asm(
|
||||||
|
".text\n"
|
||||||
|
".align 2\n"
|
||||||
|
".globl " ASMPREFIX "MipsCompilationCallback\n"
|
||||||
|
ASMPREFIX "MipsCompilationCallback:\n"
|
||||||
|
".ent " ASMPREFIX "MipsCompilationCallback\n"
|
||||||
|
".set noreorder\n"
|
||||||
|
".cpload $t9\n"
|
||||||
|
".frame $29, 32, $31\n"
|
||||||
|
|
||||||
|
"addiu $sp, $sp, -40\n"
|
||||||
|
"sw $a0, 4($sp)\n"
|
||||||
|
"sw $a1, 8($sp)\n"
|
||||||
|
"sw $a2, 12($sp)\n"
|
||||||
|
"sw $a3, 20($sp)\n"
|
||||||
|
"sw $ra, 24($sp)\n"
|
||||||
|
"sw $v0, 28($sp)\n"
|
||||||
|
"sw $v1, 32($sp)\n"
|
||||||
|
"sw $t8, 36($sp)\n"
|
||||||
|
".cprestore 16\n"
|
||||||
|
|
||||||
|
"addiu $a0, $t8, -16\n"
|
||||||
|
"jal " ASMPREFIX "MipsCompilationCallbackC\n"
|
||||||
|
"nop\n"
|
||||||
|
|
||||||
|
"lw $a0, 4($sp)\n"
|
||||||
|
"lw $a1, 8($sp)\n"
|
||||||
|
"lw $a2, 12($sp)\n"
|
||||||
|
"lw $a3, 20($sp)\n"
|
||||||
|
"lw $ra, 24($sp)\n"
|
||||||
|
"lw $v0, 28($sp)\n"
|
||||||
|
"lw $v1, 32($sp)\n"
|
||||||
|
"lw $t8, 36($sp)\n"
|
||||||
|
"addiu $sp, $sp, 40\n"
|
||||||
|
|
||||||
|
"addiu $t8, $t8, -16\n"
|
||||||
|
"jr $t8\n"
|
||||||
|
"nop\n"
|
||||||
|
|
||||||
|
".set reorder\n"
|
||||||
|
".end " ASMPREFIX "MipsCompilationCallback\n"
|
||||||
|
);
|
||||||
|
#else // host != Mips
|
||||||
|
void MipsCompilationCallback() {
|
||||||
|
llvm_unreachable(
|
||||||
|
"Cannot call MipsCompilationCallback() on a non-Mips arch!");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/// MipsCompilationCallbackC - This is the target-specific function invoked
|
||||||
|
/// by the function stub when we did not know the real target of a call.
|
||||||
|
/// This function must locate the start of the stub or call site and pass
|
||||||
|
/// it into the JIT compiler function.
|
||||||
|
extern "C" void MipsCompilationCallbackC(intptr_t StubAddr) {
|
||||||
|
|
||||||
|
// Get the address of the compiled code for this function.
|
||||||
|
intptr_t NewVal = (intptr_t) JITCompilerFunction((void*) StubAddr);
|
||||||
|
|
||||||
|
*(intptr_t *) (StubAddr) = 2 << 26 | ((NewVal & 0x0fffffff) >> 2); // J NewVal
|
||||||
|
*(intptr_t *) (StubAddr + 4) = 0; // NOP
|
||||||
|
*(intptr_t *) (StubAddr + 8) = 0; // NOP
|
||||||
|
*(intptr_t *) (StubAddr + 12) = 0; // NOP
|
||||||
|
|
||||||
|
sys::Memory::InvalidateInstructionCache((void*) StubAddr, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
TargetJITInfo::LazyResolverFn MipsJITInfo::getLazyResolverFunction(
|
||||||
|
JITCompilerFn F) {
|
||||||
|
JITCompilerFunction = F;
|
||||||
|
return MipsCompilationCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
TargetJITInfo::StubLayout MipsJITInfo::getStubLayout() {
|
||||||
|
StubLayout Result = { 24, 4 }; // {Size. Alignment} (of FunctionStub)
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *MipsJITInfo::emitFunctionStub(const Function* F, void *Fn,
|
||||||
|
JITCodeEmitter &JCE) {
|
||||||
|
JCE.emitAlignment(4);
|
||||||
|
void *Addr = (void*) (JCE.getCurrentPCValue());
|
||||||
|
|
||||||
|
unsigned arg0 = ((intptr_t) MipsCompilationCallback >> 16);
|
||||||
|
if ((((intptr_t) MipsCompilationCallback & 0xffff) >> 15) == 1) {
|
||||||
|
arg0 += 1; // same hack as in relocate()
|
||||||
|
}
|
||||||
|
|
||||||
|
// LUI t9, %hi(MipsCompilationCallback)
|
||||||
|
JCE.emitWordLE(0xf << 26 | 25 << 16 | arg0);
|
||||||
|
// ADDiu t9, t9, %lo(MipsCompilationCallback)
|
||||||
|
JCE.emitWordLE(9 << 26 | 25 << 21 | 25 << 16
|
||||||
|
| ((intptr_t) MipsCompilationCallback & 0xffff));
|
||||||
|
// JALR t8, t9
|
||||||
|
JCE.emitWordLE(25 << 21 | 24 << 11 | 9);
|
||||||
|
JCE.emitWordLE(0); // NOP
|
||||||
|
|
||||||
|
sys::Memory::InvalidateInstructionCache((void*) Addr, 16);
|
||||||
|
|
||||||
|
return Addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// relocate - Before the JIT can run a block of code that has been emitted,
|
||||||
|
/// it must rewrite the code to contain the actual addresses of any
|
||||||
|
/// referenced global symbols.
|
||||||
|
void MipsJITInfo::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();
|
||||||
|
|
||||||
|
switch ((Mips::RelocationType) MR->getRelocationType()) {
|
||||||
|
case Mips::reloc_mips_pcrel:
|
||||||
|
ResultPtr = (((ResultPtr - (intptr_t) RelocPos) - 4) >> 2) & 0xffff;
|
||||||
|
*((unsigned*) RelocPos) |= (unsigned) ResultPtr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Mips::reloc_mips_j_jal: {
|
||||||
|
ResultPtr = (ResultPtr & 0x0fffffff) >> 2;
|
||||||
|
*((unsigned*) RelocPos) |= (unsigned) ResultPtr;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Mips::reloc_mips_hi: {
|
||||||
|
ResultPtr = ResultPtr >> 16;
|
||||||
|
|
||||||
|
// see See MIPS Run Linux, chapter 9.4
|
||||||
|
if ((((intptr_t) (MR->getResultPointer()) & 0xffff) >> 15) == 1) {
|
||||||
|
ResultPtr += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*((unsigned*) RelocPos) |= (unsigned) ResultPtr;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Mips::reloc_mips_lo:
|
||||||
|
ResultPtr = ResultPtr & 0xffff;
|
||||||
|
*((unsigned*) RelocPos) |= (unsigned) ResultPtr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0 && "MipsJITInfo.unknown relocation;");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
70
lib/Target/Mips/MipsJITInfo.h
Normal file
70
lib/Target/Mips/MipsJITInfo.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
//===- MipsJITInfo.h - Mips implementation of the JIT interface -*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file contains the declaration of the MipsJITInfo class.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef MIPSJITINFO_H
|
||||||
|
#define MIPSJITINFO_H
|
||||||
|
|
||||||
|
#include "MipsMachineFunction.h"
|
||||||
|
#include "llvm/CodeGen/MachineConstantPool.h"
|
||||||
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
|
#include "llvm/CodeGen/MachineJumpTableInfo.h"
|
||||||
|
#include "llvm/Target/TargetJITInfo.h"
|
||||||
|
#include "llvm/ADT/DenseMap.h"
|
||||||
|
#include "llvm/ADT/SmallVector.h"
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
class MipsTargetMachine;
|
||||||
|
|
||||||
|
class MipsJITInfo : public TargetJITInfo {
|
||||||
|
|
||||||
|
bool IsPIC;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MipsJITInfo() :
|
||||||
|
IsPIC(false) {}
|
||||||
|
|
||||||
|
/// 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);
|
||||||
|
|
||||||
|
// getStubLayout - Returns the size and alignment of the largest call stub
|
||||||
|
// on Mips.
|
||||||
|
virtual StubLayout getStubLayout();
|
||||||
|
|
||||||
|
/// emitFunctionStub - Use the specified JITCodeEmitter object to emit a
|
||||||
|
/// small native function that simply calls the function at the specified
|
||||||
|
/// address.
|
||||||
|
virtual void *emitFunctionStub(const Function* F, void *Fn,
|
||||||
|
JITCodeEmitter &JCE);
|
||||||
|
|
||||||
|
/// getLazyResolverFunction - Expose the lazy resolver to the JIT.
|
||||||
|
virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn);
|
||||||
|
|
||||||
|
/// relocate - Before the JIT can run a block of code that has been emitted,
|
||||||
|
/// it must rewrite the code to contain the actual addresses of any
|
||||||
|
/// referenced global symbols.
|
||||||
|
virtual void relocate(void *Function, MachineRelocation *MR,
|
||||||
|
unsigned NumRelocs, unsigned char* GOTBase);
|
||||||
|
|
||||||
|
/// Initialize - Initialize internal stage for the function being JITted.
|
||||||
|
void Initialize(const MachineFunction &MF, bool isPIC) {
|
||||||
|
IsPIC = isPIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
32
lib/Target/Mips/MipsRelocations.h
Normal file
32
lib/Target/Mips/MipsRelocations.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
//===- MipsRelocations.h - Mips Code Relocations ---------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===---------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file defines the Mips target-specific relocation types
|
||||||
|
// (for relocation-model=static).
|
||||||
|
//
|
||||||
|
//===---------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef MIPSRELOCATIONS_H_
|
||||||
|
#define MIPSRELOCATIONS_H_
|
||||||
|
|
||||||
|
#include "llvm/CodeGen/MachineRelocation.h"
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
namespace Mips{
|
||||||
|
enum RelocationType {
|
||||||
|
reloc_mips_pcrel = 1,
|
||||||
|
reloc_mips_hi = 3,
|
||||||
|
reloc_mips_lo = 4,
|
||||||
|
reloc_mips_j_jal = 5
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* MIPSRELOCATIONS_H_ */
|
||||||
|
|
@ -42,7 +42,7 @@ MipsTargetMachine(const Target &T, StringRef TT,
|
|||||||
std::string("E-p:32:32:32-i8:8:32-i16:16:32-i64:64:64-n32")),
|
std::string("E-p:32:32:32-i8:8:32-i16:16:32-i64:64:64-n32")),
|
||||||
InstrInfo(*this),
|
InstrInfo(*this),
|
||||||
FrameLowering(Subtarget),
|
FrameLowering(Subtarget),
|
||||||
TLInfo(*this), TSInfo(*this) {
|
TLInfo(*this), TSInfo(*this), JITInfo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
MipselTargetMachine::
|
MipselTargetMachine::
|
||||||
@ -81,3 +81,12 @@ addPostRegAlloc(PassManagerBase &PM, CodeGenOpt::Level OptLevel) {
|
|||||||
PM.add(createMipsExpandPseudoPass(*this));
|
PM.add(createMipsExpandPseudoPass(*this));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MipsTargetMachine::addCodeEmitter(PassManagerBase &PM,
|
||||||
|
CodeGenOpt::Level OptLevel,
|
||||||
|
JITCodeEmitter &JCE) {
|
||||||
|
// Machine code emitter pass for Mips.
|
||||||
|
PM.add(createMipsJITCodeEmitterPass(*this, JCE));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
#include "llvm/Target/TargetData.h"
|
#include "llvm/Target/TargetData.h"
|
||||||
#include "llvm/Target/TargetFrameLowering.h"
|
#include "llvm/Target/TargetFrameLowering.h"
|
||||||
|
#include "MipsJITInfo.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
class formatted_raw_ostream;
|
class formatted_raw_ostream;
|
||||||
@ -33,6 +34,9 @@ namespace llvm {
|
|||||||
MipsFrameLowering FrameLowering;
|
MipsFrameLowering FrameLowering;
|
||||||
MipsTargetLowering TLInfo;
|
MipsTargetLowering TLInfo;
|
||||||
MipsSelectionDAGInfo TSInfo;
|
MipsSelectionDAGInfo TSInfo;
|
||||||
|
MipsJITInfo JITInfo;
|
||||||
|
Reloc::Model DefRelocModel; // Reloc model before it's overridden.
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MipsTargetMachine(const Target &T, StringRef TT,
|
MipsTargetMachine(const Target &T, StringRef TT,
|
||||||
StringRef CPU, StringRef FS,
|
StringRef CPU, StringRef FS,
|
||||||
@ -47,6 +51,9 @@ namespace llvm {
|
|||||||
{ return &Subtarget; }
|
{ return &Subtarget; }
|
||||||
virtual const TargetData *getTargetData() const
|
virtual const TargetData *getTargetData() const
|
||||||
{ return &DataLayout;}
|
{ return &DataLayout;}
|
||||||
|
virtual MipsJITInfo *getJITInfo()
|
||||||
|
{ return &JITInfo; }
|
||||||
|
|
||||||
|
|
||||||
virtual const MipsRegisterInfo *getRegisterInfo() const {
|
virtual const MipsRegisterInfo *getRegisterInfo() const {
|
||||||
return &InstrInfo.getRegisterInfo();
|
return &InstrInfo.getRegisterInfo();
|
||||||
@ -68,6 +75,10 @@ namespace llvm {
|
|||||||
virtual bool addPreRegAlloc(PassManagerBase &PM,
|
virtual bool addPreRegAlloc(PassManagerBase &PM,
|
||||||
CodeGenOpt::Level OptLevel);
|
CodeGenOpt::Level OptLevel);
|
||||||
virtual bool addPostRegAlloc(PassManagerBase &, CodeGenOpt::Level);
|
virtual bool addPostRegAlloc(PassManagerBase &, CodeGenOpt::Level);
|
||||||
|
virtual bool addCodeEmitter(PassManagerBase &PM,
|
||||||
|
CodeGenOpt::Level OptLevel,
|
||||||
|
JITCodeEmitter &JCE);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// MipselTargetMachine - Mipsel target machine.
|
/// MipselTargetMachine - Mipsel target machine.
|
||||||
|
@ -15,7 +15,9 @@ using namespace llvm;
|
|||||||
Target llvm::TheMipsTarget, llvm::TheMipselTarget;
|
Target llvm::TheMipsTarget, llvm::TheMipselTarget;
|
||||||
|
|
||||||
extern "C" void LLVMInitializeMipsTargetInfo() {
|
extern "C" void LLVMInitializeMipsTargetInfo() {
|
||||||
RegisterTarget<Triple::mips> X(TheMipsTarget, "mips", "Mips");
|
RegisterTarget<Triple::mips,
|
||||||
|
/*HasJIT=*/true> X(TheMipsTarget, "mips", "Mips");
|
||||||
|
|
||||||
RegisterTarget<Triple::mipsel> Y(TheMipselTarget, "mipsel", "Mipsel");
|
RegisterTarget<Triple::mipsel,
|
||||||
|
/*HasJIT=*/true> Y(TheMipselTarget, "mipsel", "Mipsel");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user