Commit 1057eaa709dba09d1c4f7a363877e635797e4623
1 parent
d96372ef
Fix 64-bit host register corruption.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2384 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
110 additions
and
94 deletions
cpu-exec.c
| @@ -226,37 +226,9 @@ static inline TranslationBlock *tb_find_fast(void) | @@ -226,37 +226,9 @@ static inline TranslationBlock *tb_find_fast(void) | ||
| 226 | 226 | ||
| 227 | int cpu_exec(CPUState *env1) | 227 | int cpu_exec(CPUState *env1) |
| 228 | { | 228 | { |
| 229 | - target_ulong saved_T0, saved_T1; | ||
| 230 | -#if defined(reg_T2) | ||
| 231 | - target_ulong saved_T2; | ||
| 232 | -#endif | ||
| 233 | - CPUState *saved_env; | ||
| 234 | -#if defined(TARGET_I386) | ||
| 235 | -#ifdef reg_EAX | ||
| 236 | - int saved_EAX; | ||
| 237 | -#endif | ||
| 238 | -#ifdef reg_ECX | ||
| 239 | - int saved_ECX; | ||
| 240 | -#endif | ||
| 241 | -#ifdef reg_EDX | ||
| 242 | - int saved_EDX; | ||
| 243 | -#endif | ||
| 244 | -#ifdef reg_EBX | ||
| 245 | - int saved_EBX; | ||
| 246 | -#endif | ||
| 247 | -#ifdef reg_ESP | ||
| 248 | - int saved_ESP; | ||
| 249 | -#endif | ||
| 250 | -#ifdef reg_EBP | ||
| 251 | - int saved_EBP; | ||
| 252 | -#endif | ||
| 253 | -#ifdef reg_ESI | ||
| 254 | - int saved_ESI; | ||
| 255 | -#endif | ||
| 256 | -#ifdef reg_EDI | ||
| 257 | - int saved_EDI; | ||
| 258 | -#endif | ||
| 259 | -#elif defined(TARGET_SPARC) | 229 | +#define DECLARE_HOST_REGS 1 |
| 230 | +#include "hostregs_helper.h" | ||
| 231 | +#if defined(TARGET_SPARC) | ||
| 260 | #if defined(reg_REGWPTR) | 232 | #if defined(reg_REGWPTR) |
| 261 | uint32_t *saved_regwptr; | 233 | uint32_t *saved_regwptr; |
| 262 | #endif | 234 | #endif |
| @@ -325,44 +297,15 @@ int cpu_exec(CPUState *env1) | @@ -325,44 +297,15 @@ int cpu_exec(CPUState *env1) | ||
| 325 | cpu_single_env = env1; | 297 | cpu_single_env = env1; |
| 326 | 298 | ||
| 327 | /* first we save global registers */ | 299 | /* first we save global registers */ |
| 328 | - saved_env = env; | 300 | +#define SAVE_HOST_REGS 1 |
| 301 | +#include "hostregs_helper.h" | ||
| 329 | env = env1; | 302 | env = env1; |
| 330 | - saved_T0 = T0; | ||
| 331 | - saved_T1 = T1; | ||
| 332 | -#if defined(reg_T2) | ||
| 333 | - saved_T2 = T2; | ||
| 334 | -#endif | ||
| 335 | #if defined(__sparc__) && !defined(HOST_SOLARIS) | 303 | #if defined(__sparc__) && !defined(HOST_SOLARIS) |
| 336 | /* we also save i7 because longjmp may not restore it */ | 304 | /* we also save i7 because longjmp may not restore it */ |
| 337 | asm volatile ("mov %%i7, %0" : "=r" (saved_i7)); | 305 | asm volatile ("mov %%i7, %0" : "=r" (saved_i7)); |
| 338 | #endif | 306 | #endif |
| 339 | 307 | ||
| 340 | #if defined(TARGET_I386) | 308 | #if defined(TARGET_I386) |
| 341 | -#ifdef reg_EAX | ||
| 342 | - saved_EAX = EAX; | ||
| 343 | -#endif | ||
| 344 | -#ifdef reg_ECX | ||
| 345 | - saved_ECX = ECX; | ||
| 346 | -#endif | ||
| 347 | -#ifdef reg_EDX | ||
| 348 | - saved_EDX = EDX; | ||
| 349 | -#endif | ||
| 350 | -#ifdef reg_EBX | ||
| 351 | - saved_EBX = EBX; | ||
| 352 | -#endif | ||
| 353 | -#ifdef reg_ESP | ||
| 354 | - saved_ESP = ESP; | ||
| 355 | -#endif | ||
| 356 | -#ifdef reg_EBP | ||
| 357 | - saved_EBP = EBP; | ||
| 358 | -#endif | ||
| 359 | -#ifdef reg_ESI | ||
| 360 | - saved_ESI = ESI; | ||
| 361 | -#endif | ||
| 362 | -#ifdef reg_EDI | ||
| 363 | - saved_EDI = EDI; | ||
| 364 | -#endif | ||
| 365 | - | ||
| 366 | env_to_regs(); | 309 | env_to_regs(); |
| 367 | /* put eflags in CPU temporary format */ | 310 | /* put eflags in CPU temporary format */ |
| 368 | CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); | 311 | CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); |
| @@ -827,32 +770,6 @@ int cpu_exec(CPUState *env1) | @@ -827,32 +770,6 @@ int cpu_exec(CPUState *env1) | ||
| 827 | #endif | 770 | #endif |
| 828 | /* restore flags in standard format */ | 771 | /* restore flags in standard format */ |
| 829 | env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK); | 772 | env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK); |
| 830 | - | ||
| 831 | - /* restore global registers */ | ||
| 832 | -#ifdef reg_EAX | ||
| 833 | - EAX = saved_EAX; | ||
| 834 | -#endif | ||
| 835 | -#ifdef reg_ECX | ||
| 836 | - ECX = saved_ECX; | ||
| 837 | -#endif | ||
| 838 | -#ifdef reg_EDX | ||
| 839 | - EDX = saved_EDX; | ||
| 840 | -#endif | ||
| 841 | -#ifdef reg_EBX | ||
| 842 | - EBX = saved_EBX; | ||
| 843 | -#endif | ||
| 844 | -#ifdef reg_ESP | ||
| 845 | - ESP = saved_ESP; | ||
| 846 | -#endif | ||
| 847 | -#ifdef reg_EBP | ||
| 848 | - EBP = saved_EBP; | ||
| 849 | -#endif | ||
| 850 | -#ifdef reg_ESI | ||
| 851 | - ESI = saved_ESI; | ||
| 852 | -#endif | ||
| 853 | -#ifdef reg_EDI | ||
| 854 | - EDI = saved_EDI; | ||
| 855 | -#endif | ||
| 856 | #elif defined(TARGET_ARM) | 773 | #elif defined(TARGET_ARM) |
| 857 | /* XXX: Save/restore host fpu exception state?. */ | 774 | /* XXX: Save/restore host fpu exception state?. */ |
| 858 | #elif defined(TARGET_SPARC) | 775 | #elif defined(TARGET_SPARC) |
| @@ -871,15 +788,13 @@ int cpu_exec(CPUState *env1) | @@ -871,15 +788,13 @@ int cpu_exec(CPUState *env1) | ||
| 871 | #else | 788 | #else |
| 872 | #error unsupported target CPU | 789 | #error unsupported target CPU |
| 873 | #endif | 790 | #endif |
| 791 | + | ||
| 792 | + /* restore global registers */ | ||
| 874 | #if defined(__sparc__) && !defined(HOST_SOLARIS) | 793 | #if defined(__sparc__) && !defined(HOST_SOLARIS) |
| 875 | asm volatile ("mov %0, %%i7" : : "r" (saved_i7)); | 794 | asm volatile ("mov %0, %%i7" : : "r" (saved_i7)); |
| 876 | #endif | 795 | #endif |
| 877 | - T0 = saved_T0; | ||
| 878 | - T1 = saved_T1; | ||
| 879 | -#if defined(reg_T2) | ||
| 880 | - T2 = saved_T2; | ||
| 881 | -#endif | ||
| 882 | - env = saved_env; | 796 | +#include "hostregs_helper.h" |
| 797 | + | ||
| 883 | /* fail safe : never use cpu_single_env outside cpu_exec() */ | 798 | /* fail safe : never use cpu_single_env outside cpu_exec() */ |
| 884 | cpu_single_env = NULL; | 799 | cpu_single_env = NULL; |
| 885 | return ret; | 800 | return ret; |
dyngen-exec.h
| @@ -62,6 +62,9 @@ typedef signed long long int64_t; | @@ -62,6 +62,9 @@ typedef signed long long int64_t; | ||
| 62 | #endif | 62 | #endif |
| 63 | #endif | 63 | #endif |
| 64 | 64 | ||
| 65 | +/* XXX: This may be wrong for 64-bit ILP32 hosts. */ | ||
| 66 | +typedef void * host_reg_t; | ||
| 67 | + | ||
| 65 | #define INT8_MIN (-128) | 68 | #define INT8_MIN (-128) |
| 66 | #define INT16_MIN (-32767-1) | 69 | #define INT16_MIN (-32767-1) |
| 67 | #define INT32_MIN (-2147483647-1) | 70 | #define INT32_MIN (-2147483647-1) |
hostregs_helper.h
0 โ 100644
| 1 | +/* | ||
| 2 | + * Save/restore host registrs. | ||
| 3 | + * | ||
| 4 | + * Copyright (c) 2007 CodeSourcery | ||
| 5 | + * | ||
| 6 | + * This library is free software; you can redistribute it and/or | ||
| 7 | + * modify it under the terms of the GNU Lesser General Public | ||
| 8 | + * License as published by the Free Software Foundation; either | ||
| 9 | + * version 2 of the License, or (at your option) any later version. | ||
| 10 | + * | ||
| 11 | + * This library is distributed in the hope that it will be useful, | ||
| 12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 14 | + * Lesser General Public License for more details. | ||
| 15 | + * | ||
| 16 | + * You should have received a copy of the GNU Lesser General Public | ||
| 17 | + * License along with this library; if not, write to the Free Software | ||
| 18 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 19 | + */ | ||
| 20 | + | ||
| 21 | +/* The GCC global register vairable extension is used to reserve some | ||
| 22 | + host registers for use by dyngen. However only the core parts of the | ||
| 23 | + translation engine are compiled with these settings. We must manually | ||
| 24 | + save/restore these registers when called from regular code. | ||
| 25 | + It is not sufficient to save/restore T0 et. al. as these may be declared | ||
| 26 | + with a datatype smaller than the actual register. */ | ||
| 27 | + | ||
| 28 | +#if defined(DECLARE_HOST_REGS) | ||
| 29 | + | ||
| 30 | +#define DO_REG(REG) \ | ||
| 31 | + register host_reg_t reg_AREG##REG asm(AREG##REG); \ | ||
| 32 | + volatile host_reg_t saved_AREG##REG; | ||
| 33 | + | ||
| 34 | +#elif defined(SAVE_HOST_REGS) | ||
| 35 | + | ||
| 36 | +#define DO_REG(REG) \ | ||
| 37 | + __asm__ __volatile__ ("" : "=r" (reg_AREG##REG)); \ | ||
| 38 | + saved_AREG##REG = reg_AREG##REG; | ||
| 39 | + | ||
| 40 | +#else | ||
| 41 | + | ||
| 42 | +#define DO_REG(REG) \ | ||
| 43 | + reg_AREG##REG = saved_AREG##REG; \ | ||
| 44 | + __asm__ __volatile__ ("" : : "r" (reg_AREG##REG)); | ||
| 45 | + | ||
| 46 | +#endif | ||
| 47 | + | ||
| 48 | +#ifdef AREG0 | ||
| 49 | +DO_REG(0) | ||
| 50 | +#endif | ||
| 51 | + | ||
| 52 | +#ifdef AREG1 | ||
| 53 | +DO_REG(1) | ||
| 54 | +#endif | ||
| 55 | + | ||
| 56 | +#ifdef AREG2 | ||
| 57 | +DO_REG(2) | ||
| 58 | +#endif | ||
| 59 | + | ||
| 60 | +#ifdef AREG3 | ||
| 61 | +DO_REG(3) | ||
| 62 | +#endif | ||
| 63 | + | ||
| 64 | +#ifdef AREG4 | ||
| 65 | +DO_REG(4) | ||
| 66 | +#endif | ||
| 67 | + | ||
| 68 | +#ifdef AREG5 | ||
| 69 | +DO_REG(5) | ||
| 70 | +#endif | ||
| 71 | + | ||
| 72 | +#ifdef AREG6 | ||
| 73 | +DO_REG(6) | ||
| 74 | +#endif | ||
| 75 | + | ||
| 76 | +#ifdef AREG7 | ||
| 77 | +DO_REG(7) | ||
| 78 | +#endif | ||
| 79 | + | ||
| 80 | +#ifdef AREG8 | ||
| 81 | +DO_REG(8) | ||
| 82 | +#endif | ||
| 83 | + | ||
| 84 | +#ifdef AREG9 | ||
| 85 | +DO_REG(9) | ||
| 86 | +#endif | ||
| 87 | + | ||
| 88 | +#ifdef AREG10 | ||
| 89 | +DO_REG(10) | ||
| 90 | +#endif | ||
| 91 | + | ||
| 92 | +#ifdef AREG11 | ||
| 93 | +DO_REG(11) | ||
| 94 | +#endif | ||
| 95 | + | ||
| 96 | +#undef SAVE_HOST_REGS | ||
| 97 | +#undef DECLARE_HOST_REGS | ||
| 98 | +#undef DO_REG |