From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1L3f1i-0007rG-42 for qemu-devel@nongnu.org; Fri, 21 Nov 2008 18:03:02 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1L3f1h-0007qk-Fa for qemu-devel@nongnu.org; Fri, 21 Nov 2008 18:03:01 -0500 Received: from [199.232.76.173] (port=41542 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1L3f1h-0007qh-CP for qemu-devel@nongnu.org; Fri, 21 Nov 2008 18:03:01 -0500 Received: from hall.aurel32.net ([88.191.82.174]:43852) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1L3f1g-0003GW-UT for qemu-devel@nongnu.org; Fri, 21 Nov 2008 18:03:01 -0500 Received: from volta-wlan.aurel32.net ([2002:52e8:2fb:ffff:21d:e0ff:fe49:1047] helo=volta.aurel32.net) by hall.aurel32.net with esmtpsa (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.63) (envelope-from ) id 1L3f1e-0003ro-QS for qemu-devel@nongnu.org; Sat, 22 Nov 2008 00:02:58 +0100 Received: from aurel32 by volta.aurel32.net with local (Exim 4.69) (envelope-from ) id 1L3f1e-000207-9a for qemu-devel@nongnu.org; Sat, 22 Nov 2008 00:02:58 +0100 Date: Sat, 22 Nov 2008 00:02:58 +0100 From: Aurelien Jarno Subject: Re: [Qemu-devel] [PATCH] target-sh4: fix 64-bit fmov to/from memory Message-ID: <20081121230258.GC4884@volta.aurel32.net> References: <20081121214632.GQ21493@volta.aurel32.net> <1227306234-14368-1-git-send-email-mans@mansr.com> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-15 Content-Disposition: inline In-Reply-To: <1227306234-14368-1-git-send-email-mans@mansr.com> Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org On Fri, Nov 21, 2008 at 10:23:54PM +0000, Mans Rullgard wrote: > When loading/storing a register pair, the even-numbered register > always maps to the low 32 bits of memory independently of target > endian configuration. > > Signed-off-by: Mans Rullgard > --- > target-sh4/translate.c | 61 ++++++++++++++++++++++++----------------------- > 1 files changed, 31 insertions(+), 30 deletions(-) > > diff --git a/target-sh4/translate.c b/target-sh4/translate.c > index 84a3f40..74894e9 100644 > --- a/target-sh4/translate.c > +++ b/target-sh4/translate.c > @@ -991,31 +991,35 @@ static void _decode_opc(DisasContext * ctx) > return; > case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */ > if (ctx->fpscr & FPSCR_SZ) { > - TCGv_i64 fp = tcg_temp_new_i64(); > - gen_load_fpr64(fp, XREG(B7_4)); > - tcg_gen_qemu_st64(fp, REG(B11_8), ctx->memidx); > - tcg_temp_free_i64(fp); > + TCGv addr_hi = tcg_temp_new(); > + int fr = XREG(B7_4); > + tcg_gen_addi_i32(addr_hi, REG(B11_8), 4); > + tcg_gen_qemu_st32(cpu_fregs[fr ], REG(B11_8), ctx->memidx); > + tcg_gen_qemu_st32(cpu_fregs[fr+1], addr_hi, ctx->memidx); > + tcg_temp_free(addr_hi); > } else { > tcg_gen_qemu_st32(cpu_fregs[FREG(B7_4)], REG(B11_8), ctx->memidx); > } > return; > case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */ > if (ctx->fpscr & FPSCR_SZ) { > - TCGv_i64 fp = tcg_temp_new_i64(); > - tcg_gen_qemu_ld64(fp, REG(B7_4), ctx->memidx); > - gen_store_fpr64(fp, XREG(B11_8)); > - tcg_temp_free_i64(fp); > + TCGv addr_hi = tcg_temp_new(); > + int fr = XREG(B11_8); > + tcg_gen_addi_i32(addr_hi, REG(B7_4), 4); > + tcg_gen_qemu_ld32u(cpu_fregs[fr ], REG(B7_4), ctx->memidx); > + tcg_gen_qemu_ld32u(cpu_fregs[fr+1], addr_hi, ctx->memidx); > + tcg_temp_free(addr_hi); > } else { > tcg_gen_qemu_ld32u(cpu_fregs[FREG(B11_8)], REG(B7_4), ctx->memidx); > } > return; > case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */ > if (ctx->fpscr & FPSCR_SZ) { > - TCGv_i64 fp = tcg_temp_new_i64(); > - tcg_gen_qemu_ld64(fp, REG(B7_4), ctx->memidx); > - gen_store_fpr64(fp, XREG(B11_8)); > - tcg_temp_free_i64(fp); > - tcg_gen_addi_i32(REG(B7_4),REG(B7_4), 8); > + int fr = XREG(B11_8); > + tcg_gen_qemu_ld32u(cpu_fregs[fr ], REG(B7_4), ctx->memidx); > + tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4); > + tcg_gen_qemu_ld32u(cpu_fregs[fr+1], REG(B7_4), ctx->memidx); > + tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4); This is wrong, the address register should only be incremented after the last load instruction, so that it has the correct value in case of exception. > } else { > tcg_gen_qemu_ld32u(cpu_fregs[FREG(B11_8)], REG(B7_4), ctx->memidx); > tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4); > @@ -1023,16 +1027,13 @@ static void _decode_opc(DisasContext * ctx) > return; > case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */ > if (ctx->fpscr & FPSCR_SZ) { > - TCGv addr; > - TCGv_i64 fp; > - addr = tcg_temp_new(); > - tcg_gen_subi_i32(addr, REG(B11_8), 8); > - fp = tcg_temp_new_i64(); > - gen_load_fpr64(fp, XREG(B7_4)); > - tcg_gen_qemu_st64(fp, addr, ctx->memidx); > - tcg_temp_free_i64(fp); > - tcg_temp_free(addr); > + TCGv addr = tcg_temp_new_i32(); > + int fr = XREG(B7_4); > + tcg_gen_subi_i32(addr, REG(B11_8), 4); > tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 8); > + tcg_gen_qemu_st32(cpu_fregs[fr ], REG(B11_8), ctx->memidx); > + tcg_gen_qemu_st32(cpu_fregs[fr+1], addr, ctx->memidx); Same here. > + tcg_temp_free(addr); > } else { > TCGv addr; > addr = tcg_temp_new_i32(); > @@ -1047,10 +1048,10 @@ static void _decode_opc(DisasContext * ctx) > TCGv addr = tcg_temp_new_i32(); > tcg_gen_add_i32(addr, REG(B7_4), REG(0)); > if (ctx->fpscr & FPSCR_SZ) { > - TCGv_i64 fp = tcg_temp_new_i64(); > - tcg_gen_qemu_ld64(fp, addr, ctx->memidx); > - gen_store_fpr64(fp, XREG(B11_8)); > - tcg_temp_free_i64(fp); > + int fr = XREG(B11_8); > + tcg_gen_qemu_ld32u(cpu_fregs[fr ], addr, ctx->memidx); > + tcg_gen_addi_i32(addr, addr, 4); > + tcg_gen_qemu_ld32u(cpu_fregs[fr+1], addr, ctx->memidx); > } else { > tcg_gen_qemu_ld32u(cpu_fregs[FREG(B11_8)], addr, ctx->memidx); > } > @@ -1062,10 +1063,10 @@ static void _decode_opc(DisasContext * ctx) > TCGv addr = tcg_temp_new(); > tcg_gen_add_i32(addr, REG(B11_8), REG(0)); > if (ctx->fpscr & FPSCR_SZ) { > - TCGv_i64 fp = tcg_temp_new_i64(); > - gen_load_fpr64(fp, XREG(B7_4)); > - tcg_gen_qemu_st64(fp, addr, ctx->memidx); > - tcg_temp_free_i64(fp); > + int fr = XREG(B7_4); > + tcg_gen_qemu_ld32u(cpu_fregs[fr ], addr, ctx->memidx); > + tcg_gen_addi_i32(addr, addr, 4); > + tcg_gen_qemu_ld32u(cpu_fregs[fr+1], addr, ctx->memidx); > } else { > tcg_gen_qemu_st32(cpu_fregs[FREG(B7_4)], addr, ctx->memidx); > } Otherwise looks ok. -- .''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' aurel32@debian.org | aurelien@aurel32.net `- people.debian.org/~aurel32 | www.aurel32.net