summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2007-01-16 19:28:58 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2007-01-16 19:28:58 +0000
commitdabd98ddf501ab9e28905f64a28282be96840a2d (patch)
tree7de0d018b25dc2d3911cdeaaab9338c7207ed2cf
parentdaf90626beeb5f20504c593f01604a554f7ef232 (diff)
downloadqemu-dabd98ddf501ab9e28905f64a28282be96840a2d.tar.gz
fixed movd mmx/sse insn
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2321 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r--target-i386/ops_sse.h19
-rw-r--r--target-i386/translate.c48
2 files changed, 59 insertions, 8 deletions
diff --git a/target-i386/ops_sse.h b/target-i386/ops_sse.h
index cdc3801200..df1527c554 100644
--- a/target-i386/ops_sse.h
+++ b/target-i386/ops_sse.h
@@ -558,6 +558,25 @@ void OPPROTO glue(op_movl_T0_mm, SUFFIX) (void)
T0 = s->L(0);
}
+#ifdef TARGET_X86_64
+void OPPROTO glue(op_movq_mm_T0, SUFFIX) (void)
+{
+ Reg *d;
+ d = (Reg *)((char *)env + PARAM1);
+ d->Q(0) = T0;
+#if SHIFT == 1
+ d->Q(1) = 0;
+#endif
+}
+
+void OPPROTO glue(op_movq_T0_mm, SUFFIX) (void)
+{
+ Reg *s;
+ s = (Reg *)((char *)env + PARAM1);
+ T0 = s->Q(0);
+}
+#endif
+
#if SHIFT == 0
void OPPROTO glue(op_pshufw, SUFFIX) (void)
{
diff --git a/target-i386/translate.c b/target-i386/translate.c
index ad18af9757..735acb0e47 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -2621,12 +2621,28 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
gen_sto_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
break;
case 0x6e: /* movd mm, ea */
- gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
- gen_op_movl_mm_T0_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
+#ifdef TARGET_X86_64
+ if (s->dflag == 2) {
+ gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 0);
+ gen_op_movq_mm_T0_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
+ } else
+#endif
+ {
+ gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
+ gen_op_movl_mm_T0_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
+ }
break;
case 0x16e: /* movd xmm, ea */
- gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
- gen_op_movl_mm_T0_xmm(offsetof(CPUX86State,xmm_regs[reg]));
+#ifdef TARGET_X86_64
+ if (s->dflag == 2) {
+ gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 0);
+ gen_op_movq_mm_T0_xmm(offsetof(CPUX86State,xmm_regs[reg]));
+ } else
+#endif
+ {
+ gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
+ gen_op_movl_mm_T0_xmm(offsetof(CPUX86State,xmm_regs[reg]));
+ }
break;
case 0x6f: /* movq mm, ea */
if (mod != 3) {
@@ -2750,12 +2766,28 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
break;
case 0x7e: /* movd ea, mm */
- gen_op_movl_T0_mm_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
- gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
+#ifdef TARGET_X86_64
+ if (s->dflag == 2) {
+ gen_op_movq_T0_mm_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
+ gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 1);
+ } else
+#endif
+ {
+ gen_op_movl_T0_mm_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
+ gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
+ }
break;
case 0x17e: /* movd ea, xmm */
- gen_op_movl_T0_mm_xmm(offsetof(CPUX86State,xmm_regs[reg]));
- gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
+#ifdef TARGET_X86_64
+ if (s->dflag == 2) {
+ gen_op_movq_T0_mm_xmm(offsetof(CPUX86State,xmm_regs[reg]));
+ gen_ldst_modrm(s, modrm, OT_QUAD, OR_TMP0, 1);
+ } else
+#endif
+ {
+ gen_op_movl_T0_mm_xmm(offsetof(CPUX86State,xmm_regs[reg]));
+ gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
+ }
break;
case 0x27e: /* movq xmm, ea */
if (mod != 3) {