Commit f76af4b3f38aa0e0bbf9ac695339bd3eb87c09eb
1 parent
717fc2ad
correct restoring of CC_OP in case of exception
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@259 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
20 additions
and
9 deletions
translate.c
| @@ -59,7 +59,9 @@ uint16_t gen_opc_buf[OPC_BUF_SIZE]; | @@ -59,7 +59,9 @@ uint16_t gen_opc_buf[OPC_BUF_SIZE]; | ||
| 59 | uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE]; | 59 | uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE]; |
| 60 | uint32_t gen_opc_pc[OPC_BUF_SIZE]; | 60 | uint32_t gen_opc_pc[OPC_BUF_SIZE]; |
| 61 | uint8_t gen_opc_instr_start[OPC_BUF_SIZE]; | 61 | uint8_t gen_opc_instr_start[OPC_BUF_SIZE]; |
| 62 | - | 62 | +#if defined(TARGET_I386) |
| 63 | +uint8_t gen_opc_cc_op[OPC_BUF_SIZE]; | ||
| 64 | +#endif | ||
| 63 | 65 | ||
| 64 | #ifdef DEBUG_DISAS | 66 | #ifdef DEBUG_DISAS |
| 65 | static const char *op_str[] = { | 67 | static const char *op_str[] = { |
| @@ -111,7 +113,7 @@ int cpu_gen_code(TranslationBlock *tb, | @@ -111,7 +113,7 @@ int cpu_gen_code(TranslationBlock *tb, | ||
| 111 | uint8_t *gen_code_buf; | 113 | uint8_t *gen_code_buf; |
| 112 | int gen_code_size; | 114 | int gen_code_size; |
| 113 | 115 | ||
| 114 | - if (gen_intermediate_code(tb, 0) < 0) | 116 | + if (gen_intermediate_code(tb) < 0) |
| 115 | return -1; | 117 | return -1; |
| 116 | 118 | ||
| 117 | /* generate machine code */ | 119 | /* generate machine code */ |
| @@ -143,18 +145,16 @@ static const unsigned short opc_copy_size[] = { | @@ -143,18 +145,16 @@ static const unsigned short opc_copy_size[] = { | ||
| 143 | #undef DEF | 145 | #undef DEF |
| 144 | }; | 146 | }; |
| 145 | 147 | ||
| 146 | -/* The simulated PC corresponding to | ||
| 147 | - 'searched_pc' in the generated code is searched. 0 is returned if | ||
| 148 | - found. *found_pc contains the found PC. | 148 | +/* The cpu state corresponding to 'searched_pc' is restored. |
| 149 | */ | 149 | */ |
| 150 | -int cpu_search_pc(TranslationBlock *tb, | ||
| 151 | - uint32_t *found_pc, unsigned long searched_pc) | 150 | +int cpu_restore_state(TranslationBlock *tb, |
| 151 | + CPUState *env, unsigned long searched_pc) | ||
| 152 | { | 152 | { |
| 153 | int j, c; | 153 | int j, c; |
| 154 | unsigned long tc_ptr; | 154 | unsigned long tc_ptr; |
| 155 | uint16_t *opc_ptr; | 155 | uint16_t *opc_ptr; |
| 156 | 156 | ||
| 157 | - if (gen_intermediate_code(tb, 1) < 0) | 157 | + if (gen_intermediate_code_pc(tb) < 0) |
| 158 | return -1; | 158 | return -1; |
| 159 | 159 | ||
| 160 | /* find opc index corresponding to search_pc */ | 160 | /* find opc index corresponding to search_pc */ |
| @@ -176,7 +176,18 @@ int cpu_search_pc(TranslationBlock *tb, | @@ -176,7 +176,18 @@ int cpu_search_pc(TranslationBlock *tb, | ||
| 176 | /* now find start of instruction before */ | 176 | /* now find start of instruction before */ |
| 177 | while (gen_opc_instr_start[j] == 0) | 177 | while (gen_opc_instr_start[j] == 0) |
| 178 | j--; | 178 | j--; |
| 179 | - *found_pc = gen_opc_pc[j]; | 179 | +#if defined(TARGET_I386) |
| 180 | + { | ||
| 181 | + int cc_op; | ||
| 182 | + | ||
| 183 | + env->eip = gen_opc_pc[j] - tb->cs_base; | ||
| 184 | + cc_op = gen_opc_cc_op[j]; | ||
| 185 | + if (cc_op != CC_OP_DYNAMIC) | ||
| 186 | + env->cc_op = cc_op; | ||
| 187 | + } | ||
| 188 | +#elif defined(TARGET_ARM) | ||
| 189 | + env->regs[15] = gen_opc_pc[j]; | ||
| 190 | +#endif | ||
| 180 | return 0; | 191 | return 0; |
| 181 | } | 192 | } |
| 182 | 193 |