Revision 3d7374c5
b/target-i386/exec.h | ||
---|---|---|
496 | 496 |
float approx_rsqrt(float a); |
497 | 497 |
float approx_rcp(float a); |
498 | 498 |
void update_fp_status(void); |
499 |
void helper_hlt(void); |
|
500 |
void helper_monitor(void); |
|
501 |
void helper_mwait(void); |
|
499 | 502 |
|
500 | 503 |
extern const uint8_t parity_table[256]; |
501 | 504 |
extern const uint8_t rclw_table[32]; |
b/target-i386/helper.c | ||
---|---|---|
3408 | 3408 |
} |
3409 | 3409 |
#endif |
3410 | 3410 |
|
3411 |
void helper_hlt(void) |
|
3412 |
{ |
|
3413 |
env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */ |
|
3414 |
env->hflags |= HF_HALTED_MASK; |
|
3415 |
env->exception_index = EXCP_HLT; |
|
3416 |
cpu_loop_exit(); |
|
3417 |
} |
|
3418 |
|
|
3419 |
void helper_monitor(void) |
|
3420 |
{ |
|
3421 |
if (ECX != 0) |
|
3422 |
raise_exception(EXCP0D_GPF); |
|
3423 |
/* XXX: store address ? */ |
|
3424 |
} |
|
3425 |
|
|
3426 |
void helper_mwait(void) |
|
3427 |
{ |
|
3428 |
if (ECX != 0) |
|
3429 |
raise_exception(EXCP0D_GPF); |
|
3430 |
/* XXX: not complete but not completely erroneous */ |
|
3431 |
if (env->cpu_index != 0 || env->next_cpu != NULL) { |
|
3432 |
/* more than one CPU: do not sleep because another CPU may |
|
3433 |
wake this one */ |
|
3434 |
} else { |
|
3435 |
helper_hlt(); |
|
3436 |
} |
|
3437 |
} |
|
3438 |
|
|
3411 | 3439 |
float approx_rsqrt(float a) |
3412 | 3440 |
{ |
3413 | 3441 |
return 1.0 / sqrt(a); |
b/target-i386/op.c | ||
---|---|---|
614 | 614 |
|
615 | 615 |
void OPPROTO op_hlt(void) |
616 | 616 |
{ |
617 |
env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */ |
|
618 |
env->hflags |= HF_HALTED_MASK; |
|
619 |
env->exception_index = EXCP_HLT; |
|
620 |
cpu_loop_exit(); |
|
617 |
helper_hlt(); |
|
618 |
} |
|
619 |
|
|
620 |
void OPPROTO op_monitor(void) |
|
621 |
{ |
|
622 |
helper_monitor(); |
|
623 |
} |
|
624 |
|
|
625 |
void OPPROTO op_mwait(void) |
|
626 |
{ |
|
627 |
helper_mwait(); |
|
621 | 628 |
} |
622 | 629 |
|
623 | 630 |
void OPPROTO op_debug(void) |
b/target-i386/translate.c | ||
---|---|---|
100 | 100 |
int popl_esp_hack; /* for correct popl with esp base handling */ |
101 | 101 |
int rip_offset; /* only used in x86_64, but left for simplicity */ |
102 | 102 |
int cpuid_features; |
103 |
int cpuid_ext_features; |
|
103 | 104 |
} DisasContext; |
104 | 105 |
|
105 | 106 |
static void gen_eob(DisasContext *s); |
... | ... | |
5567 | 5568 |
modrm = ldub_code(s->pc++); |
5568 | 5569 |
mod = (modrm >> 6) & 3; |
5569 | 5570 |
op = (modrm >> 3) & 7; |
5571 |
rm = modrm & 7; |
|
5570 | 5572 |
switch(op) { |
5571 | 5573 |
case 0: /* sgdt */ |
5572 |
case 1: /* sidt */ |
|
5573 | 5574 |
if (mod == 3) |
5574 | 5575 |
goto illegal_op; |
5575 | 5576 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr); |
5576 |
if (op == 0) |
|
5577 |
gen_op_movl_T0_env(offsetof(CPUX86State,gdt.limit)); |
|
5578 |
else |
|
5579 |
gen_op_movl_T0_env(offsetof(CPUX86State,idt.limit)); |
|
5577 |
gen_op_movl_T0_env(offsetof(CPUX86State, gdt.limit)); |
|
5580 | 5578 |
gen_op_st_T0_A0[OT_WORD + s->mem_index](); |
5581 | 5579 |
gen_add_A0_im(s, 2); |
5582 |
if (op == 0) |
|
5583 |
gen_op_movtl_T0_env(offsetof(CPUX86State,gdt.base)); |
|
5584 |
else |
|
5585 |
gen_op_movtl_T0_env(offsetof(CPUX86State,idt.base)); |
|
5580 |
gen_op_movtl_T0_env(offsetof(CPUX86State, gdt.base)); |
|
5586 | 5581 |
if (!s->dflag) |
5587 | 5582 |
gen_op_andl_T0_im(0xffffff); |
5588 | 5583 |
gen_op_st_T0_A0[CODE64(s) + OT_LONG + s->mem_index](); |
5589 | 5584 |
break; |
5585 |
case 1: |
|
5586 |
if (mod == 3) { |
|
5587 |
switch (rm) { |
|
5588 |
case 0: /* monitor */ |
|
5589 |
if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || |
|
5590 |
s->cpl != 0) |
|
5591 |
goto illegal_op; |
|
5592 |
gen_jmp_im(pc_start - s->cs_base); |
|
5593 |
#ifdef TARGET_X86_64 |
|
5594 |
if (s->aflag == 2) { |
|
5595 |
gen_op_movq_A0_reg[R_EBX](); |
|
5596 |
gen_op_addq_A0_AL(); |
|
5597 |
} else |
|
5598 |
#endif |
|
5599 |
{ |
|
5600 |
gen_op_movl_A0_reg[R_EBX](); |
|
5601 |
gen_op_addl_A0_AL(); |
|
5602 |
if (s->aflag == 0) |
|
5603 |
gen_op_andl_A0_ffff(); |
|
5604 |
} |
|
5605 |
gen_add_A0_ds_seg(s); |
|
5606 |
gen_op_monitor(); |
|
5607 |
break; |
|
5608 |
case 1: /* mwait */ |
|
5609 |
if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || |
|
5610 |
s->cpl != 0) |
|
5611 |
goto illegal_op; |
|
5612 |
if (s->cc_op != CC_OP_DYNAMIC) { |
|
5613 |
gen_op_set_cc_op(s->cc_op); |
|
5614 |
s->cc_op = CC_OP_DYNAMIC; |
|
5615 |
} |
|
5616 |
gen_jmp_im(s->pc - s->cs_base); |
|
5617 |
gen_op_mwait(); |
|
5618 |
gen_eob(s); |
|
5619 |
break; |
|
5620 |
default: |
|
5621 |
goto illegal_op; |
|
5622 |
} |
|
5623 |
} else { /* sidt */ |
|
5624 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr); |
|
5625 |
gen_op_movl_T0_env(offsetof(CPUX86State, idt.limit)); |
|
5626 |
gen_op_st_T0_A0[OT_WORD + s->mem_index](); |
|
5627 |
gen_add_A0_im(s, 2); |
|
5628 |
gen_op_movtl_T0_env(offsetof(CPUX86State, idt.base)); |
|
5629 |
if (!s->dflag) |
|
5630 |
gen_op_andl_T0_im(0xffffff); |
|
5631 |
gen_op_st_T0_A0[CODE64(s) + OT_LONG + s->mem_index](); |
|
5632 |
} |
|
5633 |
break; |
|
5590 | 5634 |
case 2: /* lgdt */ |
5591 | 5635 |
case 3: /* lidt */ |
5592 | 5636 |
if (mod == 3) |
... | ... | |
5629 | 5673 |
} else { |
5630 | 5674 |
if (mod == 3) { |
5631 | 5675 |
#ifdef TARGET_X86_64 |
5632 |
if (CODE64(s) && (modrm & 7) == 0) {
|
|
5676 |
if (CODE64(s) && rm == 0) {
|
|
5633 | 5677 |
/* swapgs */ |
5634 | 5678 |
gen_op_movtl_T0_env(offsetof(CPUX86State,segs[R_GS].base)); |
5635 | 5679 |
gen_op_movtl_T1_env(offsetof(CPUX86State,kernelgsbase)); |
... | ... | |
6348 | 6392 |
dc->mem_index = 1 * 4; |
6349 | 6393 |
} |
6350 | 6394 |
dc->cpuid_features = env->cpuid_features; |
6395 |
dc->cpuid_ext_features = env->cpuid_ext_features; |
|
6351 | 6396 |
#ifdef TARGET_X86_64 |
6352 | 6397 |
dc->lma = (flags >> HF_LMA_SHIFT) & 1; |
6353 | 6398 |
dc->code64 = (flags >> HF_CS64_SHIFT) & 1; |
Also available in: Unified diff