From 177b76b844e5d1cf548882b7793e99aff2dff9b0 Mon Sep 17 00:00:00 2001 From: Benjamin Oldenburg Date: Sun, 15 Mar 2026 17:18:54 +0700 Subject: [PATCH] Add ARM64 Windows coverage and fix native run guard --- .github/workflows/build.yml | 27 +++++++++++++++++++ tcc.c | 4 +-- win32/test_arm64_backtrace.c | 51 +++++++++++++++++++++++++++++++++++ win32/test_arm64_inline_asm.c | 50 ++++++++++++++++++++++++++++++++++ 4 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 win32/test_arm64_backtrace.c create mode 100644 win32/test_arm64_inline_asm.c diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a59d37cf..9a9568a1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -103,6 +103,20 @@ jobs: .\tcc -B. -v .\tcc -B. ..\win32\test_arm64.c -o test_arm64.exe && .\test_arm64.exe .\tcc -B. -run ..\examples\ex1.c + .\tcc -B. ..\win32\test_arm64_inline_asm.c -o test_inline_asm.exe && .\test_inline_asm.exe > test_inline_asm.out + > test_inline_asm.expect echo inline asm ok + fc /n test_inline_asm.out test_inline_asm.expect + .\tcc -B. -DTEST_GOTO ..\win32\test_arm64_inline_asm.c -o test_inline_goto.exe && .\test_inline_goto.exe > test_inline_goto.out + > test_inline_goto.expect echo asm goto ok + fc /n test_inline_goto.out test_inline_goto.expect + .\tcc -B. -DTEST_OPERANDS ..\win32\test_arm64_inline_asm.c -c -o test_inline_operands.obj > test_inline_operands.out 2>&1 + if not errorlevel 1 exit /b 1 + type test_inline_operands.out + findstr /c:"ARM64 extended inline asm is not implemented" test_inline_operands.out + .\tcc -B. -DTEST_CLOBBERS ..\win32\test_arm64_inline_asm.c -c -o test_inline_clobbers.obj > test_inline_clobbers.out 2>&1 + if not errorlevel 1 exit /b 1 + type test_inline_clobbers.out + findstr /c:"ARM64 extended inline asm is not implemented" test_inline_clobbers.out > test_rstdin.txt echo arm64 stdin .\tcc -B. -rstdin test_rstdin.txt -run ..\win32\test_rstdin.c > test_rstdin.out type test_rstdin.out @@ -111,6 +125,19 @@ jobs: fc /n test49.out ..\tests\tests2\49_bracket_evaluation.expect .\tcc -B. ..\tests\tests2\133_old_func.c -o test133.exe && .\test133.exe > test133.out fc /n test133.out ..\tests\tests2\133_old_func.expect + .\tcc -B. -b ..\tests\tests2\115_bound_setjmp.c -o test115.exe && .\test115.exe > test115.out + for %%I in (test115.out) do if not %%~zI==0 ( type test115.out & exit /b 1 ) + .\tcc -B. -b ..\tests\tests2\116_bound_setjmp2.c -o test116.exe && .\test116.exe > test116.out + for %%I in (test116.out) do if not %%~zI==0 ( type test116.out & exit /b 1 ) + .\tcc -B. -b ..\win32\test_arm64_backtrace.c -o test_bt.exe + .\test_bt.exe > test_bt.out 2>&1 + if not errorlevel 1 exit /b 1 + type test_bt.out + findstr crash4 test_bt.out + findstr crash3 test_bt.out + findstr crash2 test_bt.out + findstr crash1 test_bt.out + findstr main test_bt.out test-armv7-linux: runs-on: ubuntu-22.04 diff --git a/tcc.c b/tcc.c index 1194d6b9..ac76976a 100644 --- a/tcc.c +++ b/tcc.c @@ -23,7 +23,7 @@ #endif #include "tcc.h" -#if defined(_WIN32) && defined(__aarch64__) +#if defined(TCC_IS_NATIVE) && defined(_WIN32) && defined(__aarch64__) # include #endif #if ONE_SOURCE @@ -288,7 +288,7 @@ static unsigned getclock_ms(void) #endif } -#if defined(_WIN32) && defined(__aarch64__) +#if defined(TCC_IS_NATIVE) && defined(_WIN32) && defined(__aarch64__) static char *tcc_append_windows_arg(char *dst, const char *arg) { const char *p = arg; diff --git a/win32/test_arm64_backtrace.c b/win32/test_arm64_backtrace.c new file mode 100644 index 00000000..de531adf --- /dev/null +++ b/win32/test_arm64_backtrace.c @@ -0,0 +1,51 @@ +#include + +static volatile int crash_value; + +__attribute__((noinline)) +static void crash4(double a0, double a1, double a2, double a3, + double a4, double a5, double a6, double a7, + int i0, int i1, int i2, int i3, + int i4, int i5, int i6, int i7) +{ + volatile char frame[8192]; + + frame[0] = (char)(a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7 + + i0 + i1 + i2 + i3 + i4 + i5 + i6 + i7); + crash_value = frame[0]; + *(volatile int *)0 = crash_value; +} + +__attribute__((noinline)) +static void crash3(void) +{ + puts("crash3"); + fflush(stdout); + crash4(1.0, 2.0, 3.0, 4.0, + 5.0, 6.0, 7.0, 8.0, + 9, 10, 11, 12, 13, 14, 15, 16); +} + +__attribute__((noinline)) +static void crash2(void) +{ + puts("crash2"); + fflush(stdout); + crash3(); +} + +__attribute__((noinline)) +static void crash1(void) +{ + puts("crash1"); + fflush(stdout); + crash2(); +} + +int main(void) +{ + puts("main"); + fflush(stdout); + crash1(); + return 0; +} diff --git a/win32/test_arm64_inline_asm.c b/win32/test_arm64_inline_asm.c new file mode 100644 index 00000000..1e95ac62 --- /dev/null +++ b/win32/test_arm64_inline_asm.c @@ -0,0 +1,50 @@ +#include + +static void plain_inline_asm(void) +{ + asm("nop"); +} + +static int inline_asm_goto(void) +{ + asm goto("b %l[target]" : : : : target); + return 1; +target: + return 0; +} + +#if defined(TEST_OPERANDS) +int main(void) +{ + int input = 1; + int output = 0; + + asm("add %w0, %w1, #1" : "=r"(output) : "r"(input)); + printf("%d\n", output); + return output != 2; +} +#elif defined(TEST_CLOBBERS) +int main(void) +{ + asm volatile("nop" : : : "x0"); + return 0; +} +#elif defined(TEST_GOTO) +int main(void) +{ + int rc = inline_asm_goto(); + + printf("%s\n", rc ? "asm goto wrong" : "asm goto ok"); + return rc; +} +#else +int main(void) +{ + int rc; + + plain_inline_asm(); + rc = inline_asm_goto(); + printf("%s\n", rc ? "inline asm wrong" : "inline asm ok"); + return rc; +} +#endif