Commit 1057eaa709dba09d1c4f7a363877e635797e4623

Authored by pbrook
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
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