10 static uint8_t *gen_code_ptr;
11 int __op_param1, __op_param2, __op_param3;
14 static void error(const char *fmt, ...)
19 vfprintf(stderr, fmt, ap);
25 #define PREFIX_REPNZ 2
28 #define PREFIX_SS 0x10
29 #define PREFIX_DS 0x20
30 #define PREFIX_ES 0x40
31 #define PREFIX_FS 0x80
32 #define PREFIX_GS 0x100
33 #define PREFIX_DATA 0x200
34 #define PREFIX_ADR 0x400
35 #define PREFIX_FWAIT 0x800
37 typedef struct DisasContext {
38 /* current insn context */
41 uint8_t *pc; /* current pc */
42 uint8_t *runtime_pc; /* current pc in the runtime generated code */
43 int cc_op; /* current CC operation */
47 /* i386 arith/logic operations */
67 OP_SHL1, /* undocumented */
72 static const int fp_ops[8] = {
74 OP_FADDQ, OP_FMULQ, OP_CMP, OP_CMP,
75 OP_FSUBQ, OP_FSUBQ, OP_FDIVQ, OP_FDIVQ
79 extern char cc_table, rclw_table, rclb_table;
80 extern char helper_rcll_T0_T1_cc;
81 extern char __udivdi3, __umoddi3;
94 /* I386 int registers */
95 OR_EAX, /* MUST be even numbered */
104 /* I386 float registers */
113 OR_TMP0, /* temporary operand register */
115 OR_A0, /* temporary register used when doing address evaluation */
116 OR_EFLAGS, /* cpu flags */
117 OR_ITMP0, /* used for byte/word insertion */
118 OR_ITMP1, /* used for byte/word insertion */
119 OR_ITMP2, /* used for byte/word insertion */
120 OR_FTMP0, /* float temporary */
121 OR_DF, /* D flag, for string ops */
122 OR_ZERO, /* fixed zero register */
123 OR_IM, /* dummy immediate value register */
128 static const double tab_const[7] = {
130 3.32192809488736234789, /* log2(10) */
133 0.30102999566398119521, /* log10(2) */
139 typedef void (GenOpFunc)(void);
140 typedef void (GenOpFunc1)(long);
141 typedef void (GenOpFunc2)(long, long);
143 static GenOpFunc *gen_op_mov_reg_T0[3][8] = {
176 static GenOpFunc *gen_op_mov_reg_T1[3][8] = {
209 static GenOpFunc *gen_op_mov_reg_A0[2][8] = {
232 static GenOpFunc *gen_op_mov_TN_reg[3][2][8] =
302 static GenOpFunc *gen_op_movl_A0_reg[8] = {
313 static GenOpFunc *gen_op_addl_A0_reg_sN[4][8] = {
325 gen_op_addl_A0_EAX_s1,
326 gen_op_addl_A0_ECX_s1,
327 gen_op_addl_A0_EDX_s1,
328 gen_op_addl_A0_EBX_s1,
329 gen_op_addl_A0_ESP_s1,
330 gen_op_addl_A0_EBP_s1,
331 gen_op_addl_A0_ESI_s1,
332 gen_op_addl_A0_EDI_s1,
335 gen_op_addl_A0_EAX_s2,
336 gen_op_addl_A0_ECX_s2,
337 gen_op_addl_A0_EDX_s2,
338 gen_op_addl_A0_EBX_s2,
339 gen_op_addl_A0_ESP_s2,
340 gen_op_addl_A0_EBP_s2,
341 gen_op_addl_A0_ESI_s2,
342 gen_op_addl_A0_EDI_s2,
345 gen_op_addl_A0_EAX_s3,
346 gen_op_addl_A0_ECX_s3,
347 gen_op_addl_A0_EDX_s3,
348 gen_op_addl_A0_EBX_s3,
349 gen_op_addl_A0_ESP_s3,
350 gen_op_addl_A0_EBP_s3,
351 gen_op_addl_A0_ESI_s3,
352 gen_op_addl_A0_EDI_s3,
356 static GenOpFunc *gen_op_arith_T0_T1_cc[8] = {
357 gen_op_addl_T0_T1_cc,
359 gen_op_adcl_T0_T1_cc,
360 gen_op_sbbl_T0_T1_cc,
361 gen_op_andl_T0_T1_cc,
362 gen_op_subl_T0_T1_cc,
363 gen_op_xorl_T0_T1_cc,
364 gen_op_cmpl_T0_T1_cc,
367 static const int cc_op_arithb[8] = {
378 static GenOpFunc *gen_op_shift_T0_T1_cc[3][8] = {
380 gen_op_rolb_T0_T1_cc,
381 gen_op_rorb_T0_T1_cc,
382 gen_op_rclb_T0_T1_cc,
383 gen_op_rcrb_T0_T1_cc,
384 gen_op_shlb_T0_T1_cc,
385 gen_op_shrb_T0_T1_cc,
386 gen_op_shlb_T0_T1_cc,
387 gen_op_sarb_T0_T1_cc,
390 gen_op_rolw_T0_T1_cc,
391 gen_op_rorw_T0_T1_cc,
392 gen_op_rclw_T0_T1_cc,
393 gen_op_rcrw_T0_T1_cc,
394 gen_op_shlw_T0_T1_cc,
395 gen_op_shrw_T0_T1_cc,
396 gen_op_shlw_T0_T1_cc,
397 gen_op_sarw_T0_T1_cc,
400 gen_op_roll_T0_T1_cc,
401 gen_op_rorl_T0_T1_cc,
402 gen_op_rcll_T0_T1_cc,
403 gen_op_rcrl_T0_T1_cc,
404 gen_op_shll_T0_T1_cc,
405 gen_op_shrl_T0_T1_cc,
406 gen_op_shll_T0_T1_cc,
407 gen_op_sarl_T0_T1_cc,
411 static GenOpFunc *gen_op_lds_T0_A0[3] = {
416 static GenOpFunc *gen_op_ldu_T0_A0[3] = {
421 /* sign does not matter */
422 static GenOpFunc *gen_op_ld_T0_A0[3] = {
428 static GenOpFunc *gen_op_ld_T1_A0[3] = {
434 static GenOpFunc *gen_op_st_T0_A0[3] = {
440 static GenOpFunc *gen_op_movs[6] = {
449 static GenOpFunc *gen_op_stos[6] = {
458 static GenOpFunc *gen_op_lods[6] = {
467 static GenOpFunc *gen_op_scas[9] = {
479 static GenOpFunc *gen_op_cmps[9] = {
491 static GenOpFunc *gen_op_ins[6] = {
501 static GenOpFunc *gen_op_outs[6] = {
521 static GenOpFunc2 *gen_jcc_slow[8] = {
532 static GenOpFunc2 *gen_jcc_sub[3][8] = {
565 static GenOpFunc *gen_setcc_slow[8] = {
576 static GenOpFunc *gen_setcc_sub[3][8] = {
581 gen_op_setbe_T0_subb,
585 gen_op_setle_T0_subb,
591 gen_op_setbe_T0_subw,
595 gen_op_setle_T0_subw,
601 gen_op_setbe_T0_subl,
605 gen_op_setle_T0_subl,
609 static void gen_op(DisasContext *s1, int op, int ot, int d, int s)
612 gen_op_mov_TN_reg[ot][0][d]();
614 gen_op_mov_TN_reg[ot][1][s]();
615 if ((op == OP_ADCL || op == OP_SBBL) && s1->cc_op != CC_OP_DYNAMIC)
616 gen_op_set_cc_op(s1->cc_op);
617 gen_op_arith_T0_T1_cc[op]();
618 if (d != OR_TMP0 && op != OP_CMPL)
619 gen_op_mov_reg_T0[ot][d]();
620 s1->cc_op = cc_op_arithb[op] + ot;
623 static void gen_opi(DisasContext *s1, int op, int ot, int d, int c)
625 gen_op1_movl_T1_im(c);
626 gen_op(s1, op, ot, d, OR_TMP0);
629 static void gen_inc(DisasContext *s1, int ot, int d, int c)
632 gen_op_mov_TN_reg[ot][0][d]();
633 if (s1->cc_op != CC_OP_DYNAMIC)
634 gen_op_set_cc_op(s1->cc_op);
640 gen_op_mov_reg_T0[ot][d]();
643 static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
646 gen_op_mov_TN_reg[ot][0][d]();
648 gen_op_mov_TN_reg[ot][1][s]();
654 /* only C and O are modified, so we must update flags dynamically */
655 if (s1->cc_op != CC_OP_DYNAMIC)
656 gen_op_set_cc_op(s1->cc_op);
657 gen_op_shift_T0_T1_cc[ot][op]();
660 gen_op_shift_T0_T1_cc[ot][op]();
664 gen_op_mov_reg_T0[ot][d]();
665 s1->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
668 static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c)
670 /* currently not optimized */
671 gen_op1_movl_T1_im(c);
672 gen_shift(s1, op, ot, d, OR_TMP1);
675 static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ptr)
682 int reg1, reg2, opreg;
685 mod = (modrm >> 6) & 3;
696 code = ldub(s->pc++);
697 scale = (code >> 6) & 3;
698 index = (code >> 3) & 7;
713 disp = (int8_t)ldub(s->pc++);
725 if (havebase || (havesib && (index != 4 || scale != 0))) {
727 reg1 = OR_EAX + base;
728 if (havesib && index != 4) {
730 reg2 = index + OR_EAX;
732 reg1 = index + OR_EAX;
735 /* XXX: disp only ? */
736 if (reg2 == OR_ZERO) {
737 /* op: disp + (reg1 << scale) */
738 if (reg1 == OR_ZERO) {
739 gen_op1_movl_A0_im(disp);
740 } else if (scale == 0 && disp == 0) {
741 gen_op_movl_A0_reg[reg1]();
743 gen_op_addl_A0_reg_sN[scale][reg1]();
746 /* op: disp + reg1 + (reg2 << scale) */
748 gen_op1_movl_A0_im(disp);
749 gen_op_addl_A0_reg_sN[0][reg1]();
751 gen_op_movl_A0_reg[reg1]();
753 gen_op_addl_A0_reg_sN[scale][reg2]();
757 fprintf(stderr, "16 bit addressing not supported\n");
765 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg !=
767 static void gen_ldst_modrm(DisasContext *s, int modrm, int ot, int reg, int is_store)
769 int mod, rm, opreg, disp;
771 mod = (modrm >> 6) & 3;
776 gen_op_mov_TN_reg[ot][0][reg]();
777 gen_op_mov_reg_T0[ot][rm]();
779 gen_op_mov_TN_reg[ot][0][rm]();
781 gen_op_mov_reg_T0[ot][reg]();
784 gen_lea_modrm(s, modrm, &opreg, &disp);
787 gen_op_mov_TN_reg[ot][0][reg]();
788 gen_op_st_T0_A0[ot]();
790 gen_op_ld_T0_A0[ot]();
792 gen_op_mov_reg_T0[ot][reg]();
797 static inline uint32_t insn_get(DisasContext *s, int ot)
819 static void gen_jcc(DisasContext *s, int b, int val)
825 jcc_op = (b >> 1) & 7;
827 /* we optimize the cmp/jcc case */
831 func = gen_jcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
836 /* some jumps are easy to compute */
854 func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
857 func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
865 if (s->cc_op != CC_OP_DYNAMIC)
866 op_set_cc_op(s->cc_op);
867 func = gen_jcc_slow[jcc_op];
871 func(val, (long)s->pc);
873 func((long)s->pc, val);
877 static void gen_setcc(DisasContext *s, int b)
883 jcc_op = (b >> 1) & 7;
885 /* we optimize the cmp/jcc case */
889 func = gen_setcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
894 /* some jumps are easy to compute */
912 func = gen_setcc_sub[s->cc_op - CC_OP_ADDB][jcc_op];
915 func = gen_setcc_sub[s->cc_op - CC_OP_ADDB][jcc_op];
923 if (s->cc_op != CC_OP_DYNAMIC)
924 op_set_cc_op(s->cc_op);
925 func = gen_setcc_slow[jcc_op];
934 /* return the size of the intruction. Return -1 if no insn found */
935 int disas_insn(DisasContext *s, uint8_t *pc_start)
937 int b, prefixes, aflag, dflag;
939 int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
945 // cur_pc = s->pc; /* for insn generation */
954 prefixes |= PREFIX_REPZ;
957 prefixes |= PREFIX_REPNZ;
960 prefixes |= PREFIX_LOCK;
963 prefixes |= PREFIX_CS;
966 prefixes |= PREFIX_SS;
969 prefixes |= PREFIX_DS;
972 prefixes |= PREFIX_ES;
975 prefixes |= PREFIX_FS;
978 prefixes |= PREFIX_GS;
981 prefixes |= PREFIX_DATA;
984 prefixes |= PREFIX_ADR;
987 prefixes |= PREFIX_FWAIT;
991 if (prefixes & PREFIX_DATA)
993 if (prefixes & PREFIX_ADR)
996 s->prefix = prefixes;
1000 /* now check op code */
1004 /**************************/
1005 /* extended op code */
1006 b = ldub(s->pc++) | 0x100;
1009 /**************************/
1027 ot = dflag ? OT_LONG : OT_WORD;
1030 case 0: /* OP Ev, Gv */
1031 modrm = ldub(s->pc++);
1032 reg = ((modrm >> 3) & 7) + OR_EAX;
1033 mod = (modrm >> 6) & 3;
1036 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1037 gen_op_ld_T0_A0[ot]();
1040 opreg = OR_EAX + rm;
1042 gen_op(s, op, ot, opreg, reg);
1043 if (mod != 3 && op != 7) {
1044 gen_op_st_T0_A0[ot]();
1047 case 1: /* OP Gv, Ev */
1048 modrm = ldub(s->pc++);
1049 mod = (modrm >> 6) & 3;
1050 reg = ((modrm >> 3) & 7) + OR_EAX;
1053 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1054 gen_op_ld_T1_A0[ot]();
1057 opreg = OR_EAX + rm;
1059 gen_op(s, op, ot, reg, opreg);
1061 case 2: /* OP A, Iv */
1062 val = insn_get(s, ot);
1063 gen_opi(s, op, ot, OR_EAX, val);
1069 case 0x80: /* GRP1 */
1078 ot = dflag ? OT_LONG : OT_WORD;
1080 modrm = ldub(s->pc++);
1081 mod = (modrm >> 6) & 3;
1083 op = (modrm >> 3) & 7;
1086 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1087 gen_op_ld_T0_A0[ot]();
1090 opreg = rm + OR_EAX;
1097 val = insn_get(s, ot);
1100 val = (int8_t)insn_get(s, OT_BYTE);
1104 gen_opi(s, op, ot, opreg, val);
1105 if (op != 7 && mod != 3) {
1106 gen_op_st_T0_A0[ot]();
1111 /**************************/
1112 /* inc, dec, and other misc arith */
1113 case 0x40 ... 0x47: /* inc Gv */
1114 ot = dflag ? OT_LONG : OT_WORD;
1115 gen_inc(s, ot, OR_EAX + (b & 7), 1);
1117 case 0x48 ... 0x4f: /* dec Gv */
1118 ot = dflag ? OT_LONG : OT_WORD;
1119 gen_inc(s, ot, OR_EAX + (b & 7), -1);
1121 case 0xf6: /* GRP3 */
1126 ot = dflag ? OT_LONG : OT_WORD;
1128 modrm = ldub(s->pc++);
1129 mod = (modrm >> 6) & 3;
1131 op = (modrm >> 3) & 7;
1133 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1134 gen_op_ld_T0_A0[ot]();
1136 gen_op_mov_TN_reg[ot][0][rm]();
1141 val = insn_get(s, ot);
1142 gen_op1_movl_T1_im(val);
1143 gen_op_testl_T0_T1_cc();
1144 s->cc_op = CC_OP_LOGICB + ot;
1149 gen_op_st_T0_A0[ot]();
1151 gen_op_mov_reg_T0[ot][rm]();
1155 gen_op_negl_T0_cc();
1157 gen_op_st_T0_A0[ot]();
1159 gen_op_mov_reg_T0[ot][rm]();
1161 s->cc_op = CC_OP_SUBB + ot;
1166 gen_op_mulb_AL_T0();
1169 gen_op_mulw_AX_T0();
1173 gen_op_mull_EAX_T0();
1180 gen_op_imulb_AL_T0();
1183 gen_op_imulw_AX_T0();
1187 gen_op_imull_EAX_T0();
1194 gen_op_divb_AL_T0();
1197 gen_op_divw_AX_T0();
1201 gen_op_divl_EAX_T0();
1208 gen_op_idivb_AL_T0();
1211 gen_op_idivw_AX_T0();
1215 gen_op_idivl_EAX_T0();
1220 error("GRP3: bad instruction");
1225 case 0xfe: /* GRP4 */
1226 case 0xff: /* GRP5 */
1230 ot = dflag ? OT_LONG : OT_WORD;
1232 modrm = ldub(s->pc++);
1233 mod = (modrm >> 6) & 3;
1235 op = (modrm >> 3) & 7;
1236 if (op >= 2 && b == 0xfe) {
1237 error("GRP4: bad instruction");
1241 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1242 gen_op_ld_T0_A0[ot]();
1244 gen_op_mov_TN_reg[ot][0][rm]();
1248 case 0: /* inc Ev */
1249 gen_inc(s, ot, OR_TMP0, 1);
1251 gen_op_st_T0_A0[ot]();
1253 case 1: /* dec Ev */
1254 gen_inc(s, ot, OR_TMP0, -1);
1256 gen_op_st_T0_A0[ot]();
1258 case 2: /* call Ev */
1259 gen_op1_movl_T1_im((long)s->pc);
1263 case 4: /* jmp Ev */
1266 case 6: /* push Ev */
1270 error("GRP5: bad instruction");
1275 case 0x84: /* test Ev, Gv */
1280 ot = dflag ? OT_LONG : OT_WORD;
1282 modrm = ldub(s->pc++);
1283 mod = (modrm >> 6) & 3;
1285 reg = (modrm >> 3) & 7;
1287 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1288 gen_op_mov_TN_reg[ot][1][reg + OR_EAX]();
1289 gen_op_testl_T0_T1_cc();
1290 s->cc_op = CC_OP_LOGICB + ot;
1293 case 0xa8: /* test eAX, Iv */
1298 ot = dflag ? OT_LONG : OT_WORD;
1299 val = insn_get(s, ot);
1301 gen_op_mov_TN_reg[ot][0][OR_EAX]();
1302 gen_op1_movl_T1_im(val);
1303 gen_op_testl_T0_T1_cc();
1304 s->cc_op = CC_OP_LOGICB + ot;
1307 case 0x98: /* CWDE/CBW */
1309 gen_op_movswl_EAX_AX();
1311 gen_op_movsbw_AX_AL();
1313 case 0x99: /* CDQ/CWD */
1315 gen_op_movslq_EDX_EAX();
1317 gen_op_movswl_DX_AX();
1319 case 0x1af: /* imul Gv, Ev */
1320 case 0x69: /* imul Gv, Ev, I */
1322 ot = dflag ? OT_LONG : OT_WORD;
1323 modrm = ldub(s->pc++);
1324 reg = ((modrm >> 3) & 7) + OR_EAX;
1326 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1328 val = insn_get(s, ot);
1329 gen_op1_movl_T1_im(val);
1330 } else if (b == 0x6b) {
1331 val = insn_get(s, OT_BYTE);
1332 gen_op1_movl_T1_im(val);
1334 gen_op_mov_TN_reg[ot][1][reg]();
1337 if (ot == OT_LONG) {
1342 gen_op_mov_reg_T0[ot][reg]();
1345 /**************************/
1347 case 0x50 ... 0x57: /* push */
1348 gen_op_mov_TN_reg[OT_LONG][0][(b & 7)]();
1351 case 0x58 ... 0x5f: /* pop */
1353 gen_op_mov_reg_T0[OT_LONG][reg]();
1355 case 0x68: /* push Iv */
1357 ot = dflag ? OT_LONG : OT_WORD;
1359 val = insn_get(s, ot);
1361 val = (int8_t)insn_get(s, OT_BYTE);
1362 gen_op1_movl_T0_im(val);
1365 case 0x8f: /* pop Ev */
1366 ot = dflag ? OT_LONG : OT_WORD;
1367 modrm = ldub(s->pc++);
1369 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
1371 case 0xc9: /* leave */
1372 gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
1373 gen_op_mov_reg_T0[OT_LONG][R_ESP]();
1375 gen_op_mov_reg_T0[OT_LONG][R_EBP]();
1377 /**************************/
1380 case 0x89: /* mov Gv, Ev */
1384 ot = dflag ? OT_LONG : OT_WORD;
1385 modrm = ldub(s->pc++);
1386 reg = (modrm >> 3) & 7;
1388 /* generate a generic store */
1389 gen_ldst_modrm(s, modrm, ot, OR_EAX + reg, 1);
1392 case 0xc7: /* mov Ev, Iv */
1396 ot = dflag ? OT_LONG : OT_WORD;
1397 modrm = ldub(s->pc++);
1398 mod = (modrm >> 6) & 3;
1400 val = insn_get(s, ot);
1401 gen_op1_movl_T0_im(val);
1402 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
1405 case 0x8b: /* mov Ev, Gv */
1409 ot = dflag ? OT_LONG : OT_WORD;
1410 modrm = ldub(s->pc++);
1411 reg = (modrm >> 3) & 7;
1413 gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1414 gen_op_mov_reg_T0[ot][reg]();
1417 case 0x1b6: /* movzbS Gv, Eb */
1418 case 0x1b7: /* movzwS Gv, Eb */
1419 case 0x1be: /* movsbS Gv, Eb */
1420 case 0x1bf: /* movswS Gv, Eb */
1423 /* d_ot is the size of destination */
1424 d_ot = dflag + OT_WORD;
1425 /* ot is the size of source */
1426 ot = (b & 1) + OT_BYTE;
1427 modrm = ldub(s->pc++);
1428 reg = ((modrm >> 3) & 7) + OR_EAX;
1429 mod = (modrm >> 6) & 3;
1433 gen_op_mov_TN_reg[ot][0][rm]();
1434 switch(ot | (b & 8)) {
1436 gen_op_movzbl_T0_T0();
1439 gen_op_movsbl_T0_T0();
1442 gen_op_movzwl_T0_T0();
1446 gen_op_movswl_T0_T0();
1449 gen_op_mov_reg_T0[d_ot][reg]();
1451 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1453 gen_op_lds_T0_A0[ot]();
1455 gen_op_ldu_T0_A0[ot]();
1457 gen_op_mov_reg_T0[d_ot][reg]();
1462 case 0x8d: /* lea */
1463 ot = dflag ? OT_LONG : OT_WORD;
1464 modrm = ldub(s->pc++);
1465 reg = (modrm >> 3) & 7;
1467 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1468 gen_op_mov_reg_A0[ot - OT_WORD][reg]();
1471 case 0xa0: /* mov EAX, Ov */
1473 case 0xa2: /* mov Ov, EAX */
1478 ot = dflag ? OT_LONG : OT_WORD;
1480 offset_addr = insn_get(s, OT_LONG);
1482 offset_addr = insn_get(s, OT_WORD);
1485 gen_op_ld_T0_A0[ot]();
1486 gen_op_mov_reg_T0[ot][R_EAX]();
1488 gen_op_mov_TN_reg[ot][0][R_EAX]();
1489 gen_op_st_T0_A0[ot]();
1493 case 0xb0 ... 0xb7: /* mov R, Ib */
1494 val = insn_get(s, OT_BYTE);
1495 gen_op1_movl_T0_im(val);
1496 gen_op_mov_reg_T0[OT_BYTE][b & 7]();
1498 case 0xb8 ... 0xbf: /* mov R, Iv */
1499 ot = dflag ? OT_LONG : OT_WORD;
1500 val = insn_get(s, ot);
1501 reg = OR_EAX + (b & 7);
1502 gen_op1_movl_T0_im(val);
1503 gen_op_mov_reg_T0[ot][reg]();
1506 case 0x91 ... 0x97: /* xchg R, EAX */
1507 ot = dflag ? OT_LONG : OT_WORD;
1509 gen_op_mov_TN_reg[ot][0][reg]();
1510 gen_op_mov_TN_reg[ot][1][R_EAX]();
1511 gen_op_mov_reg_T0[ot][R_EAX]();
1512 gen_op_mov_reg_T1[ot][reg]();
1515 case 0x87: /* xchg Ev, Gv */
1519 ot = dflag ? OT_LONG : OT_WORD;
1520 modrm = ldub(s->pc++);
1521 reg = (modrm >> 3) & 7;
1523 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1524 gen_op_mov_TN_reg[ot][0][reg]();
1525 gen_op_ld_T1_A0[ot]();
1526 gen_op_st_T0_A0[ot]();
1527 gen_op_mov_reg_T1[ot][reg]();
1530 /************************/
1541 ot = dflag ? OT_LONG : OT_WORD;
1543 modrm = ldub(s->pc++);
1544 mod = (modrm >> 6) & 3;
1546 op = (modrm >> 3) & 7;
1549 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1550 gen_op_ld_T0_A0[ot]();
1553 opreg = rm + OR_EAX;
1558 gen_shift(s, op, ot, opreg, OR_ECX);
1561 shift = ldub(s->pc++);
1563 gen_shifti(s, op, ot, opreg, shift);
1567 gen_op_st_T0_A0[ot]();
1582 /************************/
1586 modrm = ldub(s->pc++);
1587 mod = (modrm >> 6) & 3;
1589 op = ((b & 7) << 3) | ((modrm >> 3) & 7);
1593 gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
1595 case 0x00 ... 0x07: /* fxxxs */
1596 case 0x10 ... 0x17: /* fixxxl */
1597 case 0x20 ... 0x27: /* fxxxl */
1598 case 0x30 ... 0x37: /* fixxx */
1601 op1 = fp_ops[op & 7];
1604 if ((op & 7) == 5 || (op & 7) == 7)
1627 /* if integer, needs to convert to float */
1629 /* XXX: potential loss of precision if large integer */
1630 gen_ld(OP_LDUB + ot, OR_TMP0, reg_addr, offset_addr);
1631 gen_insn2(OP_I2FL, OR_FTMP0, OR_TMP0);
1633 gen_ld(OP_LDUB + ot, OR_FTMP0, reg_addr, offset_addr);
1636 op1 += OP_FADDL - OP_FADDQ;
1639 gen_insn3(op1, OR_ST0, OR_ST0, OR_FTMP0);
1641 gen_insn3(op1, OR_ST0, OR_FTMP0, OR_ST0);
1643 if ((op & 7) == 3) {
1644 /* fcomp needs pop */
1649 case 0x08: /* flds */
1650 case 0x0a: /* fsts */
1651 case 0x0b: /* fstps */
1652 case 0x18: /* fildl */
1653 case 0x1a: /* fistl */
1654 case 0x1b: /* fistpl */
1655 case 0x28: /* fldl */
1656 case 0x2a: /* fstl */
1657 case 0x2b: /* fstpl */
1658 case 0x38: /* filds */
1659 case 0x3a: /* fists */
1660 case 0x3b: /* fistps */
1684 gen_insn0(OP_FPUSH);
1686 /* XXX: potential loss of precision */
1687 gen_ld(OP_LDUB + ot, OR_TMP0, reg_addr, offset_addr);
1688 gen_insn2(OP_I2FL, OR_ST0, OR_TMP0);
1690 gen_ld(OP_LDUB + ot, OR_ST0, reg_addr, offset_addr);
1695 gen_insn2(OP_F2IL, OR_TMP0, OR_ST0);
1696 gen_st(OP_STB + ot, OR_TMP0, reg_addr, offset_addr);
1698 gen_st(OP_STB + ot, OR_ST0, reg_addr, offset_addr);
1705 case 0x2f: /* fnstsw mem */
1706 gen_insn3(OP_FNSTS, OR_TMP0, OR_ZERO, OR_ZERO);
1707 gen_st(OP_STW, OR_TMP0, reg_addr, offset_addr);
1710 case 0x3c: /* fbld */
1711 case 0x3e: /* fbstp */
1712 error("float BCD not hanlded");
1714 case 0x3d: /* fildll */
1715 gen_insn0(OP_FPUSH);
1716 gen_ld(OP_LDQ, OR_TMP0, reg_addr, offset_addr);
1717 gen_insn2(OP_I2FQ, OR_ST0, OR_TMP0);
1719 case 0x3f: /* fistpll */
1720 gen_insn2(OP_F2IQ, OR_TMP0, OR_ST0);
1721 gen_st(OP_STQ, OR_TMP0, reg_addr, offset_addr);
1725 error("unhandled memory FP\n");
1729 /* register float ops */
1730 opreg = rm + OR_ST0;
1733 case 0x08: /* fld sti */
1734 gen_insn0(OP_FPUSH);
1735 gen_mov(OR_ST0, OR_ST0 + ((rm + 1) & 7));
1737 case 0x09: /* fxchg sti */
1738 gen_mov(OR_TMP0, OR_ST0);
1739 gen_mov(OR_ST0, opreg);
1740 gen_mov(opreg, OR_TMP0);
1742 case 0x0a: /* grp d9/2 */
1748 error("unhandled FP GRP d9/2\n");
1752 case 0x0c: /* grp d9/4 */
1755 gen_insn3(OP_FSUBQ, OR_ST0, OR_ZERO, OR_ST0);
1758 gen_insn2(OP_FABSQ, OR_ST0, OR_ST0);
1761 gen_insn3(OP_CMP, OR_ZERO, OR_ST0, OR_ZERO);
1764 gen_insn3(OP_FSPECIAL, OR_ZERO, OR_ST0, OR_ZERO);
1770 case 0x0d: /* grp d9/5 */
1773 error("bad GRP d9/5");
1776 /* XXX: needs constant load or symbol table */
1777 gen_insn0(OP_FPUSH);
1778 gen_ld(OP_LDQ, OR_ST0, OR_ZERO,
1779 (rm * 8) + FLOAT_CONST_ADDR);
1782 case 0x0e: /* grp d9/6 */
1785 gen_insn3(OP_FSPECIAL, OR_ST0, OR_ST0, OR_ZERO);
1788 gen_insn3(OP_FSPECIAL, OR_ST1, OR_ST0, OR_ST1);
1792 gen_insn3(OP_FSPECIAL, OR_ST0, OR_ST0, OR_ZERO);
1793 gen_insn0(OP_FPUSH);
1795 gen_ld(OP_LDQ, OR_ST0, OR_ZERO,
1796 (0 * 8) + FLOAT_CONST_ADDR);
1798 case 3: /* fpatan */
1799 gen_insn3(OP_FSPECIAL, OR_ST1, OR_ST0, OR_ST1);
1802 case 4: /* fxtract */
1803 gen_insn0(OP_FPUSH);
1804 gen_insn3(OP_FSPECIAL, OR_ST0, OR_ST1, OR_ZERO);
1805 gen_insn3(OP_FSPECIAL, OR_ST1, OR_ST1, OR_ZERO);
1807 case 5: /* fprem1 */
1808 gen_insn3(OP_FSPECIAL, OR_ST0, OR_ST0, OR_ST1);
1810 case 6: /* fdecstp */
1811 gen_insn0(OP_FPUSH);
1814 case 7: /* fdecstp */
1819 case 0x0f: /* grp d9/7 */
1822 gen_insn3(OP_FSPECIAL, OR_ST0, OR_ST0, OR_ST1);
1824 case 1: /* fyl2xp1 */
1825 gen_insn3(OP_FSPECIAL, OR_ST1, OR_ST0, OR_ST1);
1828 case 3: /* fsincos */
1829 gen_insn0(OP_FPUSH);
1830 gen_insn3(OP_FSPECIAL, OR_ST0, OR_ST1, OR_ZERO);
1831 gen_insn3(OP_FSPECIAL, OR_ST1, OR_ST1, OR_ZERO);
1833 case 5: /* fscale */
1834 gen_insn3(OP_FSPECIAL, OR_ST0, OR_ST0, OR_ST1);
1837 case 4: /* frndint */
1841 gen_insn3(OP_FSPECIAL, OR_ST0, OR_ST0, OR_ZERO);
1845 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
1846 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
1847 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
1851 op1 = fp_ops[op & 7];
1853 if ((op & 7) == 5 || (op & 7) == 7)
1857 gen_insn3(op1, opreg, OR_ST0, opreg);
1859 gen_insn3(op1, opreg, opreg, OR_ST0);
1862 gen_insn3(op1, OR_ST0, opreg, OR_ST0);
1864 gen_insn3(op1, OR_ST0, OR_ST0, opreg);
1870 case 0x02: /* fcom */
1871 gen_insn3(OP_CMP, OR_ZERO, OR_ST0, opreg);
1873 case 0x03: /* fcomp */
1874 gen_insn3(OP_CMP, OR_ZERO, OR_ST0, opreg);
1877 case 0x15: /* da/5 */
1879 case 1: /* fucompp */
1880 gen_insn3(OP_CMP, OR_ZERO, OR_ST0, opreg);
1888 case 0x2a: /* fst sti */
1889 gen_mov(opreg, OR_ST0);
1891 case 0x2b: /* fstp sti */
1892 gen_mov(opreg, OR_ST0);
1895 case 0x33: /* de/3 */
1897 case 1: /* fcompp */
1898 gen_insn3(OP_CMP, OR_ZERO, OR_ST0, opreg);
1906 case 0x3c: /* df/4 */
1909 gen_insn3(OP_FNSTS, OR_EAX, OR_ZERO, OR_ZERO);
1916 error("unhandled FP\n");
1922 /************************/
1924 case 0xa4: /* movsS */
1929 ot = dflag ? OT_LONG : OT_WORD;
1930 if (prefixes & PREFIX_REPZ) {
1931 gen_op_movs[3 + ot]();
1937 case 0xaa: /* stosS */
1942 ot = dflag ? OT_LONG : OT_WORD;
1943 if (prefixes & PREFIX_REPZ) {
1944 gen_op_stos[3 + ot]();
1949 case 0xac: /* lodsS */
1954 ot = dflag ? OT_LONG : OT_WORD;
1955 if (prefixes & PREFIX_REPZ) {
1956 gen_op_lods[3 + ot]();
1961 case 0xae: /* scasS */
1966 ot = dflag ? OT_LONG : OT_WORD;
1967 if (prefixes & PREFIX_REPNZ) {
1968 gen_op_scas[6 + ot]();
1969 } else if (prefixes & PREFIX_REPZ) {
1970 gen_op_scas[3 + ot]();
1976 case 0xa6: /* cmpsS */
1981 ot = dflag ? OT_LONG : OT_WORD;
1982 if (prefixes & PREFIX_REPNZ) {
1983 gen_op_cmps[6 + ot]();
1984 } else if (prefixes & PREFIX_REPZ) {
1985 gen_op_cmps[3 + ot]();
1991 case 0x6c: /* insS */
1996 ot = dflag ? OT_LONG : OT_WORD;
1997 if (prefixes & PREFIX_REPZ) {
1998 gen_op_ins[3 + ot]();
2003 case 0x6e: /* outsS */
2008 ot = dflag ? OT_LONG : OT_WORD;
2009 if (prefixes & PREFIX_REPZ) {
2010 gen_op_outs[3 + ot]();
2016 /************************/
2018 case 0xc2: /* ret im */
2019 /* XXX: handle stack pop ? */
2023 gen_op_addl_ESP_im(val);
2026 case 0xc3: /* ret */
2030 case 0xe8: /* call */
2031 val = insn_get(s, OT_LONG);
2033 gen_op1_movl_T1_im((long)s->pc);
2037 case 0xe9: /* jmp */
2038 val = insn_get(s, OT_LONG);
2042 case 0xeb: /* jmp Jb */
2043 val = (int8_t)insn_get(s, OT_BYTE);
2047 case 0x70 ... 0x7f: /* jcc Jb */
2048 val = (int8_t)insn_get(s, OT_BYTE);
2051 case 0x180 ... 0x18f: /* jcc Jv */
2053 val = insn_get(s, OT_LONG);
2055 val = (int16_t)insn_get(s, OT_WORD);
2057 val += (long)s->pc; /* XXX: fix 16 bit wrap */
2062 case 0x190 ... 0x19f:
2063 modrm = ldub(s->pc++);
2065 gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1);
2068 /************************/
2070 case 0x9c: /* pushf */
2071 gen_op_movl_T0_eflags();
2074 case 0x9d: /* popf */
2076 gen_op_movl_eflags_T0();
2077 s->cc_op = CC_OP_EFLAGS;
2079 case 0x9e: /* sahf */
2080 gen_op_mov_TN_reg[OT_BYTE][0][R_AH]();
2081 if (s->cc_op != CC_OP_DYNAMIC)
2082 op_set_cc_op(s->cc_op);
2083 gen_op_movb_eflags_T0();
2084 s->cc_op = CC_OP_EFLAGS;
2086 case 0x9f: /* lahf */
2087 if (s->cc_op != CC_OP_DYNAMIC)
2088 op_set_cc_op(s->cc_op);
2089 gen_op_movl_T0_eflags();
2090 gen_op_mov_reg_T0[OT_BYTE][R_AH]();
2092 case 0xf5: /* cmc */
2093 if (s->cc_op != CC_OP_DYNAMIC)
2094 op_set_cc_op(s->cc_op);
2096 s->cc_op = CC_OP_EFLAGS;
2098 case 0xf8: /* clc */
2099 if (s->cc_op != CC_OP_DYNAMIC)
2100 op_set_cc_op(s->cc_op);
2102 s->cc_op = CC_OP_EFLAGS;
2104 case 0xf9: /* stc */
2105 if (s->cc_op != CC_OP_DYNAMIC)
2106 op_set_cc_op(s->cc_op);
2108 s->cc_op = CC_OP_EFLAGS;
2110 case 0xfc: /* cld */
2113 case 0xfd: /* std */
2117 /************************/
2119 case 0x90: /* nop */
2123 case 0x1a2: /* cpuid */
2128 error("unknown opcode %x", b);