qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v3 15/37] target/ppc: implement vclrlb


From: Richard Henderson
Subject: Re: [PATCH v3 15/37] target/ppc: implement vclrlb
Date: Fri, 11 Feb 2022 16:20:59 +1100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.5.0

On 2/10/22 23:34, matheus.ferst@eldorado.org.br wrote:
From: Matheus Ferst <matheus.ferst@eldorado.org.br>

Signed-off-by: Matheus Ferst <matheus.ferst@eldorado.org.br>
---
  target/ppc/insn32.decode            |  2 ++
  target/ppc/translate/vmx-impl.c.inc | 56 +++++++++++++++++++++++++++++
  2 files changed, 58 insertions(+)

diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index ea497ecd80..483651cf9c 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -501,6 +501,8 @@ VSTRIBR         000100 ..... 00001 ..... . 0000001101   
@VX_tb_rc
  VSTRIHL         000100 ..... 00010 ..... . 0000001101   @VX_tb_rc
  VSTRIHR         000100 ..... 00011 ..... . 0000001101   @VX_tb_rc
+VCLRLB 000100 ..... ..... ..... 00110001101 @VX
+
  # VSX Load/Store Instructions
LXV 111101 ..... ..... ............ . 001 @DQ_TSX
diff --git a/target/ppc/translate/vmx-impl.c.inc 
b/target/ppc/translate/vmx-impl.c.inc
index 8bcf637ff8..3fb4935bff 100644
--- a/target/ppc/translate/vmx-impl.c.inc
+++ b/target/ppc/translate/vmx-impl.c.inc
@@ -1956,6 +1956,62 @@ TRANS(VSTRIBR, do_vstri, gen_helper_VSTRIBR)
  TRANS(VSTRIHL, do_vstri, gen_helper_VSTRIHL)
  TRANS(VSTRIHR, do_vstri, gen_helper_VSTRIHR)
+static bool trans_VCLRLB(DisasContext *ctx, arg_VX *a)
+{
+    TCGv_i64 hi, lo, rb;
+    TCGLabel *l, *end;
+
+    REQUIRE_INSNS_FLAGS2(ctx, ISA310);
+    REQUIRE_VECTOR(ctx);
+
+    l = gen_new_label();
+    end = gen_new_label();
+
+    hi = tcg_const_local_i64(0);
+    lo = tcg_const_local_i64(0);
+    rb = tcg_temp_local_new_i64();
+
+    tcg_gen_extu_tl_i64(rb, cpu_gpr[a->vrb]);
+
+    /* RB == 0: all zeros */
+    tcg_gen_brcondi_i64(TCG_COND_EQ, rb, 0, end);
+
+    get_avr64(lo, a->vra, false);
+
+    /* RB <= 8 */
+    tcg_gen_brcondi_i64(TCG_COND_LEU, rb, 8, l);
+
+    get_avr64(hi, a->vra, true);
+
+    /* RB >= 16: just copy VRA to VRB */
+    tcg_gen_brcondi_i64(TCG_COND_GEU, rb, 16, end);
+
+    /* 8 < RB < 16: copy lo and partially clear hi */
+    tcg_gen_subfi_i64(rb, 16, rb);
+    tcg_gen_shli_i64(rb, rb, 3);
+    tcg_gen_shl_i64(hi, hi, rb);
+    tcg_gen_shr_i64(hi, hi, rb);
+    tcg_gen_br(end);
+
+    /* 0 < RB <= 8: zeroes hi and partially clears lo */
+    gen_set_label(l);
+    tcg_gen_subfi_i64(rb, 8, rb);
+    tcg_gen_shli_i64(rb, rb, 3);
+    tcg_gen_shl_i64(lo, lo, rb);
+    tcg_gen_shr_i64(lo, lo, rb);

There's a bit of redundancy here, and if we exploit that we can remove the 
branches.

Compute the mask modulo 8. That result applies to either the first or second word, or neither. Use 3 movcond to select among the cases:

   sh = (rb & 7) << 3;
   mask = ~(-1 << sh);
   ml = rb < 8 ? mask : 0;
   mh = rb < 8 ? 0 : mask;
   mh = rb < 16 ? mh : -1;
   lo &= ml;
   hi &= mh;


r~



reply via email to

[Prev in Thread] Current Thread [Next in Thread]