qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: David Gibson <david@gibson.dropbear.id.au>
To: peter.maydell@linaro.org
Cc: lvivier@redhat.com, aik@ozlabs.ru,
	Richard Henderson <richard.henderson@linaro.org>,
	qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org,
	Stefan Brankovic <stefan.brankovic@rt-rk.com>,
	David Gibson <david@gibson.dropbear.id.au>
Subject: [Qemu-devel] [PULL 07/42] target/ppc: Optimize emulation of vsl and vsr instructions
Date: Wed, 21 Aug 2019 17:25:07 +1000	[thread overview]
Message-ID: <20190821072542.23090-8-david@gibson.dropbear.id.au> (raw)
In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au>

From: Stefan Brankovic <stefan.brankovic@rt-rk.com>

Optimization of altivec instructions vsl and vsr(Vector Shift Left/Rigt).
Perform shift operation (left and right respectively) on 128 bit value of
register vA by value specified in bits 125-127 of register vB. Lowest 3
bits in each byte element of register vB must be identical or result is
undefined.

For vsl instruction, the first step is bits 125-127 of register vB have
to be saved in variable sh. Then, the highest sh bits of the lower
doubleword element of register vA are saved in variable shifted,
in order not to lose those bits when shift operation is performed on
the lower doubleword element of register vA, which is the next
step. After shifting the lower doubleword element shift operation
is performed on higher doubleword element of vA, with replacement of
the lowest sh bits(that are now 0) with bits saved in shifted.

For vsr instruction, firstly, the bits 125-127 of register vB have
to be saved in variable sh. Then, the lowest sh bits of the higher
doubleword element of register vA are saved in variable shifted,
in odred not to lose those bits when the shift operation is
performed on the higher doubleword element of register vA, which is
the next step. After shifting higher doubleword element, shift operation
is performed on lower doubleword element of vA, with replacement of
highest sh bits(that are now 0) with bits saved in shifted.

Signed-off-by: Stefan Brankovic <stefan.brankovic@rt-rk.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <1563200574-11098-3-git-send-email-stefan.brankovic@rt-rk.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 target/ppc/helper.h                 |   2 -
 target/ppc/int_helper.c             |  35 ----------
 target/ppc/translate/vmx-impl.inc.c | 101 +++++++++++++++++++++++++++-
 3 files changed, 99 insertions(+), 39 deletions(-)

diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 121d7868d0..6fb823c7b4 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -217,8 +217,6 @@ DEF_HELPER_3(vrlb, void, avr, avr, avr)
 DEF_HELPER_3(vrlh, void, avr, avr, avr)
 DEF_HELPER_3(vrlw, void, avr, avr, avr)
 DEF_HELPER_3(vrld, void, avr, avr, avr)
-DEF_HELPER_3(vsl, void, avr, avr, avr)
-DEF_HELPER_3(vsr, void, avr, avr, avr)
 DEF_HELPER_4(vsldoi, void, avr, avr, avr, i32)
 DEF_HELPER_3(vextractub, void, avr, avr, i32)
 DEF_HELPER_3(vextractuh, void, avr, avr, i32)
diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index 5dcca5362b..d2cad787ad 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -1740,41 +1740,6 @@ VEXTU_X_DO(vextuhrx, 16, 0)
 VEXTU_X_DO(vextuwrx, 32, 0)
 #undef VEXTU_X_DO
 
-/*
- * The specification says that the results are undefined if all of the
- * shift counts are not identical.  We check to make sure that they
- * are to conform to what real hardware appears to do.
- */
-#define VSHIFT(suffix, leftp)                                           \
-    void helper_vs##suffix(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)    \
-    {                                                                   \
-        int shift = b->VsrB(15) & 0x7;                                  \
-        int doit = 1;                                                   \
-        int i;                                                          \
-                                                                        \
-        for (i = 0; i < ARRAY_SIZE(r->u8); i++) {                       \
-            doit = doit && ((b->u8[i] & 0x7) == shift);                 \
-        }                                                               \
-        if (doit) {                                                     \
-            if (shift == 0) {                                           \
-                *r = *a;                                                \
-            } else if (leftp) {                                         \
-                uint64_t carry = a->VsrD(1) >> (64 - shift);            \
-                                                                        \
-                r->VsrD(0) = (a->VsrD(0) << shift) | carry;             \
-                r->VsrD(1) = a->VsrD(1) << shift;                       \
-            } else {                                                    \
-                uint64_t carry = a->VsrD(0) << (64 - shift);            \
-                                                                        \
-                r->VsrD(1) = (a->VsrD(1) >> shift) | carry;             \
-                r->VsrD(0) = a->VsrD(0) >> shift;                       \
-            }                                                           \
-        }                                                               \
-    }
-VSHIFT(l, 1)
-VSHIFT(r, 0)
-#undef VSHIFT
-
 void helper_vslv(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
 {
     int i;
diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c
index a9fe3c7834..e06e65adb2 100644
--- a/target/ppc/translate/vmx-impl.inc.c
+++ b/target/ppc/translate/vmx-impl.inc.c
@@ -570,6 +570,103 @@ static void trans_lvsr(DisasContext *ctx)
     tcg_temp_free(EA);
 }
 
+/*
+ * vsl VRT,VRA,VRB - Vector Shift Left
+ *
+ * Shifting left 128 bit value of vA by value specified in bits 125-127 of vB.
+ * Lowest 3 bits in each byte element of register vB must be identical or
+ * result is undefined.
+ */
+static void trans_vsl(DisasContext *ctx)
+{
+    int VT = rD(ctx->opcode);
+    int VA = rA(ctx->opcode);
+    int VB = rB(ctx->opcode);
+    TCGv_i64 avrA = tcg_temp_new_i64();
+    TCGv_i64 avrB = tcg_temp_new_i64();
+    TCGv_i64 sh = tcg_temp_new_i64();
+    TCGv_i64 shifted = tcg_temp_new_i64();
+    TCGv_i64 tmp = tcg_temp_new_i64();
+
+    /* Place bits 125-127 of vB in sh. */
+    get_avr64(avrB, VB, false);
+    tcg_gen_andi_i64(sh, avrB, 0x07ULL);
+
+    /*
+     * Save highest sh bits of lower doubleword element of vA in variable
+     * shifted and perform shift on lower doubleword.
+     */
+    get_avr64(avrA, VA, false);
+    tcg_gen_subfi_i64(tmp, 64, sh);
+    tcg_gen_shr_i64(shifted, avrA, tmp);
+    tcg_gen_andi_i64(shifted, shifted, 0x7fULL);
+    tcg_gen_shl_i64(avrA, avrA, sh);
+    set_avr64(VT, avrA, false);
+
+    /*
+     * Perform shift on higher doubleword element of vA and replace lowest
+     * sh bits with shifted.
+     */
+    get_avr64(avrA, VA, true);
+    tcg_gen_shl_i64(avrA, avrA, sh);
+    tcg_gen_or_i64(avrA, avrA, shifted);
+    set_avr64(VT, avrA, true);
+
+    tcg_temp_free_i64(avrA);
+    tcg_temp_free_i64(avrB);
+    tcg_temp_free_i64(sh);
+    tcg_temp_free_i64(shifted);
+    tcg_temp_free_i64(tmp);
+}
+
+/*
+ * vsr VRT,VRA,VRB - Vector Shift Right
+ *
+ * Shifting right 128 bit value of vA by value specified in bits 125-127 of vB.
+ * Lowest 3 bits in each byte element of register vB must be identical or
+ * result is undefined.
+ */
+static void trans_vsr(DisasContext *ctx)
+{
+    int VT = rD(ctx->opcode);
+    int VA = rA(ctx->opcode);
+    int VB = rB(ctx->opcode);
+    TCGv_i64 avrA = tcg_temp_new_i64();
+    TCGv_i64 avrB = tcg_temp_new_i64();
+    TCGv_i64 sh = tcg_temp_new_i64();
+    TCGv_i64 shifted = tcg_temp_new_i64();
+    TCGv_i64 tmp = tcg_temp_new_i64();
+
+    /* Place bits 125-127 of vB in sh. */
+    get_avr64(avrB, VB, false);
+    tcg_gen_andi_i64(sh, avrB, 0x07ULL);
+
+    /*
+     * Save lowest sh bits of higher doubleword element of vA in variable
+     * shifted and perform shift on higher doubleword.
+     */
+    get_avr64(avrA, VA, true);
+    tcg_gen_subfi_i64(tmp, 64, sh);
+    tcg_gen_shl_i64(shifted, avrA, tmp);
+    tcg_gen_andi_i64(shifted, shifted, 0xfe00000000000000ULL);
+    tcg_gen_shr_i64(avrA, avrA, sh);
+    set_avr64(VT, avrA, true);
+    /*
+     * Perform shift on lower doubleword element of vA and replace highest
+     * sh bits with shifted.
+     */
+    get_avr64(avrA, VA, false);
+    tcg_gen_shr_i64(avrA, avrA, sh);
+    tcg_gen_or_i64(avrA, avrA, shifted);
+    set_avr64(VT, avrA, false);
+
+    tcg_temp_free_i64(avrA);
+    tcg_temp_free_i64(avrB);
+    tcg_temp_free_i64(sh);
+    tcg_temp_free_i64(shifted);
+    tcg_temp_free_i64(tmp);
+}
+
 GEN_VXFORM(vmuloub, 4, 0);
 GEN_VXFORM(vmulouh, 4, 1);
 GEN_VXFORM(vmulouw, 4, 2);
@@ -682,11 +779,11 @@ GEN_VXFORM(vrld, 2, 3);
 GEN_VXFORM(vrldmi, 2, 3);
 GEN_VXFORM_DUAL(vrld, PPC_NONE, PPC2_ALTIVEC_207, \
                 vrldmi, PPC_NONE, PPC2_ISA300)
-GEN_VXFORM(vsl, 2, 7);
+GEN_VXFORM_TRANS(vsl, 2, 7);
 GEN_VXFORM(vrldnm, 2, 7);
 GEN_VXFORM_DUAL(vsl, PPC_ALTIVEC, PPC_NONE, \
                 vrldnm, PPC_NONE, PPC2_ISA300)
-GEN_VXFORM(vsr, 2, 11);
+GEN_VXFORM_TRANS(vsr, 2, 11);
 GEN_VXFORM_ENV(vpkuhum, 7, 0);
 GEN_VXFORM_ENV(vpkuwum, 7, 1);
 GEN_VXFORM_ENV(vpkudum, 7, 17);
-- 
2.21.0



  parent reply	other threads:[~2019-08-21  7:42 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-21  7:25 [Qemu-devel] [PULL 00/42] ppc-for-4.2 queue 20190821 David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 01/42] spapr: quantify error messages regarding capability settings David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 02/42] spapr_iommu: Fix xlate trace to print translated address David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 03/42] hw: add compat machines for 4.2 David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 04/42] spapr_pci: Allow 2MiB and 16MiB IOMMU pagesizes by default David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 05/42] migration: Do not re-read the clock on pre_save in case of paused guest David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 06/42] target/ppc: Optimize emulation of lvsl and lvsr instructions David Gibson
2019-08-21  7:25 ` David Gibson [this message]
2019-08-21  7:25 ` [Qemu-devel] [PULL 08/42] target/ppc: move opcode decode tables to PowerPCCPU David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 09/42] target/ppc: Optimize emulation of vgbbd instruction David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 10/42] target/ppc: Optimize emulation of vclzd instruction David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 11/42] target/ppc: Optimize emulation of vclzw instruction David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 12/42] ppc: fix memory leak in spapr_caps_add_properties David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 13/42] ppc: fix memory leak in spapr_dt_drc() David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 14/42] ppc: fix leak in h_client_architecture_support David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 15/42] spapr: Implement dispatch tracking for tcg David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 16/42] spapr: Implement H_PROD David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 17/42] spapr: Implement H_CONFER David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 18/42] spapr: Implement H_JOIN David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 19/42] docs/specs: initial spec summary for Ultravisor-related hcalls David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 20/42] spapr: initial implementation for H_TPM_COMM/spapr-tpm-proxy David Gibson
2019-09-09 17:23   ` Peter Maydell
2019-09-09 17:51     ` Greg Kurz
2019-08-21  7:25 ` [Qemu-devel] [PULL 21/42] pseries: Update SLOF firmware image David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 22/42] ppc/xive: use an abstract type for XiveNotifier David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 23/42] ppc/xive: Implement TM_PULL_OS_CTX special command David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 24/42] ppc/xive: Provide backlog support David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 25/42] ppc/xive: Provide escalation support David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 26/42] ppc/xive: Provide unconditional " David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 27/42] ppc/xive: Provide silent " David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 28/42] ppc/xive: Improve 'info pic' support David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 29/42] machine: Add wakeup method to MachineClass David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 30/42] i386: use machine class ->wakeup method David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 31/42] spapr: Implement ibm,suspend-me David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 32/42] ppc: remove idle_timer logic David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 33/42] spapr/pci: Consolidate de-allocation of MSIs David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 34/42] spapr/pci: Free MSIs during reset David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 35/42] spapr/irq: Drop spapr_irq_msi_reset() David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 36/42] spapr: Implement better workaround in spapr-vty device David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 37/42] spapr/xive: Mask the EAS when allocating an IRQ David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 38/42] target/ppc: Add Directed Privileged Door-bell Exception State (DPDES) SPR David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 39/42] ppc: Add support for 'mffsl' instruction David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 40/42] ppc: conform to processor User's Manual for xscvdpspn David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 41/42] ppc: Fix emulated INFINITY and NAN conversions David Gibson
2019-08-21  7:25 ` [Qemu-devel] [PULL 42/42] ppc: Fix emulated single to double denormalized conversions David Gibson
2019-08-21  8:25 ` [Qemu-devel] [PULL 00/42] ppc-for-4.2 queue 20190821 no-reply
2019-08-21 14:18 ` Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190821072542.23090-8-david@gibson.dropbear.id.au \
    --to=david@gibson.dropbear.id.au \
    --cc=aik@ozlabs.ru \
    --cc=groug@kaod.org \
    --cc=lvivier@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    --cc=richard.henderson@linaro.org \
    --cc=stefan.brankovic@rt-rk.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).