Revision 4b74fe1f ops_template.h

b/ops_template.h
33 33
    cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
34 34
    pf = parity_table[(uint8_t)CC_DST];
35 35
    af = (CC_DST ^ src1 ^ src2) & 0x10;
36
    zf = ((DATA_TYPE)CC_DST != 0) << 6;
36
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
37 37
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
38 38
    of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
39 39
    return cf | pf | af | zf | sf | of;
......
47 47
    return cf;
48 48
}
49 49

  
50
static int glue(compute_all_adc, SUFFIX)(void)
51
{
52
    int cf, pf, af, zf, sf, of;
53
    int src1, src2;
54
    src1 = CC_SRC;
55
    src2 = CC_DST - CC_SRC - 1;
56
    cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
57
    pf = parity_table[(uint8_t)CC_DST];
58
    af = (CC_DST ^ src1 ^ src2) & 0x10;
59
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
60
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
61
    of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
62
    return cf | pf | af | zf | sf | of;
63
}
64

  
65
static int glue(compute_c_adc, SUFFIX)(void)
66
{
67
    int src1, cf;
68
    src1 = CC_SRC;
69
    cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
70
    return cf;
71
}
72

  
50 73
static int glue(compute_all_sub, SUFFIX)(void)
51 74
{
52 75
    int cf, pf, af, zf, sf, of;
......
56 79
    cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
57 80
    pf = parity_table[(uint8_t)CC_DST];
58 81
    af = (CC_DST ^ src1 ^ src2) & 0x10;
59
    zf = ((DATA_TYPE)CC_DST != 0) << 6;
82
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
60 83
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
61
    of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
84
    of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
62 85
    return cf | pf | af | zf | sf | of;
63 86
}
64 87

  
......
67 90
    int src1, src2, cf;
68 91
    src1 = CC_SRC;
69 92
    src2 = CC_SRC - CC_DST;
70
    cf = (DATA_TYPE)src1 < (DATA_TYPE)src1;
93
    cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
94
    return cf;
95
}
96

  
97
static int glue(compute_all_sbb, SUFFIX)(void)
98
{
99
    int cf, pf, af, zf, sf, of;
100
    int src1, src2;
101
    src1 = CC_SRC;
102
    src2 = CC_SRC - CC_DST - 1;
103
    cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
104
    pf = parity_table[(uint8_t)CC_DST];
105
    af = (CC_DST ^ src1 ^ src2) & 0x10;
106
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
107
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
108
    of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
109
    return cf | pf | af | zf | sf | of;
110
}
111

  
112
static int glue(compute_c_sbb, SUFFIX)(void)
113
{
114
    int src1, src2, cf;
115
    src1 = CC_SRC;
116
    src2 = CC_SRC - CC_DST - 1;
117
    cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
71 118
    return cf;
72 119
}
73 120

  
......
77 124
    cf = 0;
78 125
    pf = parity_table[(uint8_t)CC_DST];
79 126
    af = 0;
80
    zf = ((DATA_TYPE)CC_DST != 0) << 6;
127
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
81 128
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
82 129
    of = 0;
83 130
    return cf | pf | af | zf | sf | of;
......
97 144
    cf = CC_SRC;
98 145
    pf = parity_table[(uint8_t)CC_DST];
99 146
    af = (CC_DST ^ src1 ^ src2) & 0x10;
100
    zf = ((DATA_TYPE)CC_DST != 0) << 6;
147
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
101 148
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
102
    of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
149
    of = ((CC_DST & DATA_MASK) == SIGN_MASK) << 11;
103 150
    return cf | pf | af | zf | sf | of;
104 151
}
105 152

  
153
#if DATA_BITS == 32
106 154
static int glue(compute_c_inc, SUFFIX)(void)
107 155
{
108 156
    return CC_SRC;
109 157
}
158
#endif
110 159

  
111 160
static int glue(compute_all_dec, SUFFIX)(void)
112 161
{
......
117 166
    cf = CC_SRC;
118 167
    pf = parity_table[(uint8_t)CC_DST];
119 168
    af = (CC_DST ^ src1 ^ src2) & 0x10;
120
    zf = ((DATA_TYPE)CC_DST != 0) << 6;
169
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
121 170
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
122
    of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
171
    of = ((CC_DST & DATA_MASK) == ((uint32_t)SIGN_MASK - 1)) << 11;
123 172
    return cf | pf | af | zf | sf | of;
124 173
}
125 174

  
......
129 178
    cf = CC_SRC & 1;
130 179
    pf = parity_table[(uint8_t)CC_DST];
131 180
    af = 0; /* undefined */
132
    zf = ((DATA_TYPE)CC_DST != 0) << 6;
181
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
133 182
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
134
    of = sf << 4; /* only meaniful for shr with count == 1 */
183
    of = lshift(CC_SRC, 12 - DATA_BITS) & CC_O; /* only meaniful for shr with count == 1 */
135 184
    return cf | pf | af | zf | sf | of;
136 185
}
137 186

  
187
#if DATA_BITS == 32
138 188
static int glue(compute_c_shl, SUFFIX)(void)
139 189
{
140 190
    return CC_SRC & 1;
141 191
}
192
#endif
193

  
194
static int glue(compute_all_sar, SUFFIX)(void)
195
{
196
    int cf, pf, af, zf, sf, of;
197
    cf = CC_SRC & 1;
198
    pf = parity_table[(uint8_t)CC_DST];
199
    af = 0; /* undefined */
200
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
201
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
202
    of = 0; /* only meaniful for shr with count == 1 */
203
    return cf | pf | af | zf | sf | of;
204
}
142 205

  
143 206
/* various optimized jumps cases */
144 207

  
......
157 220

  
158 221
void OPPROTO glue(op_jz_sub, SUFFIX)(void)
159 222
{
160
    if ((DATA_TYPE)CC_DST != 0)
223
    if ((DATA_TYPE)CC_DST == 0)
161 224
        PC = PARAM1;
162 225
    else
163 226
        PC = PARAM2;
......
225 288

  
226 289
void OPPROTO glue(op_setz_T0_sub, SUFFIX)(void)
227 290
{
228
    T0 = ((DATA_TYPE)CC_DST != 0);
291
    T0 = ((DATA_TYPE)CC_DST == 0);
229 292
}
230 293

  
231 294
void OPPROTO glue(op_setbe_T0_sub, SUFFIX)(void)
......
275 338
            (T0 & CC_C);
276 339
        CC_OP = CC_OP_EFLAGS;
277 340
    }
341
    FORCE_RET();
278 342
}
279 343

  
280 344
void OPPROTO glue(glue(op_ror, SUFFIX), _T0_T1_cc)(void)
......
290 354
            ((T0 >> (DATA_BITS - 1)) & CC_C);
291 355
        CC_OP = CC_OP_EFLAGS;
292 356
    }
357
    FORCE_RET();
293 358
}
294 359

  
295 360
void OPPROTO glue(glue(op_rcl, SUFFIX), _T0_T1_cc)(void)
......
305 370
#endif
306 371
    if (count) {
307 372
        eflags = cc_table[CC_OP].compute_all();
373
        T0 &= DATA_MASK;
308 374
        src = T0;
309 375
        res = (T0 << count) | ((eflags & CC_C) << (count - 1));
310 376
        if (count > 1)
......
315 381
            ((src >> (DATA_BITS - count)) & CC_C);
316 382
        CC_OP = CC_OP_EFLAGS;
317 383
    }
384
    FORCE_RET();
318 385
}
319 386

  
320 387
void OPPROTO glue(glue(op_rcr, SUFFIX), _T0_T1_cc)(void)
......
330 397
#endif
331 398
    if (count) {
332 399
        eflags = cc_table[CC_OP].compute_all();
400
        T0 &= DATA_MASK;
333 401
        src = T0;
334 402
        res = (T0 >> count) | ((eflags & CC_C) << (DATA_BITS - count));
335 403
        if (count > 1)
......
340 408
            ((src >> (count - 1)) & CC_C);
341 409
        CC_OP = CC_OP_EFLAGS;
342 410
    }
411
    FORCE_RET();
343 412
}
344 413

  
345 414
void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1_cc)(void)
......
352 421
        CC_DST = T0;
353 422
        CC_OP = CC_OP_ADDB + SHIFT;
354 423
    } else if (count) {
355
        CC_SRC = T0 >> (DATA_BITS - count);
424
        CC_SRC = (DATA_TYPE)T0 >> (DATA_BITS - count);
356 425
        T0 = T0 << count;
357 426
        CC_DST = T0;
358 427
        CC_OP = CC_OP_SHLB + SHIFT;
359 428
    }
429
    FORCE_RET();
360 430
}
361 431

  
362 432
void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1_cc)(void)
......
370 440
        CC_DST = T0;
371 441
        CC_OP = CC_OP_SHLB + SHIFT;
372 442
    }
443
    FORCE_RET();
373 444
}
374 445

  
375 446
void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1_cc)(void)
......
381 452
        CC_SRC =  src >> (count - 1);
382 453
        T0 = src >> count;
383 454
        CC_DST = T0;
384
        CC_OP = CC_OP_SHLB + SHIFT;
455
        CC_OP = CC_OP_SARB + SHIFT;
385 456
    }
457
    FORCE_RET();
386 458
}
387 459

  
460
/* carry add/sub (we only need to set CC_OP differently) */
461

  
462
void OPPROTO glue(glue(op_adc, SUFFIX), _T0_T1_cc)(void)
463
{
464
    int cf;
465
    cf = cc_table[CC_OP].compute_c();
466
    CC_SRC = T0;
467
    T0 = T0 + T1 + cf;
468
    CC_DST = T0;
469
    CC_OP = CC_OP_ADDB + SHIFT + cf * 3;
470
}
471

  
472
void OPPROTO glue(glue(op_sbb, SUFFIX), _T0_T1_cc)(void)
473
{
474
    int cf;
475
    cf = cc_table[CC_OP].compute_c();
476
    CC_SRC = T0;
477
    T0 = T0 - T1 - cf;
478
    CC_DST = T0;
479
    CC_OP = CC_OP_SUBB + SHIFT + cf * 3;
480
}
481

  
482
/* bit operations */
483
#if DATA_BITS >= 16
484

  
485
void OPPROTO glue(glue(op_bt, SUFFIX), _T0_T1_cc)(void)
486
{
487
    int count;
488
    count = T1 & SHIFT_MASK;
489
    CC_SRC = T0 >> count;
490
}
491

  
492
void OPPROTO glue(glue(op_bts, SUFFIX), _T0_T1_cc)(void)
493
{
494
    int count;
495
    count = T1 & SHIFT_MASK;
496
    CC_SRC = T0 >> count;
497
    T0 |= (1 << count);
498
}
499

  
500
void OPPROTO glue(glue(op_btr, SUFFIX), _T0_T1_cc)(void)
501
{
502
    int count;
503
    count = T1 & SHIFT_MASK;
504
    CC_SRC = T0 >> count;
505
    T0 &= ~(1 << count);
506
}
507

  
508
void OPPROTO glue(glue(op_btc, SUFFIX), _T0_T1_cc)(void)
509
{
510
    int count;
511
    count = T1 & SHIFT_MASK;
512
    CC_SRC = T0 >> count;
513
    T0 ^= (1 << count);
514
}
515

  
516
#endif
517

  
388 518
/* string operations */
389 519
/* XXX: maybe use lower level instructions to ease exception handling */
390 520

  
......
464 594
{
465 595
    int v;
466 596

  
467
    v = glue(ldu, SUFFIX)((void *)ESI);
468
    ESI += (DF << SHIFT);
597
    v = glue(ldu, SUFFIX)((void *)EDI);
598
    EDI += (DF << SHIFT);
469 599
    CC_SRC = EAX;
470 600
    CC_DST = EAX - v;
471 601
}
......
476 606

  
477 607
    if (ECX != 0) {
478 608
        /* NOTE: the flags are not modified if ECX == 0 */
479
#if SHIFT == 0
480
        v1 = EAX & 0xff;
481
#elif SHIFT == 1
482
        v1 = EAX & 0xffff;
483
#else
484
        v1 = EAX;
485
#endif
609
        v1 = EAX & DATA_MASK;
486 610
        inc = (DF << SHIFT);
487 611
        do {
488
            v2 = glue(ldu, SUFFIX)((void *)ESI);
612
            v2 = glue(ldu, SUFFIX)((void *)EDI);
613
            EDI += inc;
614
            ECX--;
489 615
            if (v1 != v2)
490 616
                break;
491
            ESI += inc;
492
            ECX--;
493 617
        } while (ECX != 0);
494 618
        CC_SRC = v1;
495 619
        CC_DST = v1 - v2;
......
503 627

  
504 628
    if (ECX != 0) {
505 629
        /* NOTE: the flags are not modified if ECX == 0 */
506
#if SHIFT == 0
507
        v1 = EAX & 0xff;
508
#elif SHIFT == 1
509
        v1 = EAX & 0xffff;
510
#else
511
        v1 = EAX;
512
#endif
630
        v1 = EAX & DATA_MASK;
513 631
        inc = (DF << SHIFT);
514 632
        do {
515
            v2 = glue(ldu, SUFFIX)((void *)ESI);
633
            v2 = glue(ldu, SUFFIX)((void *)EDI);
634
            EDI += inc;
635
            ECX--;
516 636
            if (v1 == v2)
517 637
                break;
518
            ESI += inc;
519
            ECX--;
520 638
        } while (ECX != 0);
521 639
        CC_SRC = v1;
522 640
        CC_DST = v1 - v2;
......
543 661
        do {
544 662
            v1 = glue(ldu, SUFFIX)((void *)ESI);
545 663
            v2 = glue(ldu, SUFFIX)((void *)EDI);
546
            if (v1 != v2)
547
                break;
548 664
            ESI += inc;
549 665
            EDI += inc;
550 666
            ECX--;
667
            if (v1 != v2)
668
                break;
551 669
        } while (ECX != 0);
552 670
        CC_SRC = v1;
553 671
        CC_DST = v1 - v2;
......
563 681
        do {
564 682
            v1 = glue(ldu, SUFFIX)((void *)ESI);
565 683
            v2 = glue(ldu, SUFFIX)((void *)EDI);
566
            if (v1 == v2)
567
                break;
568 684
            ESI += inc;
569 685
            EDI += inc;
570 686
            ECX--;
687
            if (v1 == v2)
688
                break;
571 689
        } while (ECX != 0);
572 690
        CC_SRC = v1;
573 691
        CC_DST = v1 - v2;

Also available in: Unified diff