From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57149) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WO7KU-0005rT-Ou for qemu-devel@nongnu.org; Thu, 13 Mar 2014 11:14:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WO7KM-0005Ci-58 for qemu-devel@nongnu.org; Thu, 13 Mar 2014 11:13:54 -0400 From: Tom Musta Date: Thu, 13 Mar 2014 10:13:05 -0500 Message-Id: <1394723588-6072-10-git-send-email-tommusta@gmail.com> In-Reply-To: <1394723588-6072-1-git-send-email-tommusta@gmail.com> References: <1394723588-6072-1-git-send-email-tommusta@gmail.com> Subject: [Qemu-devel] [RFC 09/12] target-ppc: Introduce Translation Macros for DFP Arithmetic Forms List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Tom Musta , qemu-ppc@nongnu.org This patch adds macros to the PowerPC translate.c file that will be used by the Decimal Floating Point (DFP) arithmetic instructions. These instruction forms have a target operand (FRT) and two source operands (FRA, FRB). These forms also use the "Rc" bit to set the CR6 field of the PowerPC Condition Register (CR6), which is always a copy of bits 32-35 of the Floating Point Status and Control Register (FPSCR). The quadword form instructions use pairs of floating point registers. In these instructions, the FRT, FRA and FRB instruction fields must be even; this is handled via the illegal mask that is passed to the GEN_HANDLER_E macro. Signed-off-by: Tom Musta --- target-ppc/translate.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 63 insertions(+), 0 deletions(-) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 91c33dc..26bfebc 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -8180,6 +8180,58 @@ static void gen_xxsldwi(DisasContext *ctx) tcg_temp_free_i64(xtl); } +/*** Decimal Floating Point ***/ + +static inline TCGv_ptr gen_fprp_ptr(int reg) +{ + TCGv_ptr r = tcg_temp_new_ptr(); + tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, fpr[reg])); + return r; +} + +#if defined(TARGET_PPC64) +static void gen_set_cr6_from_fpscr(DisasContext *ctx) +{ + TCGv_i32 tmp = tcg_temp_new_i32(); + tcg_gen_trunc_tl_i32(tmp, cpu_fpscr); + tcg_gen_shri_i32(cpu_crf[1], tmp, 28); + tcg_temp_free_i32(tmp); +} +#else +static void gen_set_cr6_from_fpscr(DisasContext *ctx) +{ + tcg_gen_shri_tl(cpu_crf[1], cpu_fpscr, 28); +} +#endif + +#define _GEN_DFP_TAB(name, op1, op2) \ +static void gen_##name(DisasContext *ctx) \ +{ \ + TCGv_ptr rd, ra, rb; \ + if (unlikely(!ctx->fpu_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_FPU); \ + return; \ + } \ + gen_update_nip(ctx, ctx->nip - 4); \ + rd = gen_fprp_ptr(rD(ctx->opcode)); \ + ra = gen_fprp_ptr(rA(ctx->opcode)); \ + rb = gen_fprp_ptr(rB(ctx->opcode)); \ + gen_helper_##name(cpu_env, rd, ra, rb); \ + if (unlikely(Rc(ctx->opcode) != 0)) { \ + gen_set_cr6_from_fpscr(ctx); \ + } \ + tcg_temp_free_ptr(rd); \ + tcg_temp_free_ptr(ra); \ + tcg_temp_free_ptr(rb); \ +} + +#define GEN_DFP_TAB(name, op1, op2) \ + _GEN_DFP_TAB(name, op1, op2) \ + _GEN_DFP_TAB(name##q, op1, op2) + +/* Avoid 'defined but not used' warnings ... this will be removed in */ +/* a subsequent patch. */ +void *_TempCr6_[] = { (void *)gen_set_cr6_from_fpscr, }; /*** SPE extension ***/ /* Register moves */ @@ -10999,6 +11051,17 @@ GEN_XXSEL_ROW(0x1F) GEN_XX3FORM_DM(xxpermdi, 0x08, 0x01), +#undef _GEN_DFP_TAB +#undef GEN_DFP_TAB +#define GEN_DFP_TAB_LONG(name, op1, op2) \ + GEN_HANDLER_E(name, 0x3B, op1, op2, 0, PPC_NONE, PPC2_DFP) + +#define GEN_DFP_TAB_QUAD(name, op1, op2) \ + GEN_HANDLER_E(name, 0x3F, op1, op2, 0x00210800, PPC_NONE, PPC2_DFP) + +#define GEN_DFP_TAB(name, op1, op2) \ +GEN_DFP_TAB_LONG(name, op1, op2), \ +GEN_DFP_TAB_QUAD(name##q, op1, op2), #undef GEN_SPE #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \ GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE) -- 1.7.1