From 93b12ccc62debf438f0881898e6be0eeb51e1bdd Mon Sep 17 00:00:00 2001 From: ths Date: Sun, 20 May 2007 01:36:29 +0000 Subject: [PATCH] Fix indexed FP load/store instructions. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2837 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/op.c | 1 + target-mips/op_mem.c | 26 ++------------------------ target-mips/translate.c | 45 ++++++++++++++++++++++++++++----------------- 3 files changed, 31 insertions(+), 41 deletions(-) diff --git a/target-mips/op.c b/target-mips/op.c index 8c0c687..9ba0050 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 f0eebc0..f9fc69c 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 075be1e..03f802a 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 */ -- 2.7.4