Signed-off-by: David Hildenbrand <da...@redhat.com> --- target/s390x/helper.h | 10 ++++++++ target/s390x/insn-data.def | 4 +++ target/s390x/translate_vx.c.inc | 26 +++++++++++++++++++ target/s390x/vec_fpu_helper.c | 45 +++++++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+)
diff --git a/target/s390x/helper.h b/target/s390x/helper.h index e4d60299dc..6b4a6c5185 100644 --- a/target/s390x/helper.h +++ b/target/s390x/helper.h @@ -327,6 +327,16 @@ DEF_HELPER_FLAGS_6(gvec_vfms32s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, en DEF_HELPER_FLAGS_6(gvec_vfms64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32) DEF_HELPER_FLAGS_6(gvec_vfms64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32) DEF_HELPER_FLAGS_6(gvec_vfms128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32) +DEF_HELPER_FLAGS_6(gvec_vfnma32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32) +DEF_HELPER_FLAGS_6(gvec_vfnma32s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32) +DEF_HELPER_FLAGS_6(gvec_vfnma64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32) +DEF_HELPER_FLAGS_6(gvec_vfnma64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32) +DEF_HELPER_FLAGS_6(gvec_vfnma128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32) +DEF_HELPER_FLAGS_6(gvec_vfnms32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32) +DEF_HELPER_FLAGS_6(gvec_vfnms32s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32) +DEF_HELPER_FLAGS_6(gvec_vfnms64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32) +DEF_HELPER_FLAGS_6(gvec_vfnms64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32) +DEF_HELPER_FLAGS_6(gvec_vfnms128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32) DEF_HELPER_FLAGS_4(gvec_vfsq32, TCG_CALL_NO_WG, void, ptr, cptr, env, i32) DEF_HELPER_FLAGS_4(gvec_vfsq32s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32) DEF_HELPER_FLAGS_4(gvec_vfsq64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32) diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def index da7fe6f21c..082de27298 100644 --- a/target/s390x/insn-data.def +++ b/target/s390x/insn-data.def @@ -1259,6 +1259,10 @@ F(0xe78f, VFMA, VRR_e, V, 0, 0, 0, 0, vfma, 0, IF_VEC) /* VECTOR FP MULTIPLY AND SUBTRACT */ F(0xe78e, VFMS, VRR_e, V, 0, 0, 0, 0, vfma, 0, IF_VEC) +/* VECTOR FP NEGATIVE MULTIPLY AND ADD */ + F(0xe79f, VFNMA, VRR_e, VE, 0, 0, 0, 0, vfma, 0, IF_VEC) +/* VECTOR FP NEGATIVE MULTIPLY AND SUBTRACT */ + F(0xe79e, VFNMS, VRR_e, VE, 0, 0, 0, 0, vfma, 0, IF_VEC) /* VECTOR FP PERFORM SIGN OPERATION */ F(0xe7cc, VFPSO, VRR_a, V, 0, 0, 0, 0, vfpso, 0, IF_VEC) /* VECTOR FP SQUARE ROOT */ diff --git a/target/s390x/translate_vx.c.inc b/target/s390x/translate_vx.c.inc index 5d31498cc1..40e452f552 100644 --- a/target/s390x/translate_vx.c.inc +++ b/target/s390x/translate_vx.c.inc @@ -2884,6 +2884,32 @@ static DisasJumpType op_vfma(DisasContext *s, DisasOps *o) break; } break; + case 0x9f: + switch (fpf) { + case FPF_SHORT: + fn = se ? gen_helper_gvec_vfnma32s : gen_helper_gvec_vfnma32; + break; + case FPF_LONG: + fn = se ? gen_helper_gvec_vfnma64s : gen_helper_gvec_vfnma64; + break; + default: + fn = gen_helper_gvec_vfnma128; + break; + } + break; + case 0x9e: + switch (fpf) { + case FPF_SHORT: + fn = se ? gen_helper_gvec_vfnms32s : gen_helper_gvec_vfnms32; + break; + case FPF_LONG: + fn = se ? gen_helper_gvec_vfnms64s : gen_helper_gvec_vfnms64; + break; + default: + fn = gen_helper_gvec_vfnms128; + break; + } + break; default: g_assert_not_reached(); } diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c index 0b25718365..92858c8c59 100644 --- a/target/s390x/vec_fpu_helper.c +++ b/target/s390x/vec_fpu_helper.c @@ -769,6 +769,51 @@ void HELPER(gvec_vfms##BITS##s)(void *v1, const void *v2, const void *v3, \ DEF_GVEC_VFMS_S(32) DEF_GVEC_VFMS_S(64) +#define DEF_GVEC_VFNMA(BITS) \ +void HELPER(gvec_vfnma##BITS)(void *v1, const void *v2, const void *v3, \ + const void *v4, CPUS390XState *env, \ + uint32_t desc) \ +{ \ + vfma##BITS(v1, v2, v3, v4, env, false, float_muladd_negate_result, \ + GETPC()); \ +} +DEF_GVEC_VFNMA(32) +DEF_GVEC_VFNMA(64) +DEF_GVEC_VFNMA(128) + +#define DEF_GVEC_VFNMA_S(BITS) \ +void HELPER(gvec_vfnma##BITS##s)(void *v1, const void *v2, const void *v3, \ + const void *v4, CPUS390XState *env, \ + uint32_t desc) \ +{ \ + vfma##BITS(v1, v2, v3, v4, env, true, float_muladd_negate_result, GETPC());\ +} +DEF_GVEC_VFNMA_S(32) +DEF_GVEC_VFNMA_S(64) + +#define DEF_GVEC_VFNMS(BITS) \ +void HELPER(gvec_vfnms##BITS)(void *v1, const void *v2, const void *v3, \ + const void *v4, CPUS390XState *env, \ + uint32_t desc) \ +{ \ + vfma##BITS(v1, v2, v3, v4, env, false, \ + float_muladd_negate_c | float_muladd_negate_result, GETPC()); \ +} +DEF_GVEC_VFNMS(32) +DEF_GVEC_VFNMS(64) +DEF_GVEC_VFNMS(128) + +#define DEF_GVEC_VFNMS_S(BITS) \ +void HELPER(gvec_vfnms##BITS##s)(void *v1, const void *v2, const void *v3, \ + const void *v4, CPUS390XState *env, \ + uint32_t desc) \ +{ \ + vfma##BITS(v1, v2, v3, v4, env, true, \ + float_muladd_negate_c | float_muladd_negate_result, GETPC()); \ +} +DEF_GVEC_VFNMS_S(32) +DEF_GVEC_VFNMS_S(64) + #define DEF_GVEC_VFSQ(BITS) \ void HELPER(gvec_vfsq##BITS)(void *v1, const void *v2, CPUS390XState *env, \ uint32_t desc) \ -- 2.26.2