From patchwork Tue Oct 18 18:50:31 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 120488 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 8B66D1007D1 for ; Wed, 19 Oct 2011 05:54:26 +1100 (EST) Received: from localhost ([::1]:58457 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RGEnQ-00042B-5T for incoming@patchwork.ozlabs.org; Tue, 18 Oct 2011 14:53:52 -0400 Received: from eggs.gnu.org ([140.186.70.92]:43823) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RGEll-0001xA-5T for qemu-devel@nongnu.org; Tue, 18 Oct 2011 14:52:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RGElS-0002Dr-AC for qemu-devel@nongnu.org; Tue, 18 Oct 2011 14:51:55 -0400 Received: from mail-ww0-f53.google.com ([74.125.82.53]:33121) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RGElS-00029l-0N for qemu-devel@nongnu.org; Tue, 18 Oct 2011 14:51:50 -0400 Received: by mail-ww0-f53.google.com with SMTP id 36so1209775wwi.10 for ; Tue, 18 Oct 2011 11:51:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=sEni2ivSKE1rnV9/+6LK+bT9ZeGxpdWO1XAxYc7HByc=; b=aUElppVdUBwOyEiXgXfs4pel5kIUzRNV38shEXAHZEGGm7tfLVvT7uoS7/oNIcSRsN BXQWt6RD0rd6Z7Y4iACE3m8HdvXOOSVP04fxJOPwemU4jNKTTxNktqZ6L/f1zVHyvpAX fmVxrKmAmqHs84Xe2CS7HXW2HRi0Hb8GnXnro= Received: by 10.227.10.148 with SMTP id p20mr1168732wbp.2.1318963909377; Tue, 18 Oct 2011 11:51:49 -0700 (PDT) Received: from localhost.localdomain (c-71-227-161-214.hsd1.wa.comcast.net. [71.227.161.214]) by mx.google.com with ESMTPS id 11sm5169602wby.15.2011.10.18.11.51.47 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 18 Oct 2011 11:51:48 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Tue, 18 Oct 2011 11:50:31 -0700 Message-Id: <1318963843-25100-10-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 1.7.6.4 In-Reply-To: <1318963843-25100-1-git-send-email-rth@twiddle.net> References: <1318963843-25100-1-git-send-email-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 74.125.82.53 Cc: blauwirbel@gmail.com Subject: [Qemu-devel] [PATCH 09/21] target-sparc: Change fpr representation to doubles. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This allows a more efficient representation for 64-bit hosts. It should be about the same for 32-bit hosts, as we can still access the individual pieces of the double. Signed-off-by: Richard Henderson --- gdbstub.c | 35 +++++++--- linux-user/signal.c | 28 +++++---- monitor.c | 96 ++++++++++++++-------------- target-sparc/cpu.h | 7 +- target-sparc/cpu_init.c | 6 +- target-sparc/ldst_helper.c | 71 +++++++++------------ target-sparc/machine.c | 20 ++---- target-sparc/translate.c | 146 ++++++++++++++++++++----------------------- 8 files changed, 199 insertions(+), 210 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index 1d99e19..6c18634 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -814,7 +814,11 @@ static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64) if (n < 64) { /* fprs */ - GET_REG32(*((uint32_t *)&env->fpr[n - 32])); + if (n & 1) { + GET_REG32(env->fpr[(n - 32) / 2].l.lower); + } else { + GET_REG32(env->fpr[(n - 32) / 2].l.upper); + } } /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ switch (n) { @@ -831,15 +835,15 @@ static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) #else if (n < 64) { /* f0-f31 */ - GET_REG32(*((uint32_t *)&env->fpr[n - 32])); + if (n & 1) { + GET_REG32(env->fpr[(n - 32) / 2].l.lower); + } else { + GET_REG32(env->fpr[(n - 32) / 2].l.upper); + } } if (n < 80) { /* f32-f62 (double width, even numbers only) */ - uint64_t val; - - val = (uint64_t)*((uint32_t *)&env->fpr[(n - 64) * 2 + 32]) << 32; - val |= *((uint32_t *)&env->fpr[(n - 64) * 2 + 33]); - GET_REG64(val); + GET_REG64(env->fpr[(n - 32) / 2].ll); } switch (n) { case 80: GET_REGL(env->pc); @@ -878,7 +882,12 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64) else if (n < 64) { /* fprs */ - *((uint32_t *)&env->fpr[n - 32]) = tmp; + /* f0-f31 */ + if (n & 1) { + env->fpr[(n - 32) / 2].l.lower = tmp; + } else { + env->fpr[(n - 32) / 2].l.upper = tmp; + } } else { /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ switch (n) { @@ -896,12 +905,16 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) #else else if (n < 64) { /* f0-f31 */ - env->fpr[n] = ldfl_p(mem_buf); + tmp = ldl_p(mem_buf); + if (n & 1) { + env->fpr[(n - 32) / 2].l.lower = tmp; + } else { + env->fpr[(n - 32) / 2].l.upper = tmp; + } return 4; } else if (n < 80) { /* f32-f62 (double width, even numbers only) */ - *((uint32_t *)&env->fpr[(n - 64) * 2 + 32]) = tmp >> 32; - *((uint32_t *)&env->fpr[(n - 64) * 2 + 33]) = tmp; + env->fpr[(n - 32) / 2].ll = tmp; } else { switch (n) { case 80: env->pc = tmp; break; diff --git a/linux-user/signal.c b/linux-user/signal.c index 89276eb..d68dc94 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -2299,12 +2299,14 @@ void sparc64_set_context(CPUSPARCState *env) */ err |= __get_user(env->fprs, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs)); { - uint32_t *src, *dst; - src = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs; - dst = env->fpr; - /* XXX: check that the CPU storage is the same as user context */ - for (i = 0; i < 64; i++, dst++, src++) - err |= __get_user(*dst, src); + uint32_t *src = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs; + for (i = 0; i < 64; i++, src++) { + if (i & 1) { + err |= __get_user(env->fpr[i/2].l.lower, src); + } else { + err |= __get_user(env->fpr[i/2].l.upper, src); + } + } } err |= __get_user(env->fsr, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fsr)); @@ -2393,12 +2395,14 @@ void sparc64_get_context(CPUSPARCState *env) err |= __put_user(i7, &(mcp->mc_i7)); { - uint32_t *src, *dst; - src = env->fpr; - dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs; - /* XXX: check that the CPU storage is the same as user context */ - for (i = 0; i < 64; i++, dst++, src++) - err |= __put_user(*src, dst); + uint32_t *dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs; + for (i = 0; i < 64; i++, dst++) { + if (i & 1) { + err |= __put_user(env->fpr[i/2].l.lower, dst); + } else { + err |= __put_user(env->fpr[i/2].l.upper, dst); + } + } } err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr)); err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr)); diff --git a/monitor.c b/monitor.c index da13471..02d7e2e 100644 --- a/monitor.c +++ b/monitor.c @@ -3657,55 +3657,55 @@ static const MonitorDef monitor_defs[] = { #endif { "tbr", offsetof(CPUState, tbr) }, { "fsr", offsetof(CPUState, fsr) }, - { "f0", offsetof(CPUState, fpr[0]) }, - { "f1", offsetof(CPUState, fpr[1]) }, - { "f2", offsetof(CPUState, fpr[2]) }, - { "f3", offsetof(CPUState, fpr[3]) }, - { "f4", offsetof(CPUState, fpr[4]) }, - { "f5", offsetof(CPUState, fpr[5]) }, - { "f6", offsetof(CPUState, fpr[6]) }, - { "f7", offsetof(CPUState, fpr[7]) }, - { "f8", offsetof(CPUState, fpr[8]) }, - { "f9", offsetof(CPUState, fpr[9]) }, - { "f10", offsetof(CPUState, fpr[10]) }, - { "f11", offsetof(CPUState, fpr[11]) }, - { "f12", offsetof(CPUState, fpr[12]) }, - { "f13", offsetof(CPUState, fpr[13]) }, - { "f14", offsetof(CPUState, fpr[14]) }, - { "f15", offsetof(CPUState, fpr[15]) }, - { "f16", offsetof(CPUState, fpr[16]) }, - { "f17", offsetof(CPUState, fpr[17]) }, - { "f18", offsetof(CPUState, fpr[18]) }, - { "f19", offsetof(CPUState, fpr[19]) }, - { "f20", offsetof(CPUState, fpr[20]) }, - { "f21", offsetof(CPUState, fpr[21]) }, - { "f22", offsetof(CPUState, fpr[22]) }, - { "f23", offsetof(CPUState, fpr[23]) }, - { "f24", offsetof(CPUState, fpr[24]) }, - { "f25", offsetof(CPUState, fpr[25]) }, - { "f26", offsetof(CPUState, fpr[26]) }, - { "f27", offsetof(CPUState, fpr[27]) }, - { "f28", offsetof(CPUState, fpr[28]) }, - { "f29", offsetof(CPUState, fpr[29]) }, - { "f30", offsetof(CPUState, fpr[30]) }, - { "f31", offsetof(CPUState, fpr[31]) }, + { "f0", offsetof(CPUState, fpr[0].l.upper) }, + { "f1", offsetof(CPUState, fpr[0].l.lower) }, + { "f2", offsetof(CPUState, fpr[1].l.upper) }, + { "f3", offsetof(CPUState, fpr[1].l.lower) }, + { "f4", offsetof(CPUState, fpr[2].l.upper) }, + { "f5", offsetof(CPUState, fpr[2].l.lower) }, + { "f6", offsetof(CPUState, fpr[3].l.upper) }, + { "f7", offsetof(CPUState, fpr[3].l.lower) }, + { "f8", offsetof(CPUState, fpr[4].l.upper) }, + { "f9", offsetof(CPUState, fpr[4].l.lower) }, + { "f10", offsetof(CPUState, fpr[5].l.upper) }, + { "f11", offsetof(CPUState, fpr[5].l.lower) }, + { "f12", offsetof(CPUState, fpr[6].l.upper) }, + { "f13", offsetof(CPUState, fpr[6].l.lower) }, + { "f14", offsetof(CPUState, fpr[7].l.upper) }, + { "f15", offsetof(CPUState, fpr[7].l.lower) }, + { "f16", offsetof(CPUState, fpr[8].l.upper) }, + { "f17", offsetof(CPUState, fpr[8].l.lower) }, + { "f18", offsetof(CPUState, fpr[9].l.upper) }, + { "f19", offsetof(CPUState, fpr[9].l.lower) }, + { "f20", offsetof(CPUState, fpr[10].l.upper) }, + { "f21", offsetof(CPUState, fpr[10].l.lower) }, + { "f22", offsetof(CPUState, fpr[11].l.upper) }, + { "f23", offsetof(CPUState, fpr[11].l.lower) }, + { "f24", offsetof(CPUState, fpr[12].l.upper) }, + { "f25", offsetof(CPUState, fpr[12].l.lower) }, + { "f26", offsetof(CPUState, fpr[13].l.upper) }, + { "f27", offsetof(CPUState, fpr[13].l.lower) }, + { "f28", offsetof(CPUState, fpr[14].l.upper) }, + { "f29", offsetof(CPUState, fpr[14].l.lower) }, + { "f30", offsetof(CPUState, fpr[15].l.upper) }, + { "f31", offsetof(CPUState, fpr[15].l.lower) }, #ifdef TARGET_SPARC64 - { "f32", offsetof(CPUState, fpr[32]) }, - { "f34", offsetof(CPUState, fpr[34]) }, - { "f36", offsetof(CPUState, fpr[36]) }, - { "f38", offsetof(CPUState, fpr[38]) }, - { "f40", offsetof(CPUState, fpr[40]) }, - { "f42", offsetof(CPUState, fpr[42]) }, - { "f44", offsetof(CPUState, fpr[44]) }, - { "f46", offsetof(CPUState, fpr[46]) }, - { "f48", offsetof(CPUState, fpr[48]) }, - { "f50", offsetof(CPUState, fpr[50]) }, - { "f52", offsetof(CPUState, fpr[52]) }, - { "f54", offsetof(CPUState, fpr[54]) }, - { "f56", offsetof(CPUState, fpr[56]) }, - { "f58", offsetof(CPUState, fpr[58]) }, - { "f60", offsetof(CPUState, fpr[60]) }, - { "f62", offsetof(CPUState, fpr[62]) }, + { "f32", offsetof(CPUState, fpr[16]) }, + { "f34", offsetof(CPUState, fpr[17]) }, + { "f36", offsetof(CPUState, fpr[18]) }, + { "f38", offsetof(CPUState, fpr[19]) }, + { "f40", offsetof(CPUState, fpr[20]) }, + { "f42", offsetof(CPUState, fpr[21]) }, + { "f44", offsetof(CPUState, fpr[22]) }, + { "f46", offsetof(CPUState, fpr[23]) }, + { "f48", offsetof(CPUState, fpr[24]) }, + { "f50", offsetof(CPUState, fpr[25]) }, + { "f52", offsetof(CPUState, fpr[26]) }, + { "f54", offsetof(CPUState, fpr[27]) }, + { "f56", offsetof(CPUState, fpr[28]) }, + { "f58", offsetof(CPUState, fpr[29]) }, + { "f60", offsetof(CPUState, fpr[30]) }, + { "f62", offsetof(CPUState, fpr[31]) }, { "asi", offsetof(CPUState, asi) }, { "pstate", offsetof(CPUState, pstate) }, { "cansave", offsetof(CPUState, cansave) }, diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index a4419a5..71a890c 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -3,16 +3,17 @@ #include "config.h" #include "qemu-common.h" +#include "bswap.h" #if !defined(TARGET_SPARC64) #define TARGET_LONG_BITS 32 -#define TARGET_FPREGS 32 +#define TARGET_DPREGS 16 #define TARGET_PAGE_BITS 12 /* 4k */ #define TARGET_PHYS_ADDR_SPACE_BITS 36 #define TARGET_VIRT_ADDR_SPACE_BITS 32 #else #define TARGET_LONG_BITS 64 -#define TARGET_FPREGS 64 +#define TARGET_DPREGS 32 #define TARGET_PAGE_BITS 13 /* 8k */ #define TARGET_PHYS_ADDR_SPACE_BITS 41 # ifdef TARGET_ABI32 @@ -395,7 +396,7 @@ typedef struct CPUSPARCState { uint32_t psr; /* processor state register */ target_ulong fsr; /* FPU state register */ - float32 fpr[TARGET_FPREGS]; /* floating point registers */ + CPU_DoubleU fpr[TARGET_DPREGS]; /* floating point registers */ uint32_t cwp; /* index of current register window (extracted from PSR) */ #if !defined(TARGET_SPARC64) || defined(TARGET_ABI32) diff --git a/target-sparc/cpu_init.c b/target-sparc/cpu_init.c index 08b72a9..1118f31 100644 --- a/target-sparc/cpu_init.c +++ b/target-sparc/cpu_init.c @@ -813,11 +813,11 @@ void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf, } } cpu_fprintf(f, "\nFloating Point Registers:\n"); - for (i = 0; i < TARGET_FPREGS; i++) { + for (i = 0; i < TARGET_DPREGS; i++) { if ((i & 3) == 0) { - cpu_fprintf(f, "%%f%02d:", i); + cpu_fprintf(f, "%%f%02d:", i * 2); } - cpu_fprintf(f, " %016f", *(float *)&env->fpr[i]); + cpu_fprintf(f, " %016" PRIx64, env->fpr[i].ll); if ((i & 3) == 3) { cpu_fprintf(f, "\n"); } diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c index ec9b5f2..a4254e7 100644 --- a/target-sparc/ldst_helper.c +++ b/target-sparc/ldst_helper.c @@ -2057,7 +2057,7 @@ void helper_ldf_asi(CPUState *env, target_ulong addr, int asi, int size, int rd) { unsigned int i; - CPU_DoubleU u; + target_ulong val; helper_check_align(env, addr, 3); addr = asi_address_mask(env, asi, addr); @@ -2072,13 +2072,11 @@ void helper_ldf_asi(CPUState *env, target_ulong addr, int asi, int size, return; } helper_check_align(env, addr, 0x3f); - for (i = 0; i < 16; i++) { - *(uint32_t *)&env->fpr[rd++] = helper_ld_asi(env, addr, asi & 0x8f, - 4, 0); - addr += 4; + for (i = 0; i < 8; i++, rd += 2, addr += 8) { + env->fpr[rd/2].ll = helper_ld_asi(env, addr, asi & 0x8f, 8, 0); } - return; + case 0x16: /* UA2007 Block load primary, user privilege */ case 0x17: /* UA2007 Block load secondary, user privilege */ case 0x1e: /* UA2007 Block load primary LE, user privilege */ @@ -2092,13 +2090,11 @@ void helper_ldf_asi(CPUState *env, target_ulong addr, int asi, int size, return; } helper_check_align(env, addr, 0x3f); - for (i = 0; i < 16; i++) { - *(uint32_t *)&env->fpr[rd++] = helper_ld_asi(env, addr, asi & 0x19, - 4, 0); - addr += 4; + for (i = 0; i < 8; i++, rd += 2, addr += 4) { + env->fpr[rd/2].ll = helper_ld_asi(env, addr, asi & 0x19, 8, 0); } - return; + default: break; } @@ -2106,20 +2102,19 @@ void helper_ldf_asi(CPUState *env, target_ulong addr, int asi, int size, switch (size) { default: case 4: - *((uint32_t *)&env->fpr[rd]) = helper_ld_asi(env, addr, asi, size, 0); + val = helper_ld_asi(env, addr, asi, size, 0); + if (rd & 1) { + env->fpr[rd/2].l.lower = val; + } else { + env->fpr[rd/2].l.upper = val; + } break; case 8: - u.ll = helper_ld_asi(env, addr, asi, size, 0); - *((uint32_t *)&env->fpr[rd++]) = u.l.upper; - *((uint32_t *)&env->fpr[rd++]) = u.l.lower; + env->fpr[rd/2].ll = helper_ld_asi(env, addr, asi, size, 0); break; case 16: - u.ll = helper_ld_asi(env, addr, asi, 8, 0); - *((uint32_t *)&env->fpr[rd++]) = u.l.upper; - *((uint32_t *)&env->fpr[rd++]) = u.l.lower; - u.ll = helper_ld_asi(env, addr + 8, asi, 8, 0); - *((uint32_t *)&env->fpr[rd++]) = u.l.upper; - *((uint32_t *)&env->fpr[rd++]) = u.l.lower; + env->fpr[rd/2].ll = helper_ld_asi(env, addr, asi, 8, 0); + env->fpr[rd/2 + 1].ll = helper_ld_asi(env, addr + 8, asi, 8, 0); break; } } @@ -2128,8 +2123,7 @@ void helper_stf_asi(CPUState *env, target_ulong addr, int asi, int size, int rd) { unsigned int i; - target_ulong val = 0; - CPU_DoubleU u; + target_ulong val; helper_check_align(env, addr, 3); addr = asi_address_mask(env, asi, addr); @@ -2146,10 +2140,8 @@ void helper_stf_asi(CPUState *env, target_ulong addr, int asi, int size, return; } helper_check_align(env, addr, 0x3f); - for (i = 0; i < 16; i++) { - val = *(uint32_t *)&env->fpr[rd++]; - helper_st_asi(env, addr, val, asi & 0x8f, 4); - addr += 4; + for (i = 0; i < 8; i++, rd += 2, addr += 8) { + helper_st_asi(env, addr, env->fpr[rd/2].ll, asi & 0x8f, 8); } return; @@ -2166,10 +2158,8 @@ void helper_stf_asi(CPUState *env, target_ulong addr, int asi, int size, return; } helper_check_align(env, addr, 0x3f); - for (i = 0; i < 16; i++) { - val = *(uint32_t *)&env->fpr[rd++]; - helper_st_asi(env, addr, val, asi & 0x19, 4); - addr += 4; + for (i = 0; i < 8; i++, rd += 2, addr += 8) { + helper_st_asi(env, addr, env->fpr[rd/2].ll, asi & 0x19, 8); } return; @@ -2180,20 +2170,19 @@ void helper_stf_asi(CPUState *env, target_ulong addr, int asi, int size, switch (size) { default: case 4: - helper_st_asi(env, addr, *(uint32_t *)&env->fpr[rd], asi, size); + if (rd & 1) { + val = env->fpr[rd/2].l.lower; + } else { + val = env->fpr[rd/2].l.upper; + } + helper_st_asi(env, addr, val, asi, size); break; case 8: - u.l.upper = *(uint32_t *)&env->fpr[rd++]; - u.l.lower = *(uint32_t *)&env->fpr[rd++]; - helper_st_asi(env, addr, u.ll, asi, size); + helper_st_asi(env, addr, env->fpr[rd/2].ll, asi, size); break; case 16: - u.l.upper = *(uint32_t *)&env->fpr[rd++]; - u.l.lower = *(uint32_t *)&env->fpr[rd++]; - helper_st_asi(env, addr, u.ll, asi, 8); - u.l.upper = *(uint32_t *)&env->fpr[rd++]; - u.l.lower = *(uint32_t *)&env->fpr[rd++]; - helper_st_asi(env, addr + 8, u.ll, asi, 8); + helper_st_asi(env, addr, env->fpr[rd/2].ll, asi, 8); + helper_st_asi(env, addr + 8, env->fpr[rd/2 + 1].ll, asi, 8); break; } } diff --git a/target-sparc/machine.c b/target-sparc/machine.c index 56ae041..235b088 100644 --- a/target-sparc/machine.c +++ b/target-sparc/machine.c @@ -21,13 +21,9 @@ void cpu_save(QEMUFile *f, void *opaque) qemu_put_betls(f, &env->regbase[i]); /* FPU */ - for(i = 0; i < TARGET_FPREGS; i++) { - union { - float32 f; - uint32_t i; - } u; - u.f = env->fpr[i]; - qemu_put_be32(f, u.i); + for (i = 0; i < TARGET_DPREGS; i++) { + qemu_put_be32(f, env->fpr[i].l.upper); + qemu_put_be32(f, env->fpr[i].l.lower); } qemu_put_betls(f, &env->pc); @@ -128,13 +124,9 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) qemu_get_betls(f, &env->regbase[i]); /* FPU */ - for(i = 0; i < TARGET_FPREGS; i++) { - union { - float32 f; - uint32_t i; - } u; - u.i = qemu_get_be32(f); - env->fpr[i] = u.f; + for (i = 0; i < TARGET_DPREGS; i++) { + env->fpr[i].l.upper = qemu_get_be32(f); + env->fpr[i].l.lower = qemu_get_be32(f); } qemu_get_betls(f, &env->pc); diff --git a/target-sparc/translate.c b/target-sparc/translate.c index f8d3bf2..97a462b 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -68,7 +68,7 @@ static TCGv cpu_tmp0; static TCGv_i32 cpu_tmp32; static TCGv_i64 cpu_tmp64; /* Floating point registers */ -static TCGv_i32 cpu_fpr[TARGET_FPREGS]; +static TCGv_i64 cpu_fpr[TARGET_DPREGS]; static target_ulong gen_opc_npc[OPC_BUF_SIZE]; static target_ulong gen_opc_jump_pc[2]; @@ -87,8 +87,8 @@ typedef struct DisasContext { uint32_t cc_op; /* current CC operation */ struct TranslationBlock *tb; sparc_def_t *def; - TCGv_i64 t64[3]; - int n_t64; + TCGv_i32 t32[3]; + int n_t32; } DisasContext; // This function uses non-native bit order @@ -131,12 +131,44 @@ static inline void gen_update_fprs_dirty(int rd) /* floating point registers moves */ static TCGv_i32 gen_load_fpr_F(DisasContext *dc, unsigned int src) { - return cpu_fpr[src]; +#if TCG_TARGET_REG_BITS == 32 + if (src & 1) { + return TCGV_LOW(cpu_fpr[src / 2]); + } else { + return TCGV_HIGH(cpu_fpr[src / 2]); + } +#else + if (src & 1) { + return MAKE_TCGV_I32(GET_TCGV_I64(cpu_fpr[src / 2])); + } else { + TCGv_i32 ret = tcg_temp_local_new_i32(); + TCGv_i64 t = tcg_temp_new_i64(); + + tcg_gen_shri_i64(t, cpu_fpr[src / 2], 32); + tcg_gen_trunc_i64_i32(ret, t); + tcg_temp_free_i64(t); + + dc->t32[dc->n_t32++] = ret; + assert(dc->n_t32 <= ARRAY_SIZE(dc->t32)); + + return ret; + } +#endif } static void gen_store_fpr_F(DisasContext *dc, unsigned int dst, TCGv_i32 v) { - tcg_gen_mov_i32(cpu_fpr[dst], v); +#if TCG_TARGET_REG_BITS == 32 + if (dst & 1) { + tcg_gen_mov_i32(TCGV_LOW(cpu_fpr[dst / 2]), v); + } else { + tcg_gen_mov_i32(TCGV_HIGH(cpu_fpr[dst / 2]), v); + } +#else + TCGv_i64 t = MAKE_TCGV_I64(GET_TCGV_I32(v)); + tcg_gen_deposit_i64(cpu_fpr[dst / 2], cpu_fpr[dst / 2], t, + (dst & 1 ? 0 : 32), 32); +#endif gen_update_fprs_dirty(dst); } @@ -147,42 +179,14 @@ static TCGv_i32 gen_dest_fpr_F(void) static TCGv_i64 gen_load_fpr_D(DisasContext *dc, unsigned int src) { - TCGv_i64 ret = tcg_temp_new_i64(); src = DFPREG(src); - -#if TCG_TARGET_REG_BITS == 32 - tcg_gen_mov_i32(TCGV_HIGH(ret), cpu_fpr[src]); - tcg_gen_mov_i32(TCGV_LOW(ret), cpu_fpr[src + 1]); -#else - { - TCGv_i64 t = tcg_temp_new_i64(); - tcg_gen_extu_i32_i64(ret, cpu_fpr[src]); - tcg_gen_extu_i32_i64(t, cpu_fpr[src + 1]); - tcg_gen_shli_i64(ret, ret, 32); - tcg_gen_or_i64(ret, ret, t); - tcg_temp_free_i64(t); - } -#endif - - dc->t64[dc->n_t64++] = ret; - assert(dc->n_t64 <= ARRAY_SIZE(dc->t64)); - - return ret; + return cpu_fpr[src / 2]; } static void gen_store_fpr_D(DisasContext *dc, unsigned int dst, TCGv_i64 v) { dst = DFPREG(dst); - -#if TCG_TARGET_REG_BITS == 32 - tcg_gen_mov_i32(cpu__fpu[dst], TCGV_HIGH(v)); - tcg_gen_mov_i32(cpu__fpu[dst + 1], TCGV_LOW(v)); -#else - tcg_gen_trunc_i64_i32(cpu_fpr[dst + 1], v); - tcg_gen_shri_i64(v, v, 32); - tcg_gen_trunc_i64_i32(cpu_fpr[dst], v); -#endif - + tcg_gen_mov_i64(cpu_fpr[dst / 2], v); gen_update_fprs_dirty(dst); } @@ -193,50 +197,36 @@ static TCGv_i64 gen_dest_fpr_D(void) static void gen_op_load_fpr_QT0(unsigned int src) { - tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, qt0) + - offsetof(CPU_QuadU, l.upmost)); - tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, qt0) + - offsetof(CPU_QuadU, l.upper)); - tcg_gen_st_i32(cpu_fpr[src + 2], cpu_env, offsetof(CPUSPARCState, qt0) + - offsetof(CPU_QuadU, l.lower)); - tcg_gen_st_i32(cpu_fpr[src + 3], cpu_env, offsetof(CPUSPARCState, qt0) + - offsetof(CPU_QuadU, l.lowest)); + tcg_gen_st_i64(cpu_fpr[src / 2], cpu_env, offsetof(CPUSPARCState, qt0) + + offsetof(CPU_QuadU, ll.upper)); + tcg_gen_st_i64(cpu_fpr[src/2 + 1], cpu_env, offsetof(CPUSPARCState, qt0) + + offsetof(CPU_QuadU, ll.lower)); } static void gen_op_load_fpr_QT1(unsigned int src) { - tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, qt1) + - offsetof(CPU_QuadU, l.upmost)); - tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, qt1) + - offsetof(CPU_QuadU, l.upper)); - tcg_gen_st_i32(cpu_fpr[src + 2], cpu_env, offsetof(CPUSPARCState, qt1) + - offsetof(CPU_QuadU, l.lower)); - tcg_gen_st_i32(cpu_fpr[src + 3], cpu_env, offsetof(CPUSPARCState, qt1) + - offsetof(CPU_QuadU, l.lowest)); + tcg_gen_st_i64(cpu_fpr[src / 2], cpu_env, offsetof(CPUSPARCState, qt1) + + offsetof(CPU_QuadU, ll.upper)); + tcg_gen_st_i64(cpu_fpr[src/2 + 1], cpu_env, offsetof(CPUSPARCState, qt1) + + offsetof(CPU_QuadU, ll.lower)); } static void gen_op_store_QT0_fpr(unsigned int dst) { - tcg_gen_ld_i32(cpu_fpr[dst], cpu_env, offsetof(CPUSPARCState, qt0) + - offsetof(CPU_QuadU, l.upmost)); - tcg_gen_ld_i32(cpu_fpr[dst + 1], cpu_env, offsetof(CPUSPARCState, qt0) + - offsetof(CPU_QuadU, l.upper)); - tcg_gen_ld_i32(cpu_fpr[dst + 2], cpu_env, offsetof(CPUSPARCState, qt0) + - offsetof(CPU_QuadU, l.lower)); - tcg_gen_ld_i32(cpu_fpr[dst + 3], cpu_env, offsetof(CPUSPARCState, qt0) + - offsetof(CPU_QuadU, l.lowest)); + tcg_gen_ld_i64(cpu_fpr[dst / 2], cpu_env, offsetof(CPUSPARCState, qt0) + + offsetof(CPU_QuadU, ll.upper)); + tcg_gen_ld_i64(cpu_fpr[dst/2 + 1], cpu_env, offsetof(CPUSPARCState, qt0) + + offsetof(CPU_QuadU, ll.lower)); } #ifdef TARGET_SPARC64 -static void gen_move_Q(int rd, int rs) +static void gen_move_Q(unsigned int rd, unsigned int rs) { rd = QFPREG(rd); rs = QFPREG(rs); - tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs]); - tcg_gen_mov_i32(cpu_fpr[rd + 1], cpu_fpr[rs + 1]); - tcg_gen_mov_i32(cpu_fpr[rd + 2], cpu_fpr[rs + 2]); - tcg_gen_mov_i32(cpu_fpr[rd + 3], cpu_fpr[rs + 3]); + tcg_gen_mov_i64(cpu_fpr[rd / 2], cpu_fpr[rs / 2]); + tcg_gen_mov_i64(cpu_fpr[rd / 2 + 1], cpu_fpr[rs / 2 + 1]); gen_update_fprs_dirty(rd); } #endif @@ -5008,6 +4998,13 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) egress: tcg_temp_free(cpu_tmp1); tcg_temp_free(cpu_tmp2); + if (dc->n_t32 != 0) { + int i; + for (i = dc->n_t32 - 1; i >= 0; --i) { + tcg_temp_free_i32(dc->t32[i]); + } + dc->n_t32 = 0; + } } static inline void gen_intermediate_code_internal(TranslationBlock * tb, @@ -5109,9 +5106,6 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb, tcg_temp_free_i64(cpu_tmp64); tcg_temp_free_i32(cpu_tmp32); tcg_temp_free(cpu_tmp0); - for (j = dc->n_t64 - 1; j >= 0; --j) { - tcg_temp_free_i64(dc->t64[j]); - } if (tb->cflags & CF_LAST_IO) gen_io_end(); @@ -5177,15 +5171,11 @@ void gen_intermediate_code_init(CPUSPARCState *env) "g6", "g7", }; - static const char * const fregnames[64] = { - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", - "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", - "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", - "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", - "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39", - "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47", - "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55", - "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63", + static const char * const fregnames[32] = { + "f0", "f2", "f4", "f6", "f8", "f10", "f12", "f14", + "f16", "f18", "f20", "f22", "f24", "f26", "f28", "f30", + "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", + "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62", }; /* init various static tables */ @@ -5259,8 +5249,8 @@ void gen_intermediate_code_init(CPUSPARCState *env) cpu_gregs[i] = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, gregs[i]), gregnames[i]); - for (i = 0; i < TARGET_FPREGS; i++) - cpu_fpr[i] = tcg_global_mem_new_i32(TCG_AREG0, + for (i = 0; i < TARGET_DPREGS; i++) + cpu_fpr[i] = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, fpr[i]), fregnames[i]);