diff options
| author | Roman Divacky <rdivacky@FreeBSD.org> | 2009-12-01 11:07:05 +0000 | 
|---|---|---|
| committer | Roman Divacky <rdivacky@FreeBSD.org> | 2009-12-01 11:07:05 +0000 | 
| commit | 06f9d4012fb8acea3e9861d5722b5965dbb724d9 (patch) | |
| tree | ffe0478472eaa0686f11cb02c6df7d257b8719b0 /lib/Target/ARM/ARMJITInfo.cpp | |
| parent | 76e2e0ebfdd3d91b07a75822865ea3e9121a99ce (diff) | |
Notes
Diffstat (limited to 'lib/Target/ARM/ARMJITInfo.cpp')
| -rw-r--r-- | lib/Target/ARM/ARMJITInfo.cpp | 51 | 
1 files changed, 30 insertions, 21 deletions
| diff --git a/lib/Target/ARM/ARMJITInfo.cpp b/lib/Target/ARM/ARMJITInfo.cpp index 24990e67a381..aa50cfd3074d 100644 --- a/lib/Target/ARM/ARMJITInfo.cpp +++ b/lib/Target/ARM/ARMJITInfo.cpp @@ -139,7 +139,8 @@ ARMJITInfo::getLazyResolverFunction(JITCompilerFn F) {  void *ARMJITInfo::emitGlobalValueIndirectSym(const GlobalValue *GV, void *Ptr,                                               JITCodeEmitter &JCE) { -  JCE.startGVStub(GV, 4, 4); +  MachineCodeEmitter::BufferState BS; +  JCE.startGVStub(BS, GV, 4, 4);    intptr_t Addr = (intptr_t)JCE.getCurrentPCValue();    if (!sys::Memory::setRangeWritable((void*)Addr, 4)) {      llvm_unreachable("ERROR: Unable to mark indirect symbol writable"); @@ -148,19 +149,27 @@ void *ARMJITInfo::emitGlobalValueIndirectSym(const GlobalValue *GV, void *Ptr,    if (!sys::Memory::setRangeExecutable((void*)Addr, 4)) {      llvm_unreachable("ERROR: Unable to mark indirect symbol executable");    } -  void *PtrAddr = JCE.finishGVStub(GV); +  void *PtrAddr = JCE.finishGVStub(BS);    addIndirectSymAddr(Ptr, (intptr_t)PtrAddr);    return PtrAddr;  } +TargetJITInfo::StubLayout ARMJITInfo::getStubLayout() { +  // The stub contains up to 3 4-byte instructions, aligned at 4 bytes, and a +  // 4-byte address.  See emitFunctionStub for details. +  StubLayout Result = {16, 4}; +  return Result; +} +  void *ARMJITInfo::emitFunctionStub(const Function* F, void *Fn,                                     JITCodeEmitter &JCE) { +  void *Addr;    // If this is just a call to an external function, emit a branch instead of a    // call.  The code is the same except for one bit of the last instruction.    if (Fn != (void*)(intptr_t)ARMCompilationCallback) {      // Branch to the corresponding function addr.      if (IsPIC) { -      // The stub is 8-byte size and 4-aligned. +      // The stub is 16-byte size and 4-aligned.        intptr_t LazyPtr = getIndirectSymAddr(Fn);        if (!LazyPtr) {          // In PIC mode, the function stub is loading a lazy-ptr. @@ -172,30 +181,30 @@ void *ARMJITInfo::emitFunctionStub(const Function* F, void *Fn,                  errs() << "JIT: Stub emitted at [" << LazyPtr                         << "] for external function at '" << Fn << "'\n");        } -      JCE.startGVStub(F, 16, 4); -      intptr_t Addr = (intptr_t)JCE.getCurrentPCValue(); -      if (!sys::Memory::setRangeWritable((void*)Addr, 16)) { +      JCE.emitAlignment(4); +      Addr = (void*)JCE.getCurrentPCValue(); +      if (!sys::Memory::setRangeWritable(Addr, 16)) {          llvm_unreachable("ERROR: Unable to mark stub writable");        } -      JCE.emitWordLE(0xe59fc004);            // ldr pc, [pc, #+4] +      JCE.emitWordLE(0xe59fc004);            // ldr ip, [pc, #+4]        JCE.emitWordLE(0xe08fc00c);            // L_func$scv: add ip, pc, ip        JCE.emitWordLE(0xe59cf000);            // ldr pc, [ip] -      JCE.emitWordLE(LazyPtr - (Addr+4+8));  // func - (L_func$scv+8) -      sys::Memory::InvalidateInstructionCache((void*)Addr, 16); -      if (!sys::Memory::setRangeExecutable((void*)Addr, 16)) { +      JCE.emitWordLE(LazyPtr - (intptr_t(Addr)+4+8));  // func - (L_func$scv+8) +      sys::Memory::InvalidateInstructionCache(Addr, 16); +      if (!sys::Memory::setRangeExecutable(Addr, 16)) {          llvm_unreachable("ERROR: Unable to mark stub executable");        }      } else {        // The stub is 8-byte size and 4-aligned. -      JCE.startGVStub(F, 8, 4); -      intptr_t Addr = (intptr_t)JCE.getCurrentPCValue(); -      if (!sys::Memory::setRangeWritable((void*)Addr, 8)) { +      JCE.emitAlignment(4); +      Addr = (void*)JCE.getCurrentPCValue(); +      if (!sys::Memory::setRangeWritable(Addr, 8)) {          llvm_unreachable("ERROR: Unable to mark stub writable");        }        JCE.emitWordLE(0xe51ff004);    // ldr pc, [pc, #-4]        JCE.emitWordLE((intptr_t)Fn);  // addr of function -      sys::Memory::InvalidateInstructionCache((void*)Addr, 8); -      if (!sys::Memory::setRangeExecutable((void*)Addr, 8)) { +      sys::Memory::InvalidateInstructionCache(Addr, 8); +      if (!sys::Memory::setRangeExecutable(Addr, 8)) {          llvm_unreachable("ERROR: Unable to mark stub executable");        }      } @@ -207,9 +216,9 @@ void *ARMJITInfo::emitFunctionStub(const Function* F, void *Fn,      //      // Branch and link to the compilation callback.      // The stub is 16-byte size and 4-byte aligned. -    JCE.startGVStub(F, 16, 4); -    intptr_t Addr = (intptr_t)JCE.getCurrentPCValue(); -    if (!sys::Memory::setRangeWritable((void*)Addr, 16)) { +    JCE.emitAlignment(4); +    Addr = (void*)JCE.getCurrentPCValue(); +    if (!sys::Memory::setRangeWritable(Addr, 16)) {        llvm_unreachable("ERROR: Unable to mark stub writable");      }      // Save LR so the callback can determine which stub called it. @@ -222,13 +231,13 @@ void *ARMJITInfo::emitFunctionStub(const Function* F, void *Fn,      JCE.emitWordLE(0xe51ff004); // ldr pc, [pc, #-4]      // The address of the compilation callback.      JCE.emitWordLE((intptr_t)ARMCompilationCallback); -    sys::Memory::InvalidateInstructionCache((void*)Addr, 16); -    if (!sys::Memory::setRangeExecutable((void*)Addr, 16)) { +    sys::Memory::InvalidateInstructionCache(Addr, 16); +    if (!sys::Memory::setRangeExecutable(Addr, 16)) {        llvm_unreachable("ERROR: Unable to mark stub executable");      }    } -  return JCE.finishGVStub(F); +  return Addr;  }  intptr_t ARMJITInfo::resolveRelocDestAddr(MachineRelocation *MR) const { | 
