Revision bd7a7b33

b/target-i386/TODO
1 1
Correctness issues:
2 2

  
3
- some eflags manipulation incorrectly reset the bit 0x2.
3 4
- rework eflags optimization (will be a consequence of TCG port)
4 5
- SVM: rework the implementation: simplify code, move most intercept
5 6
  tests as dynamic, correct segment access, verify exception safety,
b/target-i386/helper.c
108 108
    spin_unlock(&global_cpu_lock);
109 109
}
110 110

  
111
void helper_write_eflags(target_ulong t0, uint32_t update_mask)
112
{
113
    load_eflags(t0, update_mask);
114
}
115

  
116
target_ulong helper_read_eflags(void)
117
{
118
    uint32_t eflags;
119
    eflags = cc_table[CC_OP].compute_all();
120
    eflags |= (DF & DF_MASK);
121
    eflags |= env->eflags & ~(VM_MASK | RF_MASK);
122
    return eflags;
123
}
124

  
111 125
/* return non zero if error */
112 126
static inline int load_segment(uint32_t *e1_ptr, uint32_t *e2_ptr,
113 127
                               int selector)
b/target-i386/helper.h
2 2

  
3 3
void helper_lock(void);
4 4
void helper_unlock(void);
5
void helper_write_eflags(target_ulong t0, uint32_t update_mask);
6
target_ulong helper_read_eflags(void);
5 7
void helper_divb_AL(target_ulong t0);
6 8
void helper_idivb_AL(target_ulong t0);
7 9
void helper_divw_AX(target_ulong t0);
b/target-i386/op.c
255 255
{
256 256
    T0 ^= 1;
257 257
}
258

  
259
/* XXX: clear VIF/VIP in all ops ? */
260

  
261
void OPPROTO op_movl_eflags_T0(void)
262
{
263
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK));
264
}
265

  
266
void OPPROTO op_movw_eflags_T0(void)
267
{
268
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK) & 0xffff);
269
}
270

  
271
void OPPROTO op_movl_eflags_T0_io(void)
272
{
273
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK));
274
}
275

  
276
void OPPROTO op_movw_eflags_T0_io(void)
277
{
278
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK) & 0xffff);
279
}
280

  
281
void OPPROTO op_movl_eflags_T0_cpl0(void)
282
{
283
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK));
284
}
285

  
286
void OPPROTO op_movw_eflags_T0_cpl0(void)
287
{
288
    load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK) & 0xffff);
289
}
290

  
291
#if 0
292
/* vm86plus version */
293
void OPPROTO op_movw_eflags_T0_vm(void)
294
{
295
    int eflags;
296
    eflags = T0;
297
    CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
298
    DF = 1 - (2 * ((eflags >> 10) & 1));
299
    /* we also update some system flags as in user mode */
300
    env->eflags = (env->eflags & ~(FL_UPDATE_MASK16 | VIF_MASK)) |
301
        (eflags & FL_UPDATE_MASK16);
302
    if (eflags & IF_MASK) {
303
        env->eflags |= VIF_MASK;
304
        if (env->eflags & VIP_MASK) {
305
            EIP = PARAM1;
306
            raise_exception(EXCP0D_GPF);
307
        }
308
    }
309
    FORCE_RET();
310
}
311

  
312
void OPPROTO op_movl_eflags_T0_vm(void)
313
{
314
    int eflags;
315
    eflags = T0;
316
    CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
317
    DF = 1 - (2 * ((eflags >> 10) & 1));
318
    /* we also update some system flags as in user mode */
319
    env->eflags = (env->eflags & ~(FL_UPDATE_MASK32 | VIF_MASK)) |
320
        (eflags & FL_UPDATE_MASK32);
321
    if (eflags & IF_MASK) {
322
        env->eflags |= VIF_MASK;
323
        if (env->eflags & VIP_MASK) {
324
            EIP = PARAM1;
325
            raise_exception(EXCP0D_GPF);
326
        }
327
    }
328
    FORCE_RET();
329
}
330
#endif
331

  
332
/* XXX: compute only O flag */
333
void OPPROTO op_movb_eflags_T0(void)
334
{
335
    int of;
336
    of = cc_table[CC_OP].compute_all() & CC_O;
337
    CC_SRC = (T0 & (CC_S | CC_Z | CC_A | CC_P | CC_C)) | of;
338
}
339

  
340
void OPPROTO op_movl_T0_eflags(void)
341
{
342
    int eflags;
343
    eflags = cc_table[CC_OP].compute_all();
344
    eflags |= (DF & DF_MASK);
345
    eflags |= env->eflags & ~(VM_MASK | RF_MASK);
346
    T0 = eflags;
347
}
348

  
349
/* vm86plus version */
350
#if 0
351
void OPPROTO op_movl_T0_eflags_vm(void)
352
{
353
    int eflags;
354
    eflags = cc_table[CC_OP].compute_all();
355
    eflags |= (DF & DF_MASK);
356
    eflags |= env->eflags & ~(VM_MASK | RF_MASK | IF_MASK);
357
    if (env->eflags & VIF_MASK)
358
        eflags |= IF_MASK;
359
    T0 = eflags;
360
}
361
#endif
362

  
363
void OPPROTO op_clc(void)
364
{
365
    int eflags;
366
    eflags = cc_table[CC_OP].compute_all();
367
    eflags &= ~CC_C;
368
    CC_SRC = eflags;
369
}
370

  
371
void OPPROTO op_stc(void)
372
{
373
    int eflags;
374
    eflags = cc_table[CC_OP].compute_all();
375
    eflags |= CC_C;
376
    CC_SRC = eflags;
377
}
378

  
379
void OPPROTO op_cmc(void)
380
{
381
    int eflags;
382
    eflags = cc_table[CC_OP].compute_all();
383
    eflags ^= CC_C;
384
    CC_SRC = eflags;
385
}
386

  
387
void OPPROTO op_salc(void)
388
{
389
    int cf;
390
    cf = cc_table[CC_OP].compute_c();
391
    EAX = (EAX & ~0xff) | ((-cf) & 0xff);
392
}
b/target-i386/translate.c
5733 5733
        } else {
5734 5734
            if (s->cc_op != CC_OP_DYNAMIC)
5735 5735
                gen_op_set_cc_op(s->cc_op);
5736
            gen_op_movl_T0_eflags();
5736
            tcg_gen_helper_1_0(helper_read_eflags, cpu_T[0]);
5737 5737
            gen_push_T0(s);
5738 5738
        }
5739 5739
        break;
......
5746 5746
            gen_pop_T0(s);
5747 5747
            if (s->cpl == 0) {
5748 5748
                if (s->dflag) {
5749
                    gen_op_movl_eflags_T0_cpl0();
5749
                    tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
5750
                                       tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK)));
5750 5751
                } else {
5751
                    gen_op_movw_eflags_T0_cpl0();
5752
                    tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
5753
                                       tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK) & 0xffff));
5752 5754
                }
5753 5755
            } else {
5754 5756
                if (s->cpl <= s->iopl) {
5755 5757
                    if (s->dflag) {
5756
                        gen_op_movl_eflags_T0_io();
5758
                        tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
5759
                                           tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK)));
5757 5760
                    } else {
5758
                        gen_op_movw_eflags_T0_io();
5761
                        tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
5762
                                           tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK) & 0xffff));
5759 5763
                    }
5760 5764
                } else {
5761 5765
                    if (s->dflag) {
5762
                        gen_op_movl_eflags_T0();
5766
                        tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
5767
                                           tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK)));
5763 5768
                    } else {
5764
                        gen_op_movw_eflags_T0();
5769
                        tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
5770
                                           tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK) & 0xffff));
5765 5771
                    }
5766 5772
                }
5767 5773
            }
......
5778 5784
        gen_op_mov_TN_reg(OT_BYTE, 0, R_AH);
5779 5785
        if (s->cc_op != CC_OP_DYNAMIC)
5780 5786
            gen_op_set_cc_op(s->cc_op);
5781
        gen_op_movb_eflags_T0();
5787
        gen_compute_eflags(cpu_cc_src);
5788
        tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
5789
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], CC_S | CC_Z | CC_A | CC_P | CC_C);
5790
        tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T[0]);
5782 5791
        s->cc_op = CC_OP_EFLAGS;
5783 5792
        break;
5784 5793
    case 0x9f: /* lahf */
......
5786 5795
            goto illegal_op;
5787 5796
        if (s->cc_op != CC_OP_DYNAMIC)
5788 5797
            gen_op_set_cc_op(s->cc_op);
5789
        gen_op_movl_T0_eflags();
5798
        gen_compute_eflags(cpu_T[0]);
5799
        /* Note: gen_compute_eflags() only gives the condition codes */
5800
        tcg_gen_ori_tl(cpu_T[0], cpu_T[0], 0x02);
5790 5801
        gen_op_mov_reg_T0(OT_BYTE, R_AH);
5791 5802
        break;
5792 5803
    case 0xf5: /* cmc */
5793 5804
        if (s->cc_op != CC_OP_DYNAMIC)
5794 5805
            gen_op_set_cc_op(s->cc_op);
5795
        gen_op_cmc();
5806
        gen_compute_eflags(cpu_cc_src);
5807
        tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
5796 5808
        s->cc_op = CC_OP_EFLAGS;
5797 5809
        break;
5798 5810
    case 0xf8: /* clc */
5799 5811
        if (s->cc_op != CC_OP_DYNAMIC)
5800 5812
            gen_op_set_cc_op(s->cc_op);
5801
        gen_op_clc();
5813
        gen_compute_eflags(cpu_cc_src);
5814
        tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
5802 5815
        s->cc_op = CC_OP_EFLAGS;
5803 5816
        break;
5804 5817
    case 0xf9: /* stc */
5805 5818
        if (s->cc_op != CC_OP_DYNAMIC)
5806 5819
            gen_op_set_cc_op(s->cc_op);
5807
        gen_op_stc();
5820
        gen_compute_eflags(cpu_cc_src);
5821
        tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
5808 5822
        s->cc_op = CC_OP_EFLAGS;
5809 5823
        break;
5810 5824
    case 0xfc: /* cld */
......
6127 6141
            goto illegal_op;
6128 6142
        if (s->cc_op != CC_OP_DYNAMIC)
6129 6143
            gen_op_set_cc_op(s->cc_op);
6130
        gen_op_salc();
6144
        gen_compute_eflags_c(cpu_T[0]);
6145
        tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
6146
        gen_op_mov_reg_T0(OT_BYTE, R_EAX);
6131 6147
        break;
6132 6148
    case 0xe0: /* loopnz */
6133 6149
    case 0xe1: /* loopz */

Also available in: Unified diff