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,7 +4,6 @@ Correctness issues: | ||
4 | - SVM: rework the implementation: simplify code, move most intercept | 4 | - SVM: rework the implementation: simplify code, move most intercept |
5 | tests as dynamic, correct segment access, verify exception safety, | 5 | tests as dynamic, correct segment access, verify exception safety, |
6 | cpu save/restore, SMM save/restore. | 6 | cpu save/restore, SMM save/restore. |
7 | -- arpl eflags computation is invalid | ||
8 | - x86_64: fxsave/fxrestore intel/amd differences | 7 | - x86_64: fxsave/fxrestore intel/amd differences |
9 | - x86_64: lcall/ljmp intel/amd differences ? | 8 | - x86_64: lcall/ljmp intel/amd differences ? |
10 | - x86_64: cmpxchgl intel/amd differences ? | 9 | - x86_64: cmpxchgl intel/amd differences ? |
@@ -32,6 +31,8 @@ Optimizations/Features: | @@ -32,6 +31,8 @@ Optimizations/Features: | ||
32 | - add VMX support | 31 | - add VMX support |
33 | - add AVX support | 32 | - add AVX support |
34 | - add SSE5 support | 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 | - evaluate x87 stack pointer statically | 36 | - evaluate x87 stack pointer statically |
36 | - find a way to avoid translating several time the same TB if CR0.TS | 37 | - find a way to avoid translating several time the same TB if CR0.TS |
37 | is set or not. | 38 | is set or not. |
target-i386/op.c
@@ -147,45 +147,6 @@ | @@ -147,45 +147,6 @@ | ||
147 | 147 | ||
148 | #endif | 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 | void OPPROTO op_movl_T0_env(void) | 150 | void OPPROTO op_movl_T0_env(void) |
190 | { | 151 | { |
191 | T0 = *(uint32_t *)((char *)env + PARAM1); | 152 | T0 = *(uint32_t *)((char *)env + PARAM1); |
target-i386/translate.c
@@ -2167,6 +2167,22 @@ static void gen_setcc(DisasContext *s, int b) | @@ -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 | /* move T0 to seg_reg and compute if the CPU state may change. Never | 2186 | /* move T0 to seg_reg and compute if the CPU state may change. Never |
2171 | call this function with seg_reg == R_CS */ | 2187 | call this function with seg_reg == R_CS */ |
2172 | static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip) | 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,7 +2201,7 @@ static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip) | ||
2185 | if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS)) | 2201 | if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS)) |
2186 | s->is_jmp = 3; | 2202 | s->is_jmp = 3; |
2187 | } else { | 2203 | } else { |
2188 | - gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[seg_reg])); | 2204 | + gen_op_movl_seg_T0_vm(seg_reg); |
2189 | if (seg_reg == R_SS) | 2205 | if (seg_reg == R_SS) |
2190 | s->is_jmp = 3; | 2206 | s->is_jmp = 3; |
2191 | } | 2207 | } |
@@ -4085,7 +4101,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) | @@ -4085,7 +4101,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) | ||
4085 | cpu_T[1], | 4101 | cpu_T[1], |
4086 | tcg_const_i32(s->pc - pc_start)); | 4102 | tcg_const_i32(s->pc - pc_start)); |
4087 | } else { | 4103 | } else { |
4088 | - gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS])); | 4104 | + gen_op_movl_seg_T0_vm(R_CS); |
4089 | gen_op_movl_T0_T1(); | 4105 | gen_op_movl_T0_T1(); |
4090 | gen_op_jmp_T0(); | 4106 | gen_op_jmp_T0(); |
4091 | } | 4107 | } |
@@ -5575,7 +5591,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) | @@ -5575,7 +5591,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) | ||
5575 | /* pop selector */ | 5591 | /* pop selector */ |
5576 | gen_op_addl_A0_im(2 << s->dflag); | 5592 | gen_op_addl_A0_im(2 << s->dflag); |
5577 | gen_op_ld_T0_A0(1 + s->dflag + s->mem_index); | 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 | /* add stack offset */ | 5595 | /* add stack offset */ |
5580 | gen_stack_update(s, val + (4 << s->dflag)); | 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,9 +6594,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) | ||
6578 | } else | 6594 | } else |
6579 | #endif | 6595 | #endif |
6580 | { | 6596 | { |
6597 | + int label1; | ||
6581 | if (!s->pe || s->vm86) | 6598 | if (!s->pe || s->vm86) |
6582 | goto illegal_op; | 6599 | goto illegal_op; |
6583 | - ot = dflag ? OT_LONG : OT_WORD; | 6600 | + ot = OT_WORD; |
6584 | modrm = ldub_code(s->pc++); | 6601 | modrm = ldub_code(s->pc++); |
6585 | reg = (modrm >> 3) & 7; | 6602 | reg = (modrm >> 3) & 7; |
6586 | mod = (modrm >> 6) & 3; | 6603 | mod = (modrm >> 6) & 3; |
@@ -6592,16 +6609,26 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) | @@ -6592,16 +6609,26 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) | ||
6592 | gen_op_mov_TN_reg(ot, 0, rm); | 6609 | gen_op_mov_TN_reg(ot, 0, rm); |
6593 | } | 6610 | } |
6594 | gen_op_mov_TN_reg(ot, 1, reg); | 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 | if (mod != 3) { | 6621 | if (mod != 3) { |
6600 | gen_op_st_T0_A0(ot + s->mem_index); | 6622 | gen_op_st_T0_A0(ot + s->mem_index); |
6601 | } else { | 6623 | } else { |
6602 | gen_op_mov_reg_T0(ot, rm); | 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 | break; | 6633 | break; |
6607 | case 0x102: /* lar */ | 6634 | case 0x102: /* lar */ |