From 8c18fa5b3eba2b5c4d1285714682db066ea711fa Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Tue, 8 Jun 2021 11:23:23 +0200 Subject: [PATCH] s390x/tcg: Implement VECTOR MULTIPLY SUM LOGICAL Fortunately, we only need the Doubleword implementation. Reviewed-by: Richard Henderson Signed-off-by: David Hildenbrand Message-Id: <20210608092337.12221-13-david@redhat.com> Signed-off-by: Cornelia Huck --- target/s390x/insn-data.def | 2 ++ target/s390x/translate_vx.c.inc | 50 +++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def index 1634a6bc5a..1a3ae7e7e7 100644 --- a/target/s390x/insn-data.def +++ b/target/s390x/insn-data.def @@ -1151,6 +1151,8 @@ F(0xe7a7, VMO, VRR_c, V, 0, 0, 0, 0, vm, 0, IF_VEC) /* VECTOR MULTIPLY LOGICAL ODD */ F(0xe7a5, VMLO, VRR_c, V, 0, 0, 0, 0, vm, 0, IF_VEC) +/* VECTOR MULTIPLY SUM LOGICAL */ + F(0xe7b8, VMSL, VRR_d, VE, 0, 0, 0, 0, vmsl, 0, IF_VEC) /* VECTOR NAND */ F(0xe76e, VNN, VRR_c, VE, 0, 0, 0, 0, vnn, 0, IF_VEC) /* VECTOR NOR */ diff --git a/target/s390x/translate_vx.c.inc b/target/s390x/translate_vx.c.inc index 96283d4ddb..6e75b40eb8 100644 --- a/target/s390x/translate_vx.c.inc +++ b/target/s390x/translate_vx.c.inc @@ -1779,6 +1779,56 @@ static DisasJumpType op_vm(DisasContext *s, DisasOps *o) return DISAS_NEXT; } +static DisasJumpType op_vmsl(DisasContext *s, DisasOps *o) +{ + TCGv_i64 l1, h1, l2, h2; + + if (get_field(s, m4) != ES_64) { + gen_program_exception(s, PGM_SPECIFICATION); + return DISAS_NORETURN; + } + + l1 = tcg_temp_new_i64(); + h1 = tcg_temp_new_i64(); + l2 = tcg_temp_new_i64(); + h2 = tcg_temp_new_i64(); + + /* Multipy both even elements from v2 and v3 */ + read_vec_element_i64(l1, get_field(s, v2), 0, ES_64); + read_vec_element_i64(h1, get_field(s, v3), 0, ES_64); + tcg_gen_mulu2_i64(l1, h1, l1, h1); + /* Shift result left by one (x2) if requested */ + if (extract32(get_field(s, m6), 3, 1)) { + tcg_gen_add2_i64(l1, h1, l1, h1, l1, h1); + } + + /* Multipy both odd elements from v2 and v3 */ + read_vec_element_i64(l2, get_field(s, v2), 1, ES_64); + read_vec_element_i64(h2, get_field(s, v3), 1, ES_64); + tcg_gen_mulu2_i64(l2, h2, l2, h2); + /* Shift result left by one (x2) if requested */ + if (extract32(get_field(s, m6), 2, 1)) { + tcg_gen_add2_i64(l2, h2, l2, h2, l2, h2); + } + + /* Add both intermediate results */ + tcg_gen_add2_i64(l1, h1, l1, h1, l2, h2); + /* Add whole v4 */ + read_vec_element_i64(h2, get_field(s, v4), 0, ES_64); + read_vec_element_i64(l2, get_field(s, v4), 1, ES_64); + tcg_gen_add2_i64(l1, h1, l1, h1, l2, h2); + + /* Store final result into v1. */ + write_vec_element_i64(h1, get_field(s, v1), 0, ES_64); + write_vec_element_i64(l1, get_field(s, v1), 1, ES_64); + + tcg_temp_free_i64(l1); + tcg_temp_free_i64(h1); + tcg_temp_free_i64(l2); + tcg_temp_free_i64(h2); + return DISAS_NEXT; +} + static DisasJumpType op_vnn(DisasContext *s, DisasOps *o) { gen_gvec_fn_3(nand, ES_8, get_field(s, v1),