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 0x60: /* pusha */
1520 case 0x61: /* popa */
1526 case 0x68: /* push Iv */
1528 ot = dflag ? OT_LONG : OT_WORD;
1530 val = insn_get(s, ot);
1532 val = (int8_t)insn_get(s, OT_BYTE);
1533 gen_op_movl_T0_im(val);
1536 case 0x8f: /* pop Ev */
1537 ot = dflag ? OT_LONG : OT_WORD;
1538 modrm = ldub(s->pc++);
1540 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
1542 case 0xc8: /* enter */
1547 level = ldub(s->pc++);
1549 gen_op_enterl(val, level);
1552 case 0xc9: /* leave */
1553 gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
1554 gen_op_mov_reg_T0[OT_LONG][R_ESP]();
1556 gen_op_mov_reg_T0[OT_LONG][R_EBP]();
1558 /**************************/
1561 case 0x89: /* mov Gv, Ev */
1565 ot = dflag ? OT_LONG : OT_WORD;
1566 modrm = ldub(s->pc++);
1567 reg = (modrm >> 3) & 7;
1569 /* generate a generic store */
1570 gen_ldst_modrm(s, modrm, ot, OR_EAX + reg, 1);
1573 case 0xc7: /* mov Ev, Iv */
1577 ot = dflag ? OT_LONG : OT_WORD;
1578 modrm = ldub(s->pc++);
1579 mod = (modrm >> 6) & 3;
1581 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1582 val = insn_get(s, ot);
1583 gen_op_movl_T0_im(val);
1585 gen_op_st_T0_A0[ot]();
1587 gen_op_mov_reg_T0[ot][modrm & 7]();
1590 case 0x8b: /* mov Ev, Gv */
1594 ot = dflag ? OT_LONG : OT_WORD;
1595 modrm = ldub(s->pc++);
1596 reg = (modrm >> 3) & 7;
1598 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1599 gen_op_mov_reg_T0[ot][reg]();
1602 case 0x1b6: /* movzbS Gv, Eb */
1603 case 0x1b7: /* movzwS Gv, Eb */
1604 case 0x1be: /* movsbS Gv, Eb */
1605 case 0x1bf: /* movswS Gv, Eb */
1608 /* d_ot is the size of destination */
1609 d_ot = dflag + OT_WORD;
1610 /* ot is the size of source */
1611 ot = (b & 1) + OT_BYTE;
1612 modrm = ldub(s->pc++);
1613 reg = ((modrm >> 3) & 7) + OR_EAX;
1614 mod = (modrm >> 6) & 3;
1618 gen_op_mov_TN_reg[ot][0][rm]();
1619 switch(ot | (b & 8)) {
1621 gen_op_movzbl_T0_T0();
1624 gen_op_movsbl_T0_T0();
1627 gen_op_movzwl_T0_T0();
1631 gen_op_movswl_T0_T0();
1634 gen_op_mov_reg_T0[d_ot][reg]();
1636 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1638 gen_op_lds_T0_A0[ot]();
1640 gen_op_ldu_T0_A0[ot]();
1642 gen_op_mov_reg_T0[d_ot][reg]();
1647 case 0x8d: /* lea */
1648 ot = dflag ? OT_LONG : OT_WORD;
1649 modrm = ldub(s->pc++);
1650 reg = (modrm >> 3) & 7;
1652 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1653 gen_op_mov_reg_A0[ot - OT_WORD][reg]();
1656 case 0xa0: /* mov EAX, Ov */
1658 case 0xa2: /* mov Ov, EAX */
1663 ot = dflag ? OT_LONG : OT_WORD;
1665 offset_addr = insn_get(s, OT_LONG);
1667 offset_addr = insn_get(s, OT_WORD);
1668 gen_op_movl_A0_im(offset_addr);
1670 gen_op_ld_T0_A0[ot]();
1671 gen_op_mov_reg_T0[ot][R_EAX]();
1673 gen_op_mov_TN_reg[ot][0][R_EAX]();
1674 gen_op_st_T0_A0[ot]();
1678 case 0xb0 ... 0xb7: /* mov R, Ib */
1679 val = insn_get(s, OT_BYTE);
1680 gen_op_movl_T0_im(val);
1681 gen_op_mov_reg_T0[OT_BYTE][b & 7]();
1683 case 0xb8 ... 0xbf: /* mov R, Iv */
1684 ot = dflag ? OT_LONG : OT_WORD;
1685 val = insn_get(s, ot);
1686 reg = OR_EAX + (b & 7);
1687 gen_op_movl_T0_im(val);
1688 gen_op_mov_reg_T0[ot][reg]();
1691 case 0x91 ... 0x97: /* xchg R, EAX */
1692 ot = dflag ? OT_LONG : OT_WORD;
1694 gen_op_mov_TN_reg[ot][0][reg]();
1695 gen_op_mov_TN_reg[ot][1][R_EAX]();
1696 gen_op_mov_reg_T0[ot][R_EAX]();
1697 gen_op_mov_reg_T1[ot][reg]();
1700 case 0x87: /* xchg Ev, Gv */
1704 ot = dflag ? OT_LONG : OT_WORD;
1705 modrm = ldub(s->pc++);
1706 reg = (modrm >> 3) & 7;
1708 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1709 gen_op_mov_TN_reg[ot][0][reg]();
1710 gen_op_ld_T1_A0[ot]();
1711 gen_op_st_T0_A0[ot]();
1712 gen_op_mov_reg_T1[ot][reg]();
1715 /************************/
1726 ot = dflag ? OT_LONG : OT_WORD;
1728 modrm = ldub(s->pc++);
1729 mod = (modrm >> 6) & 3;
1731 op = (modrm >> 3) & 7;
1734 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1735 gen_op_ld_T0_A0[ot]();
1738 opreg = rm + OR_EAX;
1743 gen_shift(s, op, ot, opreg, OR_ECX);
1746 shift = ldub(s->pc++);
1748 gen_shifti(s, op, ot, opreg, shift);
1752 gen_op_st_T0_A0[ot]();
1767 case 0x1a4: /* shld imm */
1771 case 0x1a5: /* shld cl */
1775 case 0x1ac: /* shrd imm */
1779 case 0x1ad: /* shrd cl */
1783 ot = dflag ? OT_LONG : OT_WORD;
1784 modrm = ldub(s->pc++);
1785 mod = (modrm >> 6) & 3;
1787 reg = (modrm >> 3) & 7;
1790 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1791 gen_op_ld_T0_A0[ot]();
1793 gen_op_mov_TN_reg[ot][0][rm]();
1795 gen_op_mov_TN_reg[ot][1][reg]();
1798 val = ldub(s->pc++);
1801 gen_op_shiftd_T0_T1_im_cc[ot - OT_WORD][op](val);
1802 if (op == 0 && ot != OT_WORD)
1803 s->cc_op = CC_OP_SHLB + ot;
1805 s->cc_op = CC_OP_SARB + ot;
1808 if (s->cc_op != CC_OP_DYNAMIC)
1809 gen_op_set_cc_op(s->cc_op);
1810 gen_op_shiftd_T0_T1_ECX_cc[ot - OT_WORD][op]();
1811 s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1814 gen_op_st_T0_A0[ot]();
1816 gen_op_mov_reg_T0[ot][rm]();
1820 /************************/
1823 modrm = ldub(s->pc++);
1824 mod = (modrm >> 6) & 3;
1826 op = ((b & 7) << 3) | ((modrm >> 3) & 7);
1830 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1832 case 0x00 ... 0x07: /* fxxxs */
1833 case 0x10 ... 0x17: /* fixxxl */
1834 case 0x20 ... 0x27: /* fxxxl */
1835 case 0x30 ... 0x37: /* fixxx */
1842 gen_op_flds_FT0_A0();
1845 gen_op_fildl_FT0_A0();
1848 gen_op_fldl_FT0_A0();
1852 gen_op_fild_FT0_A0();
1856 gen_op_fp_arith_ST0_FT0[op1]();
1858 /* fcomp needs pop */
1863 case 0x08: /* flds */
1864 case 0x0a: /* fsts */
1865 case 0x0b: /* fstps */
1866 case 0x18: /* fildl */
1867 case 0x1a: /* fistl */
1868 case 0x1b: /* fistpl */
1869 case 0x28: /* fldl */
1870 case 0x2a: /* fstl */
1871 case 0x2b: /* fstpl */
1872 case 0x38: /* filds */
1873 case 0x3a: /* fists */
1874 case 0x3b: /* fistps */
1881 gen_op_flds_ST0_A0();
1884 gen_op_fildl_ST0_A0();
1887 gen_op_fldl_ST0_A0();
1891 gen_op_fild_ST0_A0();
1898 gen_op_fsts_ST0_A0();
1901 gen_op_fistl_ST0_A0();
1904 gen_op_fstl_ST0_A0();
1908 gen_op_fist_ST0_A0();
1916 case 0x0d: /* fldcw mem */
1919 case 0x0f: /* fnstcw mem */
1922 case 0x1d: /* fldt mem */
1924 gen_op_fldt_ST0_A0();
1926 case 0x1f: /* fstpt mem */
1927 gen_op_fstt_ST0_A0();
1930 case 0x2f: /* fnstsw mem */
1933 case 0x3c: /* fbld */
1935 gen_op_fbld_ST0_A0();
1937 case 0x3e: /* fbstp */
1938 gen_op_fbst_ST0_A0();
1941 case 0x3d: /* fildll */
1943 gen_op_fildll_ST0_A0();
1945 case 0x3f: /* fistpll */
1946 gen_op_fistll_ST0_A0();
1950 error("unhandled FPm [op=0x%02x]\n", op);
1954 /* register float ops */
1958 case 0x08: /* fld sti */
1960 gen_op_fmov_ST0_STN((opreg + 1) & 7);
1962 case 0x09: /* fxchg sti */
1963 gen_op_fxchg_ST0_STN(opreg);
1965 case 0x0a: /* grp d9/2 */
1970 error("unhandled FP GRP d9/2\n");
1974 case 0x0c: /* grp d9/4 */
1984 gen_op_fcom_ST0_FT0();
1993 case 0x0d: /* grp d9/5 */
2002 gen_op_fldl2t_ST0();
2006 gen_op_fldl2e_ST0();
2014 gen_op_fldlg2_ST0();
2018 gen_op_fldln2_ST0();
2029 case 0x0e: /* grp d9/6 */
2040 case 3: /* fpatan */
2043 case 4: /* fxtract */
2046 case 5: /* fprem1 */
2049 case 6: /* fdecstp */
2053 case 7: /* fincstp */
2058 case 0x0f: /* grp d9/7 */
2063 case 1: /* fyl2xp1 */
2069 case 3: /* fsincos */
2072 case 5: /* fscale */
2075 case 4: /* frndint */
2087 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
2088 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
2089 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
2095 gen_op_fp_arith_STN_ST0[op1](opreg);
2099 gen_op_fmov_FT0_STN(opreg);
2100 gen_op_fp_arith_ST0_FT0[op1]();
2104 case 0x02: /* fcom */
2105 gen_op_fmov_FT0_STN(opreg);
2106 gen_op_fcom_ST0_FT0();
2108 case 0x03: /* fcomp */
2109 gen_op_fmov_FT0_STN(opreg);
2110 gen_op_fcom_ST0_FT0();
2113 case 0x15: /* da/5 */
2115 case 1: /* fucompp */
2116 gen_op_fmov_FT0_STN(1);
2117 gen_op_fucom_ST0_FT0();
2125 case 0x2a: /* fst sti */
2126 gen_op_fmov_STN_ST0(opreg);
2128 case 0x2b: /* fstp sti */
2129 gen_op_fmov_STN_ST0(opreg);
2132 case 0x2c: /* fucom st(i) */
2133 gen_op_fmov_FT0_STN(opreg);
2134 gen_op_fucom_ST0_FT0();
2136 case 0x2d: /* fucomp st(i) */
2137 gen_op_fmov_FT0_STN(opreg);
2138 gen_op_fucom_ST0_FT0();
2141 case 0x33: /* de/3 */
2143 case 1: /* fcompp */
2144 gen_op_fmov_FT0_STN(1);
2145 gen_op_fcom_ST0_FT0();
2153 case 0x3c: /* df/4 */
2156 gen_op_fnstsw_EAX();
2159 error("unhandled FP %x df/4\n", rm);
2164 error("unhandled FPr [op=0x%x]\n", op);
2169 /************************/
2171 case 0xa4: /* movsS */
2176 ot = dflag ? OT_LONG : OT_WORD;
2177 if (prefixes & PREFIX_REPZ) {
2178 gen_op_movs[3 + ot]();
2184 case 0xaa: /* stosS */
2189 ot = dflag ? OT_LONG : OT_WORD;
2190 if (prefixes & PREFIX_REPZ) {
2191 gen_op_stos[3 + ot]();
2196 case 0xac: /* lodsS */
2201 ot = dflag ? OT_LONG : OT_WORD;
2202 if (prefixes & PREFIX_REPZ) {
2203 gen_op_lods[3 + ot]();
2208 case 0xae: /* scasS */
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_scas[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_scas[3 + ot]();
2223 s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2226 s->cc_op = CC_OP_SUBB + ot;
2230 case 0xa6: /* cmpsS */
2235 ot = dflag ? OT_LONG : OT_WORD;
2236 if (prefixes & PREFIX_REPNZ) {
2237 if (s->cc_op != CC_OP_DYNAMIC)
2238 gen_op_set_cc_op(s->cc_op);
2239 gen_op_cmps[6 + ot]();
2240 s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2241 } else if (prefixes & PREFIX_REPZ) {
2242 if (s->cc_op != CC_OP_DYNAMIC)
2243 gen_op_set_cc_op(s->cc_op);
2244 gen_op_cmps[3 + ot]();
2245 s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2248 s->cc_op = CC_OP_SUBB + ot;
2252 /************************/
2254 case 0x6c: /* insS */
2259 ot = dflag ? OT_LONG : OT_WORD;
2260 if (prefixes & PREFIX_REPZ) {
2261 gen_op_ins[3 + ot]();
2266 case 0x6e: /* outsS */
2271 ot = dflag ? OT_LONG : OT_WORD;
2272 if (prefixes & PREFIX_REPZ) {
2273 gen_op_outs[3 + ot]();
2283 ot = dflag ? OT_LONG : OT_WORD;
2284 val = ldub(s->pc++);
2285 gen_op_movl_T0_im(val);
2287 gen_op_mov_reg_T1[ot][R_EAX]();
2294 ot = dflag ? OT_LONG : OT_WORD;
2295 val = ldub(s->pc++);
2296 gen_op_movl_T0_im(val);
2297 gen_op_mov_TN_reg[ot][1][R_EAX]();
2305 ot = dflag ? OT_LONG : OT_WORD;
2306 gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
2308 gen_op_mov_reg_T1[ot][R_EAX]();
2315 ot = dflag ? OT_LONG : OT_WORD;
2316 gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
2317 gen_op_mov_TN_reg[ot][1][R_EAX]();
2321 /************************/
2323 case 0xc2: /* ret im */
2324 /* XXX: handle stack pop ? */
2328 gen_op_addl_ESP_im(val);
2332 case 0xc3: /* ret */
2337 case 0xe8: /* call */
2338 val = insn_get(s, OT_LONG);
2340 gen_op_movl_T1_im((long)s->pc);
2345 case 0xe9: /* jmp */
2346 val = insn_get(s, OT_LONG);
2351 case 0xeb: /* jmp Jb */
2352 val = (int8_t)insn_get(s, OT_BYTE);
2357 case 0x70 ... 0x7f: /* jcc Jb */
2358 val = (int8_t)insn_get(s, OT_BYTE);
2361 case 0x180 ... 0x18f: /* jcc Jv */
2363 val = insn_get(s, OT_LONG);
2365 val = (int16_t)insn_get(s, OT_WORD);
2367 val += (long)s->pc; /* XXX: fix 16 bit wrap */
2373 case 0x190 ... 0x19f:
2374 modrm = ldub(s->pc++);
2376 gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1);
2379 /************************/
2381 case 0x9c: /* pushf */
2382 if (s->cc_op != CC_OP_DYNAMIC)
2383 gen_op_set_cc_op(s->cc_op);
2384 gen_op_movl_T0_eflags();
2387 case 0x9d: /* popf */
2389 gen_op_movl_eflags_T0();
2390 s->cc_op = CC_OP_EFLAGS;
2392 case 0x9e: /* sahf */
2393 gen_op_mov_TN_reg[OT_BYTE][0][R_AH]();
2394 if (s->cc_op != CC_OP_DYNAMIC)
2395 gen_op_set_cc_op(s->cc_op);
2396 gen_op_movb_eflags_T0();
2397 s->cc_op = CC_OP_EFLAGS;
2399 case 0x9f: /* lahf */
2400 if (s->cc_op != CC_OP_DYNAMIC)
2401 gen_op_set_cc_op(s->cc_op);
2402 gen_op_movl_T0_eflags();
2403 gen_op_mov_reg_T0[OT_BYTE][R_AH]();
2405 case 0xf5: /* cmc */
2406 if (s->cc_op != CC_OP_DYNAMIC)
2407 gen_op_set_cc_op(s->cc_op);
2409 s->cc_op = CC_OP_EFLAGS;
2411 case 0xf8: /* clc */
2412 if (s->cc_op != CC_OP_DYNAMIC)
2413 gen_op_set_cc_op(s->cc_op);
2415 s->cc_op = CC_OP_EFLAGS;
2417 case 0xf9: /* stc */
2418 if (s->cc_op != CC_OP_DYNAMIC)
2419 gen_op_set_cc_op(s->cc_op);
2421 s->cc_op = CC_OP_EFLAGS;
2423 case 0xfc: /* cld */
2426 case 0xfd: /* std */
2430 /************************/
2431 /* bit operations */
2432 case 0x1ba: /* bt/bts/btr/btc Gv, im */
2433 ot = dflag ? OT_LONG : OT_WORD;
2434 modrm = ldub(s->pc++);
2435 op = (modrm >> 3) & 7;
2436 mod = (modrm >> 6) & 3;
2439 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
2440 gen_op_ld_T0_A0[ot]();
2442 gen_op_mov_TN_reg[ot][0][rm]();
2445 val = ldub(s->pc++);
2446 gen_op_movl_T1_im(val);
2450 gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
2451 s->cc_op = CC_OP_SARB + ot;
2454 gen_op_st_T0_A0[ot]();
2456 gen_op_mov_reg_T0[ot][rm]();
2459 case 0x1a3: /* bt Gv, Ev */
2462 case 0x1ab: /* bts */
2465 case 0x1b3: /* btr */
2468 case 0x1bb: /* btc */
2471 ot = dflag ? OT_LONG : OT_WORD;
2472 modrm = ldub(s->pc++);
2473 reg = (modrm >> 3) & 7;
2474 mod = (modrm >> 6) & 3;
2476 gen_op_mov_TN_reg[OT_LONG][1][reg]();
2478 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
2479 /* specific case: we need to add a displacement */
2481 gen_op_add_bitw_A0_T1();
2483 gen_op_add_bitl_A0_T1();
2484 gen_op_ld_T0_A0[ot]();
2486 gen_op_mov_TN_reg[ot][0][rm]();
2488 gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
2489 s->cc_op = CC_OP_SARB + ot;
2492 gen_op_st_T0_A0[ot]();
2494 gen_op_mov_reg_T0[ot][rm]();
2497 case 0x1bc: /* bsf */
2498 case 0x1bd: /* bsr */
2499 ot = dflag ? OT_LONG : OT_WORD;
2500 modrm = ldub(s->pc++);
2501 reg = (modrm >> 3) & 7;
2502 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
2503 gen_op_bsx_T0_cc[ot - OT_WORD][b & 1]();
2504 /* NOTE: we always write back the result. Intel doc says it is
2505 undefined if T0 == 0 */
2506 gen_op_mov_reg_T0[ot][reg]();
2507 s->cc_op = CC_OP_LOGICB + ot;
2509 /************************/
2511 case 0x27: /* daa */
2512 if (s->cc_op != CC_OP_DYNAMIC)
2513 gen_op_set_cc_op(s->cc_op);
2515 s->cc_op = CC_OP_EFLAGS;
2517 case 0x2f: /* das */
2518 if (s->cc_op != CC_OP_DYNAMIC)
2519 gen_op_set_cc_op(s->cc_op);
2521 s->cc_op = CC_OP_EFLAGS;
2523 case 0x37: /* aaa */
2524 if (s->cc_op != CC_OP_DYNAMIC)
2525 gen_op_set_cc_op(s->cc_op);
2527 s->cc_op = CC_OP_EFLAGS;
2529 case 0x3f: /* aas */
2530 if (s->cc_op != CC_OP_DYNAMIC)
2531 gen_op_set_cc_op(s->cc_op);
2533 s->cc_op = CC_OP_EFLAGS;
2535 case 0xd4: /* aam */
2536 val = ldub(s->pc++);
2538 s->cc_op = CC_OP_LOGICB;
2540 case 0xd5: /* aad */
2541 val = ldub(s->pc++);
2543 s->cc_op = CC_OP_LOGICB;
2545 /************************/
2547 case 0x90: /* nop */
2549 case 0xcc: /* int3 */
2550 gen_op_int3((long)pc_start);
2553 case 0xcd: /* int N */
2554 val = ldub(s->pc++);
2555 /* XXX: currently we ignore the interrupt number */
2556 gen_op_int_im((long)pc_start);
2559 case 0xce: /* into */
2560 if (s->cc_op != CC_OP_DYNAMIC)
2561 gen_op_set_cc_op(s->cc_op);
2562 gen_op_into((long)pc_start, (long)s->pc);
2565 case 0x1c8 ... 0x1cf: /* bswap reg */
2567 gen_op_mov_TN_reg[OT_LONG][0][reg]();
2569 gen_op_mov_reg_T0[OT_LONG][reg]();
2571 case 0xd6: /* salc */
2572 if (s->cc_op != CC_OP_DYNAMIC)
2573 gen_op_set_cc_op(s->cc_op);
2576 case 0x1a2: /* rdtsc */
2580 case 0x1a2: /* cpuid */
2585 error("unknown opcode 0x%x", b);
2591 /* return the next pc */
2592 int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
2593 int *gen_code_size_ptr, uint8_t *pc_start)
2595 DisasContext dc1, *dc = &dc1;
2596 uint8_t *gen_code_end, *pc_ptr;
2600 struct disassemble_info disasm_info;
2603 dc->cc_op = CC_OP_DYNAMIC;
2604 gen_code_ptr = gen_code_buf;
2605 gen_code_end = gen_code_buf + max_code_size - 4096;
2611 ret = disas_insn(dc, pc_ptr, &is_jmp);
2613 error("unknown instruction at PC=0x%x B=%02x %02x",
2614 pc_ptr, pc_ptr[0], pc_ptr[1]);
2615 pc_ptr = (void *)ret;
2616 } while (!is_jmp && gen_code_ptr < gen_code_end);
2617 /* we must store the eflags state if it is not already done */
2618 if (dc->cc_op != CC_OP_DYNAMIC)
2619 gen_op_set_cc_op(dc->cc_op);
2621 /* we add an additionnal jmp to update the simulated PC */
2625 *gen_code_size_ptr = gen_code_ptr - gen_code_buf;
2632 INIT_DISASSEMBLE_INFO(disasm_info, logfile, fprintf);
2634 disasm_info.flavour = bfd_get_flavour (abfd);
2635 disasm_info.arch = bfd_get_arch (abfd);
2636 disasm_info.mach = bfd_get_mach (abfd);
2638 #ifdef WORDS_BIGENDIAN
2639 disasm_info.endian = BFD_ENDIAN_BIG;
2641 disasm_info.endian = BFD_ENDIAN_LITTLE;
2643 fprintf(logfile, "IN:\n");
2644 disasm_info.buffer = pc_start;
2645 disasm_info.buffer_vma = (unsigned long)pc_start;
2646 disasm_info.buffer_length = pc_ptr - pc_start;
2648 while (pc < pc_ptr) {
2649 fprintf(logfile, "0x%08lx: ", (long)pc);
2650 count = print_insn_i386((unsigned long)pc, &disasm_info);
2651 fprintf(logfile, "\n");
2654 fprintf(logfile, "\n");
2657 disasm_info.buffer = pc;
2658 disasm_info.buffer_vma = (unsigned long)pc;
2659 disasm_info.buffer_length = *gen_code_size_ptr;
2660 fprintf(logfile, "OUT: [size=%d]\n", *gen_code_size_ptr);
2661 while (pc < gen_code_ptr) {
2662 fprintf(logfile, "0x%08lx: ", (long)pc);
2663 count = print_insn_i386((unsigned long)pc, &disasm_info);
2664 fprintf(logfile, "\n");
2667 fprintf(logfile, "\n");
2673 CPUX86State *cpu_x86_init(void)
2678 cpu_x86_tblocks_init();
2680 env = malloc(sizeof(CPUX86State));
2683 memset(env, 0, sizeof(CPUX86State));
2684 /* basic FPU init */
2685 for(i = 0;i < 8; i++)
2689 env->cc_op = CC_OP_EFLAGS;
2694 void cpu_x86_close(CPUX86State *env)