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 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
... ... @@ -62,6 +62,9 @@ typedef signed long long int64_t;
62 62 #endif
63 63 #endif
64 64  
  65 +/* XXX: This may be wrong for 64-bit ILP32 hosts. */
  66 +typedef void * host_reg_t;
  67 +
65 68 #define INT8_MIN (-128)
66 69 #define INT16_MIN (-32767-1)
67 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
... ...