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 |