Revision ba1c6e37 translate-i386.c
b/translate-i386.c | ||
---|---|---|
495 | 495 |
gen_op_rep_outsl, |
496 | 496 |
}; |
497 | 497 |
|
498 |
static GenOpFunc *gen_op_in[3] = { |
|
499 |
gen_op_inb_T0_T1, |
|
500 |
gen_op_inw_T0_T1, |
|
501 |
gen_op_inl_T0_T1, |
|
502 |
}; |
|
503 |
|
|
504 |
static GenOpFunc *gen_op_out[3] = { |
|
505 |
gen_op_outb_T0_T1, |
|
506 |
gen_op_outw_T0_T1, |
|
507 |
gen_op_outl_T0_T1, |
|
508 |
}; |
|
509 |
|
|
498 | 510 |
enum { |
499 | 511 |
JCC_O, |
500 | 512 |
JCC_B, |
... | ... | |
632 | 644 |
|
633 | 645 |
static void gen_opi(DisasContext *s1, int op, int ot, int d, int c) |
634 | 646 |
{ |
635 |
gen_op1_movl_T1_im(c);
|
|
647 |
gen_op_movl_T1_im(c); |
|
636 | 648 |
gen_op(s1, op, ot, d, OR_TMP0); |
637 | 649 |
} |
638 | 650 |
|
... | ... | |
678 | 690 |
static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c) |
679 | 691 |
{ |
680 | 692 |
/* currently not optimized */ |
681 |
gen_op1_movl_T1_im(c);
|
|
693 |
gen_op_movl_T1_im(c); |
|
682 | 694 |
gen_shift(s1, op, ot, d, OR_TMP1); |
683 | 695 |
} |
684 | 696 |
|
... | ... | |
746 | 758 |
if (reg2 == OR_ZERO) { |
747 | 759 |
/* op: disp + (reg1 << scale) */ |
748 | 760 |
if (reg1 == OR_ZERO) { |
749 |
gen_op1_movl_A0_im(disp);
|
|
761 |
gen_op_movl_A0_im(disp); |
|
750 | 762 |
} else if (scale == 0 && disp == 0) { |
751 | 763 |
gen_op_movl_A0_reg[reg1](); |
752 | 764 |
} else { |
... | ... | |
755 | 767 |
} else { |
756 | 768 |
/* op: disp + reg1 + (reg2 << scale) */ |
757 | 769 |
if (disp != 0) { |
758 |
gen_op1_movl_A0_im(disp);
|
|
770 |
gen_op_movl_A0_im(disp); |
|
759 | 771 |
gen_op_addl_A0_reg_sN[0][reg1](); |
760 | 772 |
} else { |
761 | 773 |
gen_op_movl_A0_reg[reg1](); |
... | ... | |
1149 | 1161 |
switch(op) { |
1150 | 1162 |
case 0: /* test */ |
1151 | 1163 |
val = insn_get(s, ot); |
1152 |
gen_op1_movl_T1_im(val);
|
|
1164 |
gen_op_movl_T1_im(val); |
|
1153 | 1165 |
gen_op_testl_T0_T1_cc(); |
1154 | 1166 |
s->cc_op = CC_OP_LOGICB + ot; |
1155 | 1167 |
break; |
... | ... | |
1266 | 1278 |
gen_op_st_T0_A0[ot](); |
1267 | 1279 |
break; |
1268 | 1280 |
case 2: /* call Ev */ |
1269 |
gen_op1_movl_T1_im((long)s->pc);
|
|
1281 |
gen_op_movl_T1_im((long)s->pc); |
|
1270 | 1282 |
gen_op_pushl_T1(); |
1271 | 1283 |
gen_op_jmp_T0(); |
1272 | 1284 |
break; |
... | ... | |
1309 | 1321 |
val = insn_get(s, ot); |
1310 | 1322 |
|
1311 | 1323 |
gen_op_mov_TN_reg[ot][0][OR_EAX](); |
1312 |
gen_op1_movl_T1_im(val);
|
|
1324 |
gen_op_movl_T1_im(val); |
|
1313 | 1325 |
gen_op_testl_T0_T1_cc(); |
1314 | 1326 |
s->cc_op = CC_OP_LOGICB + ot; |
1315 | 1327 |
break; |
... | ... | |
1336 | 1348 |
gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0); |
1337 | 1349 |
if (b == 0x69) { |
1338 | 1350 |
val = insn_get(s, ot); |
1339 |
gen_op1_movl_T1_im(val);
|
|
1351 |
gen_op_movl_T1_im(val); |
|
1340 | 1352 |
} else if (b == 0x6b) { |
1341 | 1353 |
val = insn_get(s, OT_BYTE); |
1342 |
gen_op1_movl_T1_im(val);
|
|
1354 |
gen_op_movl_T1_im(val); |
|
1343 | 1355 |
} else { |
1344 | 1356 |
gen_op_mov_TN_reg[ot][1][reg](); |
1345 | 1357 |
} |
... | ... | |
1369 | 1381 |
val = insn_get(s, ot); |
1370 | 1382 |
else |
1371 | 1383 |
val = (int8_t)insn_get(s, OT_BYTE); |
1372 |
gen_op1_movl_T0_im(val);
|
|
1384 |
gen_op_movl_T0_im(val); |
|
1373 | 1385 |
gen_op_pushl_T0(); |
1374 | 1386 |
break; |
1375 | 1387 |
case 0x8f: /* pop Ev */ |
... | ... | |
1408 | 1420 |
mod = (modrm >> 6) & 3; |
1409 | 1421 |
|
1410 | 1422 |
val = insn_get(s, ot); |
1411 |
gen_op1_movl_T0_im(val);
|
|
1423 |
gen_op_movl_T0_im(val); |
|
1412 | 1424 |
gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1); |
1413 | 1425 |
break; |
1414 | 1426 |
case 0x8a: |
... | ... | |
1502 | 1514 |
|
1503 | 1515 |
case 0xb0 ... 0xb7: /* mov R, Ib */ |
1504 | 1516 |
val = insn_get(s, OT_BYTE); |
1505 |
gen_op1_movl_T0_im(val);
|
|
1517 |
gen_op_movl_T0_im(val); |
|
1506 | 1518 |
gen_op_mov_reg_T0[OT_BYTE][b & 7](); |
1507 | 1519 |
break; |
1508 | 1520 |
case 0xb8 ... 0xbf: /* mov R, Iv */ |
1509 | 1521 |
ot = dflag ? OT_LONG : OT_WORD; |
1510 | 1522 |
val = insn_get(s, ot); |
1511 | 1523 |
reg = OR_EAX + (b & 7); |
1512 |
gen_op1_movl_T0_im(val);
|
|
1524 |
gen_op_movl_T0_im(val); |
|
1513 | 1525 |
gen_op_mov_reg_T0[ot][reg](); |
1514 | 1526 |
break; |
1515 | 1527 |
|
... | ... | |
1978 | 1990 |
} |
1979 | 1991 |
break; |
1980 | 1992 |
|
1993 |
/************************/ |
|
1994 |
/* port I/O */ |
|
1981 | 1995 |
case 0x6c: /* insS */ |
1982 | 1996 |
case 0x6d: |
1983 | 1997 |
if ((b & 1) == 0) |
... | ... | |
2002 | 2016 |
gen_op_outs[ot](); |
2003 | 2017 |
} |
2004 | 2018 |
break; |
2019 |
case 0xe4: |
|
2020 |
case 0xe5: |
|
2021 |
if ((b & 1) == 0) |
|
2022 |
ot = OT_BYTE; |
|
2023 |
else |
|
2024 |
ot = dflag ? OT_LONG : OT_WORD; |
|
2025 |
val = ldub(s->pc++); |
|
2026 |
gen_op_movl_T0_im(val); |
|
2027 |
gen_op_in[ot](); |
|
2028 |
gen_op_mov_reg_T1[ot][R_EAX](); |
|
2029 |
break; |
|
2030 |
case 0xe6: |
|
2031 |
case 0xe7: |
|
2032 |
if ((b & 1) == 0) |
|
2033 |
ot = OT_BYTE; |
|
2034 |
else |
|
2035 |
ot = dflag ? OT_LONG : OT_WORD; |
|
2036 |
val = ldub(s->pc++); |
|
2037 |
gen_op_movl_T0_im(val); |
|
2038 |
gen_op_mov_TN_reg[ot][1][R_EAX](); |
|
2039 |
gen_op_out[ot](); |
|
2040 |
break; |
|
2041 |
case 0xec: |
|
2042 |
case 0xed: |
|
2043 |
if ((b & 1) == 0) |
|
2044 |
ot = OT_BYTE; |
|
2045 |
else |
|
2046 |
ot = dflag ? OT_LONG : OT_WORD; |
|
2047 |
gen_op_mov_TN_reg[OT_WORD][0][R_EDX](); |
|
2048 |
gen_op_in[ot](); |
|
2049 |
gen_op_mov_reg_T1[ot][R_EAX](); |
|
2050 |
break; |
|
2051 |
case 0xee: |
|
2052 |
case 0xef: |
|
2053 |
if ((b & 1) == 0) |
|
2054 |
ot = OT_BYTE; |
|
2055 |
else |
|
2056 |
ot = dflag ? OT_LONG : OT_WORD; |
|
2057 |
gen_op_mov_TN_reg[OT_WORD][0][R_EDX](); |
|
2058 |
gen_op_mov_TN_reg[ot][1][R_EAX](); |
|
2059 |
gen_op_out[ot](); |
|
2060 |
break; |
|
2005 | 2061 |
|
2006 | 2062 |
/************************/ |
2007 | 2063 |
/* control */ |
... | ... | |
2020 | 2076 |
case 0xe8: /* call */ |
2021 | 2077 |
val = insn_get(s, OT_LONG); |
2022 | 2078 |
val += (long)s->pc; |
2023 |
gen_op1_movl_T1_im((long)s->pc);
|
|
2079 |
gen_op_movl_T1_im((long)s->pc); |
|
2024 | 2080 |
gen_op_pushl_T1(); |
2025 | 2081 |
gen_op_jmp_im(val); |
2026 | 2082 |
break; |
... | ... | |
2121 | 2177 |
return (long)s->pc; |
2122 | 2178 |
} |
2123 | 2179 |
|
2180 |
/* return the next pc */ |
|
2181 |
int cpu_x86_gen_code(uint8_t *gen_code_buf, int *gen_code_size_ptr, |
|
2182 |
uint8_t *pc_start) |
|
2183 |
{ |
|
2184 |
DisasContext dc1, *dc = &dc1; |
|
2185 |
long ret; |
|
2186 |
dc->cc_op = CC_OP_DYNAMIC; |
|
2187 |
gen_code_ptr = gen_code_buf; |
|
2188 |
gen_start(); |
|
2189 |
ret = disas_insn(dc, pc_start); |
|
2190 |
if (ret == -1) |
|
2191 |
error("unknown instruction at PC=0x%x", pc_start); |
|
2192 |
gen_end(); |
|
2193 |
*gen_code_size_ptr = gen_code_ptr - gen_code_buf; |
|
2194 |
printf("0x%08lx: code_size = %d\n", (long)pc_start, *gen_code_size_ptr); |
|
2195 |
return 0; |
|
2196 |
} |
|
2197 |
|
|
2198 |
CPUX86State *cpu_x86_init(void) |
|
2199 |
{ |
|
2200 |
CPUX86State *env; |
|
2201 |
int i; |
|
2202 |
|
|
2203 |
env = malloc(sizeof(CPUX86State)); |
|
2204 |
if (!env) |
|
2205 |
return NULL; |
|
2206 |
memset(env, 0, sizeof(CPUX86State)); |
|
2207 |
/* basic FPU init */ |
|
2208 |
for(i = 0;i < 8; i++) |
|
2209 |
env->fptags[i] = 1; |
|
2210 |
env->fpuc = 0x37f; |
|
2211 |
/* flags setup */ |
|
2212 |
env->cc_op = CC_OP_EFLAGS; |
|
2213 |
env->df = 1; |
|
2214 |
return env; |
|
2215 |
} |
|
2216 |
|
|
2217 |
void cpu_x86_close(CPUX86State *env) |
|
2218 |
{ |
|
2219 |
free(env); |
|
2220 |
} |
Also available in: Unified diff