Re: [Qemu-devel] [PATCH v11 15/20] target/arm: Use vector infrastructure for aa64 constant shifts

2018-02-05 Thread Peter Maydell
On 26 January 2018 at 04:57, Richard Henderson
 wrote:
> Signed-off-by: Richard Henderson 
> ---
>  target/arm/translate-a64.c | 423 
> +
>  1 file changed, 350 insertions(+), 73 deletions(-)

Reviewed-by: Peter Maydell 

thanks
-- PMM



[Qemu-devel] [PATCH v11 15/20] target/arm: Use vector infrastructure for aa64 constant shifts

2018-01-25 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.c | 423 +
 1 file changed, 350 insertions(+), 73 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 48088dbb29..38400560db 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -87,6 +87,8 @@ typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
 
 /* Note that the gvec expanders operate on offsets + sizes.  */
 typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
+typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t,
+ uint32_t, uint32_t);
 typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
 uint32_t, uint32_t, uint32_t);
 
@@ -640,6 +642,16 @@ static void gen_gvec_fn2(DisasContext *s, bool is_q, int 
rd, int rn,
 is_q ? 16 : 8, vec_full_reg_size(s));
 }
 
+/* Expand a 2-operand + immediate AdvSIMD vector operation using
+ * an expander function.
+ */
+static void gen_gvec_fn2i(DisasContext *s, bool is_q, int rd, int rn,
+  int64_t imm, GVecGen2iFn *gvec_fn, int vece)
+{
+gvec_fn(vece, vec_full_reg_offset(s, rd), vec_full_reg_offset(s, rn),
+imm, is_q ? 16 : 8, vec_full_reg_size(s));
+}
+
 /* Expand a 3-operand AdvSIMD vector operation using an expander function.  */
 static void gen_gvec_fn3(DisasContext *s, bool is_q, int rd, int rn, int rm,
  GVecGen3Fn *gvec_fn, int vece)
@@ -648,6 +660,16 @@ static void gen_gvec_fn3(DisasContext *s, bool is_q, int 
rd, int rn, int rm,
 vec_full_reg_offset(s, rm), is_q ? 16 : 8, vec_full_reg_size(s));
 }
 
+/* Expand a 2-operand + immediate AdvSIMD vector operation using
+ * an op descriptor.
+ */
+static void gen_gvec_op2i(DisasContext *s, bool is_q, int rd,
+  int rn, int64_t imm, const GVecGen2i *gvec_op)
+{
+tcg_gen_gvec_2i(vec_full_reg_offset(s, rd), vec_full_reg_offset(s, rn),
+is_q ? 16 : 8, vec_full_reg_size(s), imm, gvec_op);
+}
+
 /* Expand a 3-operand AdvSIMD vector operation using an op descriptor.  */
 static void gen_gvec_op3(DisasContext *s, bool is_q, int rd,
  int rn, int rm, const GVecGen3 *gvec_op)
@@ -6512,32 +6534,6 @@ static void handle_shri_with_rndacc(TCGv_i64 tcg_res, 
TCGv_i64 tcg_src,
 }
 }
 
-/* Common SHL/SLI - Shift left with an optional insert */
-static void handle_shli_with_ins(TCGv_i64 tcg_res, TCGv_i64 tcg_src,
- bool insert, int shift)
-{
-if (insert) { /* SLI */
-tcg_gen_deposit_i64(tcg_res, tcg_res, tcg_src, shift, 64 - shift);
-} else { /* SHL */
-tcg_gen_shli_i64(tcg_res, tcg_src, shift);
-}
-}
-
-/* SRI: shift right with insert */
-static void handle_shri_with_ins(TCGv_i64 tcg_res, TCGv_i64 tcg_src,
- int size, int shift)
-{
-int esize = 8 << size;
-
-/* shift count same as element size is valid but does nothing;
- * special case to avoid potential shift by 64.
- */
-if (shift != esize) {
-tcg_gen_shri_i64(tcg_src, tcg_src, shift);
-tcg_gen_deposit_i64(tcg_res, tcg_res, tcg_src, 0, esize - shift);
-}
-}
-
 /* SSHR[RA]/USHR[RA] - Scalar shift right (optional rounding/accumulate) */
 static void handle_scalar_simd_shri(DisasContext *s,
 bool is_u, int immh, int immb,
@@ -6588,7 +6584,14 @@ static void handle_scalar_simd_shri(DisasContext *s,
 tcg_rd = (accumulate || insert) ? read_fp_dreg(s, rd) : tcg_temp_new_i64();
 
 if (insert) {
-handle_shri_with_ins(tcg_rd, tcg_rn, size, shift);
+/* shift count same as element size is valid but does nothing;
+ * special case to avoid potential shift by 64.
+ */
+int esize = 8 << size;
+if (shift != esize) {
+tcg_gen_shri_i64(tcg_rn, tcg_rn, shift);
+tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_rn, 0, esize - shift);
+}
 } else {
 handle_shri_with_rndacc(tcg_rd, tcg_rn, tcg_round,
 accumulate, is_u, size, shift);
@@ -6626,7 +6629,11 @@ static void handle_scalar_simd_shli(DisasContext *s, 
bool insert,
 tcg_rn = read_fp_dreg(s, rn);
 tcg_rd = insert ? read_fp_dreg(s, rd) : tcg_temp_new_i64();
 
-handle_shli_with_ins(tcg_rd, tcg_rn, insert, shift);
+if (insert) {
+tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_rn, shift, 64 - shift);
+} else {
+tcg_gen_shli_i64(tcg_rd, tcg_rn, shift);
+}
 
 write_fp_dreg(s, rd, tcg_rd);
 
@@ -8356,16 +8363,195 @@ static void 
disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn)
 }
 }
 
+static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
+{
+tcg_gen_vec_sar8i_i64(a, a, shift);
+tcg_gen_vec_add8_i64(d, d, a);
+}
+
+static void gen_ssra16_i64(TCGv_i64 d,