mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-07 17:53:56 -06:00
target/ppc: Implemented xvf16ger*
Implement the following PowerISA v3.1 instructions: xvf16ger2: VSX Vector 16-bit Floating-Point GER (rank-2 update) xvf16ger2nn: VSX Vector 16-bit Floating-Point GER (rank-2 update) Negative multiply, Negative accumulate xvf16ger2np: VSX Vector 16-bit Floating-Point GER (rank-2 update) Negative multiply, Positive accumulate xvf16ger2pn: VSX Vector 16-bit Floating-Point GER (rank-2 update) Positive multiply, Negative accumulate xvf16ger2pp: VSX Vector 16-bit Floating-Point GER (rank-2 update) Positive multiply, Positive accumulate Signed-off-by: Lucas Mateus Castro (alqotel) <lucas.araujo@eldorado.org.br> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20220524140537.27451-6-lucas.araujo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
This commit is contained in:
parent
c29018cc73
commit
2d9cba74ef
5 changed files with 115 additions and 0 deletions
|
@ -36,6 +36,15 @@ static inline float128 float128_snan_to_qnan(float128 x)
|
|||
#define float32_snan_to_qnan(x) ((x) | 0x00400000)
|
||||
#define float16_snan_to_qnan(x) ((x) | 0x0200)
|
||||
|
||||
static inline float32 bfp32_neg(float32 a)
|
||||
{
|
||||
if (unlikely(float32_is_any_nan(a))) {
|
||||
return a;
|
||||
} else {
|
||||
return float32_chs(a);
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool fp_exceptions_enabled(CPUPPCState *env)
|
||||
{
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
|
@ -3501,6 +3510,57 @@ static inline void vsxger_excp(CPUPPCState *env, uintptr_t retaddr)
|
|||
do_fpscr_check_status(env, retaddr);
|
||||
}
|
||||
|
||||
typedef float64 extract_f16(float16, float_status *);
|
||||
|
||||
static float64 extract_hf16(float16 in, float_status *fp_status)
|
||||
{
|
||||
return float16_to_float64(in, true, fp_status);
|
||||
}
|
||||
|
||||
static void vsxger16(CPUPPCState *env, ppc_vsr_t *a, ppc_vsr_t *b,
|
||||
ppc_acc_t *at, uint32_t mask, bool acc,
|
||||
bool neg_mul, bool neg_acc, extract_f16 extract)
|
||||
{
|
||||
float32 r, aux_acc;
|
||||
float64 psum, va, vb, vc, vd;
|
||||
int i, j, xmsk_bit, ymsk_bit;
|
||||
uint8_t pmsk = FIELD_EX32(mask, GER_MSK, PMSK),
|
||||
xmsk = FIELD_EX32(mask, GER_MSK, XMSK),
|
||||
ymsk = FIELD_EX32(mask, GER_MSK, YMSK);
|
||||
float_status *excp_ptr = &env->fp_status;
|
||||
for (i = 0, xmsk_bit = 1 << 3; i < 4; i++, xmsk_bit >>= 1) {
|
||||
for (j = 0, ymsk_bit = 1 << 3; j < 4; j++, ymsk_bit >>= 1) {
|
||||
if ((xmsk_bit & xmsk) && (ymsk_bit & ymsk)) {
|
||||
va = !(pmsk & 2) ? float64_zero :
|
||||
extract(a->VsrHF(2 * i), excp_ptr);
|
||||
vb = !(pmsk & 2) ? float64_zero :
|
||||
extract(b->VsrHF(2 * j), excp_ptr);
|
||||
vc = !(pmsk & 1) ? float64_zero :
|
||||
extract(a->VsrHF(2 * i + 1), excp_ptr);
|
||||
vd = !(pmsk & 1) ? float64_zero :
|
||||
extract(b->VsrHF(2 * j + 1), excp_ptr);
|
||||
psum = float64_mul(va, vb, excp_ptr);
|
||||
psum = float64r32_muladd(vc, vd, psum, 0, excp_ptr);
|
||||
r = float64_to_float32(psum, excp_ptr);
|
||||
if (acc) {
|
||||
aux_acc = at[i].VsrSF(j);
|
||||
if (neg_mul) {
|
||||
r = bfp32_neg(r);
|
||||
}
|
||||
if (neg_acc) {
|
||||
aux_acc = bfp32_neg(aux_acc);
|
||||
}
|
||||
r = float32_add(r, aux_acc, excp_ptr);
|
||||
}
|
||||
at[i].VsrSF(j) = r;
|
||||
} else {
|
||||
at[i].VsrSF(j) = float32_zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
vsxger_excp(env, GETPC());
|
||||
}
|
||||
|
||||
typedef void vsxger_zero(ppc_vsr_t *at, int, int);
|
||||
|
||||
typedef void vsxger_muladd_f(ppc_vsr_t *, ppc_vsr_t *, ppc_vsr_t *, int, int,
|
||||
|
@ -3579,6 +3639,41 @@ static void vsxger(CPUPPCState *env, ppc_vsr_t *a, ppc_vsr_t *b,
|
|||
vsxger_excp(env, GETPC());
|
||||
}
|
||||
|
||||
QEMU_FLATTEN
|
||||
void helper_XVF16GER2(CPUPPCState *env, ppc_vsr_t *a, ppc_vsr_t *b,
|
||||
ppc_acc_t *at, uint32_t mask)
|
||||
{
|
||||
vsxger16(env, a, b, at, mask, false, false, false, extract_hf16);
|
||||
}
|
||||
|
||||
QEMU_FLATTEN
|
||||
void helper_XVF16GER2PP(CPUPPCState *env, ppc_vsr_t *a, ppc_vsr_t *b,
|
||||
ppc_acc_t *at, uint32_t mask)
|
||||
{
|
||||
vsxger16(env, a, b, at, mask, true, false, false, extract_hf16);
|
||||
}
|
||||
|
||||
QEMU_FLATTEN
|
||||
void helper_XVF16GER2PN(CPUPPCState *env, ppc_vsr_t *a, ppc_vsr_t *b,
|
||||
ppc_acc_t *at, uint32_t mask)
|
||||
{
|
||||
vsxger16(env, a, b, at, mask, true, false, true, extract_hf16);
|
||||
}
|
||||
|
||||
QEMU_FLATTEN
|
||||
void helper_XVF16GER2NP(CPUPPCState *env, ppc_vsr_t *a, ppc_vsr_t *b,
|
||||
ppc_acc_t *at, uint32_t mask)
|
||||
{
|
||||
vsxger16(env, a, b, at, mask, true, true, false, extract_hf16);
|
||||
}
|
||||
|
||||
QEMU_FLATTEN
|
||||
void helper_XVF16GER2NN(CPUPPCState *env, ppc_vsr_t *a, ppc_vsr_t *b,
|
||||
ppc_acc_t *at, uint32_t mask)
|
||||
{
|
||||
vsxger16(env, a, b, at, mask, true, true, true, extract_hf16);
|
||||
}
|
||||
|
||||
QEMU_FLATTEN
|
||||
void helper_XVF32GER(CPUPPCState *env, ppc_vsr_t *a, ppc_vsr_t *b,
|
||||
ppc_acc_t *at, uint32_t mask)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue