From patchwork Wed Mar 16 10:21:22 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabien Chouteau X-Patchwork-Id: 87219 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 71DE2B7001 for ; Wed, 16 Mar 2011 21:23:07 +1100 (EST) Received: from localhost ([127.0.0.1]:57518 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Pznsc-00015c-W7 for incoming@patchwork.ozlabs.org; Wed, 16 Mar 2011 06:23:03 -0400 Received: from [140.186.70.92] (port=43167 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PznrK-000124-0W for qemu-devel@nongnu.org; Wed, 16 Mar 2011 06:21:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PznrI-0006hA-1z for qemu-devel@nongnu.org; Wed, 16 Mar 2011 06:21:41 -0400 Received: from mel.act-europe.fr ([194.98.77.210]:46072) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PznrH-0006fR-NO for qemu-devel@nongnu.org; Wed, 16 Mar 2011 06:21:40 -0400 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id A2E38CB02E5 for ; Wed, 16 Mar 2011 11:21:27 +0100 (CET) X-Virus-Scanned: amavisd-new at eu.adacore.com Received: from mel.act-europe.fr ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Evngs7G5w3Be for ; Wed, 16 Mar 2011 11:21:24 +0100 (CET) Received: from PomPomGalli.act-europe.fr (pompomgalli.act-europe.fr [10.10.1.88]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mel.act-europe.fr (Postfix) with ESMTP id A5A7CCB02D9 for ; Wed, 16 Mar 2011 11:21:24 +0100 (CET) From: Fabien Chouteau To: qemu-devel@nongnu.org Date: Wed, 16 Mar 2011 11:21:22 +0100 Message-Id: <1300270882-29640-1-git-send-email-chouteau@adacore.com> X-Mailer: git-send-email 1.7.1 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 194.98.77.210 Subject: [Qemu-devel] [PATCH] [PPC] Add support for 6 SPE instructions (evmra, evmwsmi{a{a}}, evmwumi{a{a}}) X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Signed-off-by: Fabien Chouteau Reviewed-by: Nathan Froyd --- target-ppc/translate.c | 201 +++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 197 insertions(+), 4 deletions(-) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 89413c5..e438433 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -6502,6 +6502,39 @@ GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23) /*** SPE extension ***/ /* Register moves */ + +static inline void gen_evmra(DisasContext *ctx) +{ + + if (unlikely(!ctx->spe_enabled)) { + gen_exception(ctx, POWERPC_EXCP_APU); + return; + } + +#if defined(TARGET_PPC64) + /* rD := rA */ + tcg_gen_mov_i64(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); + + /* spe_acc := rA */ + tcg_gen_st_i64(cpu_gpr[rA(ctx->opcode)], + cpu_env, + offsetof(CPUState, spe_acc)); +#else + TCGv_i64 tmp = tcg_temp_new_i64(); + + /* tmp := rA_lo + rA_hi << 32 */ + tcg_gen_concat_i32_i64(tmp, cpu_gpr[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]); + + /* spe_acc := tmp */ + tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUState, spe_acc)); + tcg_temp_free_i64(tmp); + + /* rD := rA */ + tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); + tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]); +#endif +} + static inline void gen_load_gpr64(TCGv_i64 t, int reg) { #if defined(TARGET_PPC64) @@ -7090,6 +7123,162 @@ static void gen_evsel3(DisasContext *ctx) gen_evsel(ctx); } +/* Multiply */ + +static inline void gen_evmwumi(DisasContext *ctx) +{ + TCGv_i64 t0, t1; + + if (unlikely(!ctx->spe_enabled)) { + gen_exception(ctx, POWERPC_EXCP_APU); + return; + } + + t0 = tcg_temp_new_i64(); + t1 = tcg_temp_new_i64(); + + /* t0 := rA; t1 := rB */ +#if defined(TARGET_PPC64) + tcg_gen_ext32u_tl(t0, cpu_gpr[rA(ctx->opcode)]); + tcg_gen_ext32u_tl(t1, cpu_gpr[rB(ctx->opcode)]); +#else + tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]); + tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]); +#endif + + tcg_gen_mul_i64(t0, t0, t1); /* t0 := rA * rB */ + + gen_store_gpr64(rD(ctx->opcode), t0); /* rD := t0 */ + + tcg_temp_free_i64(t0); + tcg_temp_free_i64(t1);} + +static inline void gen_evmwumia(DisasContext *ctx) +{ + TCGv_i64 tmp; + + if (unlikely(!ctx->spe_enabled)) { + gen_exception(ctx, POWERPC_EXCP_APU); + return; + } + + gen_evmwumi(ctx); /* rD := rA * rB */ + + tmp = tcg_temp_new_i64(); + + /* acc := rD */ + gen_load_gpr64(tmp, rD(ctx->opcode)); + tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUState, spe_acc)); + tcg_temp_free_i64(tmp); +} + +static inline void gen_evmwumiaa(DisasContext *ctx) +{ + TCGv_i64 acc; + TCGv_i64 tmp; + + if (unlikely(!ctx->spe_enabled)) { + gen_exception(ctx, POWERPC_EXCP_APU); + return; + } + + gen_evmwumi(ctx); /* rD := rA * rB */ + + acc = tcg_temp_new_i64(); + tmp = tcg_temp_new_i64(); + + /* tmp := rD */ + gen_load_gpr64(tmp, rD(ctx->opcode)); + + /* Load acc */ + tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUState, spe_acc)); + + /* acc := tmp + acc */ + tcg_gen_add_i64(acc, acc, tmp); + + /* Store acc */ + tcg_gen_st_i64(acc, cpu_env, offsetof(CPUState, spe_acc)); + + /* rD := acc */ + gen_store_gpr64(rD(ctx->opcode), acc); + + tcg_temp_free_i64(acc); + tcg_temp_free_i64(tmp); +} + +static inline void gen_evmwsmi(DisasContext *ctx) +{ + TCGv_i64 t0, t1; + + if (unlikely(!ctx->spe_enabled)) { + gen_exception(ctx, POWERPC_EXCP_APU); + return; + } + + t0 = tcg_temp_new_i64(); + t1 = tcg_temp_new_i64(); + + /* t0 := rA; t1 := rB */ +#if defined(TARGET_PPC64) + tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]); + tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]); +#else + tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]); + tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]); +#endif + + tcg_gen_mul_i64(t0, t0, t1); /* t0 := rA * rB */ + + gen_store_gpr64(rD(ctx->opcode), t0); /* rD := t0 */ + + tcg_temp_free_i64(t0); + tcg_temp_free_i64(t1); +} + +static inline void gen_evmwsmia(DisasContext *ctx) +{ + TCGv_i64 tmp; + + gen_evmwsmi(ctx); /* rD := rA * rB */ + + tmp = tcg_temp_new_i64(); + + /* acc := rD */ + gen_load_gpr64(tmp, rD(ctx->opcode)); + tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUState, spe_acc)); + + tcg_temp_free_i64(tmp); +} + +static inline void gen_evmwsmiaa(DisasContext *ctx) +{ + TCGv_i64 acc = tcg_temp_new_i64(); + TCGv_i64 tmp = tcg_temp_new_i64(); + + gen_evmwsmi(ctx); /* rD := rA * rB */ + + acc = tcg_temp_new_i64(); + tmp = tcg_temp_new_i64(); + + /* tmp := rD */ + gen_load_gpr64(tmp, rD(ctx->opcode)); + + /* Load acc */ + tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUState, spe_acc)); + + /* acc := tmp + acc */ + tcg_gen_add_i64(acc, acc, tmp); + + /* Store acc */ + tcg_gen_st_i64(acc, cpu_env, offsetof(CPUState, spe_acc)); + + /* rD := acc */ + gen_store_gpr64(rD(ctx->opcode), acc); + + tcg_temp_free_i64(acc); + tcg_temp_free_i64(tmp); +} + GEN_SPE(evaddw, speundef, 0x00, 0x08, 0x00000000, PPC_SPE); //// GEN_SPE(evaddiw, speundef, 0x01, 0x08, 0x00000000, PPC_SPE); GEN_SPE(evsubfw, speundef, 0x02, 0x08, 0x00000000, PPC_SPE); //// @@ -7098,10 +7287,14 @@ GEN_SPE(evabs, evneg, 0x04, 0x08, 0x0000F800, PPC_SPE); //// GEN_SPE(evextsb, evextsh, 0x05, 0x08, 0x0000F800, PPC_SPE); //// GEN_SPE(evrndw, evcntlzw, 0x06, 0x08, 0x0000F800, PPC_SPE); //// GEN_SPE(evcntlsw, brinc, 0x07, 0x08, 0x00000000, PPC_SPE); // +GEN_SPE(evmra, speundef, 0x02, 0x13, 0x0000F800, PPC_SPE); GEN_SPE(speundef, evand, 0x08, 0x08, 0x00000000, PPC_SPE); //// GEN_SPE(evandc, speundef, 0x09, 0x08, 0x00000000, PPC_SPE); //// GEN_SPE(evxor, evor, 0x0B, 0x08, 0x00000000, PPC_SPE); //// GEN_SPE(evnor, eveqv, 0x0C, 0x08, 0x00000000, PPC_SPE); //// +GEN_SPE(evmwumi, evmwsmi, 0x0C, 0x11, 0x00000000, PPC_SPE); +GEN_SPE(evmwumia, evmwsmia, 0x1C, 0x11, 0x00000000, PPC_SPE); +GEN_SPE(evmwumiaa, evmwsmiaa, 0x0C, 0x15, 0x00000000, PPC_SPE); GEN_SPE(speundef, evorc, 0x0D, 0x08, 0x00000000, PPC_SPE); //// GEN_SPE(evnand, speundef, 0x0F, 0x08, 0x00000000, PPC_SPE); //// GEN_SPE(evsrwu, evsrws, 0x10, 0x08, 0x00000000, PPC_SPE); //// @@ -7491,14 +7684,12 @@ GEN_SPE(evmwlumi, speundef, 0x04, 0x11, 0x00000000, PPC_SPE); GEN_SPE(evmwhumi, evmwhsmi, 0x06, 0x11, 0x00000000, PPC_SPE); GEN_SPE(speundef, evmwhsmf, 0x07, 0x11, 0x00000000, PPC_SPE); GEN_SPE(speundef, evmwssf, 0x09, 0x11, 0x00000000, PPC_SPE); -GEN_SPE(evmwumi, evmwsmi, 0x0C, 0x11, 0x00000000, PPC_SPE); GEN_SPE(speundef, evmwsmf, 0x0D, 0x11, 0x00000000, PPC_SPE); GEN_SPE(speundef, evmwhssfa, 0x13, 0x11, 0x00000000, PPC_SPE); GEN_SPE(evmwlumia, speundef, 0x14, 0x11, 0x00000000, PPC_SPE); GEN_SPE(evmwhumia, evmwhsmia, 0x16, 0x11, 0x00000000, PPC_SPE); GEN_SPE(speundef, evmwhsmfa, 0x17, 0x11, 0x00000000, PPC_SPE); GEN_SPE(speundef, evmwssfa, 0x19, 0x11, 0x00000000, PPC_SPE); -GEN_SPE(evmwumia, evmwsmia, 0x1C, 0x11, 0x00000000, PPC_SPE); GEN_SPE(speundef, evmwsmfa, 0x1D, 0x11, 0x00000000, PPC_SPE); GEN_SPE(evadduiaaw, evaddsiaaw, 0x00, 0x13, 0x0000F800, PPC_SPE); @@ -7506,7 +7697,6 @@ GEN_SPE(evsubfusiaaw, evsubfssiaaw, 0x01, 0x13, 0x0000F800, PPC_SPE); GEN_SPE(evaddumiaaw, evaddsmiaaw, 0x04, 0x13, 0x0000F800, PPC_SPE); GEN_SPE(evsubfumiaaw, evsubfsmiaaw, 0x05, 0x13, 0x0000F800, PPC_SPE); GEN_SPE(evdivws, evdivwu, 0x06, 0x13, 0x00000000, PPC_SPE); -GEN_SPE(evmra, speundef, 0x07, 0x13, 0x0000F800, PPC_SPE); GEN_SPE(evmheusiaaw, evmhessiaaw, 0x00, 0x14, 0x00000000, PPC_SPE); GEN_SPE(speundef, evmhessfaaw, 0x01, 0x14, 0x00000000, PPC_SPE); @@ -7524,7 +7714,6 @@ GEN_SPE(speundef, evmhogsmfaa, 0x17, 0x14, 0x00000000, PPC_SPE); GEN_SPE(evmwlusiaaw, evmwlssiaaw, 0x00, 0x15, 0x00000000, PPC_SPE); GEN_SPE(evmwlumiaaw, evmwlsmiaaw, 0x04, 0x15, 0x00000000, PPC_SPE); GEN_SPE(speundef, evmwssfaa, 0x09, 0x15, 0x00000000, PPC_SPE); -GEN_SPE(evmwumiaa, evmwsmiaa, 0x0C, 0x15, 0x00000000, PPC_SPE); GEN_SPE(speundef, evmwsmfaa, 0x0D, 0x15, 0x00000000, PPC_SPE); GEN_SPE(evmheusianw, evmhessianw, 0x00, 0x16, 0x00000000, PPC_SPE); @@ -8739,10 +8928,14 @@ GEN_SPE(evabs, evneg, 0x04, 0x08, 0x0000F800, PPC_SPE), GEN_SPE(evextsb, evextsh, 0x05, 0x08, 0x0000F800, PPC_SPE), GEN_SPE(evrndw, evcntlzw, 0x06, 0x08, 0x0000F800, PPC_SPE), GEN_SPE(evcntlsw, brinc, 0x07, 0x08, 0x00000000, PPC_SPE), +GEN_SPE(evmra, speundef, 0x02, 0x13, 0x0000F800, PPC_SPE), GEN_SPE(speundef, evand, 0x08, 0x08, 0x00000000, PPC_SPE), GEN_SPE(evandc, speundef, 0x09, 0x08, 0x00000000, PPC_SPE), GEN_SPE(evxor, evor, 0x0B, 0x08, 0x00000000, PPC_SPE), GEN_SPE(evnor, eveqv, 0x0C, 0x08, 0x00000000, PPC_SPE), +GEN_SPE(evmwumi, evmwsmi, 0x0C, 0x11, 0x00000000, PPC_SPE), +GEN_SPE(evmwumia, evmwsmia, 0x1C, 0x11, 0x00000000, PPC_SPE), +GEN_SPE(evmwumiaa, evmwsmiaa, 0x0C, 0x15, 0x00000000, PPC_SPE), GEN_SPE(speundef, evorc, 0x0D, 0x08, 0x00000000, PPC_SPE), GEN_SPE(evnand, speundef, 0x0F, 0x08, 0x00000000, PPC_SPE), GEN_SPE(evsrwu, evsrws, 0x10, 0x08, 0x00000000, PPC_SPE),