diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-05-30 20:56:52 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-05-30 20:56:52 +0000 |
commit | 932a69096921c3091ef1ce2b93cc809eb6ec8027 (patch) | |
tree | 4017655a5530eb30c16b1d31a7e77d7ef3ff0f00 /exec-all.h | |
parent | da260249a4109b1ac82016b27973c50f0a74311a (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.h | 17 |
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"); |