Revision 3bd7da9e
b/target-i386/TODO | ||
---|---|---|
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 | 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. |
b/target-i386/op.c | ||
---|---|---|
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); |
b/target-i386/translate.c | ||
---|---|---|
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 | 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 | 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 | 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 | 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 | 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 */ |
Also available in: Unified diff