11 static uint8_t *gen_code_ptr;
12 int __op_param1, __op_param2, __op_param3;
15 static void error(const char *fmt, ...)
20 vfprintf(stderr, fmt, ap);
26 #define PREFIX_REPNZ 2
29 #define PREFIX_SS 0x10
30 #define PREFIX_DS 0x20
31 #define PREFIX_ES 0x40
32 #define PREFIX_FS 0x80
33 #define PREFIX_GS 0x100
34 #define PREFIX_DATA 0x200
35 #define PREFIX_ADR 0x400
36 #define PREFIX_FWAIT 0x800
38 typedef struct DisasContext {
39 /* current insn context */
42 uint8_t *pc; /* current pc */
43 int cc_op; /* current CC operation */
47 /* i386 arith/logic operations */
67 OP_SHL1, /* undocumented */
82 /* I386 int registers */
83 OR_EAX, /* MUST be even numbered */
92 /* I386 float registers */
101 OR_TMP0, /* temporary operand register */
103 OR_A0, /* temporary register used when doing address evaluation */
104 OR_EFLAGS, /* cpu flags */
105 OR_ITMP0, /* used for byte/word insertion */
106 OR_ITMP1, /* used for byte/word insertion */
107 OR_ITMP2, /* used for byte/word insertion */
108 OR_FTMP0, /* float temporary */
109 OR_DF, /* D flag, for string ops */
110 OR_ZERO, /* fixed zero register */
111 OR_IM, /* dummy immediate value register */
116 static const double tab_const[7] = {
118 3.32192809488736234789, /* log2(10) */
121 0.30102999566398119521, /* log10(2) */
127 typedef void (GenOpFunc)(void);
128 typedef void (GenOpFunc1)(long);
129 typedef void (GenOpFunc2)(long, long);
131 static GenOpFunc *gen_op_mov_reg_T0[3][8] = {
164 static GenOpFunc *gen_op_mov_reg_T1[3][8] = {
197 static GenOpFunc *gen_op_mov_reg_A0[2][8] = {
220 static GenOpFunc *gen_op_mov_TN_reg[3][2][8] =
290 static GenOpFunc *gen_op_movl_A0_reg[8] = {
301 static GenOpFunc *gen_op_addl_A0_reg_sN[4][8] = {
313 gen_op_addl_A0_EAX_s1,
314 gen_op_addl_A0_ECX_s1,
315 gen_op_addl_A0_EDX_s1,
316 gen_op_addl_A0_EBX_s1,
317 gen_op_addl_A0_ESP_s1,
318 gen_op_addl_A0_EBP_s1,
319 gen_op_addl_A0_ESI_s1,
320 gen_op_addl_A0_EDI_s1,
323 gen_op_addl_A0_EAX_s2,
324 gen_op_addl_A0_ECX_s2,
325 gen_op_addl_A0_EDX_s2,
326 gen_op_addl_A0_EBX_s2,
327 gen_op_addl_A0_ESP_s2,
328 gen_op_addl_A0_EBP_s2,
329 gen_op_addl_A0_ESI_s2,
330 gen_op_addl_A0_EDI_s2,
333 gen_op_addl_A0_EAX_s3,
334 gen_op_addl_A0_ECX_s3,
335 gen_op_addl_A0_EDX_s3,
336 gen_op_addl_A0_EBX_s3,
337 gen_op_addl_A0_ESP_s3,
338 gen_op_addl_A0_EBP_s3,
339 gen_op_addl_A0_ESI_s3,
340 gen_op_addl_A0_EDI_s3,
344 static GenOpFunc *gen_op_arith_T0_T1_cc[8] = {
345 gen_op_addl_T0_T1_cc,
347 gen_op_adcl_T0_T1_cc,
348 gen_op_sbbl_T0_T1_cc,
349 gen_op_andl_T0_T1_cc,
350 gen_op_subl_T0_T1_cc,
351 gen_op_xorl_T0_T1_cc,
352 gen_op_cmpl_T0_T1_cc,
355 static const int cc_op_arithb[8] = {
366 static GenOpFunc *gen_op_shift_T0_T1_cc[3][8] = {
368 gen_op_rolb_T0_T1_cc,
369 gen_op_rorb_T0_T1_cc,
370 gen_op_rclb_T0_T1_cc,
371 gen_op_rcrb_T0_T1_cc,
372 gen_op_shlb_T0_T1_cc,
373 gen_op_shrb_T0_T1_cc,
374 gen_op_shlb_T0_T1_cc,
375 gen_op_sarb_T0_T1_cc,
378 gen_op_rolw_T0_T1_cc,
379 gen_op_rorw_T0_T1_cc,
380 gen_op_rclw_T0_T1_cc,
381 gen_op_rcrw_T0_T1_cc,
382 gen_op_shlw_T0_T1_cc,
383 gen_op_shrw_T0_T1_cc,
384 gen_op_shlw_T0_T1_cc,
385 gen_op_sarw_T0_T1_cc,
388 gen_op_roll_T0_T1_cc,
389 gen_op_rorl_T0_T1_cc,
390 gen_op_rcll_T0_T1_cc,
391 gen_op_rcrl_T0_T1_cc,
392 gen_op_shll_T0_T1_cc,
393 gen_op_shrl_T0_T1_cc,
394 gen_op_shll_T0_T1_cc,
395 gen_op_sarl_T0_T1_cc,
399 static GenOpFunc *gen_op_lds_T0_A0[3] = {
404 static GenOpFunc *gen_op_ldu_T0_A0[3] = {
409 /* sign does not matter */
410 static GenOpFunc *gen_op_ld_T0_A0[3] = {
416 static GenOpFunc *gen_op_ld_T1_A0[3] = {
422 static GenOpFunc *gen_op_st_T0_A0[3] = {
428 static GenOpFunc *gen_op_movs[6] = {
437 static GenOpFunc *gen_op_stos[6] = {
446 static GenOpFunc *gen_op_lods[6] = {
455 static GenOpFunc *gen_op_scas[9] = {
467 static GenOpFunc *gen_op_cmps[9] = {
479 static GenOpFunc *gen_op_ins[6] = {
489 static GenOpFunc *gen_op_outs[6] = {
509 static GenOpFunc2 *gen_jcc_slow[8] = {
520 static GenOpFunc2 *gen_jcc_sub[3][8] = {
553 static GenOpFunc *gen_setcc_slow[8] = {
564 static GenOpFunc *gen_setcc_sub[3][8] = {
569 gen_op_setbe_T0_subb,
573 gen_op_setle_T0_subb,
579 gen_op_setbe_T0_subw,
583 gen_op_setle_T0_subw,
589 gen_op_setbe_T0_subl,
593 gen_op_setle_T0_subl,
597 static GenOpFunc *gen_op_fp_arith_ST0_FT0[8] = {
603 gen_op_fsubr_ST0_FT0,
605 gen_op_fdivr_ST0_FT0,
608 static GenOpFunc1 *gen_op_fp_arith_STN_ST0[8] = {
614 gen_op_fsubr_STN_ST0,
616 gen_op_fdivr_STN_ST0,
619 static void gen_op(DisasContext *s1, int op, int ot, int d, int s)
622 gen_op_mov_TN_reg[ot][0][d]();
624 gen_op_mov_TN_reg[ot][1][s]();
625 if ((op == OP_ADCL || op == OP_SBBL) && s1->cc_op != CC_OP_DYNAMIC)
626 gen_op_set_cc_op(s1->cc_op);
627 gen_op_arith_T0_T1_cc[op]();
628 if (d != OR_TMP0 && op != OP_CMPL)
629 gen_op_mov_reg_T0[ot][d]();
630 s1->cc_op = cc_op_arithb[op] + ot;
633 static void gen_opi(DisasContext *s1, int op, int ot, int d, int c)
635 gen_op1_movl_T1_im(c);
636 gen_op(s1, op, ot, d, OR_TMP0);
639 static void gen_inc(DisasContext *s1, int ot, int d, int c)
642 gen_op_mov_TN_reg[ot][0][d]();
643 if (s1->cc_op != CC_OP_DYNAMIC)
644 gen_op_set_cc_op(s1->cc_op);
650 gen_op_mov_reg_T0[ot][d]();
653 static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
656 gen_op_mov_TN_reg[ot][0][d]();
658 gen_op_mov_TN_reg[ot][1][s]();
664 /* only C and O are modified, so we must update flags dynamically */
665 if (s1->cc_op != CC_OP_DYNAMIC)
666 gen_op_set_cc_op(s1->cc_op);
667 gen_op_shift_T0_T1_cc[ot][op]();
670 gen_op_shift_T0_T1_cc[ot][op]();
674 gen_op_mov_reg_T0[ot][d]();
675 s1->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
678 static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c)
680 /* currently not optimized */
681 gen_op1_movl_T1_im(c);
682 gen_shift(s1, op, ot, d, OR_TMP1);
685 static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ptr)
692 int reg1, reg2, opreg;
695 mod = (modrm >> 6) & 3;
706 code = ldub(s->pc++);
707 scale = (code >> 6) & 3;
708 index = (code >> 3) & 7;
723 disp = (int8_t)ldub(s->pc++);
735 if (havebase || (havesib && (index != 4 || scale != 0))) {
737 reg1 = OR_EAX + base;
738 if (havesib && index != 4) {
740 reg2 = index + OR_EAX;
742 reg1 = index + OR_EAX;
745 /* XXX: disp only ? */
746 if (reg2 == OR_ZERO) {
747 /* op: disp + (reg1 << scale) */
748 if (reg1 == OR_ZERO) {
749 gen_op1_movl_A0_im(disp);
750 } else if (scale == 0 && disp == 0) {
751 gen_op_movl_A0_reg[reg1]();
753 gen_op_addl_A0_reg_sN[scale][reg1]();
756 /* op: disp + reg1 + (reg2 << scale) */
758 gen_op1_movl_A0_im(disp);
759 gen_op_addl_A0_reg_sN[0][reg1]();
761 gen_op_movl_A0_reg[reg1]();
763 gen_op_addl_A0_reg_sN[scale][reg2]();
767 fprintf(stderr, "16 bit addressing not supported\n");
775 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg !=
777 static void gen_ldst_modrm(DisasContext *s, int modrm, int ot, int reg, int is_store)
779 int mod, rm, opreg, disp;
781 mod = (modrm >> 6) & 3;
786 gen_op_mov_TN_reg[ot][0][reg]();
787 gen_op_mov_reg_T0[ot][rm]();
789 gen_op_mov_TN_reg[ot][0][rm]();
791 gen_op_mov_reg_T0[ot][reg]();
794 gen_lea_modrm(s, modrm, &opreg, &disp);
797 gen_op_mov_TN_reg[ot][0][reg]();
798 gen_op_st_T0_A0[ot]();
800 gen_op_ld_T0_A0[ot]();
802 gen_op_mov_reg_T0[ot][reg]();
807 static inline uint32_t insn_get(DisasContext *s, int ot)
829 static void gen_jcc(DisasContext *s, int b, int val)
835 jcc_op = (b >> 1) & 7;
837 /* we optimize the cmp/jcc case */
841 func = gen_jcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
846 /* some jumps are easy to compute */
864 func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
867 func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
875 if (s->cc_op != CC_OP_DYNAMIC)
876 op_set_cc_op(s->cc_op);
877 func = gen_jcc_slow[jcc_op];
881 func(val, (long)s->pc);
883 func((long)s->pc, val);
887 static void gen_setcc(DisasContext *s, int b)
893 jcc_op = (b >> 1) & 7;
895 /* we optimize the cmp/jcc case */
899 func = gen_setcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
904 /* some jumps are easy to compute */
922 func = gen_setcc_sub[s->cc_op - CC_OP_ADDB][jcc_op];
925 func = gen_setcc_sub[s->cc_op - CC_OP_ADDB][jcc_op];
933 if (s->cc_op != CC_OP_DYNAMIC)
934 op_set_cc_op(s->cc_op);
935 func = gen_setcc_slow[jcc_op];
944 /* return the size of the intruction. Return -1 if no insn found */
945 int disas_insn(DisasContext *s, uint8_t *pc_start)
947 int b, prefixes, aflag, dflag;
949 int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
955 // cur_pc = s->pc; /* for insn generation */
964 prefixes |= PREFIX_REPZ;
967 prefixes |= PREFIX_REPNZ;
970 prefixes |= PREFIX_LOCK;
973 prefixes |= PREFIX_CS;
976 prefixes |= PREFIX_SS;
979 prefixes |= PREFIX_DS;
982 prefixes |= PREFIX_ES;
985 prefixes |= PREFIX_FS;
988 prefixes |= PREFIX_GS;
991 prefixes |= PREFIX_DATA;
994 prefixes |= PREFIX_ADR;
997 prefixes |= PREFIX_FWAIT;
1001 if (prefixes & PREFIX_DATA)
1003 if (prefixes & PREFIX_ADR)
1006 s->prefix = prefixes;
1010 /* now check op code */
1014 /**************************/
1015 /* extended op code */
1016 b = ldub(s->pc++) | 0x100;
1019 /**************************/
1037 ot = dflag ? OT_LONG : OT_WORD;
1040 case 0: /* OP Ev, Gv */
1041 modrm = ldub(s->pc++);
1042 reg = ((modrm >> 3) & 7) + OR_EAX;
1043 mod = (modrm >> 6) & 3;
1046 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1047 gen_op_ld_T0_A0[ot]();
1050 opreg = OR_EAX + rm;
1052 gen_op(s, op, ot, opreg, reg);
1053 if (mod != 3 && op != 7) {
1054 gen_op_st_T0_A0[ot]();
1057 case 1: /* OP Gv, Ev */
1058 modrm = ldub(s->pc++);
1059 mod = (modrm >> 6) & 3;
1060 reg = ((modrm >> 3) & 7) + OR_EAX;
1063 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1064 gen_op_ld_T1_A0[ot]();
1067 opreg = OR_EAX + rm;
1069 gen_op(s, op, ot, reg, opreg);
1071 case 2: /* OP A, Iv */
1072 val = insn_get(s, ot);
1073 gen_opi(s, op, ot, OR_EAX, val);
1079 case 0x80: /* GRP1 */
1088 ot = dflag ? OT_LONG : OT_WORD;
1090 modrm = ldub(s->pc++);
1091 mod = (modrm >> 6) & 3;
1093 op = (modrm >> 3) & 7;
1096 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1097 gen_op_ld_T0_A0[ot]();
1100 opreg = rm + OR_EAX;
1107 val = insn_get(s, ot);
1110 val = (int8_t)insn_get(s, OT_BYTE);
1114 gen_opi(s, op, ot, opreg, val);
1115 if (op != 7 && mod != 3) {
1116 gen_op_st_T0_A0[ot]();
1121 /**************************/
1122 /* inc, dec, and other misc arith */
1123 case 0x40 ... 0x47: /* inc Gv */
1124 ot = dflag ? OT_LONG : OT_WORD;
1125 gen_inc(s, ot, OR_EAX + (b & 7), 1);
1127 case 0x48 ... 0x4f: /* dec Gv */
1128 ot = dflag ? OT_LONG : OT_WORD;
1129 gen_inc(s, ot, OR_EAX + (b & 7), -1);
1131 case 0xf6: /* GRP3 */
1136 ot = dflag ? OT_LONG : OT_WORD;
1138 modrm = ldub(s->pc++);
1139 mod = (modrm >> 6) & 3;
1141 op = (modrm >> 3) & 7;
1143 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1144 gen_op_ld_T0_A0[ot]();
1146 gen_op_mov_TN_reg[ot][0][rm]();
1151 val = insn_get(s, ot);
1152 gen_op1_movl_T1_im(val);
1153 gen_op_testl_T0_T1_cc();
1154 s->cc_op = CC_OP_LOGICB + ot;
1159 gen_op_st_T0_A0[ot]();
1161 gen_op_mov_reg_T0[ot][rm]();
1165 gen_op_negl_T0_cc();
1167 gen_op_st_T0_A0[ot]();
1169 gen_op_mov_reg_T0[ot][rm]();
1171 s->cc_op = CC_OP_SUBB + ot;
1176 gen_op_mulb_AL_T0();
1179 gen_op_mulw_AX_T0();
1183 gen_op_mull_EAX_T0();
1190 gen_op_imulb_AL_T0();
1193 gen_op_imulw_AX_T0();
1197 gen_op_imull_EAX_T0();
1204 gen_op_divb_AL_T0();
1207 gen_op_divw_AX_T0();
1211 gen_op_divl_EAX_T0();
1218 gen_op_idivb_AL_T0();
1221 gen_op_idivw_AX_T0();
1225 gen_op_idivl_EAX_T0();
1230 error("GRP3: bad instruction");
1235 case 0xfe: /* GRP4 */
1236 case 0xff: /* GRP5 */
1240 ot = dflag ? OT_LONG : OT_WORD;
1242 modrm = ldub(s->pc++);
1243 mod = (modrm >> 6) & 3;
1245 op = (modrm >> 3) & 7;
1246 if (op >= 2 && b == 0xfe) {
1247 error("GRP4: bad instruction");
1251 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1252 gen_op_ld_T0_A0[ot]();
1254 gen_op_mov_TN_reg[ot][0][rm]();
1258 case 0: /* inc Ev */
1259 gen_inc(s, ot, OR_TMP0, 1);
1261 gen_op_st_T0_A0[ot]();
1263 case 1: /* dec Ev */
1264 gen_inc(s, ot, OR_TMP0, -1);
1266 gen_op_st_T0_A0[ot]();
1268 case 2: /* call Ev */
1269 gen_op1_movl_T1_im((long)s->pc);
1273 case 4: /* jmp Ev */
1276 case 6: /* push Ev */
1280 error("GRP5: bad instruction");
1285 case 0x84: /* test Ev, Gv */
1290 ot = dflag ? OT_LONG : OT_WORD;
1292 modrm = ldub(s->pc++);
1293 mod = (modrm >> 6) & 3;
1295 reg = (modrm >> 3) & 7;
1297 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1298 gen_op_mov_TN_reg[ot][1][reg + OR_EAX]();
1299 gen_op_testl_T0_T1_cc();
1300 s->cc_op = CC_OP_LOGICB + ot;
1303 case 0xa8: /* test eAX, Iv */
1308 ot = dflag ? OT_LONG : OT_WORD;
1309 val = insn_get(s, ot);
1311 gen_op_mov_TN_reg[ot][0][OR_EAX]();
1312 gen_op1_movl_T1_im(val);
1313 gen_op_testl_T0_T1_cc();
1314 s->cc_op = CC_OP_LOGICB + ot;
1317 case 0x98: /* CWDE/CBW */
1319 gen_op_movswl_EAX_AX();
1321 gen_op_movsbw_AX_AL();
1323 case 0x99: /* CDQ/CWD */
1325 gen_op_movslq_EDX_EAX();
1327 gen_op_movswl_DX_AX();
1329 case 0x1af: /* imul Gv, Ev */
1330 case 0x69: /* imul Gv, Ev, I */
1332 ot = dflag ? OT_LONG : OT_WORD;
1333 modrm = ldub(s->pc++);
1334 reg = ((modrm >> 3) & 7) + OR_EAX;
1336 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1338 val = insn_get(s, ot);
1339 gen_op1_movl_T1_im(val);
1340 } else if (b == 0x6b) {
1341 val = insn_get(s, OT_BYTE);
1342 gen_op1_movl_T1_im(val);
1344 gen_op_mov_TN_reg[ot][1][reg]();
1347 if (ot == OT_LONG) {
1352 gen_op_mov_reg_T0[ot][reg]();
1355 /**************************/
1357 case 0x50 ... 0x57: /* push */
1358 gen_op_mov_TN_reg[OT_LONG][0][b & 7]();
1361 case 0x58 ... 0x5f: /* pop */
1363 gen_op_mov_reg_T0[OT_LONG][b & 7]();
1365 case 0x68: /* push Iv */
1367 ot = dflag ? OT_LONG : OT_WORD;
1369 val = insn_get(s, ot);
1371 val = (int8_t)insn_get(s, OT_BYTE);
1372 gen_op1_movl_T0_im(val);
1375 case 0x8f: /* pop Ev */
1376 ot = dflag ? OT_LONG : OT_WORD;
1377 modrm = ldub(s->pc++);
1379 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
1381 case 0xc9: /* leave */
1382 gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
1383 gen_op_mov_reg_T0[OT_LONG][R_ESP]();
1385 gen_op_mov_reg_T0[OT_LONG][R_EBP]();
1387 /**************************/
1390 case 0x89: /* mov Gv, Ev */
1394 ot = dflag ? OT_LONG : OT_WORD;
1395 modrm = ldub(s->pc++);
1396 reg = (modrm >> 3) & 7;
1398 /* generate a generic store */
1399 gen_ldst_modrm(s, modrm, ot, OR_EAX + reg, 1);
1402 case 0xc7: /* mov Ev, Iv */
1406 ot = dflag ? OT_LONG : OT_WORD;
1407 modrm = ldub(s->pc++);
1408 mod = (modrm >> 6) & 3;
1410 val = insn_get(s, ot);
1411 gen_op1_movl_T0_im(val);
1412 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
1415 case 0x8b: /* mov Ev, Gv */
1419 ot = dflag ? OT_LONG : OT_WORD;
1420 modrm = ldub(s->pc++);
1421 reg = (modrm >> 3) & 7;
1423 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1424 gen_op_mov_reg_T0[ot][reg]();
1427 case 0x1b6: /* movzbS Gv, Eb */
1428 case 0x1b7: /* movzwS Gv, Eb */
1429 case 0x1be: /* movsbS Gv, Eb */
1430 case 0x1bf: /* movswS Gv, Eb */
1433 /* d_ot is the size of destination */
1434 d_ot = dflag + OT_WORD;
1435 /* ot is the size of source */
1436 ot = (b & 1) + OT_BYTE;
1437 modrm = ldub(s->pc++);
1438 reg = ((modrm >> 3) & 7) + OR_EAX;
1439 mod = (modrm >> 6) & 3;
1443 gen_op_mov_TN_reg[ot][0][rm]();
1444 switch(ot | (b & 8)) {
1446 gen_op_movzbl_T0_T0();
1449 gen_op_movsbl_T0_T0();
1452 gen_op_movzwl_T0_T0();
1456 gen_op_movswl_T0_T0();
1459 gen_op_mov_reg_T0[d_ot][reg]();
1461 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1463 gen_op_lds_T0_A0[ot]();
1465 gen_op_ldu_T0_A0[ot]();
1467 gen_op_mov_reg_T0[d_ot][reg]();
1472 case 0x8d: /* lea */
1473 ot = dflag ? OT_LONG : OT_WORD;
1474 modrm = ldub(s->pc++);
1475 reg = (modrm >> 3) & 7;
1477 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1478 gen_op_mov_reg_A0[ot - OT_WORD][reg]();
1481 case 0xa0: /* mov EAX, Ov */
1483 case 0xa2: /* mov Ov, EAX */
1488 ot = dflag ? OT_LONG : OT_WORD;
1490 offset_addr = insn_get(s, OT_LONG);
1492 offset_addr = insn_get(s, OT_WORD);
1495 gen_op_ld_T0_A0[ot]();
1496 gen_op_mov_reg_T0[ot][R_EAX]();
1498 gen_op_mov_TN_reg[ot][0][R_EAX]();
1499 gen_op_st_T0_A0[ot]();
1503 case 0xb0 ... 0xb7: /* mov R, Ib */
1504 val = insn_get(s, OT_BYTE);
1505 gen_op1_movl_T0_im(val);
1506 gen_op_mov_reg_T0[OT_BYTE][b & 7]();
1508 case 0xb8 ... 0xbf: /* mov R, Iv */
1509 ot = dflag ? OT_LONG : OT_WORD;
1510 val = insn_get(s, ot);
1511 reg = OR_EAX + (b & 7);
1512 gen_op1_movl_T0_im(val);
1513 gen_op_mov_reg_T0[ot][reg]();
1516 case 0x91 ... 0x97: /* xchg R, EAX */
1517 ot = dflag ? OT_LONG : OT_WORD;
1519 gen_op_mov_TN_reg[ot][0][reg]();
1520 gen_op_mov_TN_reg[ot][1][R_EAX]();
1521 gen_op_mov_reg_T0[ot][R_EAX]();
1522 gen_op_mov_reg_T1[ot][reg]();
1525 case 0x87: /* xchg Ev, Gv */
1529 ot = dflag ? OT_LONG : OT_WORD;
1530 modrm = ldub(s->pc++);
1531 reg = (modrm >> 3) & 7;
1533 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1534 gen_op_mov_TN_reg[ot][0][reg]();
1535 gen_op_ld_T1_A0[ot]();
1536 gen_op_st_T0_A0[ot]();
1537 gen_op_mov_reg_T1[ot][reg]();
1540 /************************/
1551 ot = dflag ? OT_LONG : OT_WORD;
1553 modrm = ldub(s->pc++);
1554 mod = (modrm >> 6) & 3;
1556 op = (modrm >> 3) & 7;
1559 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1560 gen_op_ld_T0_A0[ot]();
1563 opreg = rm + OR_EAX;
1568 gen_shift(s, op, ot, opreg, OR_ECX);
1571 shift = ldub(s->pc++);
1573 gen_shifti(s, op, ot, opreg, shift);
1577 gen_op_st_T0_A0[ot]();
1592 /************************/
1595 modrm = ldub(s->pc++);
1596 mod = (modrm >> 6) & 3;
1598 op = ((b & 7) << 3) | ((modrm >> 3) & 7);
1602 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1604 case 0x00 ... 0x07: /* fxxxs */
1605 case 0x10 ... 0x17: /* fixxxl */
1606 case 0x20 ... 0x27: /* fxxxl */
1607 case 0x30 ... 0x37: /* fixxx */
1614 gen_op_flds_FT0_A0();
1617 gen_op_fildl_FT0_A0();
1620 gen_op_fldl_FT0_A0();
1624 gen_op_fild_FT0_A0();
1628 gen_op_fp_arith_ST0_FT0[op1]();
1630 /* fcomp needs pop */
1635 case 0x08: /* flds */
1636 case 0x0a: /* fsts */
1637 case 0x0b: /* fstps */
1638 case 0x18: /* fildl */
1639 case 0x1a: /* fistl */
1640 case 0x1b: /* fistpl */
1641 case 0x28: /* fldl */
1642 case 0x2a: /* fstl */
1643 case 0x2b: /* fstpl */
1644 case 0x38: /* filds */
1645 case 0x3a: /* fists */
1646 case 0x3b: /* fistps */
1653 gen_op_flds_ST0_A0();
1656 gen_op_fildl_ST0_A0();
1659 gen_op_fldl_ST0_A0();
1663 gen_op_fild_ST0_A0();
1670 gen_op_fsts_ST0_A0();
1673 gen_op_fistl_ST0_A0();
1676 gen_op_fstl_ST0_A0();
1680 gen_op_fist_ST0_A0();
1689 case 0x2f: /* fnstsw mem */
1690 gen_insn3(OP_FNSTS, OR_TMP0, OR_ZERO, OR_ZERO);
1691 gen_st(OP_STW, OR_TMP0, reg_addr, offset_addr);
1694 case 0x3c: /* fbld */
1695 case 0x3e: /* fbstp */
1696 error("float BCD not hanlded");
1699 case 0x3d: /* fildll */
1701 gen_op_fildll_ST0_A0();
1703 case 0x3f: /* fistpll */
1704 gen_op_fistll_ST0_A0();
1708 error("unhandled memory FP\n");
1712 /* register float ops */
1716 case 0x08: /* fld sti */
1718 gen_op_fmov_ST0_STN((opreg + 1) & 7);
1720 case 0x09: /* fxchg sti */
1721 gen_op_fxchg_ST0_STN((opreg + 1) & 7);
1723 case 0x0a: /* grp d9/2 */
1728 error("unhandled FP GRP d9/2\n");
1732 case 0x0c: /* grp d9/4 */
1742 gen_op_fcom_ST0_FT0();
1751 case 0x0d: /* grp d9/5 */
1767 gen_op_fldlg2_ST0();
1770 gen_op_fldln2_ST0();
1780 case 0x0e: /* grp d9/6 */
1791 case 3: /* fpatan */
1794 case 4: /* fxtract */
1797 case 5: /* fprem1 */
1800 case 6: /* fdecstp */
1804 case 7: /* fincstp */
1809 case 0x0f: /* grp d9/7 */
1814 case 1: /* fyl2xp1 */
1820 case 3: /* fsincos */
1823 case 5: /* fscale */
1826 case 4: /* frndint */
1838 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
1839 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
1840 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
1846 gen_op_fp_arith_STN_ST0[op1](opreg);
1848 gen_op_fmov_FT0_STN(opreg);
1849 gen_op_fp_arith_ST0_FT0[op1]();
1855 case 0x02: /* fcom */
1856 gen_op_fmov_FT0_STN(opreg);
1857 gen_op_fcom_ST0_FT0();
1859 case 0x03: /* fcomp */
1860 gen_op_fmov_FT0_STN(opreg);
1861 gen_op_fcom_ST0_FT0();
1864 case 0x15: /* da/5 */
1866 case 1: /* fucompp */
1867 gen_op_fmov_FT0_STN(1);
1868 gen_op_fcom_ST0_FT0();
1876 case 0x2a: /* fst sti */
1877 gen_op_fmov_STN_ST0(opreg);
1879 case 0x2b: /* fstp sti */
1880 gen_op_fmov_STN_ST0(opreg);
1883 case 0x33: /* de/3 */
1885 case 1: /* fcompp */
1886 gen_op_fmov_FT0_STN(1);
1887 gen_op_fcom_ST0_FT0();
1895 case 0x3c: /* df/4 */
1899 gen_insn3(OP_FNSTS, OR_EAX, OR_ZERO, OR_ZERO);
1907 error("unhandled FP\n");
1912 /************************/
1914 case 0xa4: /* movsS */
1919 ot = dflag ? OT_LONG : OT_WORD;
1920 if (prefixes & PREFIX_REPZ) {
1921 gen_op_movs[3 + ot]();
1927 case 0xaa: /* stosS */
1932 ot = dflag ? OT_LONG : OT_WORD;
1933 if (prefixes & PREFIX_REPZ) {
1934 gen_op_stos[3 + ot]();
1939 case 0xac: /* lodsS */
1944 ot = dflag ? OT_LONG : OT_WORD;
1945 if (prefixes & PREFIX_REPZ) {
1946 gen_op_lods[3 + ot]();
1951 case 0xae: /* scasS */
1956 ot = dflag ? OT_LONG : OT_WORD;
1957 if (prefixes & PREFIX_REPNZ) {
1958 gen_op_scas[6 + ot]();
1959 } else if (prefixes & PREFIX_REPZ) {
1960 gen_op_scas[3 + ot]();
1966 case 0xa6: /* cmpsS */
1971 ot = dflag ? OT_LONG : OT_WORD;
1972 if (prefixes & PREFIX_REPNZ) {
1973 gen_op_cmps[6 + ot]();
1974 } else if (prefixes & PREFIX_REPZ) {
1975 gen_op_cmps[3 + ot]();
1981 case 0x6c: /* insS */
1986 ot = dflag ? OT_LONG : OT_WORD;
1987 if (prefixes & PREFIX_REPZ) {
1988 gen_op_ins[3 + ot]();
1993 case 0x6e: /* outsS */
1998 ot = dflag ? OT_LONG : OT_WORD;
1999 if (prefixes & PREFIX_REPZ) {
2000 gen_op_outs[3 + ot]();
2006 /************************/
2008 case 0xc2: /* ret im */
2009 /* XXX: handle stack pop ? */
2013 gen_op_addl_ESP_im(val);
2016 case 0xc3: /* ret */
2020 case 0xe8: /* call */
2021 val = insn_get(s, OT_LONG);
2023 gen_op1_movl_T1_im((long)s->pc);
2027 case 0xe9: /* jmp */
2028 val = insn_get(s, OT_LONG);
2032 case 0xeb: /* jmp Jb */
2033 val = (int8_t)insn_get(s, OT_BYTE);
2037 case 0x70 ... 0x7f: /* jcc Jb */
2038 val = (int8_t)insn_get(s, OT_BYTE);
2041 case 0x180 ... 0x18f: /* jcc Jv */
2043 val = insn_get(s, OT_LONG);
2045 val = (int16_t)insn_get(s, OT_WORD);
2047 val += (long)s->pc; /* XXX: fix 16 bit wrap */
2052 case 0x190 ... 0x19f:
2053 modrm = ldub(s->pc++);
2055 gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1);
2058 /************************/
2060 case 0x9c: /* pushf */
2061 gen_op_movl_T0_eflags();
2064 case 0x9d: /* popf */
2066 gen_op_movl_eflags_T0();
2067 s->cc_op = CC_OP_EFLAGS;
2069 case 0x9e: /* sahf */
2070 gen_op_mov_TN_reg[OT_BYTE][0][R_AH]();
2071 if (s->cc_op != CC_OP_DYNAMIC)
2072 op_set_cc_op(s->cc_op);
2073 gen_op_movb_eflags_T0();
2074 s->cc_op = CC_OP_EFLAGS;
2076 case 0x9f: /* lahf */
2077 if (s->cc_op != CC_OP_DYNAMIC)
2078 op_set_cc_op(s->cc_op);
2079 gen_op_movl_T0_eflags();
2080 gen_op_mov_reg_T0[OT_BYTE][R_AH]();
2082 case 0xf5: /* cmc */
2083 if (s->cc_op != CC_OP_DYNAMIC)
2084 op_set_cc_op(s->cc_op);
2086 s->cc_op = CC_OP_EFLAGS;
2088 case 0xf8: /* clc */
2089 if (s->cc_op != CC_OP_DYNAMIC)
2090 op_set_cc_op(s->cc_op);
2092 s->cc_op = CC_OP_EFLAGS;
2094 case 0xf9: /* stc */
2095 if (s->cc_op != CC_OP_DYNAMIC)
2096 op_set_cc_op(s->cc_op);
2098 s->cc_op = CC_OP_EFLAGS;
2100 case 0xfc: /* cld */
2103 case 0xfd: /* std */
2107 /************************/
2109 case 0x90: /* nop */
2113 case 0x1a2: /* cpuid */
2118 error("unknown opcode %x", b);