Fix 64-bit host register corruption.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2384 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									d96372efaa
								
							
						
					
					
						commit
						1057eaa709
					
				
							
								
								
									
										103
									
								
								cpu-exec.c
								
								
								
								
							
							
						
						
									
										103
									
								
								cpu-exec.c
								
								
								
								
							|  | @ -226,37 +226,9 @@ static inline TranslationBlock *tb_find_fast(void) | |||
| 
 | ||||
| int cpu_exec(CPUState *env1) | ||||
| { | ||||
|     target_ulong saved_T0, saved_T1; | ||||
| #if defined(reg_T2) | ||||
|     target_ulong saved_T2; | ||||
| #endif | ||||
|     CPUState *saved_env; | ||||
| #if defined(TARGET_I386) | ||||
| #ifdef reg_EAX | ||||
|     int saved_EAX; | ||||
| #endif | ||||
| #ifdef reg_ECX | ||||
|     int saved_ECX; | ||||
| #endif | ||||
| #ifdef reg_EDX | ||||
|     int saved_EDX; | ||||
| #endif | ||||
| #ifdef reg_EBX | ||||
|     int saved_EBX; | ||||
| #endif | ||||
| #ifdef reg_ESP | ||||
|     int saved_ESP; | ||||
| #endif | ||||
| #ifdef reg_EBP | ||||
|     int saved_EBP; | ||||
| #endif | ||||
| #ifdef reg_ESI | ||||
|     int saved_ESI; | ||||
| #endif | ||||
| #ifdef reg_EDI | ||||
|     int saved_EDI; | ||||
| #endif | ||||
| #elif defined(TARGET_SPARC) | ||||
| #define DECLARE_HOST_REGS 1 | ||||
| #include "hostregs_helper.h" | ||||
| #if defined(TARGET_SPARC) | ||||
| #if defined(reg_REGWPTR) | ||||
|     uint32_t *saved_regwptr; | ||||
| #endif | ||||
|  | @ -325,44 +297,15 @@ int cpu_exec(CPUState *env1) | |||
|     cpu_single_env = env1;  | ||||
| 
 | ||||
|     /* first we save global registers */ | ||||
|     saved_env = env; | ||||
| #define SAVE_HOST_REGS 1 | ||||
| #include "hostregs_helper.h" | ||||
|     env = env1; | ||||
|     saved_T0 = T0; | ||||
|     saved_T1 = T1; | ||||
| #if defined(reg_T2) | ||||
|     saved_T2 = T2; | ||||
| #endif | ||||
| #if defined(__sparc__) && !defined(HOST_SOLARIS) | ||||
|     /* we also save i7 because longjmp may not restore it */ | ||||
|     asm volatile ("mov %%i7, %0" : "=r" (saved_i7)); | ||||
| #endif | ||||
| 
 | ||||
| #if defined(TARGET_I386) | ||||
| #ifdef reg_EAX | ||||
|     saved_EAX = EAX; | ||||
| #endif | ||||
| #ifdef reg_ECX | ||||
|     saved_ECX = ECX; | ||||
| #endif | ||||
| #ifdef reg_EDX | ||||
|     saved_EDX = EDX; | ||||
| #endif | ||||
| #ifdef reg_EBX | ||||
|     saved_EBX = EBX; | ||||
| #endif | ||||
| #ifdef reg_ESP | ||||
|     saved_ESP = ESP; | ||||
| #endif | ||||
| #ifdef reg_EBP | ||||
|     saved_EBP = EBP; | ||||
| #endif | ||||
| #ifdef reg_ESI | ||||
|     saved_ESI = ESI; | ||||
| #endif | ||||
| #ifdef reg_EDI | ||||
|     saved_EDI = EDI; | ||||
| #endif | ||||
| 
 | ||||
|     env_to_regs(); | ||||
|     /* put eflags in CPU temporary format */ | ||||
|     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) | |||
| #endif | ||||
|     /* restore flags in standard format */ | ||||
|     env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK); | ||||
| 
 | ||||
|     /* restore global registers */ | ||||
| #ifdef reg_EAX | ||||
|     EAX = saved_EAX; | ||||
| #endif | ||||
| #ifdef reg_ECX | ||||
|     ECX = saved_ECX; | ||||
| #endif | ||||
| #ifdef reg_EDX | ||||
|     EDX = saved_EDX; | ||||
| #endif | ||||
| #ifdef reg_EBX | ||||
|     EBX = saved_EBX; | ||||
| #endif | ||||
| #ifdef reg_ESP | ||||
|     ESP = saved_ESP; | ||||
| #endif | ||||
| #ifdef reg_EBP | ||||
|     EBP = saved_EBP; | ||||
| #endif | ||||
| #ifdef reg_ESI | ||||
|     ESI = saved_ESI; | ||||
| #endif | ||||
| #ifdef reg_EDI | ||||
|     EDI = saved_EDI; | ||||
| #endif | ||||
| #elif defined(TARGET_ARM) | ||||
|     /* XXX: Save/restore host fpu exception state?.  */ | ||||
| #elif defined(TARGET_SPARC) | ||||
|  | @ -871,15 +788,13 @@ int cpu_exec(CPUState *env1) | |||
| #else | ||||
| #error unsupported target CPU | ||||
| #endif | ||||
| 
 | ||||
|     /* restore global registers */ | ||||
| #if defined(__sparc__) && !defined(HOST_SOLARIS) | ||||
|     asm volatile ("mov %0, %%i7" : : "r" (saved_i7)); | ||||
| #endif | ||||
|     T0 = saved_T0; | ||||
|     T1 = saved_T1; | ||||
| #if defined(reg_T2) | ||||
|     T2 = saved_T2; | ||||
| #endif | ||||
|     env = saved_env; | ||||
| #include "hostregs_helper.h" | ||||
| 
 | ||||
|     /* fail safe : never use cpu_single_env outside cpu_exec() */ | ||||
|     cpu_single_env = NULL;  | ||||
|     return ret; | ||||
|  |  | |||
|  | @ -62,6 +62,9 @@ typedef signed long long int64_t; | |||
| #endif | ||||
| #endif | ||||
| 
 | ||||
| /* XXX: This may be wrong for 64-bit ILP32 hosts.  */ | ||||
| typedef void * host_reg_t; | ||||
| 
 | ||||
| #define INT8_MIN		(-128) | ||||
| #define INT16_MIN		(-32767-1) | ||||
| #define INT32_MIN		(-2147483647-1) | ||||
|  |  | |||
|  | @ -0,0 +1,98 @@ | |||
| /*
 | ||||
|  *  Save/restore host registrs. | ||||
|  * | ||||
|  *  Copyright (c) 2007 CodeSourcery | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * This library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Lesser General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Lesser General Public | ||||
|  * License along with this library; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||||
|  */ | ||||
| 
 | ||||
| /* The GCC global register vairable extension is used to reserve some
 | ||||
|    host registers for use by dyngen.  However only the core parts of the | ||||
|    translation engine are compiled with these settings.  We must manually | ||||
|    save/restore these registers when called from regular code. | ||||
|    It is not sufficient to save/restore T0 et. al. as these may be declared | ||||
|    with a datatype smaller than the actual register.  */ | ||||
| 
 | ||||
| #if defined(DECLARE_HOST_REGS) | ||||
| 
 | ||||
| #define DO_REG(REG)					\ | ||||
|     register host_reg_t reg_AREG##REG asm(AREG##REG);	\ | ||||
|     volatile host_reg_t saved_AREG##REG; | ||||
| 
 | ||||
| #elif defined(SAVE_HOST_REGS) | ||||
| 
 | ||||
| #define DO_REG(REG)					\ | ||||
|     __asm__ __volatile__ ("" : "=r" (reg_AREG##REG));	\ | ||||
|     saved_AREG##REG = reg_AREG##REG; | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
| #define DO_REG(REG)                                     \ | ||||
|     reg_AREG##REG = saved_AREG##REG;		        \ | ||||
|     __asm__ __volatile__ ("" : : "r" (reg_AREG##REG)); | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| #ifdef AREG0 | ||||
| DO_REG(0) | ||||
| #endif | ||||
| 
 | ||||
| #ifdef AREG1 | ||||
| DO_REG(1) | ||||
| #endif | ||||
| 
 | ||||
| #ifdef AREG2 | ||||
| DO_REG(2) | ||||
| #endif | ||||
| 
 | ||||
| #ifdef AREG3 | ||||
| DO_REG(3) | ||||
| #endif | ||||
| 
 | ||||
| #ifdef AREG4 | ||||
| DO_REG(4) | ||||
| #endif | ||||
| 
 | ||||
| #ifdef AREG5 | ||||
| DO_REG(5) | ||||
| #endif | ||||
| 
 | ||||
| #ifdef AREG6 | ||||
| DO_REG(6) | ||||
| #endif | ||||
| 
 | ||||
| #ifdef AREG7 | ||||
| DO_REG(7) | ||||
| #endif | ||||
| 
 | ||||
| #ifdef AREG8 | ||||
| DO_REG(8) | ||||
| #endif | ||||
| 
 | ||||
| #ifdef AREG9 | ||||
| DO_REG(9) | ||||
| #endif | ||||
| 
 | ||||
| #ifdef AREG10 | ||||
| DO_REG(10) | ||||
| #endif | ||||
| 
 | ||||
| #ifdef AREG11 | ||||
| DO_REG(11) | ||||
| #endif | ||||
| 
 | ||||
| #undef SAVE_HOST_REGS | ||||
| #undef DECLARE_HOST_REGS | ||||
| #undef DO_REG | ||||
		Loading…
	
		Reference in New Issue
	
	 pbrook
						pbrook