Commit 0d1a29f9fcd161b07a02b9256446235208d379ca

Authored by bellard
1 parent b8b5ac63

correct handling of saved host registers


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1122 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-exec.c
... ... @@ -123,37 +123,30 @@ int cpu_exec(CPUState *env1)
123 123 #if defined(TARGET_I386)
124 124 #ifdef reg_EAX
125 125 saved_EAX = EAX;
126   - EAX = env->regs[R_EAX];
127 126 #endif
128 127 #ifdef reg_ECX
129 128 saved_ECX = ECX;
130   - ECX = env->regs[R_ECX];
131 129 #endif
132 130 #ifdef reg_EDX
133 131 saved_EDX = EDX;
134   - EDX = env->regs[R_EDX];
135 132 #endif
136 133 #ifdef reg_EBX
137 134 saved_EBX = EBX;
138   - EBX = env->regs[R_EBX];
139 135 #endif
140 136 #ifdef reg_ESP
141 137 saved_ESP = ESP;
142   - ESP = env->regs[R_ESP];
143 138 #endif
144 139 #ifdef reg_EBP
145 140 saved_EBP = EBP;
146   - EBP = env->regs[R_EBP];
147 141 #endif
148 142 #ifdef reg_ESI
149 143 saved_ESI = ESI;
150   - ESI = env->regs[R_ESI];
151 144 #endif
152 145 #ifdef reg_EDI
153 146 saved_EDI = EDI;
154   - EDI = env->regs[R_EDI];
155 147 #endif
156   -
  148 +
  149 + env_to_regs();
157 150 /* put eflags in CPU temporary format */
158 151 CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
159 152 DF = 1 - (2 * ((env->eflags >> 10) & 1));
... ... @@ -353,6 +346,8 @@ int cpu_exec(CPUState *env1)
353 346 spin_lock(&tb_lock);
354 347  
355 348 tb_invalidated_flag = 0;
  349 +
  350 + regs_to_env(); /* XXX: do it just before cpu_gen_code() */
356 351  
357 352 /* find translated block using physical mappings */
358 353 phys_pc = get_phys_addr_code(env, (unsigned long)pc);
... ... @@ -556,6 +551,7 @@ int cpu_exec(CPUState *env1)
556 551 #endif
557 552 }
558 553 } else {
  554 + env_to_regs();
559 555 }
560 556 } /* for(;;) */
561 557  
... ...
dyngen-exec.h
... ... @@ -93,8 +93,6 @@ extern int printf(const char *, ...);
93 93 #define AREG1 "r24"
94 94 #define AREG2 "r25"
95 95 #define AREG3 "r26"
96   -/* XXX: suppress this hack */
97   -#if defined(CONFIG_USER_ONLY)
98 96 #define AREG4 "r16"
99 97 #define AREG5 "r17"
100 98 #define AREG6 "r18"
... ... @@ -103,7 +101,6 @@ extern int printf(const char *, ...);
103 101 #define AREG9 "r21"
104 102 #define AREG10 "r22"
105 103 #define AREG11 "r23"
106   -#endif
107 104 #define USE_INT_TO_FLOAT_HELPERS
108 105 #define BUGGY_GCC_DIV64
109 106 #endif
... ...
target-arm/exec.h
... ... @@ -38,3 +38,11 @@ static inline int compute_cpsr(void)
38 38 return env->cpsr | (env->NZF & 0x80000000) | (ZF << 30) |
39 39 (env->CF << 29) | ((env->VF & 0x80000000) >> 3);
40 40 }
  41 +
  42 +static inline void env_to_regs(void)
  43 +{
  44 +}
  45 +
  46 +static inline void regs_to_env(void)
  47 +{
  48 +}
... ...
target-i386/exec.h
... ... @@ -20,7 +20,7 @@
20 20 #include "config.h"
21 21 #include "dyngen-exec.h"
22 22  
23   -/* at least 4 register variables are defines */
  23 +/* at least 4 register variables are defined */
24 24 register struct CPUX86State *env asm(AREG0);
25 25 register uint32_t T0 asm(AREG1);
26 26 register uint32_t T1 asm(AREG2);
... ... @@ -546,3 +546,58 @@ static inline void load_eflags(int eflags, int update_mask)
546 546 (eflags & update_mask);
547 547 }
548 548  
  549 +static inline void env_to_regs(void)
  550 +{
  551 +#ifdef reg_EAX
  552 + EAX = env->regs[R_EAX];
  553 +#endif
  554 +#ifdef reg_ECX
  555 + ECX = env->regs[R_ECX];
  556 +#endif
  557 +#ifdef reg_EDX
  558 + EDX = env->regs[R_EDX];
  559 +#endif
  560 +#ifdef reg_EBX
  561 + EBX = env->regs[R_EBX];
  562 +#endif
  563 +#ifdef reg_ESP
  564 + ESP = env->regs[R_ESP];
  565 +#endif
  566 +#ifdef reg_EBP
  567 + EBP = env->regs[R_EBP];
  568 +#endif
  569 +#ifdef reg_ESI
  570 + ESI = env->regs[R_ESI];
  571 +#endif
  572 +#ifdef reg_EDI
  573 + EDI = env->regs[R_EDI];
  574 +#endif
  575 +}
  576 +
  577 +static inline void regs_to_env(void)
  578 +{
  579 +#ifdef reg_EAX
  580 + env->regs[R_EAX] = EAX;
  581 +#endif
  582 +#ifdef reg_ECX
  583 + env->regs[R_ECX] = ECX;
  584 +#endif
  585 +#ifdef reg_EDX
  586 + env->regs[R_EDX] = EDX;
  587 +#endif
  588 +#ifdef reg_EBX
  589 + env->regs[R_EBX] = EBX;
  590 +#endif
  591 +#ifdef reg_ESP
  592 + env->regs[R_ESP] = ESP;
  593 +#endif
  594 +#ifdef reg_EBP
  595 + env->regs[R_EBP] = EBP;
  596 +#endif
  597 +#ifdef reg_ESI
  598 + env->regs[R_ESI] = ESI;
  599 +#endif
  600 +#ifdef reg_EDI
  601 + env->regs[R_EDI] = EDI;
  602 +#endif
  603 +}
... ...
target-i386/helper.c
... ... @@ -109,30 +109,7 @@ void cpu_loop_exit(void)
109 109 {
110 110 /* NOTE: the register at this point must be saved by hand because
111 111 longjmp restore them */
112   -#ifdef reg_EAX
113   - env->regs[R_EAX] = EAX;
114   -#endif
115   -#ifdef reg_ECX
116   - env->regs[R_ECX] = ECX;
117   -#endif
118   -#ifdef reg_EDX
119   - env->regs[R_EDX] = EDX;
120   -#endif
121   -#ifdef reg_EBX
122   - env->regs[R_EBX] = EBX;
123   -#endif
124   -#ifdef reg_ESP
125   - env->regs[R_ESP] = ESP;
126   -#endif
127   -#ifdef reg_EBP
128   - env->regs[R_EBP] = EBP;
129   -#endif
130   -#ifdef reg_ESI
131   - env->regs[R_ESI] = ESI;
132   -#endif
133   -#ifdef reg_EDI
134   - env->regs[R_EDI] = EDI;
135   -#endif
  112 + regs_to_env();
136 113 longjmp(env->jmp_env, 1);
137 114 }
138 115  
... ... @@ -384,16 +361,28 @@ static void switch_tss(int tss_selector,
384 361 /* 32 bit */
385 362 stl_kernel(env->tr.base + 0x20, next_eip);
386 363 stl_kernel(env->tr.base + 0x24, old_eflags);
387   - for(i = 0; i < 8; i++)
388   - stl_kernel(env->tr.base + (0x28 + i * 4), env->regs[i]);
  364 + stl_kernel(env->tr.base + (0x28 + 0 * 4), EAX);
  365 + stl_kernel(env->tr.base + (0x28 + 1 * 4), ECX);
  366 + stl_kernel(env->tr.base + (0x28 + 2 * 4), EDX);
  367 + stl_kernel(env->tr.base + (0x28 + 3 * 4), EBX);
  368 + stl_kernel(env->tr.base + (0x28 + 4 * 4), ESP);
  369 + stl_kernel(env->tr.base + (0x28 + 5 * 4), EBP);
  370 + stl_kernel(env->tr.base + (0x28 + 6 * 4), ESI);
  371 + stl_kernel(env->tr.base + (0x28 + 7 * 4), EDI);
389 372 for(i = 0; i < 6; i++)
390 373 stw_kernel(env->tr.base + (0x48 + i * 4), env->segs[i].selector);
391 374 } else {
392 375 /* 16 bit */
393 376 stw_kernel(env->tr.base + 0x0e, next_eip);
394 377 stw_kernel(env->tr.base + 0x10, old_eflags);
395   - for(i = 0; i < 8; i++)
396   - stw_kernel(env->tr.base + (0x12 + i * 2), env->regs[i]);
  378 + stw_kernel(env->tr.base + (0x12 + 0 * 2), EAX);
  379 + stw_kernel(env->tr.base + (0x12 + 1 * 2), ECX);
  380 + stw_kernel(env->tr.base + (0x12 + 2 * 2), EDX);
  381 + stw_kernel(env->tr.base + (0x12 + 3 * 2), EBX);
  382 + stw_kernel(env->tr.base + (0x12 + 4 * 2), ESP);
  383 + stw_kernel(env->tr.base + (0x12 + 5 * 2), EBP);
  384 + stw_kernel(env->tr.base + (0x12 + 6 * 2), ESI);
  385 + stw_kernel(env->tr.base + (0x12 + 7 * 2), EDI);
397 386 for(i = 0; i < 4; i++)
398 387 stw_kernel(env->tr.base + (0x22 + i * 4), env->segs[i].selector);
399 388 }
... ... @@ -437,8 +426,15 @@ static void switch_tss(int tss_selector,
437 426 if (!(type & 8))
438 427 eflags_mask &= 0xffff;
439 428 load_eflags(new_eflags, eflags_mask);
440   - for(i = 0; i < 8; i++)
441   - env->regs[i] = new_regs[i];
  429 + /* XXX: what to do in 16 bit case ? */
  430 + EAX = new_regs[0];
  431 + ECX = new_regs[1];
  432 + EDX = new_regs[2];
  433 + EBX = new_regs[3];
  434 + ESP = new_regs[4];
  435 + EBP = new_regs[5];
  436 + ESI = new_regs[6];
  437 + EDI = new_regs[7];
442 438 if (new_eflags & VM_MASK) {
443 439 for(i = 0; i < 6; i++)
444 440 load_seg_vm(i, new_segs[i]);
... ... @@ -633,13 +629,13 @@ static void do_interrupt_protected(int intno, int is_int, int error_code,
633 629 mask = 0xffffffff;
634 630 else
635 631 mask = 0xffff;
636   - esp = (env->regs[R_ESP] - (2 << shift)) & mask;
  632 + esp = (ESP - (2 << shift)) & mask;
637 633 ssp = env->segs[R_SS].base + esp;
638 634 if (shift)
639 635 stl_kernel(ssp, error_code);
640 636 else
641 637 stw_kernel(ssp, error_code);
642   - env->regs[R_ESP] = (esp & mask) | (env->regs[R_ESP] & ~mask);
  638 + ESP = (esp & mask) | (ESP & ~mask);
643 639 }
644 640 return;
645 641 case 6: /* 286 interrupt gate */
... ... @@ -868,7 +864,7 @@ void do_interrupt(int intno, int is_int, int error_code,
868 864 if (intno == 0x0e) {
869 865 fprintf(logfile, " CR2=%08x", env->cr[2]);
870 866 } else {
871   - fprintf(logfile, " EAX=%08x", env->regs[R_EAX]);
  867 + fprintf(logfile, " EAX=%08x", EAX);
872 868 }
873 869 fprintf(logfile, "\n");
874 870 #if 0
... ... @@ -911,6 +907,16 @@ void raise_interrupt(int intno, int is_int, int error_code,
911 907 cpu_loop_exit();
912 908 }
913 909  
  910 +/* same as raise_exception_err, but do not restore global registers */
  911 +static void raise_exception_err_norestore(int exception_index, int error_code)
  912 +{
  913 + env->exception_index = exception_index;
  914 + env->error_code = error_code;
  915 + env->exception_is_int = 0;
  916 + env->exception_next_eip = 0;
  917 + longjmp(env->jmp_env, 1);
  918 +}
  919 +
914 920 /* shortcuts to generate exceptions */
915 921  
916 922 void (raise_exception_err)(int exception_index, int error_code)
... ... @@ -2584,7 +2590,10 @@ void tlb_fill(unsigned long addr, int is_write, int is_user, void *retaddr)
2584 2590 cpu_restore_state(tb, env, pc, NULL);
2585 2591 }
2586 2592 }
2587   - raise_exception_err(EXCP0E_PAGE, env->error_code);
  2593 + if (retaddr)
  2594 + raise_exception_err(EXCP0E_PAGE, env->error_code);
  2595 + else
  2596 + raise_exception_err_norestore(EXCP0E_PAGE, env->error_code);
2588 2597 }
2589 2598 env = saved_env;
2590 2599 }
... ...
target-ppc/exec.h
... ... @@ -165,4 +165,12 @@ void dump_store_dbat (int ul, int nr);
165 165 void dump_store_tb (int ul);
166 166 void dump_update_tb(uint32_t param);
167 167  
  168 +static inline void env_to_regs(void)
  169 +{
  170 +}
  171 +
  172 +static inline void regs_to_env(void)
  173 +{
  174 +}
  175 +
168 176 #endif /* !defined (__PPC_H__) */
... ...
target-sparc/exec.h
... ... @@ -109,4 +109,13 @@ void memcpy32(uint32_t *dst, const uint32_t *src);
109 109 #define stq(p, v) stq_data(p, v)
110 110  
111 111 #endif /* !defined(CONFIG_USER_ONLY) */
  112 +
  113 +static inline void env_to_regs(void)
  114 +{
  115 +}
  116 +
  117 +static inline void regs_to_env(void)
  118 +{
  119 +}
  120 +
112 121 #endif
... ...