Commit 3415a4ddb4dc88a206b25cc4daec4b506bfa5096
1 parent
b7f0f463
invd and wbinvd support - fixed code gen logic for invlpg - simpler exception handling in load_seg()
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@487 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
19 additions
and
4 deletions
target-i386/op.c
| @@ -907,7 +907,7 @@ void OPPROTO op_das(void) | @@ -907,7 +907,7 @@ void OPPROTO op_das(void) | ||
| 907 | /* never use it with R_CS */ | 907 | /* never use it with R_CS */ |
| 908 | void OPPROTO op_movl_seg_T0(void) | 908 | void OPPROTO op_movl_seg_T0(void) |
| 909 | { | 909 | { |
| 910 | - load_seg(PARAM1, T0 & 0xffff, PARAM2); | 910 | + load_seg(PARAM1, T0); |
| 911 | } | 911 | } |
| 912 | 912 | ||
| 913 | /* faster VM86 version */ | 913 | /* faster VM86 version */ |
target-i386/translate.c
| @@ -1538,10 +1538,15 @@ static void gen_setcc(DisasContext *s, int b) | @@ -1538,10 +1538,15 @@ static void gen_setcc(DisasContext *s, int b) | ||
| 1538 | call this function with seg_reg == R_CS */ | 1538 | call this function with seg_reg == R_CS */ |
| 1539 | static void gen_movl_seg_T0(DisasContext *s, int seg_reg, unsigned int cur_eip) | 1539 | static void gen_movl_seg_T0(DisasContext *s, int seg_reg, unsigned int cur_eip) |
| 1540 | { | 1540 | { |
| 1541 | - if (s->pe && !s->vm86) | ||
| 1542 | - gen_op_movl_seg_T0(seg_reg, cur_eip); | ||
| 1543 | - else | 1541 | + if (s->pe && !s->vm86) { |
| 1542 | + /* XXX: optimize by finding processor state dynamically */ | ||
| 1543 | + if (s->cc_op != CC_OP_DYNAMIC) | ||
| 1544 | + gen_op_set_cc_op(s->cc_op); | ||
| 1545 | + gen_op_jmp_im(cur_eip); | ||
| 1546 | + gen_op_movl_seg_T0(seg_reg); | ||
| 1547 | + } else { | ||
| 1544 | gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[seg_reg])); | 1548 | gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[seg_reg])); |
| 1549 | + } | ||
| 1545 | /* abort translation because the register may have a non zero base | 1550 | /* abort translation because the register may have a non zero base |
| 1546 | or because ss32 may change. For R_SS, translation must always | 1551 | or because ss32 may change. For R_SS, translation must always |
| 1547 | stop as a special handling must be done to disable hardware | 1552 | stop as a special handling must be done to disable hardware |
| @@ -3982,12 +3987,22 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -3982,12 +3987,22 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
| 3982 | goto illegal_op; | 3987 | goto illegal_op; |
| 3983 | gen_lea_modrm(s, modrm, ®_addr, &offset_addr); | 3988 | gen_lea_modrm(s, modrm, ®_addr, &offset_addr); |
| 3984 | gen_op_invlpg_A0(); | 3989 | gen_op_invlpg_A0(); |
| 3990 | + gen_op_jmp_im(s->pc - s->cs_base); | ||
| 3991 | + gen_eob(s); | ||
| 3985 | } | 3992 | } |
| 3986 | break; | 3993 | break; |
| 3987 | default: | 3994 | default: |
| 3988 | goto illegal_op; | 3995 | goto illegal_op; |
| 3989 | } | 3996 | } |
| 3990 | break; | 3997 | break; |
| 3998 | + case 0x108: /* invd */ | ||
| 3999 | + case 0x109: /* wbinvd */ | ||
| 4000 | + if (s->cpl != 0) { | ||
| 4001 | + gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); | ||
| 4002 | + } else { | ||
| 4003 | + /* nothing to do */ | ||
| 4004 | + } | ||
| 4005 | + break; | ||
| 3991 | case 0x63: /* arpl */ | 4006 | case 0x63: /* arpl */ |
| 3992 | if (!s->pe || s->vm86) | 4007 | if (!s->pe || s->vm86) |
| 3993 | goto illegal_op; | 4008 | goto illegal_op; |