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;
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;
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");
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");
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");
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");
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");
53 #define xglue(x, y) x ## y
54 #define glue(x, y) xglue(x, y)
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])
67 #define CC_SRC (env->cc_src)
68 #define CC_DST (env->cc_dst)
69 #define CC_OP (env->cc_op)
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))
78 typedef struct CCTable {
79 int (*compute_all)(void); /* return all the flags */
80 int (*compute_c)(void); /* return the C flag */
83 extern CCTable cc_table[];
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,
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,
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,
136 /* n must be a constant to be efficient */
137 static inline int lshift(int x, int n)
145 /* we define the various pieces of code used by the JIT */
149 #include "opreg_template.h"
155 #include "opreg_template.h"
161 #include "opreg_template.h"
167 #include "opreg_template.h"
173 #include "opreg_template.h"
179 #include "opreg_template.h"
185 #include "opreg_template.h"
191 #include "opreg_template.h"
197 void OPPROTO op_addl_T0_T1_cc(void)
204 void OPPROTO op_orl_T0_T1_cc(void)
210 void OPPROTO op_adcl_T0_T1_cc(void)
213 T0 = T0 + T1 + cc_table[CC_OP].compute_c();
217 void OPPROTO op_sbbl_T0_T1_cc(void)
220 T0 = T0 - T1 - cc_table[CC_OP].compute_c();
224 void OPPROTO op_andl_T0_T1_cc(void)
230 void OPPROTO op_subl_T0_T1_cc(void)
237 void OPPROTO op_xorl_T0_T1_cc(void)
243 void OPPROTO op_cmpl_T0_T1_cc(void)
249 void OPPROTO op_notl_T0(void)
254 void OPPROTO op_negl_T0_cc(void)
261 void OPPROTO op_incl_T0_cc(void)
267 void OPPROTO op_decl_T0_cc(void)
273 void OPPROTO op_testl_T0_T1_cc(void)
279 /* multiply/divide */
280 void OPPROTO op_mulb_AL_T0(void)
283 res = (uint8_t)EAX * (uint8_t)T0;
284 EAX = (EAX & 0xffff0000) | res;
285 CC_SRC = (res & 0xff00);
288 void OPPROTO op_imulb_AL_T0(void)
291 res = (int8_t)EAX * (int8_t)T0;
292 EAX = (EAX & 0xffff0000) | (res & 0xffff);
293 CC_SRC = (res != (int8_t)res);
296 void OPPROTO op_mulw_AX_T0(void)
299 res = (uint16_t)EAX * (uint16_t)T0;
300 EAX = (EAX & 0xffff0000) | (res & 0xffff);
301 EDX = (EDX & 0xffff0000) | ((res >> 16) & 0xffff);
305 void OPPROTO op_imulw_AX_T0(void)
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);
314 void OPPROTO op_mull_EAX_T0(void)
317 res = (uint64_t)((uint32_t)EAX) * (uint64_t)((uint32_t)T0);
323 void OPPROTO op_imull_EAX_T0(void)
326 res = (int64_t)((int32_t)EAX) * (int64_t)((int32_t)T0);
329 CC_SRC = (res != (int32_t)res);
332 void OPPROTO op_imulw_T0_T1(void)
335 res = (int16_t)T0 * (int16_t)T1;
337 CC_SRC = (res != (int16_t)res);
340 void OPPROTO op_imull_T0_T1(void)
343 res = (int64_t)((int32_t)EAX) * (int64_t)((int32_t)T1);
345 CC_SRC = (res != (int32_t)res);
348 /* division, flags are undefined */
349 /* XXX: add exceptions for overflow & div by zero */
350 void OPPROTO op_divb_AL_T0(void)
352 unsigned int num, den, q, r;
354 num = (EAX & 0xffff);
356 q = (num / den) & 0xff;
357 r = (num % den) & 0xff;
358 EAX = (EAX & 0xffff0000) | (r << 8) | q;
361 void OPPROTO op_idivb_AL_T0(void)
367 q = (num / den) & 0xff;
368 r = (num % den) & 0xff;
369 EAX = (EAX & 0xffff0000) | (r << 8) | q;
372 void OPPROTO op_divw_AX_T0(void)
374 unsigned int num, den, q, r;
376 num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
378 q = (num / den) & 0xffff;
379 r = (num % den) & 0xffff;
380 EAX = (EAX & 0xffff0000) | q;
381 EDX = (EDX & 0xffff0000) | r;
384 void OPPROTO op_idivw_AX_T0(void)
388 num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
390 q = (num / den) & 0xffff;
391 r = (num % den) & 0xffff;
392 EAX = (EAX & 0xffff0000) | q;
393 EDX = (EDX & 0xffff0000) | r;
396 void OPPROTO op_divl_EAX_T0(void)
398 unsigned int den, q, r;
401 num = EAX | ((uint64_t)EDX << 32);
409 void OPPROTO op_idivl_EAX_T0(void)
414 num = EAX | ((uint64_t)EDX << 32);
424 void OPPROTO op1_movl_T0_im(void)
429 void OPPROTO op1_movl_T1_im(void)
434 void OPPROTO op1_movl_A0_im(void)
441 void OPPROTO op_ldub_T0_A0(void)
443 T0 = ldub((uint8_t *)A0);
446 void OPPROTO op_ldsb_T0_A0(void)
448 T0 = ldsb((int8_t *)A0);
451 void OPPROTO op_lduw_T0_A0(void)
453 T0 = lduw((uint8_t *)A0);
456 void OPPROTO op_ldsw_T0_A0(void)
458 T0 = ldsw((int8_t *)A0);
461 void OPPROTO op_ldl_T0_A0(void)
463 T0 = ldl((uint8_t *)A0);
466 void OPPROTO op_ldub_T1_A0(void)
468 T1 = ldub((uint8_t *)A0);
471 void OPPROTO op_ldsb_T1_A0(void)
473 T1 = ldsb((int8_t *)A0);
476 void OPPROTO op_lduw_T1_A0(void)
478 T1 = lduw((uint8_t *)A0);
481 void OPPROTO op_ldsw_T1_A0(void)
483 T1 = ldsw((int8_t *)A0);
486 void OPPROTO op_ldl_T1_A0(void)
488 T1 = ldl((uint8_t *)A0);
491 void OPPROTO op_stb_T0_A0(void)
493 stb((uint8_t *)A0, T0);
496 void OPPROTO op_stw_T0_A0(void)
498 stw((uint8_t *)A0, T0);
501 void OPPROTO op_stl_T0_A0(void)
503 stl((uint8_t *)A0, T0);
509 void OPPROTO op_jmp_T0(void)
514 void OPPROTO op_jmp_im(void)
524 #include "ops_template.h"
528 #include "ops_template.h"
532 #include "ops_template.h"
537 void OPPROTO op_movsbl_T0_T0(void)
542 void OPPROTO op_movzbl_T0_T0(void)
547 void OPPROTO op_movswl_T0_T0(void)
552 void OPPROTO op_movzwl_T0_T0(void)
557 void OPPROTO op_movswl_EAX_AX(void)
562 void OPPROTO op_movsbw_AX_AL(void)
564 EAX = (EAX & 0xffff0000) | ((int8_t)EAX & 0xffff);
567 void OPPROTO op_movslq_EDX_EAX(void)
569 EDX = (int32_t)EAX >> 31;
572 void OPPROTO op_movswl_DX_AX(void)
574 EDX = (EDX & 0xffff0000) | (((int16_t)EAX >> 15) & 0xffff);
578 /* XXX: add 16 bit operand/16 bit seg variants */
580 void op_pushl_T0(void)
584 stl((void *)offset, T0);
585 /* modify ESP after to handle exceptions correctly */
589 void op_pushl_T1(void)
593 stl((void *)offset, T1);
594 /* modify ESP after to handle exceptions correctly */
598 void op_popl_T0(void)
600 T0 = ldl((void *)ESP);
604 void op_addl_ESP_im(void)
611 /* slow jumps cases (compute x86 flags) */
612 void OPPROTO op_jo_cc(void)
615 eflags = cc_table[CC_OP].compute_all();
622 void OPPROTO op_jb_cc(void)
624 if (cc_table[CC_OP].compute_c())
630 void OPPROTO op_jz_cc(void)
633 eflags = cc_table[CC_OP].compute_all();
640 void OPPROTO op_jbe_cc(void)
643 eflags = cc_table[CC_OP].compute_all();
644 if (eflags & (CC_Z | CC_C))
650 void OPPROTO op_js_cc(void)
653 eflags = cc_table[CC_OP].compute_all();
660 void OPPROTO op_jp_cc(void)
663 eflags = cc_table[CC_OP].compute_all();
670 void OPPROTO op_jl_cc(void)
673 eflags = cc_table[CC_OP].compute_all();
674 if ((eflags ^ (eflags >> 4)) & 0x80)
680 void OPPROTO op_jle_cc(void)
683 eflags = cc_table[CC_OP].compute_all();
684 if (((eflags ^ (eflags >> 4)) & 0x80) || (eflags & CC_Z))
690 /* slow set cases (compute x86 flags) */
691 void OPPROTO op_seto_T0_cc(void)
694 eflags = cc_table[CC_OP].compute_all();
695 T0 = (eflags >> 11) & 1;
698 void OPPROTO op_setb_T0_cc(void)
700 T0 = cc_table[CC_OP].compute_c();
703 void OPPROTO op_setz_T0_cc(void)
706 eflags = cc_table[CC_OP].compute_all();
707 T0 = (eflags >> 6) & 1;
710 void OPPROTO op_setbe_T0_cc(void)
713 eflags = cc_table[CC_OP].compute_all();
714 T0 = (eflags & (CC_Z | CC_C)) != 0;
717 void OPPROTO op_sets_T0_cc(void)
720 eflags = cc_table[CC_OP].compute_all();
721 T0 = (eflags >> 7) & 1;
724 void OPPROTO op_setp_T0_cc(void)
727 eflags = cc_table[CC_OP].compute_all();
728 T0 = (eflags >> 2) & 1;
731 void OPPROTO op_setl_T0_cc(void)
734 eflags = cc_table[CC_OP].compute_all();
735 T0 = ((eflags ^ (eflags >> 4)) >> 7) & 1;
738 void OPPROTO op_setle_T0_cc(void)
741 eflags = cc_table[CC_OP].compute_all();
742 T0 = (((eflags ^ (eflags >> 4)) & 0x80) || (eflags & CC_Z)) != 0;
745 void OPPROTO op_xor_T0_1(void)
750 void OPPROTO op_set_cc_op(void)
755 void OPPROTO op_movl_eflags_T0(void)
758 DF = 1 - (2 * ((T0 >> 10) & 1));
761 /* XXX: compute only O flag */
762 void OPPROTO op_movb_eflags_T0(void)
765 of = cc_table[CC_OP].compute_all() & CC_O;
769 void OPPROTO op_movl_T0_eflags(void)
771 T0 = cc_table[CC_OP].compute_all();
772 T0 |= (DF & DIRECTION_FLAG);
775 void OPPROTO op_cld(void)
780 void OPPROTO op_std(void)
785 void OPPROTO op_clc(void)
788 eflags = cc_table[CC_OP].compute_all();
793 void OPPROTO op_stc(void)
796 eflags = cc_table[CC_OP].compute_all();
801 void OPPROTO op_cmc(void)
804 eflags = cc_table[CC_OP].compute_all();
809 static int compute_all_eflags(void)
814 static int compute_c_eflags(void)
816 return CC_SRC & CC_C;
819 static int compute_c_mul(void)
826 static int compute_all_mul(void)
828 int cf, pf, af, zf, sf, of;
830 pf = 0; /* undefined */
831 af = 0; /* undefined */
832 zf = 0; /* undefined */
833 sf = 0; /* undefined */
835 return cf | pf | af | zf | sf | of;
838 CCTable cc_table[CC_OP_NB] = {
839 [CC_OP_DYNAMIC] = { /* should never happen */ },
841 [CC_OP_EFLAGS] = { compute_all_eflags, compute_c_eflags },
843 [CC_OP_MUL] = { compute_all_mul, compute_c_mul },
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 },
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 },
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 },
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 },
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 },
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 },