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 | ... | ... |