diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2025-05-20 15:24:09 +0800 |
|---|---|---|
| committer | Yang Liu <liuyang22@iscas.ac.cn> | 2025-05-20 15:24:09 +0800 |
| commit | 5b8a71d720bb8a4be2a9a67f8c6d1392a48f6e36 (patch) | |
| tree | 7f1dcf02668dc988929bc8f8b4955a7f89c725c0 /src | |
| parent | 58021bbf42c3e5a5b1eddba0e5d649b1d91a8189 (diff) | |
| download | box64-5b8a71d720bb8a4be2a9a67f8c6d1392a48f6e36.tar.gz box64-5b8a71d720bb8a4be2a9a67f8c6d1392a48f6e36.zip | |
[RV64] Improved vendor extension detection to avoid conflicts (for #2645)
Diffstat (limited to 'src')
| -rw-r--r-- | src/rv64detect.c | 88 |
1 files changed, 51 insertions, 37 deletions
diff --git a/src/rv64detect.c b/src/rv64detect.c index ec41b482..8ef0ad82 100644 --- a/src/rv64detect.c +++ b/src/rv64detect.c @@ -11,7 +11,7 @@ // Detect RV64 extensions, by executing on of the opcode with a SIGILL signal handler static sigjmp_buf sigbuf = {0}; -typedef void(*vFiip_t)(int, int, void*); +typedef int (*iFiip_t)(int, int, void*); static void detect_sigill(int sig) { siglongjmp(sigbuf, 1); @@ -29,7 +29,12 @@ static int Check(void* block) signal(SIGILL, old); return 0; } - ((vFiip_t)block)(0, 1, buf); + int result = ((iFiip_t)block)(0, 1, buf); + if (result != 42) { + // wrong result, extension not present + signal(SIGILL, old); + return 0; + } // done... signal(SIGILL, old); return 1; @@ -45,37 +50,62 @@ void RV64_Detect_Function() uint32_t* block; #define EMIT(A) *block = (A); ++block - // Official extensions - // 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 + // THead vendor extensions block = (uint32_t*)my_block; - BCLR(A0, A0, A1); + ADDI(A0, xZR, 40); + ADDI(A1, xZR, 1); + TH_ADDSL(A0, A0, A1, 1); BR(xRA); - rv64_zbs = Check(my_block); + rv64_xtheadba + = rv64_xtheadbb + = rv64_xtheadbs + = rv64_xtheadcondmov + = rv64_xtheadmemidx + = rv64_xtheadmempair + = rv64_xtheadfmemidx + = rv64_xtheadmac + = rv64_xtheadfmv = Check(my_block); + + // Official extensions + + if (!rv64_xtheadba) { + // Test Zba with ADDUW + block = (uint32_t*)my_block; + ADDUW(A0, A0, A1); + ADDI(A0, xZR, 42); + BR(xRA); + rv64_zba = Check(my_block); + // Test Zbb with ANDN + block = (uint32_t*)my_block; + ANDN(A0, A0, A1); + ADDI(A0, xZR, 42); + BR(xRA); + rv64_zbb = Check(my_block); + // Test Zbc with CLMUL + block = (uint32_t*)my_block; + CLMUL(A0, A0, A1); + ADDI(A0, xZR, 42); + BR(xRA); + rv64_zbc = Check(my_block); + // Test Zbs with BCLR + block = (uint32_t*)my_block; + BCLR(A0, A0, A1); + ADDI(A0, xZR, 42); + BR(xRA); + rv64_zbs = Check(my_block); + } block = (uint32_t*)my_block; CSRRS(xZR, xZR, 0xc22 /* vlenb */); + ADDI(A0, xZR, 42); BR(xRA); rv64_vector = Check(my_block); if (rv64_vector) { block = (uint32_t*)my_block; CSRRS(xZR, xZR, 0x00f /* vcsr */); // vcsr does not exists in xtheadvector + ADDI(A0, xZR, 42); BR(xRA); rv64_xtheadvector = !Check(my_block); } @@ -90,22 +120,6 @@ void RV64_Detect_Function() } } - // THead vendor extensions - if (!rv64_zba) { - block = (uint32_t*)my_block; - TH_ADDSL(A0, A0, A1, 1); - BR(xRA); - rv64_xtheadba - = rv64_xtheadbb - = rv64_xtheadbs - = rv64_xtheadcondmov - = rv64_xtheadmemidx - = rv64_xtheadmempair - = rv64_xtheadfmemidx - = rv64_xtheadmac - = rv64_xtheadfmv = Check(my_block); - } - // Finish // Free the memory my_block munmap(my_block, box64_pagesize); |