From d083aef69020460e1d88999ec96bb2f6a81bdad4 Mon Sep 17 00:00:00 2001 From: Ruize Tang <1466040111@qq.com> Date: Wed, 25 Jun 2025 06:34:43 +0000 Subject: [PATCH] Add a simple test for checking FPU state in signal --- test/src/apps/scripts/process.sh | 1 + test/src/apps/signal_c/signal_fpu.c | 92 +++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 test/src/apps/signal_c/signal_fpu.c diff --git a/test/src/apps/scripts/process.sh b/test/src/apps/scripts/process.sh index 669a7a5d1..a090ea8b8 100755 --- a/test/src/apps/scripts/process.sh +++ b/test/src/apps/scripts/process.sh @@ -43,6 +43,7 @@ sched/sched_attr sched/sched_attr_idle shm/posix_shm signal_c/parent_death_signal +signal_c/signal_fpu signal_c/signal_test signal_c/signal_test2 " diff --git a/test/src/apps/signal_c/signal_fpu.c b/test/src/apps/signal_c/signal_fpu.c new file mode 100644 index 000000000..e512b3108 --- /dev/null +++ b/test/src/apps/signal_c/signal_fpu.c @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: MPL-2.0 + +#include +#include +#include +#include +#include +#include +#include + +volatile bool ok = true; + +void set_xmm8(uint64_t xmm8_low, uint64_t xmm8_high) +{ + // Create a buffer to hold 128 bits (16 bytes) + uint8_t xmm8_buffer[16] = { + (uint8_t)(xmm8_low), (uint8_t)(xmm8_low >> 8), + (uint8_t)(xmm8_low >> 16), (uint8_t)(xmm8_low >> 24), + (uint8_t)(xmm8_low >> 32), (uint8_t)(xmm8_low >> 40), + (uint8_t)(xmm8_low >> 48), (uint8_t)(xmm8_low >> 56), + (uint8_t)(xmm8_high), (uint8_t)(xmm8_high >> 8), + (uint8_t)(xmm8_high >> 16), (uint8_t)(xmm8_high >> 24), + (uint8_t)(xmm8_high >> 32), (uint8_t)(xmm8_high >> 40), + (uint8_t)(xmm8_high >> 48), (uint8_t)(xmm8_high >> 56) + }; + + // Load xmm8 with the 128-bit value from xmm8_buffer + asm volatile( + "movdqu %0, %%xmm8" // Load xmm8 with the value in xmm8_buffer + : + : "m"(xmm8_buffer) // Input: xmm8_buffer + ); +} + +void print_assert_xmm8(const char *prompt, uint64_t expected_xmm8_low, + uint64_t expected_xmm8_high) +{ + // Read xmm8 in the signal handler (128 bits into a buffer) + uint8_t xmm8_buffer[16]; // 128 bits + asm volatile( + "movdqu %%xmm8, %0" // Move the entire xmm8 register to memory + : "=m"(xmm8_buffer) // Output the value to xmm8_buffer + ); + + uint64_t xmm8_low, xmm8_high; + // Now extract the low and high 64-bits from the buffer + xmm8_low = *(uint64_t *)&xmm8_buffer[0]; // First 64 bits (low part) + xmm8_high = *(uint64_t *)&xmm8_buffer[8]; // Second 64 bits (high part) + + // Output xmm8 value (NOTE: dprintf might destroy xmm8, it can be only used once!) + dprintf(STDOUT_FILENO, "%s: xmm8 = 0x%016lx%016lx\n", prompt, xmm8_high, + xmm8_low); + + // Assert + if (expected_xmm8_low != xmm8_low || expected_xmm8_high != xmm8_high) { + ok = false; + } +} + +// Signal handler +void signal_handler(int signum) +{ + print_assert_xmm8("In signal", 0, 0); + set_xmm8(0x1234567890abcdef, 0xabcdef1234567890); +} + +int main() +{ + uint64_t xmm8_low = 0xcafebabecafebabe; + uint64_t xmm8_high = 0xdeadbeefdeadbeef; + + // Install signal handler + signal(SIGUSR1, signal_handler); + + // Load xmm8 with the values + set_xmm8(xmm8_low, xmm8_high); + + // Trigger the signal handler + kill(getpid(), SIGUSR1); + + // After the signal handler returns, read and output xmm8 value again + print_assert_xmm8("After signal", xmm8_low, xmm8_high); + + // Check result + if (ok) { + dprintf(STDOUT_FILENO, "All tests passed\n"); + return 0; + } else { + dprintf(STDOUT_FILENO, "ERROR: test failed!\n"); + exit(EXIT_FAILURE); + } +}