target/arm: Handle FPCR.AH in SVE FTSSEL
The negation step in the SVE FTSSEL insn mustn't negate a NaN when FPCR.AH is set. Pass FPCR.AH to the helper via the SIMD data field and use that to determine whether to do the negation. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
51330e5848
commit
6dcd51ccf6
@ -2555,6 +2555,7 @@ void HELPER(sve_fexpa_d)(void *vd, void *vn, uint32_t desc)
|
|||||||
void HELPER(sve_ftssel_h)(void *vd, void *vn, void *vm, uint32_t desc)
|
void HELPER(sve_ftssel_h)(void *vd, void *vn, void *vm, uint32_t desc)
|
||||||
{
|
{
|
||||||
intptr_t i, opr_sz = simd_oprsz(desc) / 2;
|
intptr_t i, opr_sz = simd_oprsz(desc) / 2;
|
||||||
|
bool fpcr_ah = extract32(desc, SIMD_DATA_SHIFT, 1);
|
||||||
uint16_t *d = vd, *n = vn, *m = vm;
|
uint16_t *d = vd, *n = vn, *m = vm;
|
||||||
for (i = 0; i < opr_sz; i += 1) {
|
for (i = 0; i < opr_sz; i += 1) {
|
||||||
uint16_t nn = n[i];
|
uint16_t nn = n[i];
|
||||||
@ -2562,13 +2563,17 @@ void HELPER(sve_ftssel_h)(void *vd, void *vn, void *vm, uint32_t desc)
|
|||||||
if (mm & 1) {
|
if (mm & 1) {
|
||||||
nn = float16_one;
|
nn = float16_one;
|
||||||
}
|
}
|
||||||
d[i] = nn ^ (mm & 2) << 14;
|
if (mm & 2) {
|
||||||
|
nn = float16_maybe_ah_chs(nn, fpcr_ah);
|
||||||
|
}
|
||||||
|
d[i] = nn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HELPER(sve_ftssel_s)(void *vd, void *vn, void *vm, uint32_t desc)
|
void HELPER(sve_ftssel_s)(void *vd, void *vn, void *vm, uint32_t desc)
|
||||||
{
|
{
|
||||||
intptr_t i, opr_sz = simd_oprsz(desc) / 4;
|
intptr_t i, opr_sz = simd_oprsz(desc) / 4;
|
||||||
|
bool fpcr_ah = extract32(desc, SIMD_DATA_SHIFT, 1);
|
||||||
uint32_t *d = vd, *n = vn, *m = vm;
|
uint32_t *d = vd, *n = vn, *m = vm;
|
||||||
for (i = 0; i < opr_sz; i += 1) {
|
for (i = 0; i < opr_sz; i += 1) {
|
||||||
uint32_t nn = n[i];
|
uint32_t nn = n[i];
|
||||||
@ -2576,13 +2581,17 @@ void HELPER(sve_ftssel_s)(void *vd, void *vn, void *vm, uint32_t desc)
|
|||||||
if (mm & 1) {
|
if (mm & 1) {
|
||||||
nn = float32_one;
|
nn = float32_one;
|
||||||
}
|
}
|
||||||
d[i] = nn ^ (mm & 2) << 30;
|
if (mm & 2) {
|
||||||
|
nn = float32_maybe_ah_chs(nn, fpcr_ah);
|
||||||
|
}
|
||||||
|
d[i] = nn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HELPER(sve_ftssel_d)(void *vd, void *vn, void *vm, uint32_t desc)
|
void HELPER(sve_ftssel_d)(void *vd, void *vn, void *vm, uint32_t desc)
|
||||||
{
|
{
|
||||||
intptr_t i, opr_sz = simd_oprsz(desc) / 8;
|
intptr_t i, opr_sz = simd_oprsz(desc) / 8;
|
||||||
|
bool fpcr_ah = extract32(desc, SIMD_DATA_SHIFT, 1);
|
||||||
uint64_t *d = vd, *n = vn, *m = vm;
|
uint64_t *d = vd, *n = vn, *m = vm;
|
||||||
for (i = 0; i < opr_sz; i += 1) {
|
for (i = 0; i < opr_sz; i += 1) {
|
||||||
uint64_t nn = n[i];
|
uint64_t nn = n[i];
|
||||||
@ -2590,7 +2599,10 @@ void HELPER(sve_ftssel_d)(void *vd, void *vn, void *vm, uint32_t desc)
|
|||||||
if (mm & 1) {
|
if (mm & 1) {
|
||||||
nn = float64_one;
|
nn = float64_one;
|
||||||
}
|
}
|
||||||
d[i] = nn ^ (mm & 2) << 62;
|
if (mm & 2) {
|
||||||
|
nn = float64_maybe_ah_chs(nn, fpcr_ah);
|
||||||
|
}
|
||||||
|
d[i] = nn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1238,14 +1238,14 @@ static gen_helper_gvec_2 * const fexpa_fns[4] = {
|
|||||||
gen_helper_sve_fexpa_s, gen_helper_sve_fexpa_d,
|
gen_helper_sve_fexpa_s, gen_helper_sve_fexpa_d,
|
||||||
};
|
};
|
||||||
TRANS_FEAT_NONSTREAMING(FEXPA, aa64_sve, gen_gvec_ool_zz,
|
TRANS_FEAT_NONSTREAMING(FEXPA, aa64_sve, gen_gvec_ool_zz,
|
||||||
fexpa_fns[a->esz], a->rd, a->rn, 0)
|
fexpa_fns[a->esz], a->rd, a->rn, s->fpcr_ah)
|
||||||
|
|
||||||
static gen_helper_gvec_3 * const ftssel_fns[4] = {
|
static gen_helper_gvec_3 * const ftssel_fns[4] = {
|
||||||
NULL, gen_helper_sve_ftssel_h,
|
NULL, gen_helper_sve_ftssel_h,
|
||||||
gen_helper_sve_ftssel_s, gen_helper_sve_ftssel_d,
|
gen_helper_sve_ftssel_s, gen_helper_sve_ftssel_d,
|
||||||
};
|
};
|
||||||
TRANS_FEAT_NONSTREAMING(FTSSEL, aa64_sve, gen_gvec_ool_arg_zzz,
|
TRANS_FEAT_NONSTREAMING(FTSSEL, aa64_sve, gen_gvec_ool_arg_zzz,
|
||||||
ftssel_fns[a->esz], a, 0)
|
ftssel_fns[a->esz], a, s->fpcr_ah)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*** SVE Predicate Logical Operations Group
|
*** SVE Predicate Logical Operations Group
|
||||||
|
Loading…
x
Reference in New Issue
Block a user