mirror of https://github.com/xemu-project/xemu.git
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:
parent
cfc05abe4c
commit
93b12ccc62
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue