mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2026-04-27 04:18:42 +00:00
Merging MIPS JIT/MCJIT changeset into 3.2 release branch.
Merging r169183: RuntimeDyld: Fix up r169178. MSVC doesn't like "or". Merging r169178: Runtime dynamic linker for MCJIT should support MIPS BigEndian architecture. This small change adds support for that. It will make all MCJIT tests pass in make-check on BigEndian platforms. Patch by Petar Jovanovic. Merging r169177: Classic JIT is still being supported by MIPS, along with MCJIT. This change adds endian-awareness to MipsJITInfo and emitWordLE in MipsCodeEmitter has become emitWord now to support both endianness. Patch by Petar Jovanovic. Merging r169174: Functions in MipsCodeEmitter.cpp that expand unaligned loads/stores are dead code. Removing it. Patch by Petar Jovanovic. git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_32@169296 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
1 parent
bdcb22211f
commit
7d2093c741
6 files changed
+28
-117
No files matched your search
@@ -346,7 +346,7 @@ uint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr) {
|
||||
uint32_t *StubAddr = (uint32_t*)Addr;
|
||||
*StubAddr = 0xe51ff004; // ldr pc,<label>
|
||||
return (uint8_t*)++StubAddr;
|
||||
} else if (Arch == Triple::mipsel) {
|
||||
} else if (Arch == Triple::mipsel || Arch == Triple::mips) {
|
||||
uint32_t *StubAddr = (uint32_t*)Addr;
|
||||
// 0: 3c190000 lui t9,%hi(addr).
|
||||
// 4: 27390000 addiu t9,t9,%lo(addr).
|
||||
|
||||
@@ -676,7 +676,8 @@ void RuntimeDyldELF::processRelocationRef(const ObjRelocationInfo &Rel,
|
||||
RelType, 0);
|
||||
Section.StubOffset += getMaxStubSize();
|
||||
}
|
||||
} else if (Arch == Triple::mipsel && RelType == ELF::R_MIPS_26) {
|
||||
} else if ((Arch == Triple::mipsel || Arch == Triple::mips) &&
|
||||
RelType == ELF::R_MIPS_26) {
|
||||
// This is an Mips branch relocation, need to use a stub function.
|
||||
DEBUG(dbgs() << "\t\tThis is a Mips branch relocation.");
|
||||
SectionEntry &Section = Sections[Rel.SectionID];
|
||||
|
||||
@@ -168,7 +168,7 @@ protected:
|
||||
inline unsigned getMaxStubSize() {
|
||||
if (Arch == Triple::arm || Arch == Triple::thumb)
|
||||
return 8; // 32-bit instruction and 32-bit address
|
||||
else if (Arch == Triple::mipsel)
|
||||
else if (Arch == Triple::mipsel || Arch == Triple::mips)
|
||||
return 16;
|
||||
else if (Arch == Triple::ppc64)
|
||||
return 44;
|
||||
|
||||
@@ -85,7 +85,7 @@ class MipsCodeEmitter : public MachineFunctionPass {
|
||||
|
||||
private:
|
||||
|
||||
void emitWordLE(unsigned Word);
|
||||
void emitWord(unsigned Word);
|
||||
|
||||
/// Routines that handle operands which add machine relocations which are
|
||||
/// fixed up by the relocation stage.
|
||||
@@ -112,12 +112,6 @@ class MipsCodeEmitter : public MachineFunctionPass {
|
||||
unsigned getSizeExtEncoding(const MachineInstr &MI, unsigned OpNo) const;
|
||||
unsigned getSizeInsEncoding(const MachineInstr &MI, unsigned OpNo) const;
|
||||
|
||||
int emitULW(const MachineInstr &MI);
|
||||
int emitUSW(const MachineInstr &MI);
|
||||
int emitULH(const MachineInstr &MI);
|
||||
int emitULHu(const MachineInstr &MI);
|
||||
int emitUSH(const MachineInstr &MI);
|
||||
|
||||
void emitGlobalAddressUnaligned(const GlobalValue *GV, unsigned Reloc,
|
||||
int Offset) const;
|
||||
};
|
||||
@@ -133,7 +127,7 @@ bool MipsCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
|
||||
MCPEs = &MF.getConstantPool()->getConstants();
|
||||
MJTEs = 0;
|
||||
if (MF.getJumpTableInfo()) MJTEs = &MF.getJumpTableInfo()->getJumpTables();
|
||||
JTI->Initialize(MF, IsPIC);
|
||||
JTI->Initialize(MF, IsPIC, Subtarget->isLittle());
|
||||
MCE.setModuleInfo(&getAnalysis<MachineModuleInfo> ());
|
||||
|
||||
do {
|
||||
@@ -271,103 +265,6 @@ void MipsCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB,
|
||||
Reloc, BB));
|
||||
}
|
||||
|
||||
int MipsCodeEmitter::emitUSW(const MachineInstr &MI) {
|
||||
unsigned src = getMachineOpValue(MI, MI.getOperand(0));
|
||||
unsigned base = getMachineOpValue(MI, MI.getOperand(1));
|
||||
unsigned offset = getMachineOpValue(MI, MI.getOperand(2));
|
||||
// swr src, offset(base)
|
||||
// swl src, offset+3(base)
|
||||
MCE.emitWordLE(
|
||||
(0x2e << 26) | (base << 21) | (src << 16) | (offset & 0xffff));
|
||||
MCE.emitWordLE(
|
||||
(0x2a << 26) | (base << 21) | (src << 16) | ((offset+3) & 0xffff));
|
||||
return 2;
|
||||
}
|
||||
|
||||
int MipsCodeEmitter::emitULW(const MachineInstr &MI) {
|
||||
unsigned dst = getMachineOpValue(MI, MI.getOperand(0));
|
||||
unsigned base = getMachineOpValue(MI, MI.getOperand(1));
|
||||
unsigned offset = getMachineOpValue(MI, MI.getOperand(2));
|
||||
unsigned at = 1;
|
||||
if (dst != base) {
|
||||
// lwr dst, offset(base)
|
||||
// lwl dst, offset+3(base)
|
||||
MCE.emitWordLE(
|
||||
(0x26 << 26) | (base << 21) | (dst << 16) | (offset & 0xffff));
|
||||
MCE.emitWordLE(
|
||||
(0x22 << 26) | (base << 21) | (dst << 16) | ((offset+3) & 0xffff));
|
||||
return 2;
|
||||
} else {
|
||||
// lwr at, offset(base)
|
||||
// lwl at, offset+3(base)
|
||||
// addu dst, at, $zero
|
||||
MCE.emitWordLE(
|
||||
(0x26 << 26) | (base << 21) | (at << 16) | (offset & 0xffff));
|
||||
MCE.emitWordLE(
|
||||
(0x22 << 26) | (base << 21) | (at << 16) | ((offset+3) & 0xffff));
|
||||
MCE.emitWordLE(
|
||||
(0x0 << 26) | (at << 21) | (0x0 << 16) | (dst << 11) | (0x0 << 6) | 0x21);
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
int MipsCodeEmitter::emitUSH(const MachineInstr &MI) {
|
||||
unsigned src = getMachineOpValue(MI, MI.getOperand(0));
|
||||
unsigned base = getMachineOpValue(MI, MI.getOperand(1));
|
||||
unsigned offset = getMachineOpValue(MI, MI.getOperand(2));
|
||||
unsigned at = 1;
|
||||
// sb src, offset(base)
|
||||
// srl at,src,8
|
||||
// sb at, offset+1(base)
|
||||
MCE.emitWordLE(
|
||||
(0x28 << 26) | (base << 21) | (src << 16) | (offset & 0xffff));
|
||||
MCE.emitWordLE(
|
||||
(0x0 << 26) | (0x0 << 21) | (src << 16) | (at << 11) | (0x8 << 6) | 0x2);
|
||||
MCE.emitWordLE(
|
||||
(0x28 << 26) | (base << 21) | (at << 16) | ((offset+1) & 0xffff));
|
||||
return 3;
|
||||
}
|
||||
|
||||
int MipsCodeEmitter::emitULH(const MachineInstr &MI) {
|
||||
unsigned dst = getMachineOpValue(MI, MI.getOperand(0));
|
||||
unsigned base = getMachineOpValue(MI, MI.getOperand(1));
|
||||
unsigned offset = getMachineOpValue(MI, MI.getOperand(2));
|
||||
unsigned at = 1;
|
||||
// lbu at, offset(base)
|
||||
// lb dst, offset+1(base)
|
||||
// sll dst,dst,8
|
||||
// or dst,dst,at
|
||||
MCE.emitWordLE(
|
||||
(0x24 << 26) | (base << 21) | (at << 16) | (offset & 0xffff));
|
||||
MCE.emitWordLE(
|
||||
(0x20 << 26) | (base << 21) | (dst << 16) | ((offset+1) & 0xffff));
|
||||
MCE.emitWordLE(
|
||||
(0x0 << 26) | (0x0 << 21) | (dst << 16) | (dst << 11) | (0x8 << 6) | 0x0);
|
||||
MCE.emitWordLE(
|
||||
(0x0 << 26) | (dst << 21) | (at << 16) | (dst << 11) | (0x0 << 6) | 0x25);
|
||||
return 4;
|
||||
}
|
||||
|
||||
int MipsCodeEmitter::emitULHu(const MachineInstr &MI) {
|
||||
unsigned dst = getMachineOpValue(MI, MI.getOperand(0));
|
||||
unsigned base = getMachineOpValue(MI, MI.getOperand(1));
|
||||
unsigned offset = getMachineOpValue(MI, MI.getOperand(2));
|
||||
unsigned at = 1;
|
||||
// lbu at, offset(base)
|
||||
// lbu dst, offset+1(base)
|
||||
// sll dst,dst,8
|
||||
// or dst,dst,at
|
||||
MCE.emitWordLE(
|
||||
(0x24 << 26) | (base << 21) | (at << 16) | (offset & 0xffff));
|
||||
MCE.emitWordLE(
|
||||
(0x24 << 26) | (base << 21) | (dst << 16) | ((offset+1) & 0xffff));
|
||||
MCE.emitWordLE(
|
||||
(0x0 << 26) | (0x0 << 21) | (dst << 16) | (dst << 11) | (0x8 << 6) | 0x0);
|
||||
MCE.emitWordLE(
|
||||
(0x0 << 26) | (dst << 21) | (at << 16) | (dst << 11) | (0x0 << 6) | 0x25);
|
||||
return 4;
|
||||
}
|
||||
|
||||
void MipsCodeEmitter::emitInstruction(const MachineInstr &MI) {
|
||||
DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << MI);
|
||||
|
||||
@@ -377,16 +274,19 @@ void MipsCodeEmitter::emitInstruction(const MachineInstr &MI) {
|
||||
if ((MI.getDesc().TSFlags & MipsII::FormMask) == MipsII::Pseudo)
|
||||
return;
|
||||
|
||||
emitWordLE(getBinaryCodeForInstr(MI));
|
||||
emitWord(getBinaryCodeForInstr(MI));
|
||||
++NumEmitted; // Keep track of the # of mi's emitted
|
||||
|
||||
MCE.processDebugLoc(MI.getDebugLoc(), false);
|
||||
}
|
||||
|
||||
void MipsCodeEmitter::emitWordLE(unsigned Word) {
|
||||
void MipsCodeEmitter::emitWord(unsigned Word) {
|
||||
DEBUG(errs() << " 0x";
|
||||
errs().write_hex(Word) << "\n");
|
||||
MCE.emitWordLE(Word);
|
||||
if (Subtarget->isLittle())
|
||||
MCE.emitWordLE(Word);
|
||||
else
|
||||
MCE.emitWordBE(Word);
|
||||
}
|
||||
|
||||
/// createMipsJITCodeEmitterPass - Return a pass that emits the collected Mips
|
||||
|
||||
@@ -222,10 +222,17 @@ void *MipsJITInfo::emitFunctionStub(const Function *F, void *Fn,
|
||||
// addiu t9, t9, %lo(EmittedAddr)
|
||||
// jalr t8, t9
|
||||
// nop
|
||||
JCE.emitWordLE(0xf << 26 | 25 << 16 | Hi);
|
||||
JCE.emitWordLE(9 << 26 | 25 << 21 | 25 << 16 | Lo);
|
||||
JCE.emitWordLE(25 << 21 | 24 << 11 | 9);
|
||||
JCE.emitWordLE(0);
|
||||
if (IsLittleEndian) {
|
||||
JCE.emitWordLE(0xf << 26 | 25 << 16 | Hi);
|
||||
JCE.emitWordLE(9 << 26 | 25 << 21 | 25 << 16 | Lo);
|
||||
JCE.emitWordLE(25 << 21 | 24 << 11 | 9);
|
||||
JCE.emitWordLE(0);
|
||||
} else {
|
||||
JCE.emitWordBE(0xf << 26 | 25 << 16 | Hi);
|
||||
JCE.emitWordBE(9 << 26 | 25 << 21 | 25 << 16 | Lo);
|
||||
JCE.emitWordBE(25 << 21 | 24 << 11 | 9);
|
||||
JCE.emitWordBE(0);
|
||||
}
|
||||
|
||||
sys::Memory::InvalidateInstructionCache(Addr, 16);
|
||||
if (!sys::Memory::setRangeExecutable(Addr, 16))
|
||||
|
||||
@@ -26,10 +26,11 @@ class MipsTargetMachine;
|
||||
class MipsJITInfo : public TargetJITInfo {
|
||||
|
||||
bool IsPIC;
|
||||
bool IsLittleEndian;
|
||||
|
||||
public:
|
||||
explicit MipsJITInfo() :
|
||||
IsPIC(false) {}
|
||||
IsPIC(false), IsLittleEndian(true) {}
|
||||
|
||||
/// replaceMachineCodeForFunction - Make it so that calling the function
|
||||
/// whose machine code is at OLD turns into a call to NEW, perhaps by
|
||||
@@ -58,8 +59,10 @@ class MipsJITInfo : public TargetJITInfo {
|
||||
unsigned NumRelocs, unsigned char *GOTBase);
|
||||
|
||||
/// Initialize - Initialize internal stage for the function being JITted.
|
||||
void Initialize(const MachineFunction &MF, bool isPIC) {
|
||||
void Initialize(const MachineFunction &MF, bool isPIC,
|
||||
bool isLittleEndian) {
|
||||
IsPIC = isPIC;
|
||||
IsLittleEndian = isLittleEndian;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user