Re: [PATCH 02/11] tcg/riscv: Probe for Zba, Zbb, Zicond extensions
On Wed, May 3, 2023 at 6:59 PM Richard Henderson wrote: > > Define a useful subset of the extensions. Probe for them > via compiler pre-processor feature macros and SIGILL. > > Signed-off-by: Richard Henderson Acked-by: Alistair Francis Alistair > --- > tcg/riscv/tcg-target.h | 6 +++ > tcg/riscv/tcg-target.c.inc | 96 ++ > 2 files changed, 102 insertions(+) > > diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h > index 494c986b49..863ac8ba2f 100644 > --- a/tcg/riscv/tcg-target.h > +++ b/tcg/riscv/tcg-target.h > @@ -90,6 +90,12 @@ typedef enum { > #define TCG_TARGET_CALL_ARG_I128TCG_CALL_ARG_NORMAL > #define TCG_TARGET_CALL_RET_I128TCG_CALL_RET_NORMAL > > +#if defined(__riscv_arch_test) && defined(__riscv_zbb) > +# define have_zbb true > +#else > +extern bool have_zbb; > +#endif > + > /* optional instructions */ > #define TCG_TARGET_HAS_movcond_i32 0 > #define TCG_TARGET_HAS_div_i32 1 > diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc > index 4dd33c73e8..49ff9c8b9d 100644 > --- a/tcg/riscv/tcg-target.c.inc > +++ b/tcg/riscv/tcg-target.c.inc > @@ -113,6 +113,20 @@ static const int tcg_target_call_iarg_regs[] = { > TCG_REG_A7, > }; > > +#ifndef have_zbb > +bool have_zbb; > +#endif > +#if defined(__riscv_arch_test) && defined(__riscv_zba) > +# define have_zba true > +#else > +static bool have_zba; > +#endif > +#if defined(__riscv_arch_test) && defined(__riscv_zicond) > +# define have_zicond true > +#else > +static bool have_zicond; > +#endif > + > static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot) > { > tcg_debug_assert(kind == TCG_CALL_RET_NORMAL); > @@ -234,6 +248,34 @@ typedef enum { > > OPC_FENCE = 0x000f, > OPC_NOP = OPC_ADDI, /* nop = addi r0,r0,0 */ > + > +/* Zba: Bit manipulation extension, address generation */ > +OPC_ADD_UW = 0x083b, > + > +/* Zbb: Bit manipulation extension, basic bit manipulaton */ > +OPC_ANDN = 0x40007033, > +OPC_CLZ= 0x60001013, > +OPC_CLZW = 0x6000101b, > +OPC_CPOP = 0x60201013, > +OPC_CPOPW = 0x6020101b, > +OPC_CTZ= 0x60101013, > +OPC_CTZW = 0x6010101b, > +OPC_ORN= 0x40006033, > +OPC_REV8 = 0x6b805013, > +OPC_ROL= 0x60001033, > +OPC_ROLW = 0x6000103b, > +OPC_ROR= 0x60005033, > +OPC_RORW = 0x6000503b, > +OPC_RORI = 0x60005013, > +OPC_RORIW = 0x6000501b, > +OPC_SEXT_B = 0x60401013, > +OPC_SEXT_H = 0x60501013, > +OPC_XNOR = 0x40004033, > +OPC_ZEXT_H = 0x0800403b, > + > +/* Zicond: integer conditional operations */ > +OPC_CZERO_EQZ = 0x0e005033, > +OPC_CZERO_NEZ = 0x0e007033, > } RISCVInsn; > > /* > @@ -1612,8 +1654,62 @@ static void tcg_target_qemu_prologue(TCGContext *s) > tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, TCG_REG_RA, 0); > } > > +static volatile sig_atomic_t got_sigill; > + > +static void sigill_handler(int signo, siginfo_t *si, void *data) > +{ > +/* Skip the faulty instruction */ > +ucontext_t *uc = (ucontext_t *)data; > +uc->uc_mcontext.__gregs[REG_PC] += 4; > + > +got_sigill = 1; > +} > + > +static void tcg_target_detect_isa(void) > +{ > +#if !defined(have_zba) || !defined(have_zbb) || !defined(have_zicond) > +/* > + * TODO: It is expected that this will be determinable via > + * linux riscv_hwprobe syscall, not yet merged. > + * In the meantime, test via sigill. > + */ > + > +struct sigaction sa_old, sa_new; > + > +memset(&sa_new, 0, sizeof(sa_new)); > +sa_new.sa_flags = SA_SIGINFO; > +sa_new.sa_sigaction = sigill_handler; > +sigaction(SIGILL, &sa_new, &sa_old); > + > +#ifndef have_zba > +/* Probe for Zba: add.uw zero,zero,zero. */ > +got_sigill = 0; > +asm volatile(".insn %0" : : "i"(OPC_ADD_UW) : "memory"); > +have_zba = !got_sigill; > +#endif > + > +#ifndef have_zbb > +/* Probe for Zba: andn zero,zero,zero. */ > +got_sigill = 0; > +asm volatile(".insn %0" : : "i"(OPC_ANDN) : "memory"); > +have_zbb = !got_sigill; > +#endif > + > +#ifndef have_zicond > +/* Probe for Zicond: czero.eqz zero,zero,zero. */ > +got_sigill = 0; > +asm volatile(".insn %0" : : "i"(OPC_CZERO_EQZ) : "memory"); > +have_zicond = !got_sigill; > +#endif > + > +sigaction(SIGILL, &sa_old, NULL); > +#endif > +} > + > static void tcg_target_init(TCGContext *s) > { > +tcg_target_detect_isa(); > + > tcg_target_available_regs[TCG_TYPE_I32] = 0x; > tcg_target_available_regs[TCG_TYPE_I64] = 0x; > > -- > 2.34.1 > >
Re: [PATCH 02/11] tcg/riscv: Probe for Zba, Zbb, Zicond extensions
On 5/3/23 05:56, Richard Henderson wrote: Define a useful subset of the extensions. Probe for them via compiler pre-processor feature macros and SIGILL. Signed-off-by: Richard Henderson --- Reviewed-by: Daniel Henrique Barboza tcg/riscv/tcg-target.h | 6 +++ tcg/riscv/tcg-target.c.inc | 96 ++ 2 files changed, 102 insertions(+) diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h index 494c986b49..863ac8ba2f 100644 --- a/tcg/riscv/tcg-target.h +++ b/tcg/riscv/tcg-target.h @@ -90,6 +90,12 @@ typedef enum { #define TCG_TARGET_CALL_ARG_I128TCG_CALL_ARG_NORMAL #define TCG_TARGET_CALL_RET_I128TCG_CALL_RET_NORMAL +#if defined(__riscv_arch_test) && defined(__riscv_zbb) +# define have_zbb true +#else +extern bool have_zbb; +#endif + /* optional instructions */ #define TCG_TARGET_HAS_movcond_i32 0 #define TCG_TARGET_HAS_div_i32 1 diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc index 4dd33c73e8..49ff9c8b9d 100644 --- a/tcg/riscv/tcg-target.c.inc +++ b/tcg/riscv/tcg-target.c.inc @@ -113,6 +113,20 @@ static const int tcg_target_call_iarg_regs[] = { TCG_REG_A7, }; +#ifndef have_zbb +bool have_zbb; +#endif +#if defined(__riscv_arch_test) && defined(__riscv_zba) +# define have_zba true +#else +static bool have_zba; +#endif +#if defined(__riscv_arch_test) && defined(__riscv_zicond) +# define have_zicond true +#else +static bool have_zicond; +#endif + static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot) { tcg_debug_assert(kind == TCG_CALL_RET_NORMAL); @@ -234,6 +248,34 @@ typedef enum { OPC_FENCE = 0x000f, OPC_NOP = OPC_ADDI, /* nop = addi r0,r0,0 */ + +/* Zba: Bit manipulation extension, address generation */ +OPC_ADD_UW = 0x083b, + +/* Zbb: Bit manipulation extension, basic bit manipulaton */ +OPC_ANDN = 0x40007033, +OPC_CLZ= 0x60001013, +OPC_CLZW = 0x6000101b, +OPC_CPOP = 0x60201013, +OPC_CPOPW = 0x6020101b, +OPC_CTZ= 0x60101013, +OPC_CTZW = 0x6010101b, +OPC_ORN= 0x40006033, +OPC_REV8 = 0x6b805013, +OPC_ROL= 0x60001033, +OPC_ROLW = 0x6000103b, +OPC_ROR= 0x60005033, +OPC_RORW = 0x6000503b, +OPC_RORI = 0x60005013, +OPC_RORIW = 0x6000501b, +OPC_SEXT_B = 0x60401013, +OPC_SEXT_H = 0x60501013, +OPC_XNOR = 0x40004033, +OPC_ZEXT_H = 0x0800403b, + +/* Zicond: integer conditional operations */ +OPC_CZERO_EQZ = 0x0e005033, +OPC_CZERO_NEZ = 0x0e007033, } RISCVInsn; /* @@ -1612,8 +1654,62 @@ static void tcg_target_qemu_prologue(TCGContext *s) tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, TCG_REG_RA, 0); } +static volatile sig_atomic_t got_sigill; + +static void sigill_handler(int signo, siginfo_t *si, void *data) +{ +/* Skip the faulty instruction */ +ucontext_t *uc = (ucontext_t *)data; +uc->uc_mcontext.__gregs[REG_PC] += 4; + +got_sigill = 1; +} + +static void tcg_target_detect_isa(void) +{ +#if !defined(have_zba) || !defined(have_zbb) || !defined(have_zicond) +/* + * TODO: It is expected that this will be determinable via + * linux riscv_hwprobe syscall, not yet merged. + * In the meantime, test via sigill. + */ + +struct sigaction sa_old, sa_new; + +memset(&sa_new, 0, sizeof(sa_new)); +sa_new.sa_flags = SA_SIGINFO; +sa_new.sa_sigaction = sigill_handler; +sigaction(SIGILL, &sa_new, &sa_old); + +#ifndef have_zba +/* Probe for Zba: add.uw zero,zero,zero. */ +got_sigill = 0; +asm volatile(".insn %0" : : "i"(OPC_ADD_UW) : "memory"); +have_zba = !got_sigill; +#endif + +#ifndef have_zbb +/* Probe for Zba: andn zero,zero,zero. */ +got_sigill = 0; +asm volatile(".insn %0" : : "i"(OPC_ANDN) : "memory"); +have_zbb = !got_sigill; +#endif + +#ifndef have_zicond +/* Probe for Zicond: czero.eqz zero,zero,zero. */ +got_sigill = 0; +asm volatile(".insn %0" : : "i"(OPC_CZERO_EQZ) : "memory"); +have_zicond = !got_sigill; +#endif + +sigaction(SIGILL, &sa_old, NULL); +#endif +} + static void tcg_target_init(TCGContext *s) { +tcg_target_detect_isa(); + tcg_target_available_regs[TCG_TYPE_I32] = 0x; tcg_target_available_regs[TCG_TYPE_I64] = 0x;
[PATCH 02/11] tcg/riscv: Probe for Zba, Zbb, Zicond extensions
Define a useful subset of the extensions. Probe for them via compiler pre-processor feature macros and SIGILL. Signed-off-by: Richard Henderson --- tcg/riscv/tcg-target.h | 6 +++ tcg/riscv/tcg-target.c.inc | 96 ++ 2 files changed, 102 insertions(+) diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h index 494c986b49..863ac8ba2f 100644 --- a/tcg/riscv/tcg-target.h +++ b/tcg/riscv/tcg-target.h @@ -90,6 +90,12 @@ typedef enum { #define TCG_TARGET_CALL_ARG_I128TCG_CALL_ARG_NORMAL #define TCG_TARGET_CALL_RET_I128TCG_CALL_RET_NORMAL +#if defined(__riscv_arch_test) && defined(__riscv_zbb) +# define have_zbb true +#else +extern bool have_zbb; +#endif + /* optional instructions */ #define TCG_TARGET_HAS_movcond_i32 0 #define TCG_TARGET_HAS_div_i32 1 diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc index 4dd33c73e8..49ff9c8b9d 100644 --- a/tcg/riscv/tcg-target.c.inc +++ b/tcg/riscv/tcg-target.c.inc @@ -113,6 +113,20 @@ static const int tcg_target_call_iarg_regs[] = { TCG_REG_A7, }; +#ifndef have_zbb +bool have_zbb; +#endif +#if defined(__riscv_arch_test) && defined(__riscv_zba) +# define have_zba true +#else +static bool have_zba; +#endif +#if defined(__riscv_arch_test) && defined(__riscv_zicond) +# define have_zicond true +#else +static bool have_zicond; +#endif + static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot) { tcg_debug_assert(kind == TCG_CALL_RET_NORMAL); @@ -234,6 +248,34 @@ typedef enum { OPC_FENCE = 0x000f, OPC_NOP = OPC_ADDI, /* nop = addi r0,r0,0 */ + +/* Zba: Bit manipulation extension, address generation */ +OPC_ADD_UW = 0x083b, + +/* Zbb: Bit manipulation extension, basic bit manipulaton */ +OPC_ANDN = 0x40007033, +OPC_CLZ= 0x60001013, +OPC_CLZW = 0x6000101b, +OPC_CPOP = 0x60201013, +OPC_CPOPW = 0x6020101b, +OPC_CTZ= 0x60101013, +OPC_CTZW = 0x6010101b, +OPC_ORN= 0x40006033, +OPC_REV8 = 0x6b805013, +OPC_ROL= 0x60001033, +OPC_ROLW = 0x6000103b, +OPC_ROR= 0x60005033, +OPC_RORW = 0x6000503b, +OPC_RORI = 0x60005013, +OPC_RORIW = 0x6000501b, +OPC_SEXT_B = 0x60401013, +OPC_SEXT_H = 0x60501013, +OPC_XNOR = 0x40004033, +OPC_ZEXT_H = 0x0800403b, + +/* Zicond: integer conditional operations */ +OPC_CZERO_EQZ = 0x0e005033, +OPC_CZERO_NEZ = 0x0e007033, } RISCVInsn; /* @@ -1612,8 +1654,62 @@ static void tcg_target_qemu_prologue(TCGContext *s) tcg_out_opc_imm(s, OPC_JALR, TCG_REG_ZERO, TCG_REG_RA, 0); } +static volatile sig_atomic_t got_sigill; + +static void sigill_handler(int signo, siginfo_t *si, void *data) +{ +/* Skip the faulty instruction */ +ucontext_t *uc = (ucontext_t *)data; +uc->uc_mcontext.__gregs[REG_PC] += 4; + +got_sigill = 1; +} + +static void tcg_target_detect_isa(void) +{ +#if !defined(have_zba) || !defined(have_zbb) || !defined(have_zicond) +/* + * TODO: It is expected that this will be determinable via + * linux riscv_hwprobe syscall, not yet merged. + * In the meantime, test via sigill. + */ + +struct sigaction sa_old, sa_new; + +memset(&sa_new, 0, sizeof(sa_new)); +sa_new.sa_flags = SA_SIGINFO; +sa_new.sa_sigaction = sigill_handler; +sigaction(SIGILL, &sa_new, &sa_old); + +#ifndef have_zba +/* Probe for Zba: add.uw zero,zero,zero. */ +got_sigill = 0; +asm volatile(".insn %0" : : "i"(OPC_ADD_UW) : "memory"); +have_zba = !got_sigill; +#endif + +#ifndef have_zbb +/* Probe for Zba: andn zero,zero,zero. */ +got_sigill = 0; +asm volatile(".insn %0" : : "i"(OPC_ANDN) : "memory"); +have_zbb = !got_sigill; +#endif + +#ifndef have_zicond +/* Probe for Zicond: czero.eqz zero,zero,zero. */ +got_sigill = 0; +asm volatile(".insn %0" : : "i"(OPC_CZERO_EQZ) : "memory"); +have_zicond = !got_sigill; +#endif + +sigaction(SIGILL, &sa_old, NULL); +#endif +} + static void tcg_target_init(TCGContext *s) { +tcg_target_detect_isa(); + tcg_target_available_regs[TCG_TYPE_I32] = 0x; tcg_target_available_regs[TCG_TYPE_I64] = 0x; -- 2.34.1