summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Support/Memory.cpp35
-rw-r--r--lib/Target/Mips/MipsCodeEmitter.cpp198
-rw-r--r--lib/Target/Mips/MipsInstrInfo.h27
-rw-r--r--lib/Target/Mips/MipsJITInfo.cpp137
-rw-r--r--lib/Target/Mips/MipsRelocations.h19
-rw-r--r--lib/Target/Mips/MipsTargetMachine.h1
6 files changed, 287 insertions, 130 deletions
diff --git a/lib/Support/Memory.cpp b/lib/Support/Memory.cpp
index a9689b2c39..1294744649 100644
--- a/lib/Support/Memory.cpp
+++ b/lib/Support/Memory.cpp
@@ -30,6 +30,39 @@ using namespace sys;
extern "C" void sys_icache_invalidate(const void *Addr, size_t len);
+/// ClearMipsCache - Invalidates instruction cache for Mips. This assembly code
+/// is copied from the MIPS32 Instruction Set Reference. Since the code ends
+/// with the return instruction "jr.hb ra" (Jump Register with Hazard Barrier),
+/// it must be implemented as a function (which is called from the
+/// InvalidateInstructionCache function). It cannot be directly inlined into
+/// InvalidateInstructionCache function, because in that case the epilog of
+/// InvalidateInstructionCache will not be executed.
+#if defined(__mips__)
+extern "C" void ClearMipsCache(const void* Addr, size_t Size);
+ asm volatile(
+ ".text\n"
+ ".align 2\n"
+ ".globl ClearMipsCache\n"
+ "ClearMipsCache:\n"
+ ".set noreorder\n"
+ "beq $a1, $zero, 20f\n" /* If size==0, branch around */
+ "nop\n"
+ "addu $a1, $a0, $a1\n" /* Calculate end address + 1 */
+ "rdhwr $v0, $1\n" /* Get step size for SYNCI */
+ /* $1 is $HW_SYNCI_Step */
+ "beq $v0, $zero, 20f\n" /* If no caches require synchronization, */
+ /* branch around */
+ "nop\n"
+ "10: synci 0($a0)\n" /* Synchronize all caches around address */
+ "sltu $v1, $a0, $a1\n" /* Compare current with end address */
+ "bne $v1, $zero, 10b\n" /* Branch if more to do */
+ "addu $a0, $a0, $v0\n" /* Add step size in delay slot */
+ "sync\n" /* Clear memory hazards */
+ "20: jr.hb $ra\n" /* Return, clearing instruction hazards */
+ "nop\n"
+ );
+#endif
+
/// InvalidateInstructionCache - Before the JIT can run a block of code
/// that has been emitted it must invalidate the instruction cache on some
/// platforms.
@@ -66,6 +99,8 @@ void llvm::sys::Memory::InvalidateInstructionCache(const void *Addr,
char *Start = (char*) Addr;
char *End = Start + Len;
__clear_cache(Start, End);
+# elif defined(__mips__)
+ ClearMipsCache(Addr, Len);
# endif
#endif // end apple
diff --git a/lib/Target/Mips/MipsCodeEmitter.cpp b/lib/Target/Mips/MipsCodeEmitter.cpp
index eb8f7e0870..9220d9c7ab 100644
--- a/lib/Target/Mips/MipsCodeEmitter.cpp
+++ b/lib/Target/Mips/MipsCodeEmitter.cpp
@@ -41,6 +41,8 @@
using namespace llvm;
+STATISTIC(NumEmitted, "Number of machine instructions emitted");
+
namespace {
class MipsCodeEmitter : public MachineFunctionPass {
@@ -75,65 +77,38 @@ class MipsCodeEmitter : public MachineFunctionPass {
return "Mips Machine Code Emitter";
}
- void emitInstruction(const MachineInstr &MI);
+ /// getBinaryCodeForInstr - This function, generated by the
+ /// CodeEmitterGenerator using TableGen, produces the binary encoding for
+ /// machine instructions.
+ unsigned getBinaryCodeForInstr(const MachineInstr &MI) const;
- unsigned getOperandValue(const MachineOperand &MO,
- unsigned relocType = -1);
+ void emitInstruction(const MachineInstr &MI);
- void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
- bool MayNeedFarStub = true);
+ private:
- void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc,
- intptr_t JTBase = 0);
+ void emitWordLE(unsigned Word);
- void emitExternalSymbolAddress(const char *ES, unsigned Reloc);
+ /// Routines that handle operands which add machine relocations which are
+ /// fixed up by the relocation stage.
+ void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
+ bool MayNeedFarStub) const;
+ void emitExternalSymbolAddress(const char *ES, unsigned Reloc) const;
+ void emitConstPoolAddress(unsigned CPI, unsigned Reloc) const;
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 emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc) const;
-void MipsCodeEmitter::emitJumpTableAddress(unsigned JTIndex, unsigned Reloc)
- const {
- MCE.addRelocation(
- MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(), Reloc, JTIndex,
- 0, false));
-}
+ /// getMachineOpValue - Return binary encoding of operand. If the machine
+ /// operand requires relocation, record the relocation and return zero.
+ unsigned getMachineOpValue(const MachineInstr &MI,
+ const MachineOperand &MO) const;
-void MipsCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc) {
- MCE.addRelocation(
- MachineRelocation::getConstPool
- (MCE.getCurrentPCOffset(), Reloc, CPI, 0));
-}
+ unsigned getRelocation(const MachineInstr &MI,
+ const MachineOperand &MO) const;
-/// 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;
+char MipsCodeEmitter::ID = 0;
bool MipsCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
JTI = ((MipsTargetMachine&) MF.getTarget()).getJITInfo();
@@ -163,31 +138,108 @@ bool MipsCodeEmitter::runOnMachineFunction(MachineFunction &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:
+unsigned MipsCodeEmitter::getRelocation(const MachineInstr &MI,
+ const MachineOperand &MO) const {
+ // NOTE: This relocations are for static.
+ uint64_t TSFlags = MI.getDesc().TSFlags;
+ uint64_t Form = TSFlags & MipsII::FormMask;
+ if (Form == MipsII::FrmJ)
+ return Mips::reloc_mips_26;
+ if ((Form == MipsII::FrmI || Form == MipsII::FrmFI)
+ && MI.getDesc().isBranch())
+ return Mips::reloc_mips_branch;
+ if (Form == MipsII::FrmI && MI.getOpcode() == Mips::LUi)
+ return Mips::reloc_mips_hi;
+ return Mips::reloc_mips_lo;
+}
+
+/// getMachineOpValue - Return binary encoding of operand. If the machine
+/// operand requires relocation, record the relocation and return zero.
+unsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI,
+ const MachineOperand &MO) const {
+ if (MO.isReg())
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;
+ else if (MO.isImm())
+ return static_cast<unsigned>(MO.getImm());
+ else if (MO.isGlobal())
+ emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO), true);
+ else if (MO.isSymbol())
+ emitExternalSymbolAddress(MO.getSymbolName(), getRelocation(MI, MO));
+ else if (MO.isCPI())
+ emitConstPoolAddress(MO.getIndex(), getRelocation(MI, MO));
+ else if (MO.isJTI())
+ emitJumpTableAddress(MO.getIndex(), getRelocation(MI, MO));
+ else if (MO.isMBB())
+ emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO));
+ else
+ llvm_unreachable("Unable to encode MachineOperand!");
+ return 0;
+}
+
+void MipsCodeEmitter::emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
+ bool MayNeedFarStub) const {
+ MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc,
+ const_cast<GlobalValue *>(GV), 0, MayNeedFarStub));
+}
+
+void MipsCodeEmitter::
+emitExternalSymbolAddress(const char *ES, unsigned Reloc) const {
+ MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
+ Reloc, ES, 0, 0, false));
+}
+
+void MipsCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc) const {
+ MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
+ Reloc, CPI, 0, false));
+}
+
+void MipsCodeEmitter::
+emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const {
+ MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
+ Reloc, JTIndex, 0, false));
+}
+
+void MipsCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB,
+ unsigned Reloc) const {
+ MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(),
+ Reloc, BB));
+}
+
+void MipsCodeEmitter::emitInstruction(const MachineInstr &MI) {
+ DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << MI);
+
+ MCE.processDebugLoc(MI.getDebugLoc(), true);
+
+ // Skip pseudo instructions.
+ if ((MI.getDesc().TSFlags & MipsII::FormMask) == MipsII::Pseudo)
+ return;
+
+ ++NumEmitted; // Keep track of the # of mi's emitted
+
+ switch (MI.getOpcode()) {
+ default:
+ emitWordLE(getBinaryCodeForInstr(MI));
+ break;
}
+
+ MCE.processDebugLoc(MI.getDebugLoc(), false);
}
+void MipsCodeEmitter::emitWordLE(unsigned Word) {
+ DEBUG(errs() << " 0x";
+ errs().write_hex(Word) << "\n");
+ MCE.emitWordLE(Word);
+}
+
+/// 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);
+}
+
+unsigned MipsCodeEmitter::getBinaryCodeForInstr(const MachineInstr &MI) const {
+ // this function will be automatically generated by the CodeEmitterGenerator
+ // using TableGen
+ return 0;
+}
diff --git a/lib/Target/Mips/MipsInstrInfo.h b/lib/Target/Mips/MipsInstrInfo.h
index 4421c4862f..274f30761a 100644
--- a/lib/Target/Mips/MipsInstrInfo.h
+++ b/lib/Target/Mips/MipsInstrInfo.h
@@ -74,6 +74,33 @@ namespace MipsII {
MO_TPREL_HI,
MO_TPREL_LO
};
+
+ enum {
+ //===------------------------------------------------------------------===//
+ // Instruction encodings. These are the standard/most common forms for
+ // Mips instructions.
+ //
+
+ // Pseudo - This represents an instruction that is a pseudo instruction
+ // or one that has not been implemented yet. It is illegal to code generate
+ // it, but tolerated for intermediate implementation stages.
+ Pseudo = 0,
+
+ /// FrmR - This form is for instructions of the format R.
+ FrmR = 1,
+ /// FrmI - This form is for instructions of the format I.
+ FrmI = 2,
+ /// FrmJ - This form is for instructions of the format J.
+ FrmJ = 3,
+ /// FrmFR - This form is for instructions of the format FR.
+ FrmFR = 4,
+ /// FrmFI - This form is for instructions of the format FI.
+ FrmFI = 5,
+ /// FrmOther - This form is for instructions that have no specific format.
+ FrmOther = 6,
+
+ FormMask = 15
+ };
}
class MipsInstrInfo : public MipsGenInstrInfo {
diff --git a/lib/Target/Mips/MipsJITInfo.cpp b/lib/Target/Mips/MipsJITInfo.cpp
index 88f5f2d8d8..28c2b48b2e 100644
--- a/lib/Target/Mips/MipsJITInfo.cpp
+++ b/lib/Target/Mips/MipsJITInfo.cpp
@@ -42,7 +42,11 @@ static TargetJITInfo::JITCompilerFn JITCompilerFunction;
#define GETASMPREFIX(X) GETASMPREFIX2(X)
#define ASMPREFIX GETASMPREFIX(__USER_LABEL_PREFIX__)
-// save registers, call MipsCompilationCallbackC, restore registers
+// CompilationCallback stub - We can't use a C function with inline assembly in
+// it, because the prolog/epilog inserted by GCC won't work for us. Instead,
+// write our own wrapper, which does things our way, so we have complete control
+// over register saving and restoring. This code saves registers, calls
+// MipsCompilationCallbackC and restores registers.
extern "C" {
#if defined (__mips__)
void MipsCompilationCallback();
@@ -53,35 +57,46 @@ void MipsCompilationCallback();
".globl " ASMPREFIX "MipsCompilationCallback\n"
ASMPREFIX "MipsCompilationCallback:\n"
".ent " ASMPREFIX "MipsCompilationCallback\n"
+ ".frame $29, 32, $31\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"
+ "addiu $sp, $sp, -60\n"
".cprestore 16\n"
+ // Save argument registers a0, a1, a2, a3, f12, f14 since they may contain
+ // stuff for the real target function right now. We have to act as if this
+ // whole compilation callback doesn't exist as far as the caller is
+ // concerned. We also need to save the ra register since it contains the
+ // original return address, and t8 register since it contains the address
+ // of the end of function stub.
+ "sw $a0, 20($sp)\n"
+ "sw $a1, 24($sp)\n"
+ "sw $a2, 28($sp)\n"
+ "sw $a3, 32($sp)\n"
+ "sw $ra, 36($sp)\n"
+ "sw $t8, 40($sp)\n"
+ "sdc1 $f12, 44($sp)\n"
+ "sdc1 $f14, 52($sp)\n"
+
+ // t8 points at the end of function stub. Pass the beginning of the stub
+ // to the MipsCompilationCallbackC.
"addiu $a0, $t8, -16\n"
- "jal " ASMPREFIX "MipsCompilationCallbackC\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"
-
+ // Restore registers.
+ "lw $a0, 20($sp)\n"
+ "lw $a1, 24($sp)\n"
+ "lw $a2, 28($sp)\n"
+ "lw $a3, 32($sp)\n"
+ "lw $ra, 36($sp)\n"
+ "lw $t8, 40($sp)\n"
+ "ldc1 $f12, 44($sp)\n"
+ "ldc1 $f14, 52($sp)\n"
+ "addiu $sp, $sp, 60\n"
+
+ // Jump to the (newly modified) stub to invoke the real function.
"addiu $t8, $t8, -16\n"
"jr $t8\n"
"nop\n"
@@ -102,14 +117,26 @@ void MipsCompilationCallback();
/// 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
+ // Rewrite the function stub so that we don't end up here every time we
+ // execute the call. We're replacing the first four instructions of the
+ // stub with code that jumps to the compiled function:
+ // lui $t9, %hi(NewVal)
+ // addiu $t9, $t9, %lo(NewVal)
+ // jr $t9
+ // nop
+
+ int Hi = ((unsigned)NewVal & 0xffff0000) >> 16;
+ if ((NewVal & 0x8000) != 0)
+ Hi++;
+ int Lo = (int)(NewVal & 0xffff);
+
+ *(intptr_t *)(StubAddr) = 0xf << 26 | 25 << 16 | Hi;
+ *(intptr_t *)(StubAddr + 4) = 9 << 26 | 25 << 21 | 25 << 16 | Lo;
+ *(intptr_t *)(StubAddr + 8) = 25 << 21 | 8;
+ *(intptr_t *)(StubAddr + 12) = 0;
sys::Memory::InvalidateInstructionCache((void*) StubAddr, 16);
}
@@ -121,7 +148,9 @@ TargetJITInfo::LazyResolverFn MipsJITInfo::getLazyResolverFunction(
}
TargetJITInfo::StubLayout MipsJITInfo::getStubLayout() {
- StubLayout Result = { 24, 4 }; // {Size. Alignment} (of FunctionStub)
+ // The stub contains 4 4-byte instructions, aligned at 4 bytes. See
+ // emitFunctionStub for details.
+ StubLayout Result = { 4*4, 4 };
return Result;
}
@@ -129,22 +158,33 @@ 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
+ if (!sys::Memory::setRangeWritable(Addr, 16))
+ llvm_unreachable("ERROR: Unable to mark stub writable.");
+
+ intptr_t EmittedAddr;
+ if (Fn != (void*)(intptr_t)MipsCompilationCallback)
+ EmittedAddr = (intptr_t)Fn;
+ else
+ EmittedAddr = (intptr_t)MipsCompilationCallback;
+
+
+ int Hi = ((unsigned)EmittedAddr & 0xffff0000) >> 16;
+ if ((EmittedAddr & 0x8000) != 0)
+ Hi++;
+ int Lo = (int)(EmittedAddr & 0xffff);
+
+ // lui t9, %hi(EmittedAddr)
+ // 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); // NOP
+ JCE.emitWordLE(0);
- sys::Memory::InvalidateInstructionCache((void*) Addr, 16);
+ sys::Memory::InvalidateInstructionCache(Addr, 16);
+ if (!sys::Memory::setRangeExecutable(Addr, 16))
+ llvm_unreachable("ERROR: Unable to mark stub executable.");
return Addr;
}
@@ -160,27 +200,22 @@ void MipsJITInfo::relocate(void *Function, MachineRelocation *MR,
intptr_t ResultPtr = (intptr_t) MR->getResultPointer();
switch ((Mips::RelocationType) MR->getRelocationType()) {
- case Mips::reloc_mips_pcrel:
+ case Mips::reloc_mips_branch:
ResultPtr = (((ResultPtr - (intptr_t) RelocPos) - 4) >> 2) & 0xffff;
*((unsigned*) RelocPos) |= (unsigned) ResultPtr;
break;
- case Mips::reloc_mips_j_jal: {
+ case Mips::reloc_mips_26:
ResultPtr = (ResultPtr & 0x0fffffff) >> 2;
*((unsigned*) RelocPos) |= (unsigned) ResultPtr;
- }
break;
- case Mips::reloc_mips_hi: {
+ 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:
@@ -189,7 +224,7 @@ void MipsJITInfo::relocate(void *Function, MachineRelocation *MR,
break;
default:
- assert(0 && "MipsJITInfo.unknown relocation;");
+ llvm_unreachable("ERROR: Unknown Mips relocation.");
}
}
}
diff --git a/lib/Target/Mips/MipsRelocations.h b/lib/Target/Mips/MipsRelocations.h
index 0df21be3f1..66d1bfd993 100644
--- a/lib/Target/Mips/MipsRelocations.h
+++ b/lib/Target/Mips/MipsRelocations.h
@@ -20,13 +20,22 @@
namespace llvm {
namespace Mips{
enum RelocationType {
- reloc_mips_pcrel = 1,
- reloc_mips_hi = 3,
- reloc_mips_lo = 4,
- reloc_mips_j_jal = 5
+ // reloc_mips_branch - pc relative relocation for branches. The lower 18
+ // bits of the difference between the branch target and the branch
+ // instruction, shifted right by 2.
+ reloc_mips_branch = 1,
+
+ // reloc_mips_hi - upper 16 bits of the address (modified by +1 if the
+ // lower 16 bits of the address is negative).
+ reloc_mips_hi = 2,
+
+ // reloc_mips_lo - lower 16 bits of the address.
+ reloc_mips_lo = 3,
+
+ // reloc_mips_26 - lower 28 bits of the address, shifted right by 2.
+ reloc_mips_26 = 4
};
}
}
#endif /* MIPSRELOCATIONS_H_ */
-
diff --git a/lib/Target/Mips/MipsTargetMachine.h b/lib/Target/Mips/MipsTargetMachine.h
index 36211fa446..bba9111a06 100644
--- a/lib/Target/Mips/MipsTargetMachine.h
+++ b/lib/Target/Mips/MipsTargetMachine.h
@@ -35,7 +35,6 @@ namespace llvm {
MipsTargetLowering TLInfo;
MipsSelectionDAGInfo TSInfo;
MipsJITInfo JITInfo;
- Reloc::Model DefRelocModel; // Reloc model before it's overridden.
public:
MipsTargetMachine(const Target &T, StringRef TT,