Statistics
| Branch: | Revision:

root / ops_template.h @ c50c0c3f

History | View | Annotate | Download (19.2 kB)

1
/*
2
 *  i386 micro operations (included several times to generate
3
 *  different operand sizes)
4
 * 
5
 *  Copyright (c) 2003 Fabrice Bellard
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 */
21
#define DATA_BITS (1 << (3 + SHIFT))
22
#define SHIFT_MASK (DATA_BITS - 1)
23
#define SIGN_MASK (1 << (DATA_BITS - 1))
24

    
25
#if DATA_BITS == 8
26
#define SUFFIX b
27
#define DATA_TYPE uint8_t
28
#define DATA_STYPE int8_t
29
#define DATA_MASK 0xff
30
#elif DATA_BITS == 16
31
#define SUFFIX w
32
#define DATA_TYPE uint16_t
33
#define DATA_STYPE int16_t
34
#define DATA_MASK 0xffff
35
#elif DATA_BITS == 32
36
#define SUFFIX l
37
#define DATA_TYPE uint32_t
38
#define DATA_STYPE int32_t
39
#define DATA_MASK 0xffffffff
40
#else
41
#error unhandled operand size
42
#endif
43

    
44
/* dynamic flags computation */
45

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

    
61
static int glue(compute_c_add, SUFFIX)(void)
62
{
63
    int src1, cf;
64
    src1 = CC_SRC;
65
    cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
66
    return cf;
67
}
68

    
69
static int glue(compute_all_adc, SUFFIX)(void)
70
{
71
    int cf, pf, af, zf, sf, of;
72
    int src1, src2;
73
    src1 = CC_SRC;
74
    src2 = CC_DST - CC_SRC - 1;
75
    cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
76
    pf = parity_table[(uint8_t)CC_DST];
77
    af = (CC_DST ^ src1 ^ src2) & 0x10;
78
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
79
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
80
    of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
81
    return cf | pf | af | zf | sf | of;
82
}
83

    
84
static int glue(compute_c_adc, SUFFIX)(void)
85
{
86
    int src1, cf;
87
    src1 = CC_SRC;
88
    cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
89
    return cf;
90
}
91

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

    
107
static int glue(compute_c_sub, SUFFIX)(void)
108
{
109
    int src1, src2, cf;
110
    src1 = CC_SRC;
111
    src2 = CC_SRC - CC_DST;
112
    cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
113
    return cf;
114
}
115

    
116
static int glue(compute_all_sbb, SUFFIX)(void)
117
{
118
    int cf, pf, af, zf, sf, of;
119
    int src1, src2;
120
    src1 = CC_SRC;
121
    src2 = CC_SRC - CC_DST - 1;
122
    cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
123
    pf = parity_table[(uint8_t)CC_DST];
124
    af = (CC_DST ^ src1 ^ src2) & 0x10;
125
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
126
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
127
    of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
128
    return cf | pf | af | zf | sf | of;
129
}
130

    
131
static int glue(compute_c_sbb, SUFFIX)(void)
132
{
133
    int src1, src2, cf;
134
    src1 = CC_SRC;
135
    src2 = CC_SRC - CC_DST - 1;
136
    cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
137
    return cf;
138
}
139

    
140
static int glue(compute_all_logic, SUFFIX)(void)
141
{
142
    int cf, pf, af, zf, sf, of;
143
    cf = 0;
144
    pf = parity_table[(uint8_t)CC_DST];
145
    af = 0;
146
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
147
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
148
    of = 0;
149
    return cf | pf | af | zf | sf | of;
150
}
151

    
152
static int glue(compute_c_logic, SUFFIX)(void)
153
{
154
    return 0;
155
}
156

    
157
static int glue(compute_all_inc, SUFFIX)(void)
158
{
159
    int cf, pf, af, zf, sf, of;
160
    int src1, src2;
161
    src1 = CC_DST - 1;
162
    src2 = 1;
163
    cf = CC_SRC;
164
    pf = parity_table[(uint8_t)CC_DST];
165
    af = (CC_DST ^ src1 ^ src2) & 0x10;
166
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
167
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
168
    of = ((CC_DST & DATA_MASK) == SIGN_MASK) << 11;
169
    return cf | pf | af | zf | sf | of;
170
}
171

    
172
#if DATA_BITS == 32
173
static int glue(compute_c_inc, SUFFIX)(void)
174
{
175
    return CC_SRC;
176
}
177
#endif
178

    
179
static int glue(compute_all_dec, SUFFIX)(void)
180
{
181
    int cf, pf, af, zf, sf, of;
182
    int src1, src2;
183
    src1 = CC_DST + 1;
184
    src2 = 1;
185
    cf = CC_SRC;
186
    pf = parity_table[(uint8_t)CC_DST];
187
    af = (CC_DST ^ src1 ^ src2) & 0x10;
188
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
189
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
190
    of = ((CC_DST & DATA_MASK) == ((uint32_t)SIGN_MASK - 1)) << 11;
191
    return cf | pf | af | zf | sf | of;
192
}
193

    
194
static int glue(compute_all_shl, SUFFIX)(void)
195
{
196
    int cf, pf, af, zf, sf, of;
197
    cf = (CC_SRC >> (DATA_BITS - 1)) & CC_C;
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 is defined if shift count == 1 */
203
    of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
204
    return cf | pf | af | zf | sf | of;
205
}
206

    
207
#if DATA_BITS == 32
208
static int glue(compute_c_shl, SUFFIX)(void)
209
{
210
    return CC_SRC & 1;
211
}
212
#endif
213

    
214
static int glue(compute_all_sar, SUFFIX)(void)
215
{
216
    int cf, pf, af, zf, sf, of;
217
    cf = CC_SRC & 1;
218
    pf = parity_table[(uint8_t)CC_DST];
219
    af = 0; /* undefined */
220
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
221
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
222
    /* of is defined if shift count == 1 */
223
    of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O; 
224
    return cf | pf | af | zf | sf | of;
225
}
226

    
227
/* various optimized jumps cases */
228

    
229
void OPPROTO glue(op_jb_sub, SUFFIX)(void)
230
{
231
    int src1, src2;
232
    src1 = CC_SRC;
233
    src2 = CC_SRC - CC_DST;
234

    
235
    if ((DATA_TYPE)src1 < (DATA_TYPE)src2)
236
        EIP = PARAM1;
237
    else
238
        EIP = PARAM2;
239
    FORCE_RET();
240
}
241

    
242
void OPPROTO glue(op_jz_sub, SUFFIX)(void)
243
{
244
    if ((DATA_TYPE)CC_DST == 0)
245
        EIP = PARAM1;
246
    else
247
        EIP = PARAM2;
248
    FORCE_RET();
249
}
250

    
251
void OPPROTO glue(op_jbe_sub, SUFFIX)(void)
252
{
253
    int src1, src2;
254
    src1 = CC_SRC;
255
    src2 = CC_SRC - CC_DST;
256

    
257
    if ((DATA_TYPE)src1 <= (DATA_TYPE)src2)
258
        EIP = PARAM1;
259
    else
260
        EIP = PARAM2;
261
    FORCE_RET();
262
}
263

    
264
void OPPROTO glue(op_js_sub, SUFFIX)(void)
265
{
266
    if (CC_DST & SIGN_MASK)
267
        EIP = PARAM1;
268
    else
269
        EIP = PARAM2;
270
    FORCE_RET();
271
}
272

    
273
void OPPROTO glue(op_jl_sub, SUFFIX)(void)
274
{
275
    int src1, src2;
276
    src1 = CC_SRC;
277
    src2 = CC_SRC - CC_DST;
278

    
279
    if ((DATA_STYPE)src1 < (DATA_STYPE)src2)
280
        EIP = PARAM1;
281
    else
282
        EIP = PARAM2;
283
    FORCE_RET();
284
}
285

    
286
void OPPROTO glue(op_jle_sub, SUFFIX)(void)
287
{
288
    int src1, src2;
289
    src1 = CC_SRC;
290
    src2 = CC_SRC - CC_DST;
291

    
292
    if ((DATA_STYPE)src1 <= (DATA_STYPE)src2)
293
        EIP = PARAM1;
294
    else
295
        EIP = PARAM2;
296
    FORCE_RET();
297
}
298

    
299
/* oldies */
300

    
301
#if DATA_BITS >= 16
302

    
303
void OPPROTO glue(op_loopnz, SUFFIX)(void)
304
{
305
    unsigned int tmp;
306
    int eflags;
307
    eflags = cc_table[CC_OP].compute_all();
308
    tmp = (ECX - 1) & DATA_MASK;
309
    ECX = (ECX & ~DATA_MASK) | tmp;
310
    if (tmp != 0 && !(eflags & CC_Z))
311
        EIP = PARAM1;
312
    else
313
        EIP = PARAM2;
314
    FORCE_RET();
315
}
316

    
317
void OPPROTO glue(op_loopz, SUFFIX)(void)
318
{
319
    unsigned int tmp;
320
    int eflags;
321
    eflags = cc_table[CC_OP].compute_all();
322
    tmp = (ECX - 1) & DATA_MASK;
323
    ECX = (ECX & ~DATA_MASK) | tmp;
324
    if (tmp != 0 && (eflags & CC_Z))
325
        EIP = PARAM1;
326
    else
327
        EIP = PARAM2;
328
    FORCE_RET();
329
}
330

    
331
void OPPROTO glue(op_loop, SUFFIX)(void)
332
{
333
    unsigned int tmp;
334
    tmp = (ECX - 1) & DATA_MASK;
335
    ECX = (ECX & ~DATA_MASK) | tmp;
336
    if (tmp != 0)
337
        EIP = PARAM1;
338
    else
339
        EIP = PARAM2;
340
    FORCE_RET();
341
}
342

    
343
void OPPROTO glue(op_jecxz, SUFFIX)(void)
344
{
345
    if ((DATA_TYPE)ECX == 0)
346
        EIP = PARAM1;
347
    else
348
        EIP = PARAM2;
349
    FORCE_RET();
350
}
351

    
352
#endif
353

    
354
/* various optimized set cases */
355

    
356
void OPPROTO glue(op_setb_T0_sub, SUFFIX)(void)
357
{
358
    int src1, src2;
359
    src1 = CC_SRC;
360
    src2 = CC_SRC - CC_DST;
361

    
362
    T0 = ((DATA_TYPE)src1 < (DATA_TYPE)src2);
363
}
364

    
365
void OPPROTO glue(op_setz_T0_sub, SUFFIX)(void)
366
{
367
    T0 = ((DATA_TYPE)CC_DST == 0);
368
}
369

    
370
void OPPROTO glue(op_setbe_T0_sub, SUFFIX)(void)
371
{
372
    int src1, src2;
373
    src1 = CC_SRC;
374
    src2 = CC_SRC - CC_DST;
375

    
376
    T0 = ((DATA_TYPE)src1 <= (DATA_TYPE)src2);
377
}
378

    
379
void OPPROTO glue(op_sets_T0_sub, SUFFIX)(void)
380
{
381
    T0 = lshift(CC_DST, -(DATA_BITS - 1)) & 1;
382
}
383

    
384
void OPPROTO glue(op_setl_T0_sub, SUFFIX)(void)
385
{
386
    int src1, src2;
387
    src1 = CC_SRC;
388
    src2 = CC_SRC - CC_DST;
389

    
390
    T0 = ((DATA_STYPE)src1 < (DATA_STYPE)src2);
391
}
392

    
393
void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void)
394
{
395
    int src1, src2;
396
    src1 = CC_SRC;
397
    src2 = CC_SRC - CC_DST;
398

    
399
    T0 = ((DATA_STYPE)src1 <= (DATA_STYPE)src2);
400
}
401

    
402
/* shifts */
403

    
404
void OPPROTO glue(glue(op_rol, SUFFIX), _T0_T1_cc)(void)
405
{
406
    int count, src;
407
    count = T1 & SHIFT_MASK;
408
    if (count) {
409
        CC_SRC = cc_table[CC_OP].compute_all() & ~(CC_O | CC_C);
410
        src = T0;
411
        T0 &= DATA_MASK;
412
        T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
413
        CC_SRC |= (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | 
414
            (T0 & CC_C);
415
        CC_OP = CC_OP_EFLAGS;
416
    }
417
    FORCE_RET();
418
}
419

    
420
void OPPROTO glue(glue(op_rol, SUFFIX), _T0_T1)(void)
421
{
422
    int count;
423
    count = T1 & SHIFT_MASK;
424
    if (count) {
425
        T0 &= DATA_MASK;
426
        T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
427
    }
428
    FORCE_RET();
429
}
430

    
431
void OPPROTO glue(glue(op_ror, SUFFIX), _T0_T1_cc)(void)
432
{
433
    int count, src;
434
    count = T1 & SHIFT_MASK;
435
    if (count) {
436
        CC_SRC = cc_table[CC_OP].compute_all() & ~(CC_O | CC_C);
437
        src = T0;
438
        T0 &= DATA_MASK;
439
        T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
440
        CC_SRC |= (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | 
441
            ((T0 >> (DATA_BITS - 1)) & CC_C);
442
        CC_OP = CC_OP_EFLAGS;
443
    }
444
    FORCE_RET();
445
}
446

    
447
void OPPROTO glue(glue(op_ror, SUFFIX), _T0_T1)(void)
448
{
449
    int count;
450
    count = T1 & SHIFT_MASK;
451
    if (count) {
452
        T0 &= DATA_MASK;
453
        T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
454
    }
455
    FORCE_RET();
456
}
457

    
458
void OPPROTO glue(glue(op_rcl, SUFFIX), _T0_T1_cc)(void)
459
{
460
    int count, res, eflags;
461
    unsigned int src;
462

    
463
    count = T1 & 0x1f;
464
#if DATA_BITS == 16
465
    count = rclw_table[count];
466
#elif DATA_BITS == 8
467
    count = rclb_table[count];
468
#endif
469
    if (count) {
470
        eflags = cc_table[CC_OP].compute_all();
471
        T0 &= DATA_MASK;
472
        src = T0;
473
        res = (T0 << count) | ((eflags & CC_C) << (count - 1));
474
        if (count > 1)
475
            res |= T0 >> (DATA_BITS + 1 - count);
476
        T0 = res;
477
        CC_SRC = (eflags & ~(CC_C | CC_O)) |
478
            (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | 
479
            ((src >> (DATA_BITS - count)) & CC_C);
480
        CC_OP = CC_OP_EFLAGS;
481
    }
482
    FORCE_RET();
483
}
484

    
485
void OPPROTO glue(glue(op_rcr, SUFFIX), _T0_T1_cc)(void)
486
{
487
    int count, res, eflags;
488
    unsigned int src;
489

    
490
    count = T1 & 0x1f;
491
#if DATA_BITS == 16
492
    count = rclw_table[count];
493
#elif DATA_BITS == 8
494
    count = rclb_table[count];
495
#endif
496
    if (count) {
497
        eflags = cc_table[CC_OP].compute_all();
498
        T0 &= DATA_MASK;
499
        src = T0;
500
        res = (T0 >> count) | ((eflags & CC_C) << (DATA_BITS - count));
501
        if (count > 1)
502
            res |= T0 << (DATA_BITS + 1 - count);
503
        T0 = res;
504
        CC_SRC = (eflags & ~(CC_C | CC_O)) |
505
            (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | 
506
            ((src >> (count - 1)) & CC_C);
507
        CC_OP = CC_OP_EFLAGS;
508
    }
509
    FORCE_RET();
510
}
511

    
512
void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1_cc)(void)
513
{
514
    int count;
515
    count = T1 & 0x1f;
516
    if (count) {
517
        CC_SRC = (DATA_TYPE)T0 << (count - 1);
518
        T0 = T0 << count;
519
        CC_DST = T0;
520
        CC_OP = CC_OP_SHLB + SHIFT;
521
    }
522
    FORCE_RET();
523
}
524

    
525
void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1)(void)
526
{
527
    int count;
528
    count = T1 & 0x1f;
529
    T0 = T0 << count;
530
    FORCE_RET();
531
}
532

    
533
void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1_cc)(void)
534
{
535
    int count;
536
    count = T1 & 0x1f;
537
    if (count) {
538
        T0 &= DATA_MASK;
539
        CC_SRC = T0 >> (count - 1);
540
        T0 = T0 >> count;
541
        CC_DST = T0;
542
        CC_OP = CC_OP_SARB + SHIFT;
543
    }
544
    FORCE_RET();
545
}
546

    
547
void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1)(void)
548
{
549
    int count;
550
    count = T1 & 0x1f;
551
    T0 &= DATA_MASK;
552
    T0 = T0 >> count;
553
    FORCE_RET();
554
}
555

    
556
void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1_cc)(void)
557
{
558
    int count, src;
559
    count = T1 & 0x1f;
560
    if (count) {
561
        src = (DATA_STYPE)T0;
562
        CC_SRC = src >> (count - 1);
563
        T0 = src >> count;
564
        CC_DST = T0;
565
        CC_OP = CC_OP_SARB + SHIFT;
566
    }
567
    FORCE_RET();
568
}
569

    
570
void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1)(void)
571
{
572
    int count, src;
573
    count = T1 & 0x1f;
574
    src = (DATA_STYPE)T0;
575
    T0 = src >> count;
576
    FORCE_RET();
577
}
578

    
579
#if DATA_BITS == 16
580
/* XXX: overflow flag might be incorrect in some cases in shldw */
581
void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_im_cc)(void)
582
{
583
    int count;
584
    unsigned int res;
585
    count = PARAM1;
586
    T1 &= 0xffff;
587
    res = T1 | (T0 << 16);
588
    CC_SRC = res >> (32 - count);
589
    res <<= count;
590
    if (count > 16)
591
        res |= T1 << (count - 16);
592
    T0 = res >> 16;
593
    CC_DST = T0;
594
}
595

    
596
void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_ECX_cc)(void)
597
{
598
    int count;
599
    unsigned int res;
600
    count = ECX & 0x1f;
601
    if (count) {
602
        T1 &= 0xffff;
603
        res = T1 | (T0 << 16);
604
        CC_SRC = res >> (32 - count);
605
        res <<= count;
606
        if (count > 16)
607
          res |= T1 << (count - 16);
608
        T0 = res >> 16;
609
        CC_DST = T0;
610
        CC_OP = CC_OP_SARB + SHIFT;
611
    }
612
    FORCE_RET();
613
}
614

    
615
void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_im_cc)(void)
616
{
617
    int count;
618
    unsigned int res;
619

    
620
    count = PARAM1;
621
    res = (T0 & 0xffff) | (T1 << 16);
622
    CC_SRC = res >> (count - 1);
623
    res >>= count;
624
    if (count > 16)
625
        res |= T1 << (32 - count);
626
    T0 = res;
627
    CC_DST = T0;
628
}
629

    
630

    
631
void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_ECX_cc)(void)
632
{
633
    int count;
634
    unsigned int res;
635

    
636
    count = ECX & 0x1f;
637
    if (count) {
638
        res = (T0 & 0xffff) | (T1 << 16);
639
        CC_SRC = res >> (count - 1);
640
        res >>= count;
641
        if (count > 16)
642
            res |= T1 << (32 - count);
643
        T0 = res;
644
        CC_DST = T0;
645
        CC_OP = CC_OP_SARB + SHIFT;
646
    }
647
    FORCE_RET();
648
}
649
#endif
650

    
651
#if DATA_BITS == 32
652
void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_im_cc)(void)
653
{
654
    int count;
655
    count = PARAM1;
656
    T0 &= DATA_MASK;
657
    T1 &= DATA_MASK;
658
    CC_SRC = T0 << (count - 1);
659
    T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
660
    CC_DST = T0;
661
}
662

    
663
void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_ECX_cc)(void)
664
{
665
    int count;
666
    count = ECX & 0x1f;
667
    if (count) {
668
        T0 &= DATA_MASK;
669
        T1 &= DATA_MASK;
670
        CC_SRC = T0 << (count - 1);
671
        T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
672
        CC_DST = T0;
673
        CC_OP = CC_OP_SHLB + SHIFT;
674
    }
675
    FORCE_RET();
676
}
677

    
678
void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_im_cc)(void)
679
{
680
    int count;
681
    count = PARAM1;
682
    T0 &= DATA_MASK;
683
    T1 &= DATA_MASK;
684
    CC_SRC = T0 >> (count - 1);
685
    T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
686
    CC_DST = T0;
687
}
688

    
689

    
690
void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_ECX_cc)(void)
691
{
692
    int count;
693
    count = ECX & 0x1f;
694
    if (count) {
695
        T0 &= DATA_MASK;
696
        T1 &= DATA_MASK;
697
        CC_SRC = T0 >> (count - 1);
698
        T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
699
        CC_DST = T0;
700
        CC_OP = CC_OP_SARB + SHIFT;
701
    }
702
    FORCE_RET();
703
}
704
#endif
705

    
706
/* carry add/sub (we only need to set CC_OP differently) */
707

    
708
void OPPROTO glue(glue(op_adc, SUFFIX), _T0_T1_cc)(void)
709
{
710
    int cf;
711
    cf = cc_table[CC_OP].compute_c();
712
    CC_SRC = T0;
713
    T0 = T0 + T1 + cf;
714
    CC_DST = T0;
715
    CC_OP = CC_OP_ADDB + SHIFT + cf * 3;
716
}
717

    
718
void OPPROTO glue(glue(op_sbb, SUFFIX), _T0_T1_cc)(void)
719
{
720
    int cf;
721
    cf = cc_table[CC_OP].compute_c();
722
    CC_SRC = T0;
723
    T0 = T0 - T1 - cf;
724
    CC_DST = T0;
725
    CC_OP = CC_OP_SUBB + SHIFT + cf * 3;
726
}
727

    
728
void OPPROTO glue(glue(op_cmpxchg, SUFFIX), _T0_T1_EAX_cc)(void)
729
{
730
    CC_SRC = EAX;
731
    CC_DST = EAX - T0;
732
    if ((DATA_TYPE)CC_DST == 0) {
733
        T0 = T1;
734
    } else {
735
        EAX = (EAX & ~DATA_MASK) | (T0 & DATA_MASK);
736
    }
737
    FORCE_RET();
738
}
739

    
740
/* bit operations */
741
#if DATA_BITS >= 16
742

    
743
void OPPROTO glue(glue(op_bt, SUFFIX), _T0_T1_cc)(void)
744
{
745
    int count;
746
    count = T1 & SHIFT_MASK;
747
    CC_SRC = T0 >> count;
748
}
749

    
750
void OPPROTO glue(glue(op_bts, SUFFIX), _T0_T1_cc)(void)
751
{
752
    int count;
753
    count = T1 & SHIFT_MASK;
754
    CC_SRC = T0 >> count;
755
    T0 |= (1 << count);
756
}
757

    
758
void OPPROTO glue(glue(op_btr, SUFFIX), _T0_T1_cc)(void)
759
{
760
    int count;
761
    count = T1 & SHIFT_MASK;
762
    CC_SRC = T0 >> count;
763
    T0 &= ~(1 << count);
764
}
765

    
766
void OPPROTO glue(glue(op_btc, SUFFIX), _T0_T1_cc)(void)
767
{
768
    int count;
769
    count = T1 & SHIFT_MASK;
770
    CC_SRC = T0 >> count;
771
    T0 ^= (1 << count);
772
}
773

    
774
void OPPROTO glue(glue(op_bsf, SUFFIX), _T0_cc)(void)
775
{
776
    int res, count;
777
    res = T0 & DATA_MASK;
778
    if (res != 0) {
779
        count = 0;
780
        while ((res & 1) == 0) {
781
            count++;
782
            res >>= 1;
783
        }
784
        T0 = count;
785
        CC_DST = 1; /* ZF = 1 */
786
    } else {
787
        CC_DST = 0; /* ZF = 1 */
788
    }
789
    FORCE_RET();
790
}
791

    
792
void OPPROTO glue(glue(op_bsr, SUFFIX), _T0_cc)(void)
793
{
794
    int res, count;
795
    res = T0 & DATA_MASK;
796
    if (res != 0) {
797
        count = DATA_BITS - 1;
798
        while ((res & SIGN_MASK) == 0) {
799
            count--;
800
            res <<= 1;
801
        }
802
        T0 = count;
803
        CC_DST = 1; /* ZF = 1 */
804
    } else {
805
        CC_DST = 0; /* ZF = 1 */
806
    }
807
    FORCE_RET();
808
}
809

    
810
#endif
811

    
812
/* string operations */
813
/* XXX: maybe use lower level instructions to ease 16 bit / segment handling */
814

    
815
#define STRING_SUFFIX _fast
816
#define SI_ADDR (void *)ESI
817
#define DI_ADDR (void *)EDI
818
#define INC_SI() ESI += inc
819
#define INC_DI() EDI += inc
820
#define CX ECX
821
#define DEC_CX() ECX--
822
#include "op_string.h"
823

    
824
#define STRING_SUFFIX _a32
825
#define SI_ADDR (uint8_t *)A0 + ESI
826
#define DI_ADDR env->seg_cache[R_ES].base + EDI
827
#define INC_SI() ESI += inc
828
#define INC_DI() EDI += inc
829
#define CX ECX
830
#define DEC_CX() ECX--
831
#include "op_string.h"
832

    
833
#define STRING_SUFFIX _a16
834
#define SI_ADDR (uint8_t *)A0 + (ESI & 0xffff)
835
#define DI_ADDR env->seg_cache[R_ES].base + (EDI & 0xffff)
836
#define INC_SI() ESI = (ESI & ~0xffff) | ((ESI + inc) & 0xffff)
837
#define INC_DI() EDI = (EDI & ~0xffff) | ((EDI + inc) & 0xffff)
838
#define CX (ECX & 0xffff)
839
#define DEC_CX() ECX = (ECX & ~0xffff) | ((ECX - 1) & 0xffff)
840
#include "op_string.h"
841

    
842
/* port I/O */
843

    
844
void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void)
845
{
846
    glue(cpu_x86_out, SUFFIX)(env, T0 & 0xffff, T1 & DATA_MASK);
847
}
848

    
849
void OPPROTO glue(glue(op_in, SUFFIX), _T0_T1)(void)
850
{
851
    T1 = glue(cpu_x86_in, SUFFIX)(env, T0 & 0xffff);
852
}
853

    
854
#undef DATA_BITS
855
#undef SHIFT_MASK
856
#undef SIGN_MASK
857
#undef DATA_TYPE
858
#undef DATA_STYPE
859
#undef DATA_MASK
860
#undef SUFFIX