Statistics
| Branch: | Revision:

root / op-i386.c @ 367e86e8

History | View | Annotate | Download (16.1 kB)

1
typedef unsigned char uint8_t;
2
typedef unsigned short uint16_t;
3
typedef unsigned int uint32_t;
4
typedef unsigned long long uint64_t;
5

    
6
typedef signed char int8_t;
7
typedef signed short int16_t;
8
typedef signed int int32_t;
9
typedef signed long long int64_t;
10

    
11
#define NULL 0
12

    
13
#ifdef __i386__
14
register int T0 asm("esi");
15
register int T1 asm("ebx");
16
register int A0 asm("edi");
17
register struct CPU86State *env asm("ebp");
18
#define FORCE_RET() asm volatile ("ret");
19
#endif
20
#ifdef __powerpc__
21
register int T0 asm("r24");
22
register int T1 asm("r25");
23
register int A0 asm("r26");
24
register struct CPU86State *env asm("r27");
25
#define FORCE_RET() asm volatile ("blr");
26
#endif
27
#ifdef __arm__
28
register int T0 asm("r4");
29
register int T1 asm("r5");
30
register int A0 asm("r6");
31
register struct CPU86State *env asm("r7");
32
#define FORCE_RET() asm volatile ("mov pc, lr");
33
#endif
34
#ifdef __mips__
35
register int T0 asm("s0");
36
register int T1 asm("s1");
37
register int A0 asm("s2");
38
register struct CPU86State *env asm("s3");
39
#define FORCE_RET() asm volatile ("jr $31");
40
#endif
41
#ifdef __sparc__
42
register int T0 asm("l0");
43
register int T1 asm("l1");
44
register int A0 asm("l2");
45
register struct CPU86State *env asm("l3");
46
#define FORCE_RET() asm volatile ("retl ; nop");
47
#endif
48

    
49
#ifndef OPPROTO
50
#define OPPROTO
51
#endif
52

    
53
#define xglue(x, y) x ## y
54
#define glue(x, y) xglue(x, y)
55

    
56
#define EAX (env->regs[R_EAX])
57
#define ECX (env->regs[R_ECX])
58
#define EDX (env->regs[R_EDX])
59
#define EBX (env->regs[R_EBX])
60
#define ESP (env->regs[R_ESP])
61
#define EBP (env->regs[R_EBP])
62
#define ESI (env->regs[R_ESI])
63
#define EDI (env->regs[R_EDI])
64
#define PC  (env->pc)
65
#define DF  (env->df)
66

    
67
#define CC_SRC (env->cc_src)
68
#define CC_DST (env->cc_dst)
69
#define CC_OP (env->cc_op)
70

    
71
extern int __op_param1, __op_param2, __op_param3;
72
#define PARAM1 ((long)(&__op_param1))
73
#define PARAM2 ((long)(&__op_param2))
74
#define PARAM3 ((long)(&__op_param3))
75

    
76
#include "cpu-i386.h"
77

    
78
typedef struct CCTable {
79
    int (*compute_all)(void); /* return all the flags */
80
    int (*compute_c)(void);  /* return the C flag */
81
} CCTable;
82

    
83
extern CCTable cc_table[];
84

    
85
uint8_t parity_table[256] = {
86
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
87
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
88
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
89
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
90
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
91
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
92
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
93
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
94
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
95
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
96
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
97
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
98
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
99
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
100
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
101
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
102
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
103
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
104
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
105
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
106
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
107
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
108
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
109
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
110
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
111
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
112
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
113
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
114
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
115
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
116
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
117
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
118
};
119

    
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
};
127

    
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
};
135

    
136
/* n must be a constant to be efficient */
137
static inline int lshift(int x, int n)
138
{
139
    if (n >= 0)
140
        return x << n;
141
    else
142
        return x >> (-n);
143
}
144

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

    
147
#define REG EAX
148
#define REGNAME _EAX
149
#include "opreg_template.h"
150
#undef REG
151
#undef REGNAME
152

    
153
#define REG ECX
154
#define REGNAME _ECX
155
#include "opreg_template.h"
156
#undef REG
157
#undef REGNAME
158

    
159
#define REG EDX
160
#define REGNAME _EDX
161
#include "opreg_template.h"
162
#undef REG
163
#undef REGNAME
164

    
165
#define REG EBX
166
#define REGNAME _EBX
167
#include "opreg_template.h"
168
#undef REG
169
#undef REGNAME
170

    
171
#define REG ESP
172
#define REGNAME _ESP
173
#include "opreg_template.h"
174
#undef REG
175
#undef REGNAME
176

    
177
#define REG EBP
178
#define REGNAME _EBP
179
#include "opreg_template.h"
180
#undef REG
181
#undef REGNAME
182

    
183
#define REG ESI
184
#define REGNAME _ESI
185
#include "opreg_template.h"
186
#undef REG
187
#undef REGNAME
188

    
189
#define REG EDI
190
#define REGNAME _EDI
191
#include "opreg_template.h"
192
#undef REG
193
#undef REGNAME
194

    
195
/* operations */
196

    
197
void OPPROTO op_addl_T0_T1_cc(void)
198
{
199
    CC_SRC = T0;
200
    T0 += T1;
201
    CC_DST = T0;
202
}
203

    
204
void OPPROTO op_orl_T0_T1_cc(void)
205
{
206
    T0 |= T1;
207
    CC_DST = T0;
208
}
209

    
210
void OPPROTO op_adcl_T0_T1_cc(void)
211
{
212
    CC_SRC = T0;
213
    T0 = T0 + T1 + cc_table[CC_OP].compute_c();
214
    CC_DST = T0;
215
}
216

    
217
void OPPROTO op_sbbl_T0_T1_cc(void)
218
{
219
    CC_SRC = T0;
220
    T0 = T0 - T1 - cc_table[CC_OP].compute_c();
221
    CC_DST = T0;
222
}
223

    
224
void OPPROTO op_andl_T0_T1_cc(void)
225
{
226
    T0 &= T1;
227
    CC_DST = T0;
228
}
229

    
230
void OPPROTO op_subl_T0_T1_cc(void)
231
{
232
    CC_SRC = T0;
233
    T0 -= T1;
234
    CC_DST = T0;
235
}
236

    
237
void OPPROTO op_xorl_T0_T1_cc(void)
238
{
239
    T0 ^= T1;
240
    CC_DST = T0;
241
}
242

    
243
void OPPROTO op_cmpl_T0_T1_cc(void)
244
{
245
    CC_SRC = T0;
246
    CC_DST = T0 - T1;
247
}
248

    
249
void OPPROTO op_notl_T0(void)
250
{
251
    T0 = ~T0;
252
}
253

    
254
void OPPROTO op_negl_T0_cc(void)
255
{
256
    CC_SRC = 0;
257
    T0 = -T0;
258
    CC_DST = T0;
259
}
260

    
261
void OPPROTO op_incl_T0_cc(void)
262
{
263
    T0++;
264
    CC_DST = T0;
265
}
266

    
267
void OPPROTO op_decl_T0_cc(void)
268
{
269
    T0--;
270
    CC_DST = T0;
271
}
272

    
273
void OPPROTO op_testl_T0_T1_cc(void)
274
{
275
    CC_SRC = T0;
276
    CC_DST = T0 & T1;
277
}
278

    
279
/* multiply/divide */
280
void OPPROTO op_mulb_AL_T0(void)
281
{
282
    unsigned int res;
283
    res = (uint8_t)EAX * (uint8_t)T0;
284
    EAX = (EAX & 0xffff0000) | res;
285
    CC_SRC = (res & 0xff00);
286
}
287

    
288
void OPPROTO op_imulb_AL_T0(void)
289
{
290
    int res;
291
    res = (int8_t)EAX * (int8_t)T0;
292
    EAX = (EAX & 0xffff0000) | (res & 0xffff);
293
    CC_SRC = (res != (int8_t)res);
294
}
295

    
296
void OPPROTO op_mulw_AX_T0(void)
297
{
298
    unsigned int res;
299
    res = (uint16_t)EAX * (uint16_t)T0;
300
    EAX = (EAX & 0xffff0000) | (res & 0xffff);
301
    EDX = (EDX & 0xffff0000) | ((res >> 16) & 0xffff);
302
    CC_SRC = res >> 16;
303
}
304

    
305
void OPPROTO op_imulw_AX_T0(void)
306
{
307
    int res;
308
    res = (int16_t)EAX * (int16_t)T0;
309
    EAX = (EAX & 0xffff0000) | (res & 0xffff);
310
    EDX = (EDX & 0xffff0000) | ((res >> 16) & 0xffff);
311
    CC_SRC = (res != (int16_t)res);
312
}
313

    
314
void OPPROTO op_mull_EAX_T0(void)
315
{
316
    uint64_t res;
317
    res = (uint64_t)((uint32_t)EAX) * (uint64_t)((uint32_t)T0);
318
    EAX = res;
319
    EDX = res >> 32;
320
    CC_SRC = res >> 32;
321
}
322

    
323
void OPPROTO op_imull_EAX_T0(void)
324
{
325
    int64_t res;
326
    res = (int64_t)((int32_t)EAX) * (int64_t)((int32_t)T0);
327
    EAX = res;
328
    EDX = res >> 32;
329
    CC_SRC = (res != (int32_t)res);
330
}
331

    
332
void OPPROTO op_imulw_T0_T1(void)
333
{
334
    int res;
335
    res = (int16_t)T0 * (int16_t)T1;
336
    T0 = res;
337
    CC_SRC = (res != (int16_t)res);
338
}
339

    
340
void OPPROTO op_imull_T0_T1(void)
341
{
342
    int64_t res;
343
    res = (int64_t)((int32_t)EAX) * (int64_t)((int32_t)T1);
344
    T0 = res;
345
    CC_SRC = (res != (int32_t)res);
346
}
347

    
348
/* division, flags are undefined */
349
/* XXX: add exceptions for overflow & div by zero */
350
void OPPROTO op_divb_AL_T0(void)
351
{
352
    unsigned int num, den, q, r;
353

    
354
    num = (EAX & 0xffff);
355
    den = (T0 & 0xff);
356
    q = (num / den) & 0xff;
357
    r = (num % den) & 0xff;
358
    EAX = (EAX & 0xffff0000) | (r << 8) | q;
359
}
360

    
361
void OPPROTO op_idivb_AL_T0(void)
362
{
363
    int num, den, q, r;
364

    
365
    num = (int16_t)EAX;
366
    den = (int8_t)T0;
367
    q = (num / den) & 0xff;
368
    r = (num % den) & 0xff;
369
    EAX = (EAX & 0xffff0000) | (r << 8) | q;
370
}
371

    
372
void OPPROTO op_divw_AX_T0(void)
373
{
374
    unsigned int num, den, q, r;
375

    
376
    num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
377
    den = (T0 & 0xffff);
378
    q = (num / den) & 0xffff;
379
    r = (num % den) & 0xffff;
380
    EAX = (EAX & 0xffff0000) | q;
381
    EDX = (EDX & 0xffff0000) | r;
382
}
383

    
384
void OPPROTO op_idivw_AX_T0(void)
385
{
386
    int num, den, q, r;
387

    
388
    num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
389
    den = (int16_t)T0;
390
    q = (num / den) & 0xffff;
391
    r = (num % den) & 0xffff;
392
    EAX = (EAX & 0xffff0000) | q;
393
    EDX = (EDX & 0xffff0000) | r;
394
}
395

    
396
void OPPROTO op_divl_EAX_T0(void)
397
{
398
    unsigned int den, q, r;
399
    uint64_t num;
400
    
401
    num = EAX | ((uint64_t)EDX << 32);
402
    den = T0;
403
    q = (num / den);
404
    r = (num % den);
405
    EAX = q;
406
    EDX = r;
407
}
408

    
409
void OPPROTO op_idivl_EAX_T0(void)
410
{
411
    int den, q, r;
412
    int16_t num;
413
    
414
    num = EAX | ((uint64_t)EDX << 32);
415
    den = (int16_t)T0;
416
    q = (num / den);
417
    r = (num % den);
418
    EAX = q;
419
    EDX = r;
420
}
421

    
422
/* constant load */
423

    
424
void OPPROTO op1_movl_T0_im(void)
425
{
426
    T0 = PARAM1;
427
}
428

    
429
void OPPROTO op1_movl_T1_im(void)
430
{
431
    T1 = PARAM1;
432
}
433

    
434
void OPPROTO op1_movl_A0_im(void)
435
{
436
    A0 = PARAM1;
437
}
438

    
439
/* memory access */
440

    
441
void OPPROTO op_ldub_T0_A0(void)
442
{
443
    T0 = ldub((uint8_t *)A0);
444
}
445

    
446
void OPPROTO op_ldsb_T0_A0(void)
447
{
448
    T0 = ldsb((int8_t *)A0);
449
}
450

    
451
void OPPROTO op_lduw_T0_A0(void)
452
{
453
    T0 = lduw((uint8_t *)A0);
454
}
455

    
456
void OPPROTO op_ldsw_T0_A0(void)
457
{
458
    T0 = ldsw((int8_t *)A0);
459
}
460

    
461
void OPPROTO op_ldl_T0_A0(void)
462
{
463
    T0 = ldl((uint8_t *)A0);
464
}
465

    
466
void OPPROTO op_ldub_T1_A0(void)
467
{
468
    T1 = ldub((uint8_t *)A0);
469
}
470

    
471
void OPPROTO op_ldsb_T1_A0(void)
472
{
473
    T1 = ldsb((int8_t *)A0);
474
}
475

    
476
void OPPROTO op_lduw_T1_A0(void)
477
{
478
    T1 = lduw((uint8_t *)A0);
479
}
480

    
481
void OPPROTO op_ldsw_T1_A0(void)
482
{
483
    T1 = ldsw((int8_t *)A0);
484
}
485

    
486
void OPPROTO op_ldl_T1_A0(void)
487
{
488
    T1 = ldl((uint8_t *)A0);
489
}
490

    
491
void OPPROTO op_stb_T0_A0(void)
492
{
493
    stb((uint8_t *)A0, T0);
494
}
495

    
496
void OPPROTO op_stw_T0_A0(void)
497
{
498
    stw((uint8_t *)A0, T0);
499
}
500

    
501
void OPPROTO op_stl_T0_A0(void)
502
{
503
    stl((uint8_t *)A0, T0);
504
}
505

    
506
/* jumps */
507

    
508
/* indirect jump */
509
void OPPROTO op_jmp_T0(void)
510
{
511
    PC = T0;
512
}
513

    
514
void OPPROTO op_jmp_im(void)
515
{
516
    PC = PARAM1;
517
}
518

    
519
/* string ops */
520

    
521
#define ldul ldl
522

    
523
#define SHIFT 0
524
#include "ops_template.h"
525
#undef SHIFT
526

    
527
#define SHIFT 1
528
#include "ops_template.h"
529
#undef SHIFT
530

    
531
#define SHIFT 2
532
#include "ops_template.h"
533
#undef SHIFT
534

    
535
/* sign extend */
536

    
537
void OPPROTO op_movsbl_T0_T0(void)
538
{
539
    T0 = (int8_t)T0;
540
}
541

    
542
void OPPROTO op_movzbl_T0_T0(void)
543
{
544
    T0 = (uint8_t)T0;
545
}
546

    
547
void OPPROTO op_movswl_T0_T0(void)
548
{
549
    T0 = (int16_t)T0;
550
}
551

    
552
void OPPROTO op_movzwl_T0_T0(void)
553
{
554
    T0 = (uint16_t)T0;
555
}
556

    
557
void OPPROTO op_movswl_EAX_AX(void)
558
{
559
    EAX = (int16_t)EAX;
560
}
561

    
562
void OPPROTO op_movsbw_AX_AL(void)
563
{
564
    EAX = (EAX & 0xffff0000) | ((int8_t)EAX & 0xffff);
565
}
566

    
567
void OPPROTO op_movslq_EDX_EAX(void)
568
{
569
    EDX = (int32_t)EAX >> 31;
570
}
571

    
572
void OPPROTO op_movswl_DX_AX(void)
573
{
574
    EDX = (EDX & 0xffff0000) | (((int16_t)EAX >> 15) & 0xffff);
575
}
576

    
577
/* push/pop */
578
/* XXX: add 16 bit operand/16 bit seg variants */
579

    
580
void op_pushl_T0(void)
581
{
582
    uint32_t offset;
583
    offset = ESP - 4;
584
    stl((void *)offset, T0);
585
    /* modify ESP after to handle exceptions correctly */
586
    ESP = offset;
587
}
588

    
589
void op_pushl_T1(void)
590
{
591
    uint32_t offset;
592
    offset = ESP - 4;
593
    stl((void *)offset, T1);
594
    /* modify ESP after to handle exceptions correctly */
595
    ESP = offset;
596
}
597

    
598
void op_popl_T0(void)
599
{
600
    T0 = ldl((void *)ESP);
601
    ESP += 4;
602
}
603

    
604
void op_addl_ESP_im(void)
605
{
606
    ESP += PARAM1;
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
};