Skip to content

Commit

Permalink
s390x/tcg: Simplify vop64_3() handling
Browse files Browse the repository at this point in the history
Let's simplify, reworking our handler generation, passing the whole "m5"
register content and not providing specialized handlers for "se", and
reading/writing proper float64 values using new helpers.

Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20210608092337.12221-4-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
  • Loading branch information
davidhildenbrand authored and cohuck committed Jun 21, 2021
1 parent 0bd3c28 commit 863b950
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 79 deletions.
4 changes: 0 additions & 4 deletions target/s390x/helper.h
Expand Up @@ -247,7 +247,6 @@ DEF_HELPER_6(gvec_vstrc_cc_rt32, void, ptr, cptr, cptr, cptr, env, i32)

/* === Vector Floating-Point Instructions */
DEF_HELPER_FLAGS_5(gvec_vfa64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfa64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_4(gvec_wfc64, void, cptr, cptr, env, i32)
DEF_HELPER_4(gvec_wfk64, void, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfce64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
Expand All @@ -271,23 +270,20 @@ DEF_HELPER_FLAGS_4(gvec_vcgd64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vclgd64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vclgd64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfd64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfd64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfi64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfi64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfll32, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfll32s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vflr64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vflr64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfm64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfm64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_6(gvec_vfma64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_6(gvec_vfma64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
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_4(gvec_vfsq64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfsq64s, TCG_CALL_NO_WG, void, ptr, 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_4(gvec_vftci64, void, ptr, cptr, env, i32)
DEF_HELPER_4(gvec_vftci64s, void, ptr, cptr, env, i32)

Expand Down
11 changes: 5 additions & 6 deletions target/s390x/translate_vx.c.inc
Expand Up @@ -2443,7 +2443,6 @@ static DisasJumpType op_vfa(DisasContext *s, DisasOps *o)
{
const uint8_t fpf = get_field(s, m4);
const uint8_t m5 = get_field(s, m5);
const bool se = extract32(m5, 3, 1);
gen_helper_gvec_3_ptr *fn;

if (fpf != FPF_LONG || extract32(m5, 0, 3)) {
Expand All @@ -2453,22 +2452,22 @@ static DisasJumpType op_vfa(DisasContext *s, DisasOps *o)

switch (s->fields.op2) {
case 0xe3:
fn = se ? gen_helper_gvec_vfa64s : gen_helper_gvec_vfa64;
fn = gen_helper_gvec_vfa64;
break;
case 0xe5:
fn = se ? gen_helper_gvec_vfd64s : gen_helper_gvec_vfd64;
fn = gen_helper_gvec_vfd64;
break;
case 0xe7:
fn = se ? gen_helper_gvec_vfm64s : gen_helper_gvec_vfm64;
fn = gen_helper_gvec_vfm64;
break;
case 0xe2:
fn = se ? gen_helper_gvec_vfs64s : gen_helper_gvec_vfs64;
fn = gen_helper_gvec_vfs64;
break;
default:
g_assert_not_reached();
}
gen_gvec_3_ptr(get_field(s, v1), get_field(s, v2),
get_field(s, v3), cpu_env, 0, fn);
get_field(s, v3), cpu_env, m5, fn);
return DISAS_NEXT;
}

Expand Down
94 changes: 25 additions & 69 deletions target/s390x/vec_fpu_helper.c
Expand Up @@ -78,6 +78,16 @@ static void handle_ieee_exc(CPUS390XState *env, uint8_t vxc, uint8_t vec_exc,
}
}

static float64 s390_vec_read_float64(const S390Vector *v, uint8_t enr)
{
return make_float64(s390_vec_read_element64(v, enr));
}

static void s390_vec_write_float64(S390Vector *v, uint8_t enr, float64 data)
{
return s390_vec_write_element64(v, enr, data);
}

typedef uint64_t (*vop64_2_fn)(uint64_t a, float_status *s);
static void vop64_2(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
bool s, bool XxC, uint8_t erm, vop64_2_fn fn,
Expand All @@ -102,7 +112,7 @@ static void vop64_2(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
*v1 = tmp;
}

typedef uint64_t (*vop64_3_fn)(uint64_t a, uint64_t b, float_status *s);
typedef float64 (*vop64_3_fn)(float64 a, float64 b, float_status *s);
static void vop64_3(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
CPUS390XState *env, bool s, vop64_3_fn fn,
uintptr_t retaddr)
Expand All @@ -112,10 +122,10 @@ static void vop64_3(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
int i;

for (i = 0; i < 2; i++) {
const uint64_t a = s390_vec_read_element64(v2, i);
const uint64_t b = s390_vec_read_element64(v3, i);
const float64 a = s390_vec_read_float64(v2, i);
const float64 b = s390_vec_read_float64(v3, i);

s390_vec_write_element64(&tmp, i, fn(a, b, &env->fpu_status));
s390_vec_write_float64(&tmp, i, fn(a, b, &env->fpu_status));
vxc = check_ieee_exc(env, i, false, &vec_exc);
if (s || vxc) {
break;
Expand All @@ -125,22 +135,19 @@ static void vop64_3(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
*v1 = tmp;
}

static uint64_t vfa64(uint64_t a, uint64_t b, float_status *s)
{
return float64_add(a, b, s);
#define DEF_GVEC_VOP3(NAME, OP) \
void HELPER(gvec_##NAME##64)(void *v1, const void *v2, const void *v3, \
CPUS390XState *env, uint32_t desc) \
{ \
const bool se = extract32(simd_data(desc), 3, 1); \
\
vop64_3(v1, v2, v3, env, se, float64_##OP, GETPC()); \
}

void HELPER(gvec_vfa64)(void *v1, const void *v2, const void *v3,
CPUS390XState *env, uint32_t desc)
{
vop64_3(v1, v2, v3, env, false, vfa64, GETPC());
}

void HELPER(gvec_vfa64s)(void *v1, const void *v2, const void *v3,
CPUS390XState *env, uint32_t desc)
{
vop64_3(v1, v2, v3, env, true, vfa64, GETPC());
}
DEF_GVEC_VOP3(vfa, add)
DEF_GVEC_VOP3(vfs, sub)
DEF_GVEC_VOP3(vfd, div)
DEF_GVEC_VOP3(vfm, mul)

static int wfc64(const S390Vector *v1, const S390Vector *v2,
CPUS390XState *env, bool signal, uintptr_t retaddr)
Expand Down Expand Up @@ -374,23 +381,6 @@ void HELPER(gvec_vclgd64s)(void *v1, const void *v2, CPUS390XState *env,
vop64_2(v1, v2, env, true, XxC, erm, vclgd64, GETPC());
}

static uint64_t vfd64(uint64_t a, uint64_t b, float_status *s)
{
return float64_div(a, b, s);
}

void HELPER(gvec_vfd64)(void *v1, const void *v2, const void *v3,
CPUS390XState *env, uint32_t desc)
{
vop64_3(v1, v2, v3, env, false, vfd64, GETPC());
}

void HELPER(gvec_vfd64s)(void *v1, const void *v2, const void *v3,
CPUS390XState *env, uint32_t desc)
{
vop64_3(v1, v2, v3, env, true, vfd64, GETPC());
}

static uint64_t vfi64(uint64_t a, float_status *s)
{
return float64_round_to_int(a, s);
Expand Down Expand Up @@ -492,23 +482,6 @@ void HELPER(gvec_vflr64s)(void *v1, const void *v2, CPUS390XState *env,
vflr64(v1, v2, env, true, XxC, erm, GETPC());
}

static uint64_t vfm64(uint64_t a, uint64_t b, float_status *s)
{
return float64_mul(a, b, s);
}

void HELPER(gvec_vfm64)(void *v1, const void *v2, const void *v3,
CPUS390XState *env, uint32_t desc)
{
vop64_3(v1, v2, v3, env, false, vfm64, GETPC());
}

void HELPER(gvec_vfm64s)(void *v1, const void *v2, const void *v3,
CPUS390XState *env, uint32_t desc)
{
vop64_3(v1, v2, v3, env, true, vfm64, GETPC());
}

static void vfma64(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
const S390Vector *v4, CPUS390XState *env, bool s, int flags,
uintptr_t retaddr)
Expand Down Expand Up @@ -574,23 +547,6 @@ void HELPER(gvec_vfsq64s)(void *v1, const void *v2, CPUS390XState *env,
vop64_2(v1, v2, env, true, false, 0, vfsq64, GETPC());
}

static uint64_t vfs64(uint64_t a, uint64_t b, float_status *s)
{
return float64_sub(a, b, s);
}

void HELPER(gvec_vfs64)(void *v1, const void *v2, const void *v3,
CPUS390XState *env, uint32_t desc)
{
vop64_3(v1, v2, v3, env, false, vfs64, GETPC());
}

void HELPER(gvec_vfs64s)(void *v1, const void *v2, const void *v3,
CPUS390XState *env, uint32_t desc)
{
vop64_3(v1, v2, v3, env, true, vfs64, GETPC());
}

static int vftci64(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
bool s, uint16_t i3)
{
Expand Down

0 comments on commit 863b950

Please sign in to comment.