aboutsummaryrefslogtreecommitdiff
path: root/translate-i386.c
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2003-03-16 22:54:06 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2003-03-16 22:54:06 +0000
commit5dd9488c09081a76ff86e0d74e56a9d98d666d64 (patch)
tree59911b567f66eb5f51f8f7ea427fbfa2519ef187 /translate-i386.c
parent60cd49d5d7e6dd3858f72916fbcf462ba60bbd6e (diff)
added cmov instruction
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@32 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'translate-i386.c')
-rw-r--r--translate-i386.c61
1 files changed, 43 insertions, 18 deletions
diff --git a/translate-i386.c b/translate-i386.c
index 7737dc1219..9bf7f5607e 100644
--- a/translate-i386.c
+++ b/translate-i386.c
@@ -44,19 +44,6 @@ int __op_param1, __op_param2, __op_param3;
extern FILE *logfile;
extern int loglevel;
-/* supress that */
-static void error(const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- fprintf(stderr, "\n");
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
- va_end(ap);
- exit(1);
-}
-
#define PREFIX_REPZ 1
#define PREFIX_REPNZ 2
#define PREFIX_LOCK 4
@@ -352,6 +339,29 @@ static GenOpFunc *gen_op_addl_A0_reg_sN[4][8] = {
},
};
+static GenOpFunc *gen_op_cmov_reg_T1_T0[2][8] = {
+ [0] = {
+ gen_op_cmovw_EAX_T1_T0,
+ gen_op_cmovw_ECX_T1_T0,
+ gen_op_cmovw_EDX_T1_T0,
+ gen_op_cmovw_EBX_T1_T0,
+ gen_op_cmovw_ESP_T1_T0,
+ gen_op_cmovw_EBP_T1_T0,
+ gen_op_cmovw_ESI_T1_T0,
+ gen_op_cmovw_EDI_T1_T0,
+ },
+ [1] = {
+ gen_op_cmovl_EAX_T1_T0,
+ gen_op_cmovl_ECX_T1_T0,
+ gen_op_cmovl_EDX_T1_T0,
+ gen_op_cmovl_EBX_T1_T0,
+ gen_op_cmovl_ESP_T1_T0,
+ gen_op_cmovl_EBP_T1_T0,
+ gen_op_cmovl_ESI_T1_T0,
+ gen_op_cmovl_EDI_T1_T0,
+ },
+};
+
static GenOpFunc *gen_op_arith_T0_T1_cc[8] = {
gen_op_addl_T0_T1_cc,
gen_op_orl_T0_T1_cc,
@@ -2586,12 +2596,27 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
s->is_jmp = 1;
break;
- case 0x190 ... 0x19f:
+ case 0x190 ... 0x19f: /* setcc Gv */
modrm = ldub(s->pc++);
gen_setcc(s, b);
gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1);
break;
-
+ case 0x140 ... 0x14f: /* cmov Gv, Ev */
+ ot = dflag ? OT_LONG : OT_WORD;
+ modrm = ldub(s->pc++);
+ reg = (modrm >> 3) & 7;
+ mod = (modrm >> 6) & 3;
+ gen_setcc(s, b);
+ if (mod != 3) {
+ gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
+ gen_op_ld_T1_A0[ot]();
+ } else {
+ rm = modrm & 7;
+ gen_op_mov_TN_reg[ot][1][rm]();
+ }
+ gen_op_cmov_reg_T1_T0[ot - OT_WORD][reg]();
+ break;
+
/************************/
/* flags */
case 0x9c: /* pushf */
@@ -2801,7 +2826,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
gen_op_loop[s->aflag][b & 3](val, (long)s->pc);
s->is_jmp = 1;
break;
- case 0x1a2: /* rdtsc */
+ case 0x131: /* rdtsc */
gen_op_rdtsc();
break;
#if 0
@@ -2841,8 +2866,8 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
do {
ret = disas_insn(dc, pc_ptr);
if (ret == -1) {
- error("unknown instruction at PC=0x%x B=%02x %02x %02x",
- pc_ptr, pc_ptr[0], pc_ptr[1], pc_ptr[2]);
+ fprintf(stderr, "unknown instruction at PC=0x%08lx B=%02x %02x %02x",
+ (long)pc_ptr, pc_ptr[0], pc_ptr[1], pc_ptr[2]);
abort();
}
pc_ptr = (void *)ret;