diff options
Diffstat (limited to 'linux-user')
-rw-r--r-- | linux-user/elfload.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/linux-user/elfload.c b/linux-user/elfload.c index a57b7049dd..5451d262ec 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1308,6 +1308,34 @@ static inline void init_thread(struct target_pt_regs *regs, #define ELF_DATA ELFDATA2MSB #define ELF_ARCH EM_S390 +#include "elf.h" + +#define ELF_HWCAP get_elf_hwcap() + +#define GET_FEATURE(_feat, _hwcap) \ + do { if (s390_has_feat(_feat)) { hwcap |= _hwcap; } } while (0) + +static uint32_t get_elf_hwcap(void) +{ + /* + * Let's assume we always have esan3 and zarch. + * 31-bit processes can use 64-bit registers (high gprs). + */ + uint32_t hwcap = HWCAP_S390_ESAN3 | HWCAP_S390_ZARCH | HWCAP_S390_HIGH_GPRS; + + GET_FEATURE(S390_FEAT_STFLE, HWCAP_S390_STFLE); + GET_FEATURE(S390_FEAT_MSA, HWCAP_S390_MSA); + GET_FEATURE(S390_FEAT_LONG_DISPLACEMENT, HWCAP_S390_LDISP); + GET_FEATURE(S390_FEAT_EXTENDED_IMMEDIATE, HWCAP_S390_EIMM); + if (s390_has_feat(S390_FEAT_EXTENDED_TRANSLATION_3) && + s390_has_feat(S390_FEAT_ETF3_ENH)) { + hwcap |= HWCAP_S390_ETF3EH; + } + GET_FEATURE(S390_FEAT_VECTOR, HWCAP_S390_VXRS); + + return hwcap; +} + static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) { regs->psw.addr = infop->entry; |