new x86 CPU core
[qemu] / op-i386.c
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 };