diff options
author | ths <ths@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-07-31 23:46:55 +0000 |
---|---|---|
committer | ths <ths@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-07-31 23:46:55 +0000 |
commit | 9bbc5cc8295670fd3f80fbdbc7fdddcecb403880 (patch) | |
tree | 87516e3cf11c2d583e44abc540764d1ac043dc5f | |
parent | 8f860bb83cb872461ebac017232604b1dc2d2604 (diff) | |
download | qemu-9bbc5cc8295670fd3f80fbdbc7fdddcecb403880.tar.gz qemu-9bbc5cc8295670fd3f80fbdbc7fdddcecb403880.tar.bz2 qemu-9bbc5cc8295670fd3f80fbdbc7fdddcecb403880.zip |
Fiddly dyngen bits for s390 host support, by Ulrich Hecht.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3105 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r-- | dyngen-exec.h | 2 | ||||
-rw-r--r-- | exec-all.h | 18 |
2 files changed, 19 insertions, 1 deletions
diff --git a/dyngen-exec.h b/dyngen-exec.h index 9f5fcc6ce5..75d27ce169 100644 --- a/dyngen-exec.h +++ b/dyngen-exec.h @@ -254,7 +254,7 @@ extern int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3; #define GOTO_LABEL_PARAM(n) asm volatile ("b " ASM_NAME(__op_gen_label) #n) #elif defined(__s390__) #define EXIT_TB() asm volatile ("br %r14") -#define GOTO_LABEL_PARAM(n) asm volatile ("b " ASM_NAME(__op_gen_label) #n) +#define GOTO_LABEL_PARAM(n) asm volatile ("bras %r7,8; .long " ASM_NAME(__op_gen_label) #n "; l %r7, 0(%r7); br %r7") #elif defined(__alpha__) #define EXIT_TB() asm volatile ("ret") #elif defined(__ia64__) diff --git a/exec-all.h b/exec-all.h index 8ea057b79c..31914ee2f3 100644 --- a/exec-all.h +++ b/exec-all.h @@ -340,6 +340,24 @@ do {\ "1:\n");\ } while (0) +#elif defined(__s390__) +/* GCC spills R13, so we have to restore it before branching away */ + +#define GOTO_TB(opname, tbparam, n)\ +do {\ + static void __attribute__((used)) *dummy ## n = &&dummy_label ## n;\ + static void __attribute__((used)) *__op_label ## n \ + __asm__(ASM_OP_LABEL_NAME(n, opname)) = &&label ## n;\ + __asm__ __volatile__ ( \ + "l %%r13,52(%%r15)\n" \ + "br %0\n" \ + : : "r" (((TranslationBlock*)tbparam)->tb_next[n]));\ + \ + for(;*((int*)0);); /* just to keep GCC busy */ \ +label ## n: ;\ +dummy_label ## n: ;\ +} while(0) + #else /* jump to next block operations (more portable code, does not need |