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 | 226 | |
| 227 | 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 | 232 | #if defined(reg_REGWPTR) |
| 261 | 233 | uint32_t *saved_regwptr; |
| 262 | 234 | #endif |
| ... | ... | @@ -325,44 +297,15 @@ int cpu_exec(CPUState *env1) |
| 325 | 297 | cpu_single_env = env1; |
| 326 | 298 | |
| 327 | 299 | /* first we save global registers */ |
| 328 | - saved_env = env; | |
| 300 | +#define SAVE_HOST_REGS 1 | |
| 301 | +#include "hostregs_helper.h" | |
| 329 | 302 | env = env1; |
| 330 | - saved_T0 = T0; | |
| 331 | - saved_T1 = T1; | |
| 332 | -#if defined(reg_T2) | |
| 333 | - saved_T2 = T2; | |
| 334 | -#endif | |
| 335 | 303 | #if defined(__sparc__) && !defined(HOST_SOLARIS) |
| 336 | 304 | /* we also save i7 because longjmp may not restore it */ |
| 337 | 305 | asm volatile ("mov %%i7, %0" : "=r" (saved_i7)); |
| 338 | 306 | #endif |
| 339 | 307 | |
| 340 | 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 | 309 | env_to_regs(); |
| 367 | 310 | /* put eflags in CPU temporary format */ |
| 368 | 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 | 770 | #endif |
| 828 | 771 | /* restore flags in standard format */ |
| 829 | 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 | 773 | #elif defined(TARGET_ARM) |
| 857 | 774 | /* XXX: Save/restore host fpu exception state?. */ |
| 858 | 775 | #elif defined(TARGET_SPARC) |
| ... | ... | @@ -871,15 +788,13 @@ int cpu_exec(CPUState *env1) |
| 871 | 788 | #else |
| 872 | 789 | #error unsupported target CPU |
| 873 | 790 | #endif |
| 791 | + | |
| 792 | + /* restore global registers */ | |
| 874 | 793 | #if defined(__sparc__) && !defined(HOST_SOLARIS) |
| 875 | 794 | asm volatile ("mov %0, %%i7" : : "r" (saved_i7)); |
| 876 | 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 | 798 | /* fail safe : never use cpu_single_env outside cpu_exec() */ |
| 884 | 799 | cpu_single_env = NULL; |
| 885 | 800 | return ret; | ... | ... |
dyngen-exec.h
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 | ... | ... |