Fix indexed FP load/store instructions.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2837 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
ths 2007-05-20 01:36:29 +00:00
parent cfc05abe4c
commit 93b12ccc62
3 changed files with 31 additions and 41 deletions

View File

@ -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

View File

@ -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();
}

View File

@ -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 */