summaryrefslogtreecommitdiff
path: root/target-mips/translate.c
diff options
context:
space:
mode:
Diffstat (limited to 'target-mips/translate.c')
-rw-r--r--target-mips/translate.c45
1 files changed, 28 insertions, 17 deletions
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 075be1ed0..03f802a27 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 */