[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 07/15] target/s390x: vxeh2: Update for changes to vector shifts
From: |
Thomas Huth |
Subject: |
[PULL 07/15] target/s390x: vxeh2: Update for changes to vector shifts |
Date: |
Wed, 4 May 2022 13:05:13 +0200 |
From: David Miller <dmiller423@gmail.com>
Signed-off-by: David Miller <dmiller423@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Tested-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Message-Id: <20220428094708.84835-8-david@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
target/s390x/helper.h | 3 ++
target/s390x/tcg/vec_int_helper.c | 55 +++++++++++++++++++++
target/s390x/tcg/translate_vx.c.inc | 75 ++++++++++++-----------------
target/s390x/tcg/insn-data.def | 12 ++---
4 files changed, 95 insertions(+), 50 deletions(-)
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 7412130883..bf33d86f74 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -203,8 +203,11 @@ DEF_HELPER_FLAGS_3(gvec_vpopct16, TCG_CALL_NO_RWG, void,
ptr, cptr, i32)
DEF_HELPER_FLAGS_4(gvec_verim8, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
DEF_HELPER_FLAGS_4(gvec_verim16, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
DEF_HELPER_FLAGS_4(gvec_vsl, TCG_CALL_NO_RWG, void, ptr, cptr, i64, i32)
+DEF_HELPER_FLAGS_4(gvec_vsl_ve2, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
DEF_HELPER_FLAGS_4(gvec_vsra, TCG_CALL_NO_RWG, void, ptr, cptr, i64, i32)
+DEF_HELPER_FLAGS_4(gvec_vsra_ve2, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
DEF_HELPER_FLAGS_4(gvec_vsrl, TCG_CALL_NO_RWG, void, ptr, cptr, i64, i32)
+DEF_HELPER_FLAGS_4(gvec_vsrl_ve2, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
DEF_HELPER_FLAGS_4(gvec_vscbi8, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
DEF_HELPER_FLAGS_4(gvec_vscbi16, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
DEF_HELPER_4(gvec_vtm, void, ptr, cptr, env, i32)
diff --git a/target/s390x/tcg/vec_int_helper.c
b/target/s390x/tcg/vec_int_helper.c
index b44859ee16..53ab5c5eb3 100644
--- a/target/s390x/tcg/vec_int_helper.c
+++ b/target/s390x/tcg/vec_int_helper.c
@@ -539,18 +539,73 @@ void HELPER(gvec_vsl)(void *v1, const void *v2, uint64_t
count,
s390_vec_shl(v1, v2, count);
}
+void HELPER(gvec_vsl_ve2)(void *v1, const void *v2, const void *v3,
+ uint32_t desc)
+{
+ S390Vector tmp;
+ uint32_t sh, e0, e1 = 0;
+ int i;
+
+ for (i = 15; i >= 0; --i, e1 = e0) {
+ e0 = s390_vec_read_element8(v2, i);
+ sh = s390_vec_read_element8(v3, i) & 7;
+
+ s390_vec_write_element8(&tmp, i, rol32(e0 | (e1 << 24), sh));
+ }
+
+ *(S390Vector *)v1 = tmp;
+}
+
void HELPER(gvec_vsra)(void *v1, const void *v2, uint64_t count,
uint32_t desc)
{
s390_vec_sar(v1, v2, count);
}
+void HELPER(gvec_vsra_ve2)(void *v1, const void *v2, const void *v3,
+ uint32_t desc)
+{
+ S390Vector tmp;
+ uint32_t sh, e0, e1 = 0;
+ int i = 0;
+
+ /* Byte 0 is special only. */
+ e0 = (int32_t)(int8_t)s390_vec_read_element8(v2, i);
+ sh = s390_vec_read_element8(v3, i) & 7;
+ s390_vec_write_element8(&tmp, i, e0 >> sh);
+
+ e1 = e0;
+ for (i = 1; i < 16; ++i, e1 = e0) {
+ e0 = s390_vec_read_element8(v2, i);
+ sh = s390_vec_read_element8(v3, i) & 7;
+ s390_vec_write_element8(&tmp, i, (e0 | e1 << 8) >> sh);
+ }
+
+ *(S390Vector *)v1 = tmp;
+}
+
void HELPER(gvec_vsrl)(void *v1, const void *v2, uint64_t count,
uint32_t desc)
{
s390_vec_shr(v1, v2, count);
}
+void HELPER(gvec_vsrl_ve2)(void *v1, const void *v2, const void *v3,
+ uint32_t desc)
+{
+ S390Vector tmp;
+ uint32_t sh, e0, e1 = 0;
+
+ for (int i = 0; i < 16; ++i, e1 = e0) {
+ e0 = s390_vec_read_element8(v2, i);
+ sh = s390_vec_read_element8(v3, i) & 7;
+
+ s390_vec_write_element8(&tmp, i, (e0 | (e1 << 8)) >> sh);
+ }
+
+ *(S390Vector *)v1 = tmp;
+}
+
#define DEF_VSCBI(BITS)
\
void HELPER(gvec_vscbi##BITS)(void *v1, const void *v2, const void *v3,
\
uint32_t desc)
\
diff --git a/target/s390x/tcg/translate_vx.c.inc
b/target/s390x/tcg/translate_vx.c.inc
index 8ddbd440e2..81673ea68f 100644
--- a/target/s390x/tcg/translate_vx.c.inc
+++ b/target/s390x/tcg/translate_vx.c.inc
@@ -2018,23 +2018,44 @@ static DisasJumpType op_ves(DisasContext *s, DisasOps
*o)
return DISAS_NEXT;
}
-static DisasJumpType op_vsl(DisasContext *s, DisasOps *o)
+static DisasJumpType gen_vsh_by_byte(DisasContext *s, DisasOps *o,
+ gen_helper_gvec_2i *gen,
+ gen_helper_gvec_3 *gen_ve2)
{
- TCGv_i64 shift = tcg_temp_new_i64();
+ bool byte = s->insn->data;
- read_vec_element_i64(shift, get_field(s, v3), 7, ES_8);
- if (s->fields.op2 == 0x74) {
- tcg_gen_andi_i64(shift, shift, 0x7);
+ if (!byte && s390_has_feat(S390_FEAT_VECTOR_ENH2)) {
+ gen_gvec_3_ool(get_field(s, v1), get_field(s, v2),
+ get_field(s, v3), 0, gen_ve2);
} else {
- tcg_gen_andi_i64(shift, shift, 0x78);
- }
+ TCGv_i64 shift = tcg_temp_new_i64();
- gen_gvec_2i_ool(get_field(s, v1), get_field(s, v2),
- shift, 0, gen_helper_gvec_vsl);
- tcg_temp_free_i64(shift);
+ read_vec_element_i64(shift, get_field(s, v3), 7, ES_8);
+ tcg_gen_andi_i64(shift, shift, byte ? 0x78 : 7);
+ gen_gvec_2i_ool(get_field(s, v1), get_field(s, v2), shift, 0, gen);
+ tcg_temp_free_i64(shift);
+ }
return DISAS_NEXT;
}
+static DisasJumpType op_vsl(DisasContext *s, DisasOps *o)
+{
+ return gen_vsh_by_byte(s, o, gen_helper_gvec_vsl,
+ gen_helper_gvec_vsl_ve2);
+}
+
+static DisasJumpType op_vsra(DisasContext *s, DisasOps *o)
+{
+ return gen_vsh_by_byte(s, o, gen_helper_gvec_vsra,
+ gen_helper_gvec_vsra_ve2);
+}
+
+static DisasJumpType op_vsrl(DisasContext *s, DisasOps *o)
+{
+ return gen_vsh_by_byte(s, o, gen_helper_gvec_vsrl,
+ gen_helper_gvec_vsrl_ve2);
+}
+
static DisasJumpType op_vsldb(DisasContext *s, DisasOps *o)
{
const uint8_t i4 = get_field(s, i4) & 0xf;
@@ -2064,40 +2085,6 @@ static DisasJumpType op_vsldb(DisasContext *s, DisasOps
*o)
return DISAS_NEXT;
}
-static DisasJumpType op_vsra(DisasContext *s, DisasOps *o)
-{
- TCGv_i64 shift = tcg_temp_new_i64();
-
- read_vec_element_i64(shift, get_field(s, v3), 7, ES_8);
- if (s->fields.op2 == 0x7e) {
- tcg_gen_andi_i64(shift, shift, 0x7);
- } else {
- tcg_gen_andi_i64(shift, shift, 0x78);
- }
-
- gen_gvec_2i_ool(get_field(s, v1), get_field(s, v2),
- shift, 0, gen_helper_gvec_vsra);
- tcg_temp_free_i64(shift);
- return DISAS_NEXT;
-}
-
-static DisasJumpType op_vsrl(DisasContext *s, DisasOps *o)
-{
- TCGv_i64 shift = tcg_temp_new_i64();
-
- read_vec_element_i64(shift, get_field(s, v3), 7, ES_8);
- if (s->fields.op2 == 0x7c) {
- tcg_gen_andi_i64(shift, shift, 0x7);
- } else {
- tcg_gen_andi_i64(shift, shift, 0x78);
- }
-
- gen_gvec_2i_ool(get_field(s, v1), get_field(s, v2),
- shift, 0, gen_helper_gvec_vsrl);
- tcg_temp_free_i64(shift);
- return DISAS_NEXT;
-}
-
static DisasJumpType op_vs(DisasContext *s, DisasOps *o)
{
const uint8_t es = get_field(s, m4);
diff --git a/target/s390x/tcg/insn-data.def b/target/s390x/tcg/insn-data.def
index 46add91a0e..f487a64abf 100644
--- a/target/s390x/tcg/insn-data.def
+++ b/target/s390x/tcg/insn-data.def
@@ -1204,19 +1204,19 @@
F(0xe778, VESRLV, VRR_c, V, 0, 0, 0, 0, vesv, 0, IF_VEC)
F(0xe738, VESRL, VRS_a, V, la2, 0, 0, 0, ves, 0, IF_VEC)
/* VECTOR SHIFT LEFT */
- F(0xe774, VSL, VRR_c, V, 0, 0, 0, 0, vsl, 0, IF_VEC)
+ E(0xe774, VSL, VRR_c, V, 0, 0, 0, 0, vsl, 0, 0, IF_VEC)
/* VECTOR SHIFT LEFT BY BYTE */
- F(0xe775, VSLB, VRR_c, V, 0, 0, 0, 0, vsl, 0, IF_VEC)
+ E(0xe775, VSLB, VRR_c, V, 0, 0, 0, 0, vsl, 0, 1, IF_VEC)
/* VECTOR SHIFT LEFT DOUBLE BY BYTE */
F(0xe777, VSLDB, VRI_d, V, 0, 0, 0, 0, vsldb, 0, IF_VEC)
/* VECTOR SHIFT RIGHT ARITHMETIC */
- F(0xe77e, VSRA, VRR_c, V, 0, 0, 0, 0, vsra, 0, IF_VEC)
+ E(0xe77e, VSRA, VRR_c, V, 0, 0, 0, 0, vsra, 0, 0, IF_VEC)
/* VECTOR SHIFT RIGHT ARITHMETIC BY BYTE */
- F(0xe77f, VSRAB, VRR_c, V, 0, 0, 0, 0, vsra, 0, IF_VEC)
+ E(0xe77f, VSRAB, VRR_c, V, 0, 0, 0, 0, vsra, 0, 1, IF_VEC)
/* VECTOR SHIFT RIGHT LOGICAL */
- F(0xe77c, VSRL, VRR_c, V, 0, 0, 0, 0, vsrl, 0, IF_VEC)
+ E(0xe77c, VSRL, VRR_c, V, 0, 0, 0, 0, vsrl, 0, 0, IF_VEC)
/* VECTOR SHIFT RIGHT LOGICAL BY BYTE */
- F(0xe77d, VSRLB, VRR_c, V, 0, 0, 0, 0, vsrl, 0, IF_VEC)
+ E(0xe77d, VSRLB, VRR_c, V, 0, 0, 0, 0, vsrl, 0, 1, IF_VEC)
/* VECTOR SUBTRACT */
F(0xe7f7, VS, VRR_c, V, 0, 0, 0, 0, vs, 0, IF_VEC)
/* VECTOR SUBTRACT COMPUTE BORROW INDICATION */
--
2.27.0
- [PULL 02/15] s390x/cpu_models: drop "msa5" from the TCG "max" model, (continued)
- [PULL 02/15] s390x/cpu_models: drop "msa5" from the TCG "max" model, Thomas Huth, 2022/05/04
- [PULL 03/15] s390x/cpu_models: make "max" match the unmodified "qemu" CPU model under TCG, Thomas Huth, 2022/05/04
- [PULL 01/15] target/s390x: Fix writeback to v1 in helper_vstl, Thomas Huth, 2022/05/04
- [PULL 04/15] tcg: Implement tcg_gen_{h,w}swap_{i32,i64}, Thomas Huth, 2022/05/04
- [PULL 06/15] target/s390x: vxeh2: vector string search, Thomas Huth, 2022/05/04
- [PULL 13/15] tests/tcg/s390x: Tests for Vector Enhancements Facility 2, Thomas Huth, 2022/05/04
- [PULL 08/15] target/s390x: vxeh2: vector shift double by bit, Thomas Huth, 2022/05/04
- [PULL 07/15] target/s390x: vxeh2: Update for changes to vector shifts,
Thomas Huth <=
- [PULL 09/15] target/s390x: vxeh2: vector {load, store} elements reversed, Thomas Huth, 2022/05/04
- [PULL 05/15] target/s390x: vxeh2: vector convert short/32b, Thomas Huth, 2022/05/04
- [PULL 10/15] target/s390x: vxeh2: vector {load, store} byte reversed elements, Thomas Huth, 2022/05/04
- [PULL 12/15] target/s390x: add S390_FEAT_VECTOR_ENH2 to qemu CPU model, Thomas Huth, 2022/05/04
- [PULL 15/15] tests/tcg/s390x: Use a different PCRel32 notation in branch-relative-long.c, Thomas Huth, 2022/05/04
- [PULL 11/15] target/s390x: vxeh2: vector {load, store} byte reversed element, Thomas Huth, 2022/05/04
- [PULL 14/15] disas: Remove old libopcode s390 disassembler, Thomas Huth, 2022/05/04
- Re: [PULL 00/15] s390x patches, Richard Henderson, 2022/05/04