4 * Copyright (c) 2003 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
37 static uint8_t *gen_code_ptr;
38 int __op_param1, __op_param2, __op_param3;
44 static void error(const char *fmt, ...)
49 fprintf(stderr, "\n");
50 vfprintf(stderr, fmt, ap);
51 fprintf(stderr, "\n");
57 #define PREFIX_REPNZ 2
60 #define PREFIX_SS 0x10
61 #define PREFIX_DS 0x20
62 #define PREFIX_ES 0x40
63 #define PREFIX_FS 0x80
64 #define PREFIX_GS 0x100
65 #define PREFIX_DATA 0x200
66 #define PREFIX_ADR 0x400
67 #define PREFIX_FWAIT 0x800
69 typedef struct DisasContext {
70 /* current insn context */
73 uint8_t *pc; /* current pc */
74 int cc_op; /* current CC operation */
78 /* i386 arith/logic operations */
98 OP_SHL1, /* undocumented */
113 /* I386 int registers */
114 OR_EAX, /* MUST be even numbered */
122 OR_TMP0, /* temporary operand register */
124 OR_A0, /* temporary register used when doing address evaluation */
125 OR_ZERO, /* fixed zero register */
129 typedef void (GenOpFunc)(void);
130 typedef void (GenOpFunc1)(long);
131 typedef void (GenOpFunc2)(long, long);
133 static GenOpFunc *gen_op_mov_reg_T0[3][8] = {
166 static GenOpFunc *gen_op_mov_reg_T1[3][8] = {
199 static GenOpFunc *gen_op_mov_reg_A0[2][8] = {
222 static GenOpFunc *gen_op_mov_TN_reg[3][2][8] =
292 static GenOpFunc *gen_op_movl_A0_reg[8] = {
303 static GenOpFunc *gen_op_addl_A0_reg_sN[4][8] = {
315 gen_op_addl_A0_EAX_s1,
316 gen_op_addl_A0_ECX_s1,
317 gen_op_addl_A0_EDX_s1,
318 gen_op_addl_A0_EBX_s1,
319 gen_op_addl_A0_ESP_s1,
320 gen_op_addl_A0_EBP_s1,
321 gen_op_addl_A0_ESI_s1,
322 gen_op_addl_A0_EDI_s1,
325 gen_op_addl_A0_EAX_s2,
326 gen_op_addl_A0_ECX_s2,
327 gen_op_addl_A0_EDX_s2,
328 gen_op_addl_A0_EBX_s2,
329 gen_op_addl_A0_ESP_s2,
330 gen_op_addl_A0_EBP_s2,
331 gen_op_addl_A0_ESI_s2,
332 gen_op_addl_A0_EDI_s2,
335 gen_op_addl_A0_EAX_s3,
336 gen_op_addl_A0_ECX_s3,
337 gen_op_addl_A0_EDX_s3,
338 gen_op_addl_A0_EBX_s3,
339 gen_op_addl_A0_ESP_s3,
340 gen_op_addl_A0_EBP_s3,
341 gen_op_addl_A0_ESI_s3,
342 gen_op_addl_A0_EDI_s3,
346 static GenOpFunc *gen_op_arith_T0_T1_cc[8] = {
347 gen_op_addl_T0_T1_cc,
351 gen_op_andl_T0_T1_cc,
352 gen_op_subl_T0_T1_cc,
353 gen_op_xorl_T0_T1_cc,
354 gen_op_cmpl_T0_T1_cc,
357 static GenOpFunc *gen_op_arithc_T0_T1_cc[3][2] = {
359 gen_op_adcb_T0_T1_cc,
360 gen_op_sbbb_T0_T1_cc,
363 gen_op_adcw_T0_T1_cc,
364 gen_op_sbbw_T0_T1_cc,
367 gen_op_adcl_T0_T1_cc,
368 gen_op_sbbl_T0_T1_cc,
372 static const int cc_op_arithb[8] = {
383 static GenOpFunc *gen_op_shift_T0_T1_cc[3][8] = {
385 gen_op_rolb_T0_T1_cc,
386 gen_op_rorb_T0_T1_cc,
387 gen_op_rclb_T0_T1_cc,
388 gen_op_rcrb_T0_T1_cc,
389 gen_op_shlb_T0_T1_cc,
390 gen_op_shrb_T0_T1_cc,
391 gen_op_shlb_T0_T1_cc,
392 gen_op_sarb_T0_T1_cc,
395 gen_op_rolw_T0_T1_cc,
396 gen_op_rorw_T0_T1_cc,
397 gen_op_rclw_T0_T1_cc,
398 gen_op_rcrw_T0_T1_cc,
399 gen_op_shlw_T0_T1_cc,
400 gen_op_shrw_T0_T1_cc,
401 gen_op_shlw_T0_T1_cc,
402 gen_op_sarw_T0_T1_cc,
405 gen_op_roll_T0_T1_cc,
406 gen_op_rorl_T0_T1_cc,
407 gen_op_rcll_T0_T1_cc,
408 gen_op_rcrl_T0_T1_cc,
409 gen_op_shll_T0_T1_cc,
410 gen_op_shrl_T0_T1_cc,
411 gen_op_shll_T0_T1_cc,
412 gen_op_sarl_T0_T1_cc,
416 static GenOpFunc1 *gen_op_shiftd_T0_T1_im_cc[2][2] = {
418 gen_op_shldw_T0_T1_im_cc,
419 gen_op_shrdw_T0_T1_im_cc,
422 gen_op_shldl_T0_T1_im_cc,
423 gen_op_shrdl_T0_T1_im_cc,
427 static GenOpFunc *gen_op_shiftd_T0_T1_ECX_cc[2][2] = {
429 gen_op_shldw_T0_T1_ECX_cc,
430 gen_op_shrdw_T0_T1_ECX_cc,
433 gen_op_shldl_T0_T1_ECX_cc,
434 gen_op_shrdl_T0_T1_ECX_cc,
438 static GenOpFunc *gen_op_btx_T0_T1_cc[2][4] = {
441 gen_op_btsw_T0_T1_cc,
442 gen_op_btrw_T0_T1_cc,
443 gen_op_btcw_T0_T1_cc,
447 gen_op_btsl_T0_T1_cc,
448 gen_op_btrl_T0_T1_cc,
449 gen_op_btcl_T0_T1_cc,
453 static GenOpFunc *gen_op_bsx_T0_cc[2][2] = {
464 static GenOpFunc *gen_op_lds_T0_A0[3] = {
469 static GenOpFunc *gen_op_ldu_T0_A0[3] = {
474 /* sign does not matter */
475 static GenOpFunc *gen_op_ld_T0_A0[3] = {
481 static GenOpFunc *gen_op_ld_T1_A0[3] = {
487 static GenOpFunc *gen_op_st_T0_A0[3] = {
493 static GenOpFunc *gen_op_movs[6] = {
502 static GenOpFunc *gen_op_stos[6] = {
511 static GenOpFunc *gen_op_lods[6] = {
520 static GenOpFunc *gen_op_scas[9] = {
532 static GenOpFunc *gen_op_cmps[9] = {
544 static GenOpFunc *gen_op_ins[6] = {
554 static GenOpFunc *gen_op_outs[6] = {
563 static GenOpFunc *gen_op_in[3] = {
569 static GenOpFunc *gen_op_out[3] = {
586 static GenOpFunc2 *gen_jcc_slow[8] = {
597 static GenOpFunc2 *gen_jcc_sub[3][8] = {
630 static GenOpFunc *gen_setcc_slow[8] = {
641 static GenOpFunc *gen_setcc_sub[3][8] = {
646 gen_op_setbe_T0_subb,
650 gen_op_setle_T0_subb,
656 gen_op_setbe_T0_subw,
660 gen_op_setle_T0_subw,
666 gen_op_setbe_T0_subl,
670 gen_op_setle_T0_subl,
674 static GenOpFunc *gen_op_fp_arith_ST0_FT0[8] = {
680 gen_op_fsubr_ST0_FT0,
682 gen_op_fdivr_ST0_FT0,
685 /* NOTE the exception in "r" op ordering */
686 static GenOpFunc1 *gen_op_fp_arith_STN_ST0[8] = {
691 gen_op_fsubr_STN_ST0,
693 gen_op_fdivr_STN_ST0,
697 static void gen_op(DisasContext *s1, int op, int ot, int d, int s)
700 gen_op_mov_TN_reg[ot][0][d]();
702 gen_op_mov_TN_reg[ot][1][s]();
703 if (op == OP_ADCL || op == OP_SBBL) {
704 if (s1->cc_op != CC_OP_DYNAMIC)
705 gen_op_set_cc_op(s1->cc_op);
706 gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL]();
707 s1->cc_op = CC_OP_DYNAMIC;
709 gen_op_arith_T0_T1_cc[op]();
710 s1->cc_op = cc_op_arithb[op] + ot;
712 if (d != OR_TMP0 && op != OP_CMPL)
713 gen_op_mov_reg_T0[ot][d]();
716 static void gen_opi(DisasContext *s1, int op, int ot, int d, int c)
718 gen_op_movl_T1_im(c);
719 gen_op(s1, op, ot, d, OR_TMP1);
722 static void gen_inc(DisasContext *s1, int ot, int d, int c)
725 gen_op_mov_TN_reg[ot][0][d]();
726 if (s1->cc_op != CC_OP_DYNAMIC)
727 gen_op_set_cc_op(s1->cc_op);
730 s1->cc_op = CC_OP_INCB + ot;
733 s1->cc_op = CC_OP_DECB + ot;
736 gen_op_mov_reg_T0[ot][d]();
739 static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
742 gen_op_mov_TN_reg[ot][0][d]();
744 gen_op_mov_TN_reg[ot][1][s]();
745 /* for zero counts, flags are not updated, so must do it dynamically */
746 if (s1->cc_op != CC_OP_DYNAMIC)
747 gen_op_set_cc_op(s1->cc_op);
749 gen_op_shift_T0_T1_cc[ot][op]();
752 gen_op_mov_reg_T0[ot][d]();
753 s1->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
756 static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c)
758 /* currently not optimized */
759 gen_op_movl_T1_im(c);
760 gen_shift(s1, op, ot, d, OR_TMP1);
763 static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ptr)
770 int reg1, reg2, opreg;
773 mod = (modrm >> 6) & 3;
784 code = ldub(s->pc++);
785 scale = (code >> 6) & 3;
786 index = (code >> 3) & 7;
801 disp = (int8_t)ldub(s->pc++);
813 if (havebase || (havesib && (index != 4 || scale != 0))) {
815 reg1 = OR_EAX + base;
816 if (havesib && index != 4) {
818 reg2 = index + OR_EAX;
820 reg1 = index + OR_EAX;
823 /* XXX: disp only ? */
824 if (reg2 == OR_ZERO) {
825 /* op: disp + (reg1 << scale) */
826 if (reg1 == OR_ZERO) {
827 gen_op_movl_A0_im(disp);
828 } else if (scale == 0 && disp == 0) {
829 gen_op_movl_A0_reg[reg1]();
831 gen_op_movl_A0_im(disp);
832 gen_op_addl_A0_reg_sN[scale][reg1]();
835 /* op: disp + reg1 + (reg2 << scale) */
837 gen_op_movl_A0_im(disp);
838 gen_op_addl_A0_reg_sN[0][reg1]();
840 gen_op_movl_A0_reg[reg1]();
842 gen_op_addl_A0_reg_sN[scale][reg2]();
850 gen_op_movl_A0_im(disp);
857 disp = (int8_t)ldub(s->pc++);
867 gen_op_movl_A0_reg[R_EBX]();
868 gen_op_addl_A0_reg_sN[0][R_ESI]();
871 gen_op_movl_A0_reg[R_EBX]();
872 gen_op_addl_A0_reg_sN[0][R_EDI]();
875 gen_op_movl_A0_reg[R_EBP]();
876 gen_op_addl_A0_reg_sN[0][R_ESI]();
879 gen_op_movl_A0_reg[R_EBP]();
880 gen_op_addl_A0_reg_sN[0][R_EDI]();
883 gen_op_movl_A0_reg[R_ESI]();
886 gen_op_movl_A0_reg[R_EDI]();
889 gen_op_movl_A0_reg[R_EBP]();
893 gen_op_movl_A0_reg[R_EBX]();
897 gen_op_addl_A0_im(disp);
898 gen_op_andl_A0_ffff();
907 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg !=
909 static void gen_ldst_modrm(DisasContext *s, int modrm, int ot, int reg, int is_store)
911 int mod, rm, opreg, disp;
913 mod = (modrm >> 6) & 3;
918 gen_op_mov_TN_reg[ot][0][reg]();
919 gen_op_mov_reg_T0[ot][rm]();
921 gen_op_mov_TN_reg[ot][0][rm]();
923 gen_op_mov_reg_T0[ot][reg]();
926 gen_lea_modrm(s, modrm, &opreg, &disp);
929 gen_op_mov_TN_reg[ot][0][reg]();
930 gen_op_st_T0_A0[ot]();
932 gen_op_ld_T0_A0[ot]();
934 gen_op_mov_reg_T0[ot][reg]();
939 static inline uint32_t insn_get(DisasContext *s, int ot)
961 static void gen_jcc(DisasContext *s, int b, int val)
967 jcc_op = (b >> 1) & 7;
969 /* we optimize the cmp/jcc case */
973 func = gen_jcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
978 /* some jumps are easy to compute */
1005 func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
1008 func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
1016 if (s->cc_op != CC_OP_DYNAMIC)
1017 gen_op_set_cc_op(s->cc_op);
1018 func = gen_jcc_slow[jcc_op];
1022 func(val, (long)s->pc);
1024 func((long)s->pc, val);
1028 static void gen_setcc(DisasContext *s, int b)
1034 jcc_op = (b >> 1) & 7;
1036 /* we optimize the cmp/jcc case */
1040 func = gen_setcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
1045 /* some jumps are easy to compute */
1063 func = gen_setcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
1066 func = gen_setcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
1074 if (s->cc_op != CC_OP_DYNAMIC)
1075 gen_op_set_cc_op(s->cc_op);
1076 func = gen_setcc_slow[jcc_op];
1085 /* return the next pc address. Return -1 if no insn found. *is_jmp_ptr
1086 is set to true if the instruction sets the PC (last instruction of
1088 long disas_insn(DisasContext *s, uint8_t *pc_start, int *is_jmp_ptr)
1090 int b, prefixes, aflag, dflag;
1092 int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
1098 // cur_pc = s->pc; /* for insn generation */
1102 /* check prefixes */
1105 prefixes |= PREFIX_REPZ;
1108 prefixes |= PREFIX_REPNZ;
1111 prefixes |= PREFIX_LOCK;
1114 prefixes |= PREFIX_CS;
1117 prefixes |= PREFIX_SS;
1120 prefixes |= PREFIX_DS;
1123 prefixes |= PREFIX_ES;
1126 prefixes |= PREFIX_FS;
1129 prefixes |= PREFIX_GS;
1132 prefixes |= PREFIX_DATA;
1135 prefixes |= PREFIX_ADR;
1138 prefixes |= PREFIX_FWAIT;
1142 if (prefixes & PREFIX_DATA)
1144 if (prefixes & PREFIX_ADR)
1147 s->prefix = prefixes;
1151 /* now check op code */
1155 /**************************/
1156 /* extended op code */
1157 b = ldub(s->pc++) | 0x100;
1160 /**************************/
1178 ot = dflag ? OT_LONG : OT_WORD;
1181 case 0: /* OP Ev, Gv */
1182 modrm = ldub(s->pc++);
1183 reg = ((modrm >> 3) & 7) + OR_EAX;
1184 mod = (modrm >> 6) & 3;
1187 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1188 gen_op_ld_T0_A0[ot]();
1191 opreg = OR_EAX + rm;
1193 gen_op(s, op, ot, opreg, reg);
1194 if (mod != 3 && op != 7) {
1195 gen_op_st_T0_A0[ot]();
1198 case 1: /* OP Gv, Ev */
1199 modrm = ldub(s->pc++);
1200 mod = (modrm >> 6) & 3;
1201 reg = ((modrm >> 3) & 7) + OR_EAX;
1204 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1205 gen_op_ld_T1_A0[ot]();
1208 opreg = OR_EAX + rm;
1210 gen_op(s, op, ot, reg, opreg);
1212 case 2: /* OP A, Iv */
1213 val = insn_get(s, ot);
1214 gen_opi(s, op, ot, OR_EAX, val);
1220 case 0x80: /* GRP1 */
1229 ot = dflag ? OT_LONG : OT_WORD;
1231 modrm = ldub(s->pc++);
1232 mod = (modrm >> 6) & 3;
1234 op = (modrm >> 3) & 7;
1237 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1238 gen_op_ld_T0_A0[ot]();
1241 opreg = rm + OR_EAX;
1248 val = insn_get(s, ot);
1251 val = (int8_t)insn_get(s, OT_BYTE);
1255 gen_opi(s, op, ot, opreg, val);
1256 if (op != 7 && mod != 3) {
1257 gen_op_st_T0_A0[ot]();
1262 /**************************/
1263 /* inc, dec, and other misc arith */
1264 case 0x40 ... 0x47: /* inc Gv */
1265 ot = dflag ? OT_LONG : OT_WORD;
1266 gen_inc(s, ot, OR_EAX + (b & 7), 1);
1268 case 0x48 ... 0x4f: /* dec Gv */
1269 ot = dflag ? OT_LONG : OT_WORD;
1270 gen_inc(s, ot, OR_EAX + (b & 7), -1);
1272 case 0xf6: /* GRP3 */
1277 ot = dflag ? OT_LONG : OT_WORD;
1279 modrm = ldub(s->pc++);
1280 mod = (modrm >> 6) & 3;
1282 op = (modrm >> 3) & 7;
1284 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1285 gen_op_ld_T0_A0[ot]();
1287 gen_op_mov_TN_reg[ot][0][rm]();
1292 val = insn_get(s, ot);
1293 gen_op_movl_T1_im(val);
1294 gen_op_testl_T0_T1_cc();
1295 s->cc_op = CC_OP_LOGICB + ot;
1300 gen_op_st_T0_A0[ot]();
1302 gen_op_mov_reg_T0[ot][rm]();
1306 gen_op_negl_T0_cc();
1308 gen_op_st_T0_A0[ot]();
1310 gen_op_mov_reg_T0[ot][rm]();
1312 s->cc_op = CC_OP_SUBB + ot;
1317 gen_op_mulb_AL_T0();
1320 gen_op_mulw_AX_T0();
1324 gen_op_mull_EAX_T0();
1327 s->cc_op = CC_OP_MUL;
1332 gen_op_imulb_AL_T0();
1335 gen_op_imulw_AX_T0();
1339 gen_op_imull_EAX_T0();
1342 s->cc_op = CC_OP_MUL;
1347 gen_op_divb_AL_T0();
1350 gen_op_divw_AX_T0();
1354 gen_op_divl_EAX_T0();
1361 gen_op_idivb_AL_T0();
1364 gen_op_idivw_AX_T0();
1368 gen_op_idivl_EAX_T0();
1373 error("GRP3: bad instruction");
1378 case 0xfe: /* GRP4 */
1379 case 0xff: /* GRP5 */
1383 ot = dflag ? OT_LONG : OT_WORD;
1385 modrm = ldub(s->pc++);
1386 mod = (modrm >> 6) & 3;
1388 op = (modrm >> 3) & 7;
1389 if (op >= 2 && b == 0xfe) {
1390 error("GRP4: bad instruction");
1394 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1395 gen_op_ld_T0_A0[ot]();
1397 gen_op_mov_TN_reg[ot][0][rm]();
1401 case 0: /* inc Ev */
1402 gen_inc(s, ot, OR_TMP0, 1);
1404 gen_op_st_T0_A0[ot]();
1406 gen_op_mov_reg_T0[ot][rm]();
1408 case 1: /* dec Ev */
1409 gen_inc(s, ot, OR_TMP0, -1);
1411 gen_op_st_T0_A0[ot]();
1413 gen_op_mov_reg_T0[ot][rm]();
1415 case 2: /* call Ev */
1416 gen_op_movl_T1_im((long)s->pc);
1421 case 4: /* jmp Ev */
1425 case 6: /* push Ev */
1429 error("GRP5: bad instruction");
1434 case 0x84: /* test Ev, Gv */
1439 ot = dflag ? OT_LONG : OT_WORD;
1441 modrm = ldub(s->pc++);
1442 mod = (modrm >> 6) & 3;
1444 reg = (modrm >> 3) & 7;
1446 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1447 gen_op_mov_TN_reg[ot][1][reg + OR_EAX]();
1448 gen_op_testl_T0_T1_cc();
1449 s->cc_op = CC_OP_LOGICB + ot;
1452 case 0xa8: /* test eAX, Iv */
1457 ot = dflag ? OT_LONG : OT_WORD;
1458 val = insn_get(s, ot);
1460 gen_op_mov_TN_reg[ot][0][OR_EAX]();
1461 gen_op_movl_T1_im(val);
1462 gen_op_testl_T0_T1_cc();
1463 s->cc_op = CC_OP_LOGICB + ot;
1466 case 0x98: /* CWDE/CBW */
1468 gen_op_movswl_EAX_AX();
1470 gen_op_movsbw_AX_AL();
1472 case 0x99: /* CDQ/CWD */
1474 gen_op_movslq_EDX_EAX();
1476 gen_op_movswl_DX_AX();
1478 case 0x1af: /* imul Gv, Ev */
1479 case 0x69: /* imul Gv, Ev, I */
1481 ot = dflag ? OT_LONG : OT_WORD;
1482 modrm = ldub(s->pc++);
1483 reg = ((modrm >> 3) & 7) + OR_EAX;
1484 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1486 val = insn_get(s, ot);
1487 gen_op_movl_T1_im(val);
1488 } else if (b == 0x6b) {
1489 val = insn_get(s, OT_BYTE);
1490 gen_op_movl_T1_im(val);
1492 gen_op_mov_TN_reg[ot][1][reg]();
1495 if (ot == OT_LONG) {
1496 gen_op_imull_T0_T1();
1498 gen_op_imulw_T0_T1();
1500 gen_op_mov_reg_T0[ot][reg]();
1501 s->cc_op = CC_OP_MUL;
1504 /**************************/
1506 case 0x50 ... 0x57: /* push */
1507 gen_op_mov_TN_reg[OT_LONG][0][b & 7]();
1510 case 0x58 ... 0x5f: /* pop */
1512 gen_op_mov_reg_T0[OT_LONG][b & 7]();
1514 case 0x68: /* push Iv */
1516 ot = dflag ? OT_LONG : OT_WORD;
1518 val = insn_get(s, ot);
1520 val = (int8_t)insn_get(s, OT_BYTE);
1521 gen_op_movl_T0_im(val);
1524 case 0x8f: /* pop Ev */
1525 ot = dflag ? OT_LONG : OT_WORD;
1526 modrm = ldub(s->pc++);
1528 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
1530 case 0xc9: /* leave */
1531 gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
1532 gen_op_mov_reg_T0[OT_LONG][R_ESP]();
1534 gen_op_mov_reg_T0[OT_LONG][R_EBP]();
1536 /**************************/
1539 case 0x89: /* mov Gv, Ev */
1543 ot = dflag ? OT_LONG : OT_WORD;
1544 modrm = ldub(s->pc++);
1545 reg = (modrm >> 3) & 7;
1547 /* generate a generic store */
1548 gen_ldst_modrm(s, modrm, ot, OR_EAX + reg, 1);
1551 case 0xc7: /* mov Ev, Iv */
1555 ot = dflag ? OT_LONG : OT_WORD;
1556 modrm = ldub(s->pc++);
1557 mod = (modrm >> 6) & 3;
1559 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1560 val = insn_get(s, ot);
1561 gen_op_movl_T0_im(val);
1563 gen_op_st_T0_A0[ot]();
1565 gen_op_mov_reg_T0[ot][modrm & 7]();
1568 case 0x8b: /* mov Ev, Gv */
1572 ot = dflag ? OT_LONG : OT_WORD;
1573 modrm = ldub(s->pc++);
1574 reg = (modrm >> 3) & 7;
1576 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1577 gen_op_mov_reg_T0[ot][reg]();
1580 case 0x1b6: /* movzbS Gv, Eb */
1581 case 0x1b7: /* movzwS Gv, Eb */
1582 case 0x1be: /* movsbS Gv, Eb */
1583 case 0x1bf: /* movswS Gv, Eb */
1586 /* d_ot is the size of destination */
1587 d_ot = dflag + OT_WORD;
1588 /* ot is the size of source */
1589 ot = (b & 1) + OT_BYTE;
1590 modrm = ldub(s->pc++);
1591 reg = ((modrm >> 3) & 7) + OR_EAX;
1592 mod = (modrm >> 6) & 3;
1596 gen_op_mov_TN_reg[ot][0][rm]();
1597 switch(ot | (b & 8)) {
1599 gen_op_movzbl_T0_T0();
1602 gen_op_movsbl_T0_T0();
1605 gen_op_movzwl_T0_T0();
1609 gen_op_movswl_T0_T0();
1612 gen_op_mov_reg_T0[d_ot][reg]();
1614 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1616 gen_op_lds_T0_A0[ot]();
1618 gen_op_ldu_T0_A0[ot]();
1620 gen_op_mov_reg_T0[d_ot][reg]();
1625 case 0x8d: /* lea */
1626 ot = dflag ? OT_LONG : OT_WORD;
1627 modrm = ldub(s->pc++);
1628 reg = (modrm >> 3) & 7;
1630 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1631 gen_op_mov_reg_A0[ot - OT_WORD][reg]();
1634 case 0xa0: /* mov EAX, Ov */
1636 case 0xa2: /* mov Ov, EAX */
1641 ot = dflag ? OT_LONG : OT_WORD;
1643 offset_addr = insn_get(s, OT_LONG);
1645 offset_addr = insn_get(s, OT_WORD);
1646 gen_op_movl_A0_im(offset_addr);
1648 gen_op_ld_T0_A0[ot]();
1649 gen_op_mov_reg_T0[ot][R_EAX]();
1651 gen_op_mov_TN_reg[ot][0][R_EAX]();
1652 gen_op_st_T0_A0[ot]();
1656 case 0xb0 ... 0xb7: /* mov R, Ib */
1657 val = insn_get(s, OT_BYTE);
1658 gen_op_movl_T0_im(val);
1659 gen_op_mov_reg_T0[OT_BYTE][b & 7]();
1661 case 0xb8 ... 0xbf: /* mov R, Iv */
1662 ot = dflag ? OT_LONG : OT_WORD;
1663 val = insn_get(s, ot);
1664 reg = OR_EAX + (b & 7);
1665 gen_op_movl_T0_im(val);
1666 gen_op_mov_reg_T0[ot][reg]();
1669 case 0x91 ... 0x97: /* xchg R, EAX */
1670 ot = dflag ? OT_LONG : OT_WORD;
1672 gen_op_mov_TN_reg[ot][0][reg]();
1673 gen_op_mov_TN_reg[ot][1][R_EAX]();
1674 gen_op_mov_reg_T0[ot][R_EAX]();
1675 gen_op_mov_reg_T1[ot][reg]();
1678 case 0x87: /* xchg Ev, Gv */
1682 ot = dflag ? OT_LONG : OT_WORD;
1683 modrm = ldub(s->pc++);
1684 reg = (modrm >> 3) & 7;
1686 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1687 gen_op_mov_TN_reg[ot][0][reg]();
1688 gen_op_ld_T1_A0[ot]();
1689 gen_op_st_T0_A0[ot]();
1690 gen_op_mov_reg_T1[ot][reg]();
1693 /************************/
1704 ot = dflag ? OT_LONG : OT_WORD;
1706 modrm = ldub(s->pc++);
1707 mod = (modrm >> 6) & 3;
1709 op = (modrm >> 3) & 7;
1712 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1713 gen_op_ld_T0_A0[ot]();
1716 opreg = rm + OR_EAX;
1721 gen_shift(s, op, ot, opreg, OR_ECX);
1724 shift = ldub(s->pc++);
1726 gen_shifti(s, op, ot, opreg, shift);
1730 gen_op_st_T0_A0[ot]();
1745 case 0x1a4: /* shld imm */
1749 case 0x1a5: /* shld cl */
1753 case 0x1ac: /* shrd imm */
1757 case 0x1ad: /* shrd cl */
1761 ot = dflag ? OT_LONG : OT_WORD;
1762 modrm = ldub(s->pc++);
1763 mod = (modrm >> 6) & 3;
1765 reg = (modrm >> 3) & 7;
1768 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1769 gen_op_ld_T0_A0[ot]();
1771 gen_op_mov_TN_reg[ot][0][rm]();
1773 gen_op_mov_TN_reg[ot][1][reg]();
1776 val = ldub(s->pc++);
1779 gen_op_shiftd_T0_T1_im_cc[ot - OT_WORD][op](val);
1780 if (op == 0 && ot != OT_WORD)
1781 s->cc_op = CC_OP_SHLB + ot;
1783 s->cc_op = CC_OP_SARB + ot;
1786 if (s->cc_op != CC_OP_DYNAMIC)
1787 gen_op_set_cc_op(s->cc_op);
1788 gen_op_shiftd_T0_T1_ECX_cc[ot - OT_WORD][op]();
1789 s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1792 gen_op_st_T0_A0[ot]();
1794 gen_op_mov_reg_T0[ot][rm]();
1798 /************************/
1801 modrm = ldub(s->pc++);
1802 mod = (modrm >> 6) & 3;
1804 op = ((b & 7) << 3) | ((modrm >> 3) & 7);
1808 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1810 case 0x00 ... 0x07: /* fxxxs */
1811 case 0x10 ... 0x17: /* fixxxl */
1812 case 0x20 ... 0x27: /* fxxxl */
1813 case 0x30 ... 0x37: /* fixxx */
1820 gen_op_flds_FT0_A0();
1823 gen_op_fildl_FT0_A0();
1826 gen_op_fldl_FT0_A0();
1830 gen_op_fild_FT0_A0();
1834 gen_op_fp_arith_ST0_FT0[op1]();
1836 /* fcomp needs pop */
1841 case 0x08: /* flds */
1842 case 0x0a: /* fsts */
1843 case 0x0b: /* fstps */
1844 case 0x18: /* fildl */
1845 case 0x1a: /* fistl */
1846 case 0x1b: /* fistpl */
1847 case 0x28: /* fldl */
1848 case 0x2a: /* fstl */
1849 case 0x2b: /* fstpl */
1850 case 0x38: /* filds */
1851 case 0x3a: /* fists */
1852 case 0x3b: /* fistps */
1859 gen_op_flds_ST0_A0();
1862 gen_op_fildl_ST0_A0();
1865 gen_op_fldl_ST0_A0();
1869 gen_op_fild_ST0_A0();
1876 gen_op_fsts_ST0_A0();
1879 gen_op_fistl_ST0_A0();
1882 gen_op_fstl_ST0_A0();
1886 gen_op_fist_ST0_A0();
1894 case 0x0d: /* fldcw mem */
1897 case 0x0f: /* fnstcw mem */
1900 case 0x1d: /* fldt mem */
1902 gen_op_fldt_ST0_A0();
1904 case 0x1f: /* fstpt mem */
1905 gen_op_fstt_ST0_A0();
1908 case 0x2f: /* fnstsw mem */
1911 case 0x3c: /* fbld */
1913 gen_op_fbld_ST0_A0();
1915 case 0x3e: /* fbstp */
1916 gen_op_fbst_ST0_A0();
1919 case 0x3d: /* fildll */
1921 gen_op_fildll_ST0_A0();
1923 case 0x3f: /* fistpll */
1924 gen_op_fistll_ST0_A0();
1928 error("unhandled FPm [op=0x%02x]\n", op);
1932 /* register float ops */
1936 case 0x08: /* fld sti */
1938 gen_op_fmov_ST0_STN((opreg + 1) & 7);
1940 case 0x09: /* fxchg sti */
1941 gen_op_fxchg_ST0_STN(opreg);
1943 case 0x0a: /* grp d9/2 */
1948 error("unhandled FP GRP d9/2\n");
1952 case 0x0c: /* grp d9/4 */
1962 gen_op_fcom_ST0_FT0();
1971 case 0x0d: /* grp d9/5 */
1980 gen_op_fldl2t_ST0();
1984 gen_op_fldl2e_ST0();
1992 gen_op_fldlg2_ST0();
1996 gen_op_fldln2_ST0();
2007 case 0x0e: /* grp d9/6 */
2018 case 3: /* fpatan */
2021 case 4: /* fxtract */
2024 case 5: /* fprem1 */
2027 case 6: /* fdecstp */
2031 case 7: /* fincstp */
2036 case 0x0f: /* grp d9/7 */
2041 case 1: /* fyl2xp1 */
2047 case 3: /* fsincos */
2050 case 5: /* fscale */
2053 case 4: /* frndint */
2065 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
2066 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
2067 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
2073 gen_op_fp_arith_STN_ST0[op1](opreg);
2077 gen_op_fmov_FT0_STN(opreg);
2078 gen_op_fp_arith_ST0_FT0[op1]();
2082 case 0x02: /* fcom */
2083 gen_op_fmov_FT0_STN(opreg);
2084 gen_op_fcom_ST0_FT0();
2086 case 0x03: /* fcomp */
2087 gen_op_fmov_FT0_STN(opreg);
2088 gen_op_fcom_ST0_FT0();
2091 case 0x15: /* da/5 */
2093 case 1: /* fucompp */
2094 gen_op_fmov_FT0_STN(1);
2095 gen_op_fucom_ST0_FT0();
2103 case 0x2a: /* fst sti */
2104 gen_op_fmov_STN_ST0(opreg);
2106 case 0x2b: /* fstp sti */
2107 gen_op_fmov_STN_ST0(opreg);
2110 case 0x2c: /* fucom st(i) */
2111 gen_op_fmov_FT0_STN(opreg);
2112 gen_op_fucom_ST0_FT0();
2114 case 0x2d: /* fucomp st(i) */
2115 gen_op_fmov_FT0_STN(opreg);
2116 gen_op_fucom_ST0_FT0();
2119 case 0x33: /* de/3 */
2121 case 1: /* fcompp */
2122 gen_op_fmov_FT0_STN(1);
2123 gen_op_fcom_ST0_FT0();
2131 case 0x3c: /* df/4 */
2134 gen_op_fnstsw_EAX();
2137 error("unhandled FP %x df/4\n", rm);
2142 error("unhandled FPr [op=0x%x]\n", op);
2147 /************************/
2149 case 0xa4: /* movsS */
2154 ot = dflag ? OT_LONG : OT_WORD;
2155 if (prefixes & PREFIX_REPZ) {
2156 gen_op_movs[3 + ot]();
2162 case 0xaa: /* stosS */
2167 ot = dflag ? OT_LONG : OT_WORD;
2168 if (prefixes & PREFIX_REPZ) {
2169 gen_op_stos[3 + ot]();
2174 case 0xac: /* lodsS */
2179 ot = dflag ? OT_LONG : OT_WORD;
2180 if (prefixes & PREFIX_REPZ) {
2181 gen_op_lods[3 + ot]();
2186 case 0xae: /* scasS */
2191 ot = dflag ? OT_LONG : OT_WORD;
2192 if (prefixes & PREFIX_REPNZ) {
2193 if (s->cc_op != CC_OP_DYNAMIC)
2194 gen_op_set_cc_op(s->cc_op);
2195 gen_op_scas[6 + ot]();
2196 s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2197 } else if (prefixes & PREFIX_REPZ) {
2198 if (s->cc_op != CC_OP_DYNAMIC)
2199 gen_op_set_cc_op(s->cc_op);
2200 gen_op_scas[3 + ot]();
2201 s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2204 s->cc_op = CC_OP_SUBB + ot;
2208 case 0xa6: /* cmpsS */
2213 ot = dflag ? OT_LONG : OT_WORD;
2214 if (prefixes & PREFIX_REPNZ) {
2215 if (s->cc_op != CC_OP_DYNAMIC)
2216 gen_op_set_cc_op(s->cc_op);
2217 gen_op_cmps[6 + ot]();
2218 s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2219 } else if (prefixes & PREFIX_REPZ) {
2220 if (s->cc_op != CC_OP_DYNAMIC)
2221 gen_op_set_cc_op(s->cc_op);
2222 gen_op_cmps[3 + ot]();
2223 s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2226 s->cc_op = CC_OP_SUBB + ot;
2230 /************************/
2232 case 0x6c: /* insS */
2237 ot = dflag ? OT_LONG : OT_WORD;
2238 if (prefixes & PREFIX_REPZ) {
2239 gen_op_ins[3 + ot]();
2244 case 0x6e: /* outsS */
2249 ot = dflag ? OT_LONG : OT_WORD;
2250 if (prefixes & PREFIX_REPZ) {
2251 gen_op_outs[3 + ot]();
2261 ot = dflag ? OT_LONG : OT_WORD;
2262 val = ldub(s->pc++);
2263 gen_op_movl_T0_im(val);
2265 gen_op_mov_reg_T1[ot][R_EAX]();
2272 ot = dflag ? OT_LONG : OT_WORD;
2273 val = ldub(s->pc++);
2274 gen_op_movl_T0_im(val);
2275 gen_op_mov_TN_reg[ot][1][R_EAX]();
2283 ot = dflag ? OT_LONG : OT_WORD;
2284 gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
2286 gen_op_mov_reg_T1[ot][R_EAX]();
2293 ot = dflag ? OT_LONG : OT_WORD;
2294 gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
2295 gen_op_mov_TN_reg[ot][1][R_EAX]();
2299 /************************/
2301 case 0xc2: /* ret im */
2302 /* XXX: handle stack pop ? */
2306 gen_op_addl_ESP_im(val);
2310 case 0xc3: /* ret */
2315 case 0xe8: /* call */
2316 val = insn_get(s, OT_LONG);
2318 gen_op_movl_T1_im((long)s->pc);
2323 case 0xe9: /* jmp */
2324 val = insn_get(s, OT_LONG);
2329 case 0xeb: /* jmp Jb */
2330 val = (int8_t)insn_get(s, OT_BYTE);
2335 case 0x70 ... 0x7f: /* jcc Jb */
2336 val = (int8_t)insn_get(s, OT_BYTE);
2339 case 0x180 ... 0x18f: /* jcc Jv */
2341 val = insn_get(s, OT_LONG);
2343 val = (int16_t)insn_get(s, OT_WORD);
2345 val += (long)s->pc; /* XXX: fix 16 bit wrap */
2351 case 0x190 ... 0x19f:
2352 modrm = ldub(s->pc++);
2354 gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1);
2357 /************************/
2359 case 0x9c: /* pushf */
2360 if (s->cc_op != CC_OP_DYNAMIC)
2361 gen_op_set_cc_op(s->cc_op);
2362 gen_op_movl_T0_eflags();
2365 case 0x9d: /* popf */
2367 gen_op_movl_eflags_T0();
2368 s->cc_op = CC_OP_EFLAGS;
2370 case 0x9e: /* sahf */
2371 gen_op_mov_TN_reg[OT_BYTE][0][R_AH]();
2372 if (s->cc_op != CC_OP_DYNAMIC)
2373 gen_op_set_cc_op(s->cc_op);
2374 gen_op_movb_eflags_T0();
2375 s->cc_op = CC_OP_EFLAGS;
2377 case 0x9f: /* lahf */
2378 if (s->cc_op != CC_OP_DYNAMIC)
2379 gen_op_set_cc_op(s->cc_op);
2380 gen_op_movl_T0_eflags();
2381 gen_op_mov_reg_T0[OT_BYTE][R_AH]();
2383 case 0xf5: /* cmc */
2384 if (s->cc_op != CC_OP_DYNAMIC)
2385 gen_op_set_cc_op(s->cc_op);
2387 s->cc_op = CC_OP_EFLAGS;
2389 case 0xf8: /* clc */
2390 if (s->cc_op != CC_OP_DYNAMIC)
2391 gen_op_set_cc_op(s->cc_op);
2393 s->cc_op = CC_OP_EFLAGS;
2395 case 0xf9: /* stc */
2396 if (s->cc_op != CC_OP_DYNAMIC)
2397 gen_op_set_cc_op(s->cc_op);
2399 s->cc_op = CC_OP_EFLAGS;
2401 case 0xfc: /* cld */
2404 case 0xfd: /* std */
2408 /************************/
2409 /* bit operations */
2410 case 0x1ba: /* bt/bts/btr/btc Gv, im */
2411 ot = dflag ? OT_LONG : OT_WORD;
2412 modrm = ldub(s->pc++);
2413 op = (modrm >> 3) & 7;
2414 mod = (modrm >> 6) & 3;
2417 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
2418 gen_op_ld_T0_A0[ot]();
2420 gen_op_mov_TN_reg[ot][0][rm]();
2423 val = ldub(s->pc++);
2424 gen_op_movl_T1_im(val);
2428 gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
2429 s->cc_op = CC_OP_SARB + ot;
2432 gen_op_st_T0_A0[ot]();
2434 gen_op_mov_reg_T0[ot][rm]();
2437 case 0x1a3: /* bt Gv, Ev */
2440 case 0x1ab: /* bts */
2443 case 0x1b3: /* btr */
2446 case 0x1bb: /* btc */
2449 ot = dflag ? OT_LONG : OT_WORD;
2450 modrm = ldub(s->pc++);
2451 reg = (modrm >> 3) & 7;
2452 mod = (modrm >> 6) & 3;
2454 gen_op_mov_TN_reg[OT_LONG][1][reg]();
2456 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
2457 /* specific case: we need to add a displacement */
2459 gen_op_add_bitw_A0_T1();
2461 gen_op_add_bitl_A0_T1();
2462 gen_op_ld_T0_A0[ot]();
2464 gen_op_mov_TN_reg[ot][0][rm]();
2466 gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
2467 s->cc_op = CC_OP_SARB + ot;
2470 gen_op_st_T0_A0[ot]();
2472 gen_op_mov_reg_T0[ot][rm]();
2475 case 0x1bc: /* bsf */
2476 case 0x1bd: /* bsr */
2477 ot = dflag ? OT_LONG : OT_WORD;
2478 modrm = ldub(s->pc++);
2479 reg = (modrm >> 3) & 7;
2480 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
2481 gen_op_bsx_T0_cc[ot - OT_WORD][b & 1]();
2482 /* NOTE: we always write back the result. Intel doc says it is
2483 undefined if T0 == 0 */
2484 gen_op_mov_reg_T0[ot][reg]();
2485 s->cc_op = CC_OP_LOGICB + ot;
2487 /************************/
2489 case 0x90: /* nop */
2491 case 0xcc: /* int3 */
2492 gen_op_int3((long)pc_start);
2495 case 0xcd: /* int N */
2496 val = ldub(s->pc++);
2497 /* XXX: currently we ignore the interrupt number */
2498 gen_op_int_im((long)pc_start);
2501 case 0xce: /* into */
2502 if (s->cc_op != CC_OP_DYNAMIC)
2503 gen_op_set_cc_op(s->cc_op);
2504 gen_op_into((long)pc_start, (long)s->pc);
2507 case 0x1c8 ... 0x1cf: /* bswap reg */
2509 gen_op_mov_TN_reg[OT_LONG][0][reg]();
2511 gen_op_mov_reg_T0[OT_LONG][reg]();
2515 case 0x1a2: /* cpuid */
2520 error("unknown opcode %x", b);
2526 /* return the next pc */
2527 int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
2528 int *gen_code_size_ptr, uint8_t *pc_start)
2530 DisasContext dc1, *dc = &dc1;
2531 uint8_t *gen_code_end, *pc_ptr;
2535 struct disassemble_info disasm_info;
2538 dc->cc_op = CC_OP_DYNAMIC;
2539 gen_code_ptr = gen_code_buf;
2540 gen_code_end = gen_code_buf + max_code_size - 4096;
2546 ret = disas_insn(dc, pc_ptr, &is_jmp);
2548 error("unknown instruction at PC=0x%x B=%02x %02x",
2549 pc_ptr, pc_ptr[0], pc_ptr[1]);
2550 pc_ptr = (void *)ret;
2551 } while (!is_jmp && gen_code_ptr < gen_code_end);
2552 /* we must store the eflags state if it is not already done */
2553 if (dc->cc_op != CC_OP_DYNAMIC)
2554 gen_op_set_cc_op(dc->cc_op);
2556 /* we add an additionnal jmp to update the simulated PC */
2560 *gen_code_size_ptr = gen_code_ptr - gen_code_buf;
2567 INIT_DISASSEMBLE_INFO(disasm_info, logfile, fprintf);
2569 disasm_info.flavour = bfd_get_flavour (abfd);
2570 disasm_info.arch = bfd_get_arch (abfd);
2571 disasm_info.mach = bfd_get_mach (abfd);
2573 #ifdef WORDS_BIGENDIAN
2574 disasm_info.endian = BFD_ENDIAN_BIG;
2576 disasm_info.endian = BFD_ENDIAN_LITTLE;
2578 fprintf(logfile, "IN:\n");
2579 disasm_info.buffer = pc_start;
2580 disasm_info.buffer_vma = (unsigned long)pc_start;
2581 disasm_info.buffer_length = pc_ptr - pc_start;
2583 while (pc < pc_ptr) {
2584 fprintf(logfile, "0x%08lx: ", (long)pc);
2585 count = print_insn_i386((unsigned long)pc, &disasm_info);
2586 fprintf(logfile, "\n");
2589 fprintf(logfile, "\n");
2592 disasm_info.buffer = pc;
2593 disasm_info.buffer_vma = (unsigned long)pc;
2594 disasm_info.buffer_length = *gen_code_size_ptr;
2595 fprintf(logfile, "OUT: [size=%d]\n", *gen_code_size_ptr);
2596 while (pc < gen_code_ptr) {
2597 fprintf(logfile, "0x%08lx: ", (long)pc);
2598 count = print_insn_i386((unsigned long)pc, &disasm_info);
2599 fprintf(logfile, "\n");
2602 fprintf(logfile, "\n");
2608 CPUX86State *cpu_x86_init(void)
2613 cpu_x86_tblocks_init();
2615 env = malloc(sizeof(CPUX86State));
2618 memset(env, 0, sizeof(CPUX86State));
2619 /* basic FPU init */
2620 for(i = 0;i < 8; i++)
2624 env->cc_op = CC_OP_EFLAGS;
2629 void cpu_x86_close(CPUX86State *env)