linux-user/sparc: Add more hwcap bits for sparc64

Supply HWCAP_SPARC_V8PLUS, HWCAP_SPARC_MUL32, HWCAP_SPARC_DIV32,
HWCAP_SPARC_POPC, HWCAP_SPARC_FSMULD, HWCAP_SPARC_VIS, HWCAP_SPARC_VIS2.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20240502165528.244004-2-richard.henderson@linaro.org>
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
This commit is contained in:
Richard Henderson 2024-05-02 09:55:22 -07:00 committed by Mark Cave-Ayland
parent 7c420a4d7c
commit 1cde1a2a89

View File

@ -968,24 +968,44 @@ const char *elf_hwcap2_str(uint32_t bit)
#endif /* TARGET_ARM */
#ifdef TARGET_SPARC
#ifdef TARGET_SPARC64
#define ELF_HWCAP (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | HWCAP_SPARC_SWAP \
| HWCAP_SPARC_MULDIV | HWCAP_SPARC_V9)
#ifndef TARGET_ABI32
#define elf_check_arch(x) ( (x) == EM_SPARCV9 || (x) == EM_SPARC32PLUS )
#ifndef TARGET_SPARC64
# define ELF_CLASS ELFCLASS32
# define ELF_ARCH EM_SPARC
#elif defined(TARGET_ABI32)
# define ELF_CLASS ELFCLASS32
# define elf_check_arch(x) ((x) == EM_SPARC32PLUS || (x) == EM_SPARC)
#else
#define elf_check_arch(x) ( (x) == EM_SPARC32PLUS || (x) == EM_SPARC )
# define ELF_CLASS ELFCLASS64
# define ELF_ARCH EM_SPARCV9
#endif
#define ELF_CLASS ELFCLASS64
#define ELF_ARCH EM_SPARCV9
#else
#define ELF_HWCAP (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | HWCAP_SPARC_SWAP \
| HWCAP_SPARC_MULDIV)
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_SPARC
#endif /* TARGET_SPARC64 */
#include "elf.h"
#define ELF_HWCAP get_elf_hwcap()
static uint32_t get_elf_hwcap(void)
{
/* There are not many sparc32 hwcap bits -- we have all of them. */
uint32_t r = HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR |
HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV;
#ifdef TARGET_SPARC64
CPUSPARCState *env = cpu_env(thread_cpu);
uint32_t features = env->def.features;
r |= HWCAP_SPARC_V9 | HWCAP_SPARC_V8PLUS;
/* 32x32 multiply and divide are efficient. */
r |= HWCAP_SPARC_MUL32 | HWCAP_SPARC_DIV32;
/* We don't have an internal feature bit for this. */
r |= HWCAP_SPARC_POPC;
r |= features & CPU_FEATURE_FSMULD ? HWCAP_SPARC_FSMULD : 0;
r |= features & CPU_FEATURE_VIS1 ? HWCAP_SPARC_VIS : 0;
r |= features & CPU_FEATURE_VIS2 ? HWCAP_SPARC_VIS2 : 0;
#endif
return r;
}
static inline void init_thread(struct target_pt_regs *regs,
struct image_info *infop)