From 264229a0d426bfb8ea10430ae86d210a851439cc Mon Sep 17 00:00:00 2001 From: kbkpbot Date: Wed, 19 Nov 2025 17:14:22 +0800 Subject: [PATCH] Add arm64 alloca() support. --- lib/Makefile | 2 +- lib/alloca.S | 78 ++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 70 insertions(+), 10 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index 26d23d3a..9c3b9a34 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -38,7 +38,7 @@ XFLAGS += -I$(TOP) I386_O = libtcc1.o alloca.o alloca-bt.o $(COMMON_O) X86_64_O = libtcc1.o alloca.o alloca-bt.o $(COMMON_O) ARM_O = libtcc1.o armeabi.o alloca.o armflush.o $(COMMON_O) -ARM64_O = lib-arm64.o $(COMMON_O) +ARM64_O = lib-arm64.o alloca.o $(COMMON_O) RISCV64_O = lib-arm64.o $(COMMON_O) COMMON_O = stdatomic.o atomic.o builtin.o WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o diff --git a/lib/alloca.S b/lib/alloca.S index f77a0cca..43dabd64 100644 --- a/lib/alloca.S +++ b/lib/alloca.S @@ -70,16 +70,76 @@ p3: /* ---------------------------------------------- */ #elif defined __arm__ - .text - .align 2 - .global alloca - .type alloca, %function + .text + .align + .global alloca + .type alloca, %function alloca: - rsb sp, r0, sp - bic sp, sp, #7 - mov r0, sp - mov pc, lr - .size alloca, .-alloca + rsb sp, r0, sp + bic sp, sp, #7 + mov r0, sp + mov pc, lr + .size alloca, .-alloca /* ---------------------------------------------- */ +#elif defined __aarch64__ || defined __arm64__ + + .text + .align 2 + .global alloca + .type alloca, %function +alloca: +#ifdef __TINYC__ + .int 0x91003c00 + .int 0x927cec00 +#ifdef _WIN32 + .int 0xb4000160 + .int 0xd2820001 + .int 0xeb01001f + .int 0x540000c3 + .int 0xcb2163e2 + .int 0xf940005f + .int 0xcb2163ff + .int 0xcb010000 + .int 0x17fffffa +#endif + .int 0xb4000040 + .int 0xcb2063ff + .int 0x910003e0 + .int 0xd65f03c0 +#else + add x0, x0, #15 // Round up to 16-byte boundary + and x0, x0, #-16 // Ensure 16-byte alignment + cbz x0, p100 // If size is 0, skip to return +#ifdef _WIN32 + // Windows requires page-wise allocation with stack probing + mov x1, #4096 // Page size = 4096 bytes + +p101: + cmp x0, x1 // Compare remaining size with page size + b.lo p102 // If less than page, jump to remainder + + // Probe first, then allocate + sub x2, sp, x1 // Calculate guard page address (sp - 4096) + ldr xzr, [x2] // Touch guard page FIRST + sub sp, sp, x1 // THEN allocate the page + + sub x0, x0, x1 // Decrement remaining size + b p101 // Continue loop + +p102: + // Allocate remaining bytes (less than one page) + cbz x0, p100 // If no remaining bytes, skip + sub sp, sp, x0 // Allocate remaining space +#else + // Non-Windows: simple one-time allocation + sub sp, sp, x0 // Allocate space on stack +#endif + +p100: + mov x0, sp // Return allocated address + ret // Return to caller +#endif + .size alloca, .-alloca +/* ---------------------------------------------- */ #endif