mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-02-05 22:33:37 +00:00
checkasm/riscv: report an error upon SIGILL
Terminating the whole checkasm process is not very helpful. This will report if an illegal instruction occurs while executing a tested function. This is a common occurrence whilst developping RISC-V assembler, due to the compatibility between vector configuration and instruction done at run-time.
This commit is contained in:
parent
286d674221
commit
7212466e73
@ -27,6 +27,7 @@
|
||||
# define _GNU_SOURCE // for syscall (performance monitoring API), strsignal()
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -734,6 +735,14 @@ int main(int argc, char *argv[])
|
||||
if (have_vfp(av_get_cpu_flags()) || have_neon(av_get_cpu_flags()))
|
||||
checkasm_checked_call = checkasm_checked_call_vfp;
|
||||
#endif
|
||||
#if ARCH_RISCV
|
||||
struct sigaction act = {
|
||||
.sa_handler = checkasm_handle_signal,
|
||||
.sa_flags = 0,
|
||||
};
|
||||
|
||||
sigaction(SIGILL, &act, NULL);
|
||||
#endif
|
||||
|
||||
if (!tests[0].func || !cpus[0].flag) {
|
||||
fprintf(stderr, "checkasm: no tests to perform\n");
|
||||
|
@ -23,6 +23,7 @@
|
||||
#ifndef TESTS_CHECKASM_CHECKASM_H
|
||||
#define TESTS_CHECKASM_CHECKASM_H
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <stdint.h>
|
||||
#include "config.h"
|
||||
|
||||
@ -211,14 +212,20 @@ void checkasm_checked_call(void *func, ...);
|
||||
checked_call(func_new, 0, 0, 0, 0, 0, 0, 0, __VA_ARGS__,\
|
||||
7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0))
|
||||
#elif ARCH_RISCV
|
||||
void checkasm_set_function(void *);
|
||||
void checkasm_set_function(void *, sigjmp_buf);
|
||||
void *checkasm_get_wrapper(void);
|
||||
void checkasm_handle_signal(int signum);
|
||||
|
||||
#if (__riscv_xlen == 64) && defined (__riscv_d)
|
||||
#define declare_new(ret, ...) \
|
||||
int checked_call_signum = 0; \
|
||||
sigjmp_buf checked_call_jb; \
|
||||
ret (*checked_call)(__VA_ARGS__) = checkasm_get_wrapper();
|
||||
#define call_new(...) \
|
||||
(checkasm_set_function(func_new), checked_call(__VA_ARGS__))
|
||||
(checkasm_set_function(func_new, checked_call_jb), \
|
||||
(checked_call_signum = sigsetjmp(checked_call_jb, 1)) == 0 \
|
||||
? checked_call(__VA_ARGS__) \
|
||||
: (checkasm_fail_signal(checked_call_signum), 0))
|
||||
#endif
|
||||
#else
|
||||
#define declare_new(ret, ...)
|
||||
|
@ -41,6 +41,7 @@ endconst
|
||||
|
||||
checked_func:
|
||||
.quad 0
|
||||
.quad 0
|
||||
|
||||
saved_regs:
|
||||
/* Space to spill RA, SP, GP, TP, S0-S11 and FS0-FS11 */
|
||||
@ -52,6 +53,7 @@ func checkasm_set_function
|
||||
la.tls.ie t0, checked_func
|
||||
add t0, tp, t0
|
||||
sd a0, (t0)
|
||||
sd a1, 8(t0)
|
||||
ret
|
||||
endfunc
|
||||
|
||||
@ -175,4 +177,14 @@ func checkasm_get_wrapper, v
|
||||
call checkasm_fail_func
|
||||
j 4b
|
||||
endfunc
|
||||
|
||||
func checkasm_handle_signal
|
||||
mv a1, a0
|
||||
la.tls.ie a0, checked_func
|
||||
add a0, tp, a0
|
||||
ld a0, 8(a0)
|
||||
beqz a0, 8f
|
||||
tail siglongjmp
|
||||
8: tail abort /* No jump buffer to go to */
|
||||
endfunc
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user