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
target-mips
@ -3,6 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2004-2005 Jocelyn Mayer
|
* Copyright (c) 2004-2005 Jocelyn Mayer
|
||||||
* Copyright (c) 2006 Marius Groeger (FPU operations)
|
* 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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* 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);
|
glue(stq, MEMSUFFIX)(T0, DT0);
|
||||||
RETURN();
|
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)
|
void glue(op_luxc1, MEMSUFFIX) (void)
|
||||||
{
|
{
|
||||||
/* XXX: is defined as unaligned */
|
DT0 = glue(ldq, MEMSUFFIX)(T0 & ~0x7);
|
||||||
DT0 = glue(ldq, MEMSUFFIX)(T0 + T1);
|
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
void glue(op_suxc1, MEMSUFFIX) (void)
|
void glue(op_suxc1, MEMSUFFIX) (void)
|
||||||
{
|
{
|
||||||
/* XXX: is defined as unaligned */
|
glue(stq, MEMSUFFIX)(T0 & ~0x7, DT0);
|
||||||
glue(stq, MEMSUFFIX)(T0 + T1, DT0);
|
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
@ -711,10 +711,6 @@ OP_LD_TABLE(wc1);
|
|||||||
OP_ST_TABLE(wc1);
|
OP_ST_TABLE(wc1);
|
||||||
OP_LD_TABLE(dc1);
|
OP_LD_TABLE(dc1);
|
||||||
OP_ST_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_LD_TABLE(uxc1);
|
||||||
OP_ST_TABLE(uxc1);
|
OP_ST_TABLE(uxc1);
|
||||||
|
|
||||||
@ -1092,7 +1088,7 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GEN_STORE_TN_REG(rt, T0);
|
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 */
|
/* Arithmetic */
|
||||||
@ -5242,25 +5238,36 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
|
|||||||
|
|
||||||
/* Coprocessor 3 (FPU) */
|
/* Coprocessor 3 (FPU) */
|
||||||
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd,
|
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";
|
const char *opn = "extended float load/store";
|
||||||
|
int store = 0;
|
||||||
|
|
||||||
/* All of those work only on 64bit FPUs. */
|
/* All of those work only on 64bit FPUs. */
|
||||||
gen_op_cp1_64bitmode();
|
gen_op_cp1_64bitmode();
|
||||||
GEN_LOAD_REG_TN(T0, base);
|
if (base == 0) {
|
||||||
GEN_LOAD_REG_TN(T1, index);
|
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
|
/* Don't do NOP if destination is zero: we must perform the actual
|
||||||
* memory access
|
* memory access
|
||||||
*/
|
*/
|
||||||
switch (opc) {
|
switch (opc) {
|
||||||
case OPC_LWXC1:
|
case OPC_LWXC1:
|
||||||
op_ldst(lwxc1);
|
op_ldst(lwc1);
|
||||||
GEN_STORE_FTN_FREG(fd, WT0);
|
GEN_STORE_FTN_FREG(fd, WT0);
|
||||||
opn = "lwxc1";
|
opn = "lwxc1";
|
||||||
break;
|
break;
|
||||||
case OPC_LDXC1:
|
case OPC_LDXC1:
|
||||||
op_ldst(ldxc1);
|
op_ldst(ldc1);
|
||||||
GEN_STORE_FTN_FREG(fd, DT0);
|
GEN_STORE_FTN_FREG(fd, DT0);
|
||||||
opn = "ldxc1";
|
opn = "ldxc1";
|
||||||
break;
|
break;
|
||||||
@ -5270,26 +5277,30 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd,
|
|||||||
opn = "luxc1";
|
opn = "luxc1";
|
||||||
break;
|
break;
|
||||||
case OPC_SWXC1:
|
case OPC_SWXC1:
|
||||||
GEN_LOAD_FREG_FTN(WT0, fd);
|
GEN_LOAD_FREG_FTN(WT0, fs);
|
||||||
op_ldst(swxc1);
|
op_ldst(swc1);
|
||||||
opn = "swxc1";
|
opn = "swxc1";
|
||||||
|
store = 1;
|
||||||
break;
|
break;
|
||||||
case OPC_SDXC1:
|
case OPC_SDXC1:
|
||||||
GEN_LOAD_FREG_FTN(DT0, fd);
|
GEN_LOAD_FREG_FTN(DT0, fs);
|
||||||
op_ldst(sdxc1);
|
op_ldst(sdc1);
|
||||||
opn = "sdxc1";
|
opn = "sdxc1";
|
||||||
|
store = 1;
|
||||||
break;
|
break;
|
||||||
case OPC_SUXC1:
|
case OPC_SUXC1:
|
||||||
GEN_LOAD_FREG_FTN(DT0, fd);
|
GEN_LOAD_FREG_FTN(DT0, fs);
|
||||||
op_ldst(suxc1);
|
op_ldst(suxc1);
|
||||||
opn = "suxc1";
|
opn = "suxc1";
|
||||||
|
store = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
MIPS_INVAL(opn);
|
MIPS_INVAL(opn);
|
||||||
generate_exception(ctx, EXCP_RI);
|
generate_exception(ctx, EXCP_RI);
|
||||||
return;
|
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,
|
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_SWXC1:
|
||||||
case OPC_SDXC1:
|
case OPC_SDXC1:
|
||||||
case OPC_SUXC1:
|
case OPC_SUXC1:
|
||||||
gen_flt3_ldst(ctx, op1, sa, rs, rt);
|
gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
|
||||||
break;
|
break;
|
||||||
case OPC_PREFX:
|
case OPC_PREFX:
|
||||||
/* treat as noop */
|
/* treat as noop */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user