From aac1663d7579cb9e821d342dda9f999623d20b62 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Mon, 1 May 2023 10:24:46 +0000 Subject: [RV64_DYNAREC] Add detection of Zba, Zbb, Zbc and Zbs CPU extensions --- src/rv64detect.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/rv64detect.c (limited to 'src/rv64detect.c') diff --git a/src/rv64detect.c b/src/rv64detect.c new file mode 100644 index 00000000..5e84423b --- /dev/null +++ b/src/rv64detect.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include +#include +#include + +#include "debug.h" +#include "dynarec/rv64/rv64_emitter.h" + +// Detect RV64 extensions, by executing on of the opcode with a SIGILL signal handler + +static sigjmp_buf sigbuf = {0}; +typedef void(*vFii_t)(int, int); +static void detect_sigill(int sig) +{ + siglongjmp(sigbuf, 1); +} + +static int Check(void* block) +{ + // Clear instruction cache + __clear_cache(block, block+box64_pagesize); + // Setup SIGILL signal handler + signal(SIGILL, detect_sigill); + if(sigsetjmp(sigbuf, 1)) { + // didn't work, extension not present + signal(SIGILL, SIG_DFL); + return 0; + } + ((vFii_t)block)(0, 1); + // done... + signal(SIGILL, SIG_DFL); + return 1; +} + +void RV64_Detect_Function() +{ + // Alloc memory to execute stuffs + void* my_block = mmap(NULL, box64_pagesize, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + if(my_block==(void*)-1) { + return; + } + uint32_t* block; + #define EMIT(A) *block = (A); ++block + // Test Zba with ADDUW + block = (uint32_t*)my_block; + ADDUW(A0, A0, A1); + BR(xRA); + rv64_zba = Check(my_block); + // Test Zbb with ANDN + block = (uint32_t*)my_block; + ANDN(A0, A0, A1); + BR(xRA); + rv64_zbb = Check(my_block); + // Test Zbc with CLMUL + block = (uint32_t*)my_block; + CLMUL(A0, A0, A1); + BR(xRA); + rv64_zbc = Check(my_block); + // Test Zbs with BCLR + block = (uint32_t*)my_block; + BCLR(A0, A0, A1); + BR(xRA); + rv64_zbs = Check(my_block); + + // Finish + // Free the memory my_block + munmap(my_block, box64_pagesize); +} \ No newline at end of file -- cgit 1.4.1