Revision 367e86e8 op-i386.c

b/op-i386.c
8 8
typedef signed int int32_t;
9 9
typedef signed long long int64_t;
10 10

  
11
#define NULL 0
12

  
11 13
#ifdef __i386__
12 14
register int T0 asm("esi");
13 15
register int T1 asm("ebx");
......
74 76
#include "cpu-i386.h"
75 77

  
76 78
typedef struct CCTable {
77
    int (*compute_c)(void);  /* return the C flag */
78
    int (*compute_z)(void);  /* return the Z flag */
79
    int (*compute_s)(void);  /* return the S flag */
80
    int (*compute_o)(void);  /* return the O flag */
81 79
    int (*compute_all)(void); /* return all the flags */
80
    int (*compute_c)(void);  /* return the C flag */
82 81
} CCTable;
83 82

  
83
extern CCTable cc_table[];
84

  
84 85
uint8_t parity_table[256] = {
85 86
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
86 87
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
......
116 117
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
117 118
};
118 119

  
119
static int compute_eflags_all(void)
120
{
121
    return CC_SRC;
122
}
123

  
124
static int compute_eflags_addb(void)
125
{
126
    int cf, pf, af, zf, sf, of;
127
    int src1, src2;
128
    src1 = CC_SRC;
129
    src2 = CC_DST - CC_SRC;
130
    cf = (uint8_t)CC_DST < (uint8_t)src1;
131
    pf = parity_table[(uint8_t)CC_DST];
132
    af = (CC_DST ^ src1 ^ src2) & 0x10;
133
    zf = ((uint8_t)CC_DST != 0) << 6;
134
    sf = CC_DST & 0x80;
135
    of = ((src1 ^ src2 ^ -1) & (src1 ^ CC_DST) & 0x80) << 4;
136
    return cf | pf | af | zf | sf | of;
137
}
138

  
139
static int compute_eflags_subb(void)
140
{
141
    int cf, pf, af, zf, sf, of;
142
    int src1, src2;
143
    src1 = CC_SRC;
144
    src2 = CC_SRC - CC_DST;
145
    cf = (uint8_t)src1 < (uint8_t)src2;
146
    pf = parity_table[(uint8_t)CC_DST];
147
    af = (CC_DST ^ src1 ^ src2) & 0x10;
148
    zf = ((uint8_t)CC_DST != 0) << 6;
149
    sf = CC_DST & 0x80;
150
    of = ((src1 ^ src2 ^ -1) & (src1 ^ CC_DST) & 0x80) << 4;
151
    return cf | pf | af | zf | sf | of;
152
}
153

  
154
static int compute_eflags_logicb(void)
155
{
156
    cf = 0;
157
    pf = parity_table[(uint8_t)CC_DST];
158
    af = 0;
159
    zf = ((uint8_t)CC_DST != 0) << 6;
160
    sf = CC_DST & 0x80;
161
    of = 0;
162
    return cf | pf | af | zf | sf | of;
163
}
164

  
165
static int compute_eflags_incb(void)
166
{
167
    int cf, pf, af, zf, sf, of;
168
    int src2;
169
    src1 = CC_DST - 1;
170
    src2 = 1;
171
    cf = CC_SRC;
172
    pf = parity_table[(uint8_t)CC_DST];
173
    af = (CC_DST ^ src1 ^ src2) & 0x10;
174
    zf = ((uint8_t)CC_DST != 0) << 6;
175
    sf = CC_DST & 0x80;
176
    of = ((src1 ^ src2 ^ -1) & (src1 ^ CC_DST) & 0x80) << 4;
177
    return cf | pf | af | zf | sf | of;
178
}
179

  
180
static int compute_eflags_decb(void)
181
{
182
    int cf, pf, af, zf, sf, of;
183
    int src1, src2;
184
    src1 = CC_DST + 1;
185
    src2 = 1;
186
    cf = (uint8_t)src1 < (uint8_t)src2;
187
    pf = parity_table[(uint8_t)CC_DST];
188
    af = (CC_DST ^ src1 ^ src2) & 0x10;
189
    zf = ((uint8_t)CC_DST != 0) << 6;
190
    sf = CC_DST & 0x80;
191
    of = ((src1 ^ src2 ^ -1) & (src1 ^ CC_DST) & 0x80) << 4;
192
    return cf | pf | af | zf | sf | of;
193
}
194

  
195
static int compute_eflags_shlb(void)
196
{
197
    cf = CC_SRC;
198
    pf = parity_table[(uint8_t)CC_DST];
199
    af = 0; /* undefined */
200
    zf = ((uint8_t)CC_DST != 0) << 6;
201
    sf = CC_DST & 0x80;
202
    of = 0; /* undefined */
203
    return cf | pf | af | zf | sf | of;
204
}
120
/* modulo 17 table */
121
const uint8_t rclw_table[32] = {
122
    0, 1, 2, 3, 4, 5, 6, 7, 
123
    8, 9,10,11,12,13,14,15,
124
   16, 0, 1, 2, 3, 4, 5, 6,
125
    7, 8, 9,10,11,12,13,14,
126
};
205 127

  
206
static int compute_eflags_shrb(void)
207
{
208
    cf = CC_SRC & 1;
209
    pf = parity_table[(uint8_t)CC_DST];
210
    af = 0; /* undefined */
211
    zf = ((uint8_t)CC_DST != 0) << 6;
212
    sf = CC_DST & 0x80;
213
    of = sf << 4;
214
    return cf | pf | af | zf | sf | of;
215
}
128
/* modulo 9 table */
129
const uint8_t rclb_table[32] = {
130
    0, 1, 2, 3, 4, 5, 6, 7, 
131
    8, 0, 1, 2, 3, 4, 5, 6,
132
    7, 8, 0, 1, 2, 3, 4, 5, 
133
    6, 7, 8, 0, 1, 2, 3, 4,
134
};
216 135

  
217
static int compute_eflags_mul(void)
136
/* n must be a constant to be efficient */
137
static inline int lshift(int x, int n)
218 138
{
219
    cf = (CC_SRC != 0);
220
    pf = 0; /* undefined */
221
    af = 0; /* undefined */
222
    zf = 0; /* undefined */
223
    sf = 0; /* undefined */
224
    of = cf << 11;
225
    return cf | pf | af | zf | sf | of;
139
    if (n >= 0)
140
        return x << n;
141
    else
142
        return x >> (-n);
226 143
}
227
    
228
CTable cc_table[CC_OP_NB] = {
229
    [CC_OP_DYNAMIC] = { NULL, NULL, NULL },
230
    [CC_OP_EFLAGS] = { NULL, NULL, NULL },
231
    
232
};
233 144

  
234 145
/* we define the various pieces of code used by the JIT */
235 146

  
......
365 276
    CC_DST = T0 & T1;
366 277
}
367 278

  
368
/* shifts */
369

  
370
void OPPROTO op_roll_T0_T1_cc(void)
371
{
372
    int count;
373
    count = T1 & 0x1f;
374
    if (count) {
375
        CC_SRC = T0;
376
        T0 = (T0 << count) | (T0 >> (32 - count));
377
        CC_DST = T0;
378
        CC_OP = CC_OP_ROLL;
379
    }
380
}
381

  
382
void OPPROTO op_rolw_T0_T1_cc(void)
383
{
384
    int count;
385
    count = T1 & 0xf;
386
    if (count) {
387
        T0 = T0 & 0xffff;
388
        CC_SRC = T0;
389
        T0 = (T0 << count) | (T0 >> (16 - count));
390
        CC_DST = T0;
391
        CC_OP = CC_OP_ROLW;
392
    }
393
}
394

  
395
void OPPROTO op_rolb_T0_T1_cc(void)
396
{
397
    int count;
398
    count = T1 & 0x7;
399
    if (count) {
400
        T0 = T0 & 0xff;
401
        CC_SRC = T0;
402
        T0 = (T0 << count) | (T0 >> (8 - count));
403
        CC_DST = T0;
404
        CC_OP = CC_OP_ROLB;
405
    }
406
}
407

  
408
void OPPROTO op_rorl_T0_T1_cc(void)
409
{
410
    int count;
411
    count = T1 & 0x1f;
412
    if (count) {
413
        CC_SRC = T0;
414
        T0 = (T0 >> count) | (T0 << (32 - count));
415
        CC_DST = T0;
416
        CC_OP = CC_OP_RORB;
417
    }
418
}
419

  
420
void OPPROTO op_rorw_T0_T1_cc(void)
421
{
422
    int count;
423
    count = T1 & 0xf;
424
    if (count) {
425
        CC_SRC = T0;
426
        T0 = (T0 >> count) | (T0 << (16 - count));
427
        CC_DST = T0;
428
        CC_OP = CC_OP_RORW;
429
    }
430
}
431

  
432
void OPPROTO op_rorb_T0_T1_cc(void)
433
{
434
    int count;
435
    count = T1 & 0x7;
436
    if (count) {
437
        CC_SRC = T0;
438
        T0 = (T0 >> count) | (T0 << (8 - count));
439
        CC_DST = T0;
440
        CC_OP = CC_OP_RORL;
441
    }
442
}
443

  
444
/* modulo 17 table */
445
const uint8_t rclw_table[32] = {
446
    0, 1, 2, 3, 4, 5, 6, 7, 
447
    8, 9,10,11,12,13,14,15,
448
   16, 0, 1, 2, 3, 4, 5, 6,
449
    7, 8, 9,10,11,12,13,14,
450
};
451

  
452
/* modulo 9 table */
453
const uint8_t rclb_table[32] = {
454
    0, 1, 2, 3, 4, 5, 6, 7, 
455
    8, 0, 1, 2, 3, 4, 5, 6,
456
    7, 8, 0, 1, 2, 3, 4, 5, 
457
    6, 7, 8, 0, 1, 2, 3, 4,
458
};
459

  
460
void helper_rcll_T0_T1_cc(void)
461
{
462
    int count, res;
463

  
464
    count = T1 & 0x1f;
465
    if (count) {
466
        CC_SRC = T0;
467
        res = (T0 << count) | (cc_table[CC_OP].compute_c() << (count - 1));
468
        if (count > 1)
469
            res |= T0 >> (33 - count);
470
        T0 = res;
471
        CC_DST = T0 ^ CC_SRC;    /* O is in bit 31 */
472
        CC_SRC >>= (32 - count); /* CC is in bit 0 */
473
        CC_OP = CC_OP_RCLL;
474
    }
475
}
476

  
477
void OPPROTO op_rcll_T0_T1_cc(void)
478
{
479
    helper_rcll_T0_T1_cc();
480
}
481

  
482
void OPPROTO op_rclw_T0_T1_cc(void)
483
{
484
    int count;
485
    count = rclw_table[T1 & 0x1f];
486
    if (count) {
487
        T0 = T0 & 0xffff;
488
        CC_SRC = T0;
489
        T0 = (T0 << count) | (cc_table[CC_OP].compute_c() << (count - 1)) |
490
            (T0 >> (17 - count));
491
        CC_DST = T0 ^ CC_SRC;
492
        CC_SRC >>= (16 - count);
493
        CC_OP = CC_OP_RCLW;
494
    }
495
}
496

  
497
void OPPROTO op_rclb_T0_T1_cc(void)
498
{
499
    int count;
500
    count = rclb_table[T1 & 0x1f];
501
    if (count) {
502
        T0 = T0 & 0xff;
503
        CC_SRC = T0;
504
        T0 = (T0 << count) | (cc_table[CC_OP].compute_c() << (count - 1)) |
505
            (T0 >> (9 - count));
506
        CC_DST = T0 ^ CC_SRC;
507
        CC_SRC >>= (8 - count);
508
        CC_OP = CC_OP_RCLB;
509
    }
510
}
511

  
512
void OPPROTO op_rcrl_T0_T1_cc(void)
513
{
514
    int count, res;
515
    count = T1 & 0x1f;
516
    if (count) {
517
        CC_SRC = T0;
518
        res = (T0 >> count) | (cc_table[CC_OP].compute_c() << (32 - count));
519
        if (count > 1)
520
            res |= T0 << (33 - count);
521
        T0 = res;
522
        CC_DST = T0 ^ CC_SRC;
523
        CC_SRC >>= (count - 1);
524
        CC_OP = CC_OP_RCLL;
525
    }
526
}
527

  
528
void OPPROTO op_rcrw_T0_T1_cc(void)
529
{
530
    int count;
531
    count = rclw_table[T1 & 0x1f];
532
    if (count) {
533
        T0 = T0 & 0xffff;
534
        CC_SRC = T0;
535
        T0 = (T0 >> count) | (cc_table[CC_OP].compute_c() << (16 - count)) |
536
            (T0 << (17 - count));
537
        CC_DST = T0 ^ CC_SRC;
538
        CC_SRC >>= (count - 1);
539
        CC_OP = CC_OP_RCLW;
540
    }
541
}
542

  
543
void OPPROTO op_rcrb_T0_T1_cc(void)
544
{
545
    int count;
546
    count = rclb_table[T1 & 0x1f];
547
    if (count) {
548
        T0 = T0 & 0xff;
549
        CC_SRC = T0;
550
        T0 = (T0 >> count) | (cc_table[CC_OP].compute_c() << (8 - count)) |
551
            (T0 << (9 - count));
552
        CC_DST = T0 ^ CC_SRC;
553
        CC_SRC >>= (count - 1);
554
        CC_OP = CC_OP_RCLB;
555
    }
556
}
557

  
558
void OPPROTO op_shll_T0_T1_cc(void)
559
{
560
    int count;
561
    count = T1 & 0x1f;
562
    if (count == 1) {
563
        CC_SRC = T0;
564
        T0 = T0 << 1;
565
        CC_DST = T0;
566
        CC_OP = CC_OP_ADDL;
567
    } else if (count) {
568
        CC_SRC = T0 >> (32 - count);
569
        T0 = T0 << count;
570
        CC_DST = T0;
571
        CC_OP = CC_OP_SHLL;
572
    }
573
}
574

  
575
void OPPROTO op_shlw_T0_T1_cc(void)
576
{
577
    int count;
578
    count = T1 & 0x1f;
579
    if (count == 1) {
580
        CC_SRC = T0;
581
        T0 = T0 << 1;
582
        CC_DST = T0;
583
        CC_OP = CC_OP_ADDW;
584
    } else if (count) {
585
        CC_SRC = T0 >> (16 - count);
586
        T0 = T0 << count;
587
        CC_DST = T0;
588
        CC_OP = CC_OP_SHLW;
589
    }
590
}
591

  
592
void OPPROTO op_shlb_T0_T1_cc(void)
593
{
594
    int count;
595
    count = T1 & 0x1f;
596
    if (count == 1) {
597
        CC_SRC = T0;
598
        T0 = T0 << 1;
599
        CC_DST = T0;
600
        CC_OP = CC_OP_ADDB;
601
    } else if (count) {
602
        CC_SRC = T0 >> (8 - count);
603
        T0 = T0 << count;
604
        CC_DST = T0;
605
        CC_OP = CC_OP_SHLB;
606
    }
607
}
608

  
609
void OPPROTO op_shrl_T0_T1_cc(void)
610
{
611
    int count;
612
    count = T1 & 0x1f;
613
    if (count == 1) {
614
        CC_SRC = T0;
615
        T0 = T0 >> 1;
616
        CC_DST = T0;
617
        CC_OP = CC_OP_SHRL;
618
    } else if (count) {
619
        CC_SRC = T0 >> (count - 1);
620
        T0 = T0 >> count;
621
        CC_DST = T0;
622
        CC_OP = CC_OP_SHLL;
623
    }
624
}
625

  
626
void OPPROTO op_shrw_T0_T1_cc(void)
627
{
628
    int count;
629
    count = T1 & 0x1f;
630
    if (count == 1) {
631
        T0 = T0 & 0xffff;
632
        CC_SRC = T0;
633
        T0 = T0 >> 1;
634
        CC_DST = T0;
635
        CC_OP = CC_OP_SHRW;
636
    } else if (count) {
637
        T0 = T0 & 0xffff;
638
        CC_SRC = T0 >> (count - 1);
639
        T0 = T0 >> count;
640
        CC_DST = T0;
641
        CC_OP = CC_OP_SHLW;
642
    }
643
}
644

  
645
void OPPROTO op_shrb_T0_T1_cc(void)
646
{
647
    int count;
648
    count = T1 & 0x1f;
649
    if (count == 1) {
650
        T0 = T0 & 0xff;
651
        CC_SRC = T0;
652
        T0 = T0 >> 1;
653
        CC_DST = T0;
654
        CC_OP = CC_OP_SHRB;
655
    } else if (count) {
656
        T0 = T0 & 0xff;
657
        CC_SRC = T0 >> (count - 1);
658
        T0 = T0 >> count;
659
        CC_DST = T0;
660
        CC_OP = CC_OP_SHLB;
661
    }
662
}
663

  
664
void OPPROTO op_sarl_T0_T1_cc(void)
665
{
666
    int count;
667
    count = T1 & 0x1f;
668
    if (count) {
669
        CC_SRC = (int32_t)T0 >> (count - 1);
670
        T0 = (int32_t)T0 >> count;
671
        CC_DST = T0;
672
        CC_OP = CC_OP_SHLL;
673
    }
674
}
675

  
676
void OPPROTO op_sarw_T0_T1_cc(void)
677
{
678
    int count;
679
    count = T1 & 0x1f;
680
    if (count) {
681
        CC_SRC = (int16_t)T0 >> (count - 1);
682
        T0 = (int16_t)T0 >> count;
683
        CC_DST = T0;
684
        CC_OP = CC_OP_SHLW;
685
    }
686
}
687

  
688
void OPPROTO op_sarb_T0_T1_cc(void)
689
{
690
    int count;
691
    count = T1 & 0x1f;
692
    if (count) {
693
        CC_SRC = (int8_t)T0 >> (count - 1);
694
        T0 = (int8_t)T0 >> count;
695
        CC_DST = T0;
696
        CC_OP = CC_OP_SHLB;
697
    }
698
}
699

  
700 279
/* multiply/divide */
701 280
void OPPROTO op_mulb_AL_T0(void)
702 281
{
......
924 503
    stl((uint8_t *)A0, T0);
925 504
}
926 505

  
927
/* flags */
928

  
929
void OPPROTO op_set_cc_op(void)
930
{
931
    CC_OP = PARAM1;
932
}
933

  
934
void OPPROTO op_movl_eflags_T0(void)
935
{
936
    CC_SRC = T0;
937
    DF = (T0 & DIRECTION_FLAG) ? -1 : 1;
938
}
939

  
940
void OPPROTO op_movb_eflags_T0(void)
941
{
942
    int cc_o;
943
    cc_o = cc_table[CC_OP].compute_o();
944
    CC_SRC = T0 | (cc_o << 11);
945
}
946

  
947
void OPPROTO op_movl_T0_eflags(void)
948
{
949
    cc_table[CC_OP].compute_eflags();
950
}
951

  
952
void OPPROTO op_cld(void)
953
{
954
    DF = 1;
955
}
956

  
957
void OPPROTO op_std(void)
958
{
959
    DF = -1;
960
}
961

  
962 506
/* jumps */
963 507

  
964 508
/* indirect jump */
......
972 516
    PC = PARAM1;
973 517
}
974 518

  
975
void OPPROTO op_jne_b(void)
976
{
977
    if ((uint8_t)CC_DST != 0)
978
        PC += PARAM1;
979
    else
980
        PC += PARAM2;
981
    FORCE_RET();
982
}
983

  
984
void OPPROTO op_jne_w(void)
985
{
986
    if ((uint16_t)CC_DST != 0)
987
        PC += PARAM1;
988
    else
989
        PC += PARAM2;
990
    FORCE_RET();
991
}
992

  
993
void OPPROTO op_jne_l(void)
994
{
995
    if (CC_DST != 0)
996
        PC += PARAM1;
997
    else
998
        PC += PARAM2;
999
    FORCE_RET(); /* generate a return so that gcc does not generate an
1000
                    early function return */
1001
}
1002

  
1003 519
/* string ops */
1004 520

  
1005 521
#define ldul ldl
1006 522

  
1007
#define SUFFIX b
1008 523
#define SHIFT 0
1009
#include "opstring_template.h"
1010
#undef SUFFIX
524
#include "ops_template.h"
1011 525
#undef SHIFT
1012 526

  
1013
#define SUFFIX w
1014 527
#define SHIFT 1
1015
#include "opstring_template.h"
1016
#undef SUFFIX
528
#include "ops_template.h"
1017 529
#undef SHIFT
1018 530

  
1019
#define SUFFIX l
1020 531
#define SHIFT 2
1021
#include "opstring_template.h"
1022
#undef SUFFIX
532
#include "ops_template.h"
1023 533
#undef SHIFT
1024 534

  
1025 535
/* sign extend */
......
1095 605
{
1096 606
    ESP += PARAM1;
1097 607
}
608

  
609
/* flags handling */
610

  
611
/* slow jumps cases (compute x86 flags) */
612
void OPPROTO op_jo_cc(void)
613
{
614
    int eflags;
615
    eflags = cc_table[CC_OP].compute_all();
616
    if (eflags & CC_O)
617
        PC += PARAM1;
618
    else
619
        PC += PARAM2;
620
}
621

  
622
void OPPROTO op_jb_cc(void)
623
{
624
    if (cc_table[CC_OP].compute_c())
625
        PC += PARAM1;
626
    else
627
        PC += PARAM2;
628
}
629

  
630
void OPPROTO op_jz_cc(void)
631
{
632
    int eflags;
633
    eflags = cc_table[CC_OP].compute_all();
634
    if (eflags & CC_Z)
635
        PC += PARAM1;
636
    else
637
        PC += PARAM2;
638
}
639

  
640
void OPPROTO op_jbe_cc(void)
641
{
642
    int eflags;
643
    eflags = cc_table[CC_OP].compute_all();
644
    if (eflags & (CC_Z | CC_C))
645
        PC += PARAM1;
646
    else
647
        PC += PARAM2;
648
}
649

  
650
void OPPROTO op_js_cc(void)
651
{
652
    int eflags;
653
    eflags = cc_table[CC_OP].compute_all();
654
    if (eflags & CC_S)
655
        PC += PARAM1;
656
    else
657
        PC += PARAM2;
658
}
659

  
660
void OPPROTO op_jp_cc(void)
661
{
662
    int eflags;
663
    eflags = cc_table[CC_OP].compute_all();
664
    if (eflags & CC_P)
665
        PC += PARAM1;
666
    else
667
        PC += PARAM2;
668
}
669

  
670
void OPPROTO op_jl_cc(void)
671
{
672
    int eflags;
673
    eflags = cc_table[CC_OP].compute_all();
674
    if ((eflags ^ (eflags >> 4)) & 0x80)
675
        PC += PARAM1;
676
    else
677
        PC += PARAM2;
678
}
679

  
680
void OPPROTO op_jle_cc(void)
681
{
682
    int eflags;
683
    eflags = cc_table[CC_OP].compute_all();
684
    if (((eflags ^ (eflags >> 4)) & 0x80) || (eflags & CC_Z))
685
        PC += PARAM1;
686
    else
687
        PC += PARAM2;
688
}
689

  
690
/* slow set cases (compute x86 flags) */
691
void OPPROTO op_seto_T0_cc(void)
692
{
693
    int eflags;
694
    eflags = cc_table[CC_OP].compute_all();
695
    T0 = (eflags >> 11) & 1;
696
}
697

  
698
void OPPROTO op_setb_T0_cc(void)
699
{
700
    T0 = cc_table[CC_OP].compute_c();
701
}
702

  
703
void OPPROTO op_setz_T0_cc(void)
704
{
705
    int eflags;
706
    eflags = cc_table[CC_OP].compute_all();
707
    T0 = (eflags >> 6) & 1;
708
}
709

  
710
void OPPROTO op_setbe_T0_cc(void)
711
{
712
    int eflags;
713
    eflags = cc_table[CC_OP].compute_all();
714
    T0 = (eflags & (CC_Z | CC_C)) != 0;
715
}
716

  
717
void OPPROTO op_sets_T0_cc(void)
718
{
719
    int eflags;
720
    eflags = cc_table[CC_OP].compute_all();
721
    T0 = (eflags >> 7) & 1;
722
}
723

  
724
void OPPROTO op_setp_T0_cc(void)
725
{
726
    int eflags;
727
    eflags = cc_table[CC_OP].compute_all();
728
    T0 = (eflags >> 2) & 1;
729
}
730

  
731
void OPPROTO op_setl_T0_cc(void)
732
{
733
    int eflags;
734
    eflags = cc_table[CC_OP].compute_all();
735
    T0 = ((eflags ^ (eflags >> 4)) >> 7) & 1;
736
}
737

  
738
void OPPROTO op_setle_T0_cc(void)
739
{
740
    int eflags;
741
    eflags = cc_table[CC_OP].compute_all();
742
    T0 = (((eflags ^ (eflags >> 4)) & 0x80) || (eflags & CC_Z)) != 0;
743
}
744

  
745
void OPPROTO op_xor_T0_1(void)
746
{
747
    T0 ^= 1;
748
}
749

  
750
void OPPROTO op_set_cc_op(void)
751
{
752
    CC_OP = PARAM1;
753
}
754

  
755
void OPPROTO op_movl_eflags_T0(void)
756
{
757
    CC_SRC = T0;
758
    DF = 1 - (2 * ((T0 >> 10) & 1));
759
}
760

  
761
/* XXX: compute only O flag */
762
void OPPROTO op_movb_eflags_T0(void)
763
{
764
    int of;
765
    of = cc_table[CC_OP].compute_all() & CC_O;
766
    CC_SRC = T0 | of;
767
}
768

  
769
void OPPROTO op_movl_T0_eflags(void)
770
{
771
    T0 = cc_table[CC_OP].compute_all();
772
    T0 |= (DF & DIRECTION_FLAG);
773
}
774

  
775
void OPPROTO op_cld(void)
776
{
777
    DF = 1;
778
}
779

  
780
void OPPROTO op_std(void)
781
{
782
    DF = -1;
783
}
784

  
785
void OPPROTO op_clc(void)
786
{
787
    int eflags;
788
    eflags = cc_table[CC_OP].compute_all();
789
    eflags &= ~CC_C;
790
    CC_SRC = eflags;
791
}
792

  
793
void OPPROTO op_stc(void)
794
{
795
    int eflags;
796
    eflags = cc_table[CC_OP].compute_all();
797
    eflags |= CC_C;
798
    CC_SRC = eflags;
799
}
800

  
801
void OPPROTO op_cmc(void)
802
{
803
    int eflags;
804
    eflags = cc_table[CC_OP].compute_all();
805
    eflags ^= CC_C;
806
    CC_SRC = eflags;
807
}
808

  
809
static int compute_all_eflags(void)
810
{
811
    return CC_SRC;
812
}
813

  
814
static int compute_c_eflags(void)
815
{
816
    return CC_SRC & CC_C;
817
}
818

  
819
static int compute_c_mul(void)
820
{
821
    int cf;
822
    cf = (CC_SRC != 0);
823
    return cf;
824
}
825

  
826
static int compute_all_mul(void)
827
{
828
    int cf, pf, af, zf, sf, of;
829
    cf = (CC_SRC != 0);
830
    pf = 0; /* undefined */
831
    af = 0; /* undefined */
832
    zf = 0; /* undefined */
833
    sf = 0; /* undefined */
834
    of = cf << 11;
835
    return cf | pf | af | zf | sf | of;
836
}
837
    
838
CCTable cc_table[CC_OP_NB] = {
839
    [CC_OP_DYNAMIC] = { /* should never happen */ },
840

  
841
    [CC_OP_EFLAGS] = { compute_all_eflags, compute_c_eflags },
842

  
843
    [CC_OP_MUL] = { compute_all_mul, compute_c_mul },
844

  
845
    [CC_OP_ADDB] = { compute_all_addb, compute_c_addb },
846
    [CC_OP_ADDW] = { compute_all_addw, compute_c_addw  },
847
    [CC_OP_ADDL] = { compute_all_addl, compute_c_addl  },
848

  
849
    [CC_OP_SUBB] = { compute_all_subb, compute_c_subb  },
850
    [CC_OP_SUBW] = { compute_all_subw, compute_c_subw  },
851
    [CC_OP_SUBL] = { compute_all_subl, compute_c_subl  },
852
    
853
    [CC_OP_LOGICB] = { compute_all_logicb, compute_c_logicb },
854
    [CC_OP_LOGICW] = { compute_all_logicw, compute_c_logicw },
855
    [CC_OP_LOGICL] = { compute_all_logicl, compute_c_logicl },
856
    
857
    [CC_OP_INCB] = { compute_all_incb, compute_c_incb },
858
    [CC_OP_INCW] = { compute_all_incw, compute_c_incw },
859
    [CC_OP_INCL] = { compute_all_incl, compute_c_incl },
860
    
861
    [CC_OP_DECB] = { compute_all_decb, compute_c_incb },
862
    [CC_OP_DECW] = { compute_all_decw, compute_c_incw },
863
    [CC_OP_DECL] = { compute_all_decl, compute_c_incl },
864
    
865
    [CC_OP_SHLB] = { compute_all_shlb, compute_c_shlb },
866
    [CC_OP_SHLW] = { compute_all_shlw, compute_c_shlw },
867
    [CC_OP_SHLL] = { compute_all_shll, compute_c_shll },
868
};

Also available in: Unified diff