Signed-off-by: David Hildenbrand <da...@redhat.com> --- target/s390x/helper.h | 3 ++ target/s390x/translate_vx.c.inc | 26 ++++++++--- target/s390x/vec_fpu_helper.c | 76 +++++++++++++++++++-------------- 3 files changed, 69 insertions(+), 36 deletions(-)
diff --git a/target/s390x/helper.h b/target/s390x/helper.h index bee283e3d4..c2ded83669 100644 --- a/target/s390x/helper.h +++ b/target/s390x/helper.h @@ -331,8 +331,11 @@ DEF_HELPER_FLAGS_5(gvec_vfs32s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32) DEF_HELPER_FLAGS_5(gvec_vfs64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32) DEF_HELPER_FLAGS_5(gvec_vfs64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32) DEF_HELPER_FLAGS_5(gvec_vfs128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32) +DEF_HELPER_4(gvec_vftci32, void, ptr, cptr, env, i32) +DEF_HELPER_4(gvec_vftci32s, void, ptr, cptr, env, i32) DEF_HELPER_4(gvec_vftci64, void, ptr, cptr, env, i32) DEF_HELPER_4(gvec_vftci64s, void, ptr, cptr, env, i32) +DEF_HELPER_4(gvec_vftci128, void, ptr, cptr, env, i32) #ifndef CONFIG_USER_ONLY DEF_HELPER_3(servc, i32, env, i64, i64) diff --git a/target/s390x/translate_vx.c.inc b/target/s390x/translate_vx.c.inc index 7d4811ccf7..6bd599b319 100644 --- a/target/s390x/translate_vx.c.inc +++ b/target/s390x/translate_vx.c.inc @@ -2991,16 +2991,32 @@ static DisasJumpType op_vftci(DisasContext *s, DisasOps *o) const uint16_t i3 = get_field(s, i3); const uint8_t fpf = get_field(s, m4); const uint8_t m5 = get_field(s, m5); - gen_helper_gvec_2_ptr *fn = gen_helper_gvec_vftci64; + const bool se = extract32(m5, 3, 1); + gen_helper_gvec_2_ptr *fn = NULL; - if (fpf != FPF_LONG || extract32(m5, 0, 3)) { + switch (fpf) { + case FPF_SHORT: + if (s390_has_feat(S390_FEAT_VECTOR_ENH)) { + fn = se ? gen_helper_gvec_vftci32s : gen_helper_gvec_vftci32; + } + break; + case FPF_LONG: + fn = se ? gen_helper_gvec_vftci64s : gen_helper_gvec_vftci64; + break; + case FPF_EXT: + if (s390_has_feat(S390_FEAT_VECTOR_ENH)) { + fn = gen_helper_gvec_vftci128; + } + break; + default: + break; + } + + if (!fn || extract32(m5, 0, 3)) { gen_program_exception(s, PGM_SPECIFICATION); return DISAS_NORETURN; } - if (extract32(m5, 3, 1)) { - fn = gen_helper_gvec_vftci64s; - } gen_gvec_2_ptr(get_field(s, v1), get_field(s, v2), cpu_env, i3, fn); set_cc_static(s); return DISAS_NEXT; diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c index b7045e85d6..f18f0ae8e2 100644 --- a/target/s390x/vec_fpu_helper.c +++ b/target/s390x/vec_fpu_helper.c @@ -23,6 +23,9 @@ const float32 float32_ones = make_float32(-1u); const float64 float64_ones = make_float64(-1ull); const float128 float128_ones = make_float128(-1ull, -1ull); +const float32 float32_zeroes = make_float32(0); +const float64 float64_zeroes = make_float64(0); +const float128 float128_zeroes = make_float128(0, 0); #define VIC_INVALID 0x1 #define VIC_DIVBYZERO 0x2 @@ -782,39 +785,50 @@ void HELPER(gvec_vfs##BITS##s)(void *v1, const void *v2, const void *v3, \ DEF_GVEC_FVS_S(32) DEF_GVEC_FVS_S(64) -static int vftci64(S390Vector *v1, const S390Vector *v2, CPUS390XState *env, - bool s, uint16_t i3) -{ - int i, match = 0; - - for (i = 0; i < 2; i++) { - float64 a = s390_vec_read_element64(v2, i); - - if (float64_dcmask(env, a) & i3) { - match++; - s390_vec_write_element64(v1, i, -1ull); - } else { - s390_vec_write_element64(v1, i, 0); - } - if (s) { - break; - } - } - - if (match) { - return s || match == 2 ? 0 : 1; - } - return 3; +#define DEF_VFTCI(BITS) \ +static int vftci##BITS(S390Vector *v1, const S390Vector *v2, \ + CPUS390XState *env, bool s, uint16_t i3) \ +{ \ + int i, match = 0; \ + \ + for (i = 0; i < (128 / BITS); i++) { \ + float##BITS a = s390_vec_read_float##BITS(v2, i); \ + \ + if (float##BITS##_dcmask(env, a) & i3) { \ + match++; \ + s390_vec_write_float##BITS(v1, i, float##BITS##_ones); \ + } else { \ + s390_vec_write_float##BITS(v1, i, float##BITS##_zeroes); \ + } \ + if (s) { \ + break; \ + } \ + } \ + \ + if (match) { \ + return s || match == (128 / BITS) ? 0 : 1; \ + } \ + return 3; \ } +DEF_VFTCI(32) +DEF_VFTCI(64) +DEF_VFTCI(128) -void HELPER(gvec_vftci64)(void *v1, const void *v2, CPUS390XState *env, - uint32_t desc) -{ - env->cc_op = vftci64(v1, v2, env, false, simd_data(desc)); +#define DEF_GVEC_VFTCI(BITS) \ +void HELPER(gvec_vftci##BITS)(void *v1, const void *v2, CPUS390XState *env, \ + uint32_t desc) \ +{ \ + env->cc_op = vftci##BITS(v1, v2, env, false, simd_data(desc)); \ } +DEF_GVEC_VFTCI(32) +DEF_GVEC_VFTCI(64) +DEF_GVEC_VFTCI(128) -void HELPER(gvec_vftci64s)(void *v1, const void *v2, CPUS390XState *env, - uint32_t desc) -{ - env->cc_op = vftci64(v1, v2, env, true, simd_data(desc)); +#define DEF_GVEC_VFTCI_S(BITS) \ +void HELPER(gvec_vftci##BITS##s)(void *v1, const void *v2, CPUS390XState *env, \ + uint32_t desc) \ +{ \ + env->cc_op = vftci##BITS(v1, v2, env, true, simd_data(desc)); \ } +DEF_GVEC_VFTCI_S(32) +DEF_GVEC_VFTCI_S(64) -- 2.26.2