Commit 3bd7da9e1851f024919c07eba4c29acf209ecd6e
1 parent
cec6843e
convert remaining segment handling to TCG
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4514 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
38 additions
and
49 deletions
target-i386/TODO
... | ... | @@ -4,7 +4,6 @@ Correctness issues: |
4 | 4 | - SVM: rework the implementation: simplify code, move most intercept |
5 | 5 | tests as dynamic, correct segment access, verify exception safety, |
6 | 6 | cpu save/restore, SMM save/restore. |
7 | -- arpl eflags computation is invalid | |
8 | 7 | - x86_64: fxsave/fxrestore intel/amd differences |
9 | 8 | - x86_64: lcall/ljmp intel/amd differences ? |
10 | 9 | - x86_64: cmpxchgl intel/amd differences ? |
... | ... | @@ -32,6 +31,8 @@ Optimizations/Features: |
32 | 31 | - add VMX support |
33 | 32 | - add AVX support |
34 | 33 | - add SSE5 support |
34 | +- faster EFLAGS update: consider SZAP, C, O can be updated separately | |
35 | + with a bit field in CC_OP and more state variables. | |
35 | 36 | - evaluate x87 stack pointer statically |
36 | 37 | - find a way to avoid translating several time the same TB if CR0.TS |
37 | 38 | is set or not. | ... | ... |
target-i386/op.c
... | ... | @@ -147,45 +147,6 @@ |
147 | 147 | |
148 | 148 | #endif |
149 | 149 | |
150 | -/* segment handling */ | |
151 | - | |
152 | -/* faster VM86 version */ | |
153 | -void OPPROTO op_movl_seg_T0_vm(void) | |
154 | -{ | |
155 | - int selector; | |
156 | - SegmentCache *sc; | |
157 | - | |
158 | - selector = T0 & 0xffff; | |
159 | - /* env->segs[] access */ | |
160 | - sc = (SegmentCache *)((char *)env + PARAM1); | |
161 | - sc->selector = selector; | |
162 | - sc->base = (selector << 4); | |
163 | -} | |
164 | - | |
165 | -void OPPROTO op_movl_T0_seg(void) | |
166 | -{ | |
167 | - T0 = env->segs[PARAM1].selector; | |
168 | -} | |
169 | - | |
170 | -void OPPROTO op_arpl(void) | |
171 | -{ | |
172 | - if ((T0 & 3) < (T1 & 3)) { | |
173 | - /* XXX: emulate bug or 0xff3f0000 oring as in bochs ? */ | |
174 | - T0 = (T0 & ~3) | (T1 & 3); | |
175 | - T1 = CC_Z; | |
176 | - } else { | |
177 | - T1 = 0; | |
178 | - } | |
179 | - FORCE_RET(); | |
180 | -} | |
181 | - | |
182 | -void OPPROTO op_arpl_update(void) | |
183 | -{ | |
184 | - int eflags; | |
185 | - eflags = cc_table[CC_OP].compute_all(); | |
186 | - CC_SRC = (eflags & ~CC_Z) | T1; | |
187 | -} | |
188 | - | |
189 | 150 | void OPPROTO op_movl_T0_env(void) |
190 | 151 | { |
191 | 152 | T0 = *(uint32_t *)((char *)env + PARAM1); | ... | ... |
target-i386/translate.c
... | ... | @@ -2167,6 +2167,22 @@ static void gen_setcc(DisasContext *s, int b) |
2167 | 2167 | } |
2168 | 2168 | } |
2169 | 2169 | |
2170 | +static inline void gen_op_movl_T0_seg(int seg_reg) | |
2171 | +{ | |
2172 | + tcg_gen_ld32u_tl(cpu_T[0], cpu_env, | |
2173 | + offsetof(CPUX86State,segs[seg_reg].selector)); | |
2174 | +} | |
2175 | + | |
2176 | +static inline void gen_op_movl_seg_T0_vm(int seg_reg) | |
2177 | +{ | |
2178 | + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff); | |
2179 | + tcg_gen_st32_tl(cpu_T[0], cpu_env, | |
2180 | + offsetof(CPUX86State,segs[seg_reg].selector)); | |
2181 | + tcg_gen_shli_tl(cpu_T[0], cpu_T[0], 4); | |
2182 | + tcg_gen_st_tl(cpu_T[0], cpu_env, | |
2183 | + offsetof(CPUX86State,segs[seg_reg].base)); | |
2184 | +} | |
2185 | + | |
2170 | 2186 | /* move T0 to seg_reg and compute if the CPU state may change. Never |
2171 | 2187 | call this function with seg_reg == R_CS */ |
2172 | 2188 | static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip) |
... | ... | @@ -2185,7 +2201,7 @@ static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip) |
2185 | 2201 | if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS)) |
2186 | 2202 | s->is_jmp = 3; |
2187 | 2203 | } else { |
2188 | - gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[seg_reg])); | |
2204 | + gen_op_movl_seg_T0_vm(seg_reg); | |
2189 | 2205 | if (seg_reg == R_SS) |
2190 | 2206 | s->is_jmp = 3; |
2191 | 2207 | } |
... | ... | @@ -4085,7 +4101,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
4085 | 4101 | cpu_T[1], |
4086 | 4102 | tcg_const_i32(s->pc - pc_start)); |
4087 | 4103 | } else { |
4088 | - gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS])); | |
4104 | + gen_op_movl_seg_T0_vm(R_CS); | |
4089 | 4105 | gen_op_movl_T0_T1(); |
4090 | 4106 | gen_op_jmp_T0(); |
4091 | 4107 | } |
... | ... | @@ -5575,7 +5591,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
5575 | 5591 | /* pop selector */ |
5576 | 5592 | gen_op_addl_A0_im(2 << s->dflag); |
5577 | 5593 | gen_op_ld_T0_A0(1 + s->dflag + s->mem_index); |
5578 | - gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS])); | |
5594 | + gen_op_movl_seg_T0_vm(R_CS); | |
5579 | 5595 | /* add stack offset */ |
5580 | 5596 | gen_stack_update(s, val + (4 << s->dflag)); |
5581 | 5597 | } |
... | ... | @@ -6578,9 +6594,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
6578 | 6594 | } else |
6579 | 6595 | #endif |
6580 | 6596 | { |
6597 | + int label1; | |
6581 | 6598 | if (!s->pe || s->vm86) |
6582 | 6599 | goto illegal_op; |
6583 | - ot = dflag ? OT_LONG : OT_WORD; | |
6600 | + ot = OT_WORD; | |
6584 | 6601 | modrm = ldub_code(s->pc++); |
6585 | 6602 | reg = (modrm >> 3) & 7; |
6586 | 6603 | mod = (modrm >> 6) & 3; |
... | ... | @@ -6592,16 +6609,26 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
6592 | 6609 | gen_op_mov_TN_reg(ot, 0, rm); |
6593 | 6610 | } |
6594 | 6611 | gen_op_mov_TN_reg(ot, 1, reg); |
6595 | - if (s->cc_op != CC_OP_DYNAMIC) | |
6596 | - gen_op_set_cc_op(s->cc_op); | |
6597 | - gen_op_arpl(); | |
6598 | - s->cc_op = CC_OP_EFLAGS; | |
6612 | + tcg_gen_andi_tl(cpu_tmp0, cpu_T[0], 3); | |
6613 | + tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 3); | |
6614 | + tcg_gen_movi_tl(cpu_T3, 0); | |
6615 | + label1 = gen_new_label(); | |
6616 | + tcg_gen_brcond_tl(TCG_COND_GE, cpu_tmp0, cpu_T[1], label1); | |
6617 | + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], ~3); | |
6618 | + tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]); | |
6619 | + tcg_gen_movi_tl(cpu_T3, CC_Z); | |
6620 | + gen_set_label(label1); | |
6599 | 6621 | if (mod != 3) { |
6600 | 6622 | gen_op_st_T0_A0(ot + s->mem_index); |
6601 | 6623 | } else { |
6602 | 6624 | gen_op_mov_reg_T0(ot, rm); |
6603 | 6625 | } |
6604 | - gen_op_arpl_update(); | |
6626 | + if (s->cc_op != CC_OP_DYNAMIC) | |
6627 | + gen_op_set_cc_op(s->cc_op); | |
6628 | + gen_compute_eflags(cpu_cc_src); | |
6629 | + tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z); | |
6630 | + tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T3); | |
6631 | + s->cc_op = CC_OP_EFLAGS; | |
6605 | 6632 | } |
6606 | 6633 | break; |
6607 | 6634 | case 0x102: /* lar */ | ... | ... |