aboutsummaryrefslogtreecommitdiff
path: root/exec-all.h
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2008-05-30 20:56:52 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2008-05-30 20:56:52 +0000
commit932a69096921c3091ef1ce2b93cc809eb6ec8027 (patch)
tree4017655a5530eb30c16b1d31a7e77d7ef3ff0f00 /exec-all.h
parentda260249a4109b1ac82016b27973c50f0a74311a (diff)
support of long calls for PPC (malc)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4629 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'exec-all.h')
-rw-r--r--exec-all.h17
1 files changed, 14 insertions, 3 deletions
diff --git a/exec-all.h b/exec-all.h
index 1f5906c7c4..6cc3f70f44 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -187,12 +187,23 @@ extern int code_gen_max_blocks;
static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
{
uint32_t val, *ptr;
+ long disp = addr - jmp_addr;
- /* patch the branch destination */
ptr = (uint32_t *)jmp_addr;
val = *ptr;
- val = (val & ~0x03fffffc) | ((addr - jmp_addr) & 0x03fffffc);
- *ptr = val;
+
+ if ((disp << 6) >> 6 != disp) {
+ uint16_t *p1;
+
+ p1 = (uint16_t *) ptr;
+ *ptr = (val & ~0x03fffffc) | 4;
+ p1[3] = addr >> 16;
+ p1[5] = addr & 0xffff;
+ } else {
+ /* patch the branch destination */
+ val = (val & ~0x03fffffc) | (disp & 0x03fffffc);
+ *ptr = val;
+ }
/* flush icache */
asm volatile ("dcbst 0,%0" : : "r"(ptr) : "memory");
asm volatile ("sync" : : : "memory");