summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorMisha Brukman <brukman+llvm@gmail.com>2003-11-21 23:48:54 +0000
committerMisha Brukman <brukman+llvm@gmail.com>2003-11-21 23:48:54 +0000
commitd1816660520653ee976cdaa8626b25b782e8ba72 (patch)
tree574b075b3da7680f839346c3796deb9e4ee68bfb /llvm/lib/Target
parent3ae303cc8c8d58d7e4d97515c23e1aead6ede13a (diff)
downloadbcm5719-llvm-d1816660520653ee976cdaa8626b25b782e8ba72.tar.gz
bcm5719-llvm-d1816660520653ee976cdaa8626b25b782e8ba72.zip
* Add code to flush the ICache, which any self-respecting SMC must do
* Restore registers *after* everything else to avoid any possible side effects This fixes McCat-imp. llvm-svn: 10147
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp13
1 files changed, 8 insertions, 5 deletions
diff --git a/llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp b/llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp
index f56e7f3b63f..be677e0fdf8 100644
--- a/llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp
+++ b/llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp
@@ -380,18 +380,21 @@ void JITResolver::CompilationCallback() {
// Overwrite it
TheJITResolver->insertJumpAtAddr(Target, CodeBegin);
- RestoreRegisters(DoubleFP, FSR, FPRS, CCR);
+ // Flush the I-Cache: FLUSH clears out a doubleword at a given address
+ // Self-modifying code MUST clear out the I-Cache to be portable
+#if defined(sparc) || defined(__sparc__) || defined(__sparcv9)
+ for (int i = -Offset, e = 32-((int64_t)Offset); i < e; i += 8)
+ __asm__ __volatile__ ("flush %%i7 + %0" : : "r" (i));
+#endif
// Change the return address to re-execute the restore, then the jump.
- // However, we can't just modify %i7 here, because we return to the function
- // that will restore the floating-point registers for us. Thus, we just return
- // the value we want it to be, and the parent will take care of setting %i7
- // correctly.
DEBUG(std::cerr << "Callback returning to: 0x"
<< std::hex << (CameFrom-Offset-12) << "\n");
#if defined(sparc) || defined(__sparc__) || defined(__sparcv9)
__asm__ __volatile__ ("sub %%i7, %0, %%i7" : : "r" (Offset+12));
#endif
+
+ RestoreRegisters(DoubleFP, FSR, FPRS, CCR);
}
/// emitStubForFunction - This method is used by the JIT when it needs to emit
OpenPOWER on IntegriCloud