aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>2007-05-20 01:36:29 +0000
committerths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>2007-05-20 01:36:29 +0000
commit93b12ccc62debf438f0881898e6be0eeb51e1bdd (patch)
treee8b26686d267fbe918c60f90614ac2bab8102cdb
parentcfc05abe4c4640a3a83c36a6874815a1514d31e7 (diff)
Fix indexed FP load/store instructions.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2837 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r--target-mips/op.c1
-rw-r--r--target-mips/op_mem.c26
-rw-r--r--target-mips/translate.c45
3 files changed, 31 insertions, 41 deletions
diff --git a/target-mips/op.c b/target-mips/op.c
index 8c0c687a83..9ba0050ce6 100644
--- a/target-mips/op.c
+++ b/target-mips/op.c
@@ -3,6 +3,7 @@
*
* Copyright (c) 2004-2005 Jocelyn Mayer
* Copyright (c) 2006 Marius Groeger (FPU operations)
+ * Copyright (c) 2007 Thiemo Seufer (64-bit FPU support)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
diff --git a/target-mips/op_mem.c b/target-mips/op_mem.c
index f0eebc09dd..f9fc69c8e3 100644
--- a/target-mips/op_mem.c
+++ b/target-mips/op_mem.c
@@ -220,35 +220,13 @@ void glue(op_sdc1, MEMSUFFIX) (void)
glue(stq, MEMSUFFIX)(T0, DT0);
RETURN();
}
-void glue(op_lwxc1, MEMSUFFIX) (void)
-{
- WT0 = glue(ldl, MEMSUFFIX)(T0 + T1);
- RETURN();
-}
-void glue(op_swxc1, MEMSUFFIX) (void)
-{
- glue(stl, MEMSUFFIX)(T0 + T1, WT0);
- RETURN();
-}
-void glue(op_ldxc1, MEMSUFFIX) (void)
-{
- DT0 = glue(ldq, MEMSUFFIX)(T0 + T1);
- RETURN();
-}
-void glue(op_sdxc1, MEMSUFFIX) (void)
-{
- glue(stq, MEMSUFFIX)(T0 + T1, DT0);
- RETURN();
-}
void glue(op_luxc1, MEMSUFFIX) (void)
{
- /* XXX: is defined as unaligned */
- DT0 = glue(ldq, MEMSUFFIX)(T0 + T1);
+ DT0 = glue(ldq, MEMSUFFIX)(T0 & ~0x7);
RETURN();
}
void glue(op_suxc1, MEMSUFFIX) (void)
{
- /* XXX: is defined as unaligned */
- glue(stq, MEMSUFFIX)(T0 + T1, DT0);
+ glue(stq, MEMSUFFIX)(T0 & ~0x7, DT0);
RETURN();
}
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 075be1ed05..03f802a272 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -711,10 +711,6 @@ OP_LD_TABLE(wc1);
OP_ST_TABLE(wc1);
OP_LD_TABLE(dc1);
OP_ST_TABLE(dc1);
-OP_LD_TABLE(wxc1);
-OP_ST_TABLE(wxc1);
-OP_LD_TABLE(dxc1);
-OP_ST_TABLE(dxc1);
OP_LD_TABLE(uxc1);
OP_ST_TABLE(uxc1);
@@ -1092,7 +1088,7 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
return;
}
GEN_STORE_TN_REG(rt, T0);
- MIPS_DEBUG("%s %s, %s, %x", opn, regnames[rt], regnames[rs], uimm);
+ MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
}
/* Arithmetic */
@@ -5242,25 +5238,36 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
/* Coprocessor 3 (FPU) */
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd,
- int base, int index)
+ int fs, int base, int index)
{
const char *opn = "extended float load/store";
+ int store = 0;
/* All of those work only on 64bit FPUs. */
gen_op_cp1_64bitmode();
- GEN_LOAD_REG_TN(T0, base);
- GEN_LOAD_REG_TN(T1, index);
+ if (base == 0) {
+ if (index == 0)
+ gen_op_reset_T0();
+ else
+ GEN_LOAD_REG_TN(T0, index);
+ } else if (index == 0) {
+ GEN_LOAD_REG_TN(T0, base);
+ } else {
+ GEN_LOAD_REG_TN(T0, base);
+ GEN_LOAD_REG_TN(T1, index);
+ gen_op_addr_add();
+ }
/* Don't do NOP if destination is zero: we must perform the actual
* memory access
*/
switch (opc) {
case OPC_LWXC1:
- op_ldst(lwxc1);
+ op_ldst(lwc1);
GEN_STORE_FTN_FREG(fd, WT0);
opn = "lwxc1";
break;
case OPC_LDXC1:
- op_ldst(ldxc1);
+ op_ldst(ldc1);
GEN_STORE_FTN_FREG(fd, DT0);
opn = "ldxc1";
break;
@@ -5270,26 +5277,30 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd,
opn = "luxc1";
break;
case OPC_SWXC1:
- GEN_LOAD_FREG_FTN(WT0, fd);
- op_ldst(swxc1);
+ GEN_LOAD_FREG_FTN(WT0, fs);
+ op_ldst(swc1);
opn = "swxc1";
+ store = 1;
break;
case OPC_SDXC1:
- GEN_LOAD_FREG_FTN(DT0, fd);
- op_ldst(sdxc1);
+ GEN_LOAD_FREG_FTN(DT0, fs);
+ op_ldst(sdc1);
opn = "sdxc1";
+ store = 1;
break;
case OPC_SUXC1:
- GEN_LOAD_FREG_FTN(DT0, fd);
+ GEN_LOAD_FREG_FTN(DT0, fs);
op_ldst(suxc1);
opn = "suxc1";
+ store = 1;
break;
default:
MIPS_INVAL(opn);
generate_exception(ctx, EXCP_RI);
return;
}
- MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[fd],regnames[index], regnames[base]);
+ MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
+ regnames[index], regnames[base]);
}
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, int fd,
@@ -5882,7 +5893,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
case OPC_SWXC1:
case OPC_SDXC1:
case OPC_SUXC1:
- gen_flt3_ldst(ctx, op1, sa, rs, rt);
+ gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
break;
case OPC_PREFX:
/* treat as noop */