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, &reg_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, &reg_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