mirror of https://github.com/xemu-project/xemu.git
target/arm: Implement SVE floating-point compare vectors
Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20180627043328.11531-17-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
408ecde97b
commit
abfdefd5bd
|
@ -839,6 +839,55 @@ DEF_HELPER_FLAGS_5(sve_ucvt_ds, TCG_CALL_NO_RWG,
|
|||
DEF_HELPER_FLAGS_5(sve_ucvt_dd, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_6(sve_fcmge_h, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_6(sve_fcmge_s, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_6(sve_fcmge_d, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_6(sve_fcmgt_h, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_6(sve_fcmgt_s, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_6(sve_fcmgt_d, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_6(sve_fcmeq_h, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_6(sve_fcmeq_s, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_6(sve_fcmeq_d, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_6(sve_fcmne_h, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_6(sve_fcmne_s, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_6(sve_fcmne_d, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_6(sve_fcmuo_h, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_6(sve_fcmuo_s, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_6(sve_fcmuo_d, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_6(sve_facge_h, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_6(sve_facge_s, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_6(sve_facge_d, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_6(sve_facgt_h, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_6(sve_facgt_s, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_6(sve_facgt_d, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
|
||||
DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
|
||||
DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
|
||||
|
|
|
@ -324,6 +324,17 @@ UXTH 00000100 .. 010 011 101 ... ..... ..... @rd_pg_rn
|
|||
SXTW 00000100 .. 010 100 101 ... ..... ..... @rd_pg_rn
|
||||
UXTW 00000100 .. 010 101 101 ... ..... ..... @rd_pg_rn
|
||||
|
||||
### SVE Floating Point Compare - Vectors Group
|
||||
|
||||
# SVE floating-point compare vectors
|
||||
FCMGE_ppzz 01100101 .. 0 ..... 010 ... ..... 0 .... @pd_pg_rn_rm
|
||||
FCMGT_ppzz 01100101 .. 0 ..... 010 ... ..... 1 .... @pd_pg_rn_rm
|
||||
FCMEQ_ppzz 01100101 .. 0 ..... 011 ... ..... 0 .... @pd_pg_rn_rm
|
||||
FCMNE_ppzz 01100101 .. 0 ..... 011 ... ..... 1 .... @pd_pg_rn_rm
|
||||
FCMUO_ppzz 01100101 .. 0 ..... 110 ... ..... 0 .... @pd_pg_rn_rm
|
||||
FACGE_ppzz 01100101 .. 0 ..... 110 ... ..... 1 .... @pd_pg_rn_rm
|
||||
FACGT_ppzz 01100101 .. 0 ..... 111 ... ..... 1 .... @pd_pg_rn_rm
|
||||
|
||||
### SVE Integer Multiply-Add Group
|
||||
|
||||
# SVE integer multiply-add writing addend (predicated)
|
||||
|
|
|
@ -3193,6 +3193,68 @@ void HELPER(sve_fnmls_zpzzz_d)(CPUARMState *env, void *vg, uint32_t desc)
|
|||
do_fmla_zpzzz_d(env, vg, desc, 0, INT64_MIN);
|
||||
}
|
||||
|
||||
/* Two operand floating-point comparison controlled by a predicate.
|
||||
* Unlike the integer version, we are not allowed to optimistically
|
||||
* compare operands, since the comparison may have side effects wrt
|
||||
* the FPSR.
|
||||
*/
|
||||
#define DO_FPCMP_PPZZ(NAME, TYPE, H, OP) \
|
||||
void HELPER(NAME)(void *vd, void *vn, void *vm, void *vg, \
|
||||
void *status, uint32_t desc) \
|
||||
{ \
|
||||
intptr_t i = simd_oprsz(desc), j = (i - 1) >> 6; \
|
||||
uint64_t *d = vd, *g = vg; \
|
||||
do { \
|
||||
uint64_t out = 0, pg = g[j]; \
|
||||
do { \
|
||||
i -= sizeof(TYPE), out <<= sizeof(TYPE); \
|
||||
if (likely((pg >> (i & 63)) & 1)) { \
|
||||
TYPE nn = *(TYPE *)(vn + H(i)); \
|
||||
TYPE mm = *(TYPE *)(vm + H(i)); \
|
||||
out |= OP(TYPE, nn, mm, status); \
|
||||
} \
|
||||
} while (i & 63); \
|
||||
d[j--] = out; \
|
||||
} while (i > 0); \
|
||||
}
|
||||
|
||||
#define DO_FPCMP_PPZZ_H(NAME, OP) \
|
||||
DO_FPCMP_PPZZ(NAME##_h, float16, H1_2, OP)
|
||||
#define DO_FPCMP_PPZZ_S(NAME, OP) \
|
||||
DO_FPCMP_PPZZ(NAME##_s, float32, H1_4, OP)
|
||||
#define DO_FPCMP_PPZZ_D(NAME, OP) \
|
||||
DO_FPCMP_PPZZ(NAME##_d, float64, , OP)
|
||||
|
||||
#define DO_FPCMP_PPZZ_ALL(NAME, OP) \
|
||||
DO_FPCMP_PPZZ_H(NAME, OP) \
|
||||
DO_FPCMP_PPZZ_S(NAME, OP) \
|
||||
DO_FPCMP_PPZZ_D(NAME, OP)
|
||||
|
||||
#define DO_FCMGE(TYPE, X, Y, ST) TYPE##_compare(Y, X, ST) <= 0
|
||||
#define DO_FCMGT(TYPE, X, Y, ST) TYPE##_compare(Y, X, ST) < 0
|
||||
#define DO_FCMEQ(TYPE, X, Y, ST) TYPE##_compare_quiet(X, Y, ST) == 0
|
||||
#define DO_FCMNE(TYPE, X, Y, ST) TYPE##_compare_quiet(X, Y, ST) != 0
|
||||
#define DO_FCMUO(TYPE, X, Y, ST) \
|
||||
TYPE##_compare_quiet(X, Y, ST) == float_relation_unordered
|
||||
#define DO_FACGE(TYPE, X, Y, ST) \
|
||||
TYPE##_compare(TYPE##_abs(Y), TYPE##_abs(X), ST) <= 0
|
||||
#define DO_FACGT(TYPE, X, Y, ST) \
|
||||
TYPE##_compare(TYPE##_abs(Y), TYPE##_abs(X), ST) < 0
|
||||
|
||||
DO_FPCMP_PPZZ_ALL(sve_fcmge, DO_FCMGE)
|
||||
DO_FPCMP_PPZZ_ALL(sve_fcmgt, DO_FCMGT)
|
||||
DO_FPCMP_PPZZ_ALL(sve_fcmeq, DO_FCMEQ)
|
||||
DO_FPCMP_PPZZ_ALL(sve_fcmne, DO_FCMNE)
|
||||
DO_FPCMP_PPZZ_ALL(sve_fcmuo, DO_FCMUO)
|
||||
DO_FPCMP_PPZZ_ALL(sve_facge, DO_FACGE)
|
||||
DO_FPCMP_PPZZ_ALL(sve_facgt, DO_FACGT)
|
||||
|
||||
#undef DO_FPCMP_PPZZ_ALL
|
||||
#undef DO_FPCMP_PPZZ_D
|
||||
#undef DO_FPCMP_PPZZ_S
|
||||
#undef DO_FPCMP_PPZZ_H
|
||||
#undef DO_FPCMP_PPZZ
|
||||
|
||||
/*
|
||||
* Load contiguous data, protected by a governing predicate.
|
||||
*/
|
||||
|
|
|
@ -3533,6 +3533,46 @@ DO_FP3(FMULX, fmulx)
|
|||
|
||||
#undef DO_FP3
|
||||
|
||||
static bool do_fp_cmp(DisasContext *s, arg_rprr_esz *a,
|
||||
gen_helper_gvec_4_ptr *fn)
|
||||
{
|
||||
if (fn == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (sve_access_check(s)) {
|
||||
unsigned vsz = vec_full_reg_size(s);
|
||||
TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
|
||||
tcg_gen_gvec_4_ptr(pred_full_reg_offset(s, a->rd),
|
||||
vec_full_reg_offset(s, a->rn),
|
||||
vec_full_reg_offset(s, a->rm),
|
||||
pred_full_reg_offset(s, a->pg),
|
||||
status, vsz, vsz, 0, fn);
|
||||
tcg_temp_free_ptr(status);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#define DO_FPCMP(NAME, name) \
|
||||
static bool trans_##NAME##_ppzz(DisasContext *s, arg_rprr_esz *a, \
|
||||
uint32_t insn) \
|
||||
{ \
|
||||
static gen_helper_gvec_4_ptr * const fns[4] = { \
|
||||
NULL, gen_helper_sve_##name##_h, \
|
||||
gen_helper_sve_##name##_s, gen_helper_sve_##name##_d \
|
||||
}; \
|
||||
return do_fp_cmp(s, a, fns[a->esz]); \
|
||||
}
|
||||
|
||||
DO_FPCMP(FCMGE, fcmge)
|
||||
DO_FPCMP(FCMGT, fcmgt)
|
||||
DO_FPCMP(FCMEQ, fcmeq)
|
||||
DO_FPCMP(FCMNE, fcmne)
|
||||
DO_FPCMP(FCMUO, fcmuo)
|
||||
DO_FPCMP(FACGE, facge)
|
||||
DO_FPCMP(FACGT, facgt)
|
||||
|
||||
#undef DO_FPCMP
|
||||
|
||||
typedef void gen_helper_sve_fmla(TCGv_env, TCGv_ptr, TCGv_i32);
|
||||
|
||||
static bool do_fmla(DisasContext *s, arg_rprrr_esz *a, gen_helper_sve_fmla *fn)
|
||||
|
|
Loading…
Reference in New Issue