14 #define DEBUG_TYPE "jit"
32 const unsigned NopInstr = 0x0;
35 if ((NewAddr & 0xF0000000) == ((OldAddr + 4) & 0xF0000000)) {
36 unsigned *OldInstruction = (
unsigned *)Old;
37 *OldInstruction = 0x08000000;
38 unsigned JTargetAddr = NewAddr & 0x0FFFFFFC;
41 *OldInstruction |= JTargetAddr;
45 *OldInstruction = NopInstr;
50 const unsigned HintMask = 0xFFFFF83F, ReturnSequence = 0x03e00008;
51 unsigned* CurrentInstr = (
unsigned*)Old;
52 unsigned CurrInstrHintClear = (*CurrentInstr) & HintMask;
53 unsigned* NextInstr = CurrentInstr + 1;
54 unsigned NextInstrHintClear = (*NextInstr) & HintMask;
58 if ((CurrInstrHintClear != ReturnSequence) &&
59 (NextInstrHintClear != ReturnSequence)) {
60 const unsigned LuiT0Instr = 0x3c080000, AddiuT0Instr = 0x25080000;
61 const unsigned JrT0Instr = 0x01000008;
63 (*(CurrentInstr++)) = LuiT0Instr | ((NewAddr & 0xffff0000) >> 16);
65 (*(CurrentInstr++)) = AddiuT0Instr | (NewAddr & 0x0000ffff);
67 (*(CurrentInstr++)) = JrT0Instr;
68 (*CurrentInstr) = NopInstr;
83 #ifndef __USER_LABEL_PREFIX__
84 #define __USER_LABEL_PREFIX__
86 #define GETASMPREFIX2(X) #X
87 #define GETASMPREFIX(X) GETASMPREFIX2(X)
88 #define ASMPREFIX GETASMPREFIX(__USER_LABEL_PREFIX__)
96 #if defined (__mips__)
102 ".globl " ASMPREFIX "MipsCompilationCallback\n"
104 ".ent " ASMPREFIX "MipsCompilationCallback\n"
105 ".frame $sp, 32, $ra\n"
109 "addiu $sp, $sp, -64\n"
124 "sdc1 $f12, 48($sp)\n"
125 "sdc1 $f14, 56($sp)\n"
129 "addiu $a0, $t8, -16\n"
130 "jal " ASMPREFIX "MipsCompilationCallbackC\n"
140 "ldc1 $f12, 48($sp)\n"
141 "ldc1 $f14, 56($sp)\n"
142 "addiu $sp, $sp, 64\n"
145 "addiu $t8, $t8, -16\n"
150 ".end " ASMPREFIX "MipsCompilationCallback\n"
152 #else // host != Mips
155 "Cannot call MipsCompilationCallback() on a non-Mips arch!");
176 int Hi = ((
unsigned)NewVal & 0xffff0000) >> 16;
177 if ((NewVal & 0x8000) != 0)
179 int Lo = (int)(NewVal & 0xffff);
181 *(
intptr_t *)(StubAddr) = 0xf << 26 | 25 << 16 |
Hi;
182 *(
intptr_t *)(StubAddr + 4) = 9 << 26 | 25 << 21 | 25 << 16 |
Lo;
183 *(
intptr_t *)(StubAddr + 8) = 25 << 21 | 8;
216 int Hi = ((
unsigned)EmittedAddr & 0xffff0000) >> 16;
217 if ((EmittedAddr & 0x8000) != 0)
219 int Lo = (int)(EmittedAddr & 0xffff);
225 if (IsLittleEndian) {
227 JCE.
emitWordLE(9 << 26 | 25 << 21 | 25 << 16 | Lo);
232 JCE.
emitWordBE(9 << 26 | 25 << 21 | 25 << 16 | Lo);
248 unsigned NumRelocs,
unsigned char *GOTBase) {
249 for (
unsigned i = 0; i != NumRelocs; ++i, ++MR) {
256 ResultPtr = (((ResultPtr - (
intptr_t) RelocPos) - 4) >> 2) & 0xffff;
257 *((
unsigned*) RelocPos) |= (
unsigned) ResultPtr;
261 ResultPtr = (ResultPtr & 0x0fffffff) >> 2;
262 *((
unsigned*) RelocPos) |= (
unsigned) ResultPtr;
266 ResultPtr = ResultPtr >> 16;
270 *((
unsigned*) RelocPos) |= (
unsigned) ResultPtr;
277 int Addend = *((
unsigned*) RelocPos) & 0xffff;
278 ResultPtr = (ResultPtr + Addend) & 0xffff;
279 *((
unsigned*) RelocPos) &= 0xffff0000;
280 *((
unsigned*) RelocPos) |= (
unsigned) ResultPtr;
void emitAlignment(unsigned Alignment)
unsigned getRelocationType() const
static bool setRangeWritable(const void *Addr, size_t Size)
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
void *(* JITCompilerFn)(void *)
static void InvalidateInstructionCache(const void *Addr, size_t Len)
#define llvm_unreachable(msg)
static TargetJITInfo::JITCompilerFn JITCompilerFunction
void MipsCompilationCallback()
virtual void replaceMachineCodeForFunction(void *Old, void *New)
void MipsCompilationCallbackC(intptr_t StubAddr)
void emitWordBE(uint32_t W)
intptr_t getMachineCodeOffset() const
virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn)
getLazyResolverFunction - Expose the lazy resolver to the JIT.
static bool setRangeExecutable(const void *Addr, size_t Size)
virtual void * emitFunctionStub(const Function *F, void *Fn, JITCodeEmitter &JCE)
void * getResultPointer() const
virtual uintptr_t getCurrentPCValue() const
void emitWordLE(uint32_t W)
virtual StubLayout getStubLayout()
Returns the maximum size and alignment for a call stub on this target.
virtual void relocate(void *Function, MachineRelocation *MR, unsigned NumRelocs, unsigned char *GOTBase)
Records the required size and alignment for a call stub in bytes.