From patchwork Fri Apr 26 18:21:49 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 239988 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 3FA102C0114 for ; Sat, 27 Apr 2013 04:40:10 +1000 (EST) Received: from localhost ([::1]:41242 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UVnZ2-0003pS-Bu for incoming@patchwork.ozlabs.org; Fri, 26 Apr 2013 14:40:08 -0400 Received: from eggs.gnu.org ([208.118.235.92]:55521) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UVnHU-0003cV-Or for qemu-devel@nongnu.org; Fri, 26 Apr 2013 14:22:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UVnHM-00050B-QY for qemu-devel@nongnu.org; Fri, 26 Apr 2013 14:22:00 -0400 Received: from cantor2.suse.de ([195.135.220.15]:38918 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UVnHM-0004ye-3t; Fri, 26 Apr 2013 14:21:52 -0400 Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 526235E000220; Fri, 26 Apr 2013 20:21:51 +0200 (CEST) From: Alexander Graf To: qemu-ppc@nongnu.org Date: Fri, 26 Apr 2013 20:21:49 +0200 Message-Id: <1367000509-8833-31-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.6.0.2 In-Reply-To: <1367000509-8833-1-git-send-email-agraf@suse.de> References: <1367000509-8833-1-git-send-email-agraf@suse.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x X-Received-From: 195.135.220.15 Cc: Blue Swirl , qemu-devel@nongnu.org, Aurelien Jarno Subject: [Qemu-devel] [PATCH 30/30] target-ppc: add support for extended mtfsf/mtfsfi forms 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 From: Aurelien Jarno Power ISA 2.05 adds support for extended mtfsf/mtfsfi form, with a new W field to select the upper part of the FPCSR register. For that the helper is changed to handle 64-bit input values and mask with up to 16 bits. The mtfsf/mtfsfi instructions do not have the W bit marked as invalid anymore. Instead this is checked in the helper, which therefore needs to access to the insns/insns_flags2. They are added in the DisasContext struct. Finally change all accesses to the opcode fields through extract helpers, prefixed with FP for consistency. Signed-off-by: Aurelien Jarno Signed-off-by: Alexander Graf --- target-ppc/fpu_helper.c | 17 +++++++---------- target-ppc/translate.c | 46 ++++++++++++++++++++++++++++++++++------------ 2 files changed, 41 insertions(+), 22 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index 1f0eeab..4f60218 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -430,20 +430,17 @@ void helper_fpscr_setbit(CPUPPCState *env, uint32_t bit) void helper_store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask) { - /* - * We use only the 32 LSB of the incoming fpr - */ - uint32_t prev, new; + target_ulong prev, new; int i; prev = env->fpscr; - new = (uint32_t)arg; - new &= ~0x60000000; - new |= prev & 0x60000000; - for (i = 0; i < 8; i++) { + new = (target_ulong)arg; + new &= ~0x60000000LL; + new |= prev & 0x60000000LL; + for (i = 0; i < sizeof(target_ulong) * 2; i++) { if (mask & (1 << i)) { - env->fpscr &= ~(0xF << (4 * i)); - env->fpscr |= new & (0xF << (4 * i)); + env->fpscr &= ~(0xFLL << (4 * i)); + env->fpscr |= new & (0xFLL << (4 * i)); } } /* Update VX and FEX */ diff --git a/target-ppc/translate.c b/target-ppc/translate.c index aba7e3f..9ecbc2e 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -202,6 +202,8 @@ typedef struct DisasContext { int spe_enabled; ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */ int singlestep_enabled; + uint64_t insns_flags; + uint64_t insns_flags2; } DisasContext; /* True when active word size < size of target_long. */ @@ -423,9 +425,14 @@ EXTRACT_HELPER(ME, 1, 5); EXTRACT_HELPER(TO, 21, 5); EXTRACT_HELPER(CRM, 12, 8); -EXTRACT_HELPER(FM, 17, 8); EXTRACT_HELPER(SR, 16, 4); + +/* mtfsf/mtfsfi */ +EXTRACT_HELPER(FPBF, 19, 3); EXTRACT_HELPER(FPIMM, 12, 4); +EXTRACT_HELPER(FPL, 21, 1); +EXTRACT_HELPER(FPFLM, 17, 8); +EXTRACT_HELPER(FPW, 16, 1); /*** Jump target decoding ***/ /* Displacement */ @@ -2360,19 +2367,27 @@ static void gen_mtfsb1(DisasContext *ctx) static void gen_mtfsf(DisasContext *ctx) { TCGv_i32 t0; - int L = ctx->opcode & 0x02000000; + int flm, l, w; if (unlikely(!ctx->fpu_enabled)) { gen_exception(ctx, POWERPC_EXCP_FPU); return; } + flm = FPFLM(ctx->opcode); + l = FPL(ctx->opcode); + w = FPW(ctx->opcode); + if (unlikely(w & !(ctx->insns_flags2 & PPC2_ISA205))) { + gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); + return; + } /* NIP cannot be restored if the memory exception comes from an helper */ gen_update_nip(ctx, ctx->nip - 4); gen_reset_fpstatus(); - if (L) - t0 = tcg_const_i32(0xff); - else - t0 = tcg_const_i32(FM(ctx->opcode)); + if (l) { + t0 = tcg_const_i32((ctx->insns_flags2 & PPC2_ISA205) ? 0xffff : 0xff); + } else { + t0 = tcg_const_i32(flm << (w * 8)); + } gen_helper_store_fpscr(cpu_env, cpu_fpr[rB(ctx->opcode)], t0); tcg_temp_free_i32(t0); if (unlikely(Rc(ctx->opcode) != 0)) { @@ -2386,7 +2401,7 @@ static void gen_mtfsf(DisasContext *ctx) /* mtfsfi */ static void gen_mtfsfi(DisasContext *ctx) { - int bf, sh; + int bf, sh, w; TCGv_i64 t0; TCGv_i32 t1; @@ -2394,12 +2409,17 @@ static void gen_mtfsfi(DisasContext *ctx) gen_exception(ctx, POWERPC_EXCP_FPU); return; } - bf = crbD(ctx->opcode) >> 2; - sh = 7 - bf; + w = FPW(ctx->opcode); + bf = FPBF(ctx->opcode); + if (unlikely(w & !(ctx->insns_flags2 & PPC2_ISA205))) { + gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); + return; + } + sh = (8 * w) + 7 - bf; /* NIP cannot be restored if the memory exception comes from an helper */ gen_update_nip(ctx, ctx->nip - 4); gen_reset_fpstatus(); - t0 = tcg_const_i64(FPIMM(ctx->opcode) << (4 * sh)); + t0 = tcg_const_i64(((uint64_t)FPIMM(ctx->opcode)) << (4 * sh)); t1 = tcg_const_i32(1 << sh); gen_helper_store_fpscr(cpu_env, t0, t1); tcg_temp_free_i64(t0); @@ -8682,8 +8702,8 @@ GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT), GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT), GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT), GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT), -GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00010000, PPC_FLOAT), -GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT), +GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00000000, PPC_FLOAT), +GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006e0800, PPC_FLOAT), #if defined(TARGET_PPC64) GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B), GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX), @@ -9721,6 +9741,8 @@ static inline void gen_intermediate_code_internal(CPUPPCState *env, ctx.exception = POWERPC_EXCP_NONE; ctx.spr_cb = env->spr_cb; ctx.mem_idx = env->mmu_idx; + ctx.insns_flags = env->insns_flags; + ctx.insns_flags2 = env->insns_flags2; ctx.access_type = -1; ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0; #if defined(TARGET_PPC64)