/* ---------------------------------------------- *//* alloca-bt.S */ #ifdef __leading_underscore# define _(s) _##s#else# define _(s) s#endif /* ---------------------------------------------- */#if defined __i386__ .globl _(__bound_alloca)_(__bound_alloca): pop %edx pop %eax mov %eax, %ecx test %eax,%eax jz p6 add $3 + 1,%eax and $-4,%eax #ifdef _WIN32p4: cmp $4096,%eax jb p5 test %eax,-4096(%esp) sub $4096,%esp sub $4096,%eax jmp p4 p5:#endif sub %eax,%esp mov %esp,%eax push %edx push %eax push %ecx push %eax call _(__bound_new_region) add $8, %esp pop %eax pop %edx p6: push %edx push %edx ret /* ---------------------------------------------- */#elif defined __x86_64__ .globl _(__bound_alloca)_(__bound_alloca):#ifdef _WIN32 inc %rcx # add one extra to separate regions jmp _(alloca).globl _(__bound_alloca_nr)_(__bound_alloca_nr): dec %rcx push %rax mov %rcx,%rdx mov %rax,%rcx sub $32,%rsp call _(__bound_new_region) add $32,%rsp pop %rax ret#else pop %rdx mov %rdi,%rax and %eax,%eax jz p3 mov %rax,%rsi # size, a second parm to the __bound_new_region add $15 + 1,%rax # add one extra to separate regions and $-16,%rax sub %rax,%rsp mov %rsp,%rdi # pointer, a first parm to the __bound_new_region mov %rsp,%rax push %rdx push %rax call _(__bound_new_region) pop %rax pop %rdx p3: push %rdx ret#endif /* ---------------------------------------------- */#elif defined __arm__ .globl _(__bound_alloca)_(__bound_alloca): mov r1, r0 add r0, r0, #1 rsb sp, r0, sp bic sp, sp, #7 mov r0, sp push { lr } bl _(__bound_new_region) pop { lr } mov r0, sp mov pc, lr /* ---------------------------------------------- */#elif defined __aarch64__ || defined __arm64__ .globl _(__bound_alloca)_(__bound_alloca):#ifdef __TINYC__ .int 0xaa0003e1 .int 0x91004000 .int 0x927cec00#ifdef _WIN32 .int 0xb4000160 .int 0xd2820002 .int 0xeb02001f .int 0x540000c3 .int 0xcb2263e3 .int 0xf940007f .int 0xcb2263ff .int 0xcb020000 .int 0x17fffffa .int 0xb4000040#endif .int 0xcb2063ff .int 0x910003e0 .int 0xa9bf7bfd .reloc ., R_AARCH64_CALL26, _(__bound_new_region) .int 0x94000000 .int 0xa8c17bfd .int 0x910003e0 .int 0xd65f03c0#else mov x1, x0 add x0, x0, #16 // Round up to 16-byte boundary and x0, x0, #-16 // Ensure 16-byte alignment#ifdef _WIN32 cbz x0, p100 // If size is 0, skip to return // Windows requires page-wise allocation with stack probing mov x2, #4096 // Page size = 4096 bytes p101: cmp x0, x2 // Compare remaining size with page size b.lo p102 // If less than page, jump to remainder // Probe first, then allocate sub x3, sp, x2 // Calculate guard page address (sp - 4096) ldr xzr, [x3] // Touch guard page FIRST sub sp, sp, x2 // THEN allocate the page sub x0, x0, x2 // 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 stp x29, x30, [sp, #-16]! bl _(__bound_new_region) ldp x29, x30, [sp], #16 mov x0, sp // Return allocated address ret // Return to caller#endif /* ---------------------------------------------- */#elif defined __riscv .globl _(__bound_alloca)_(__bound_alloca): mv a1, a0 sub sp, sp, a0 addi sp, sp, -16 andi sp, sp, -16 add a0, sp, zero addi sp,sp,-16 sd s0,0(sp) sd ra,8(sp) jal _(__bound_new_region) ld s0,0(sp) ld ra,8(sp) addi sp,sp,16 add a0, sp, zero ret /* ---------------------------------------------- */#endif
/* ---------------------------------------------- */
/* alloca-bt.S */
#ifdef __leading_underscore
# define _(s) _##s
#else
# define _(s) s
#endif
/* ---------------------------------------------- */
#if defined __i386__
.globl _(__bound_alloca)
_(__bound_alloca):
pop %edx
pop %eax
mov %eax, %ecx
test %eax,%eax
jz p6
add $3 + 1,%eax
and $-4,%eax
#ifdef _WIN32
p4:
cmp $4096,%eax
jb p5
test %eax,-4096(%esp)
sub $4096,%esp
sub $4096,%eax
jmp p4
p5:
#endif
sub %eax,%esp
mov %esp,%eax
push %edx
push %eax
push %ecx
push %eax
call _(__bound_new_region)
add $8, %esp
pop %eax
pop %edx
p6:
push %edx
push %edx
ret
/* ---------------------------------------------- */
#elif defined __x86_64__
.globl _(__bound_alloca)
_(__bound_alloca):
#ifdef _WIN32
inc %rcx # add one extra to separate regions
jmp _(alloca)
.globl _(__bound_alloca_nr)
_(__bound_alloca_nr):
dec %rcx
push %rax
mov %rcx,%rdx
mov %rax,%rcx
sub $32,%rsp
call _(__bound_new_region)
add $32,%rsp
pop %rax
ret
#else
pop %rdx
mov %rdi,%rax
and %eax,%eax
jz p3
mov %rax,%rsi # size, a second parm to the __bound_new_region
add $15 + 1,%rax # add one extra to separate regions
and $-16,%rax
sub %rax,%rsp
mov %rsp,%rdi # pointer, a first parm to the __bound_new_region
mov %rsp,%rax
push %rdx
push %rax
call _(__bound_new_region)
pop %rax
pop %rdx
p3:
push %rdx
ret
#endif
/* ---------------------------------------------- */
#elif defined __arm__
.globl _(__bound_alloca)
_(__bound_alloca):
mov r1, r0
add r0, r0, #1
rsb sp, r0, sp
bic sp, sp, #7
mov r0, sp
push { lr }
bl _(__bound_new_region)
pop { lr }
mov r0, sp
mov pc, lr
/* ---------------------------------------------- */
#elif defined __aarch64__ || defined __arm64__
.globl _(__bound_alloca)
_(__bound_alloca):
#ifdef __TINYC__
.int 0xaa0003e1
.int 0x91004000
.int 0x927cec00
#ifdef _WIN32
.int 0xb4000160
.int 0xd2820002
.int 0xeb02001f
.int 0x540000c3
.int 0xcb2263e3
.int 0xf940007f
.int 0xcb2263ff
.int 0xcb020000
.int 0x17fffffa
.int 0xb4000040
#endif
.int 0xcb2063ff
.int 0x910003e0
.int 0xa9bf7bfd
.reloc ., R_AARCH64_CALL26, _(__bound_new_region)
.int 0x94000000
.int 0xa8c17bfd
.int 0x910003e0
.int 0xd65f03c0
#else
mov x1, x0
add x0, x0, #16 // Round up to 16-byte boundary
and x0, x0, #-16 // Ensure 16-byte alignment
#ifdef _WIN32
cbz x0, p100 // If size is 0, skip to return
// Windows requires page-wise allocation with stack probing
mov x2, #4096 // Page size = 4096 bytes
p101:
cmp x0, x2 // Compare remaining size with page size
b.lo p102 // If less than page, jump to remainder
// Probe first, then allocate
sub x3, sp, x2 // Calculate guard page address (sp - 4096)
ldr xzr, [x3] // Touch guard page FIRST
sub sp, sp, x2 // THEN allocate the page
sub x0, x0, x2 // 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
stp x29, x30, [sp, #-16]!
bl _(__bound_new_region)
ldp x29, x30, [sp], #16
mov x0, sp // Return allocated address
ret // Return to caller
#endif
/* ---------------------------------------------- */
#elif defined __riscv
.globl _(__bound_alloca)
_(__bound_alloca):
mv a1, a0
sub sp, sp, a0
addi sp, sp, -16
andi sp, sp, -16
add a0, sp, zero
addi sp,sp,-16
sd s0,0(sp)
sd ra,8(sp)
jal _(__bound_new_region)
ld s0,0(sp)
ld ra,8(sp)
addi sp,sp,16
add a0, sp, zero
ret
/* ---------------------------------------------- */
#endif