split current_stack_size u64 into current/max u32 to allow deallocating the top stack allocation
This commit is contained in:
parent
16bdac93ad
commit
703aa299c8
|
|
@ -271,7 +271,8 @@ stackvar_cmp:
|
||||||
;; text: Vec<u8>,
|
;; text: Vec<u8>,
|
||||||
;; }
|
;; }
|
||||||
;; struct FunctionCtx {
|
;; struct FunctionCtx {
|
||||||
;; current_stack_size: u64,
|
;; current_stack_size: u32,
|
||||||
|
;; max_stack_size: u32,
|
||||||
;; stack_vars: Vec<(u64, u64)>,
|
;; stack_vars: Vec<(u64, u64)>,
|
||||||
;; register_bitset: u16,
|
;; register_bitset: u16,
|
||||||
;; dirtied_register_bitset: u16,
|
;; dirtied_register_bitset: u16,
|
||||||
|
|
@ -326,6 +327,38 @@ codegen_allocate_register:
|
||||||
pop rbp
|
pop rbp
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
;; rdi: *FunctionCtx
|
||||||
|
;; rsi: width
|
||||||
|
;; define-fn: fn codegen_allocate_place(ctx: *mut FunctionCtx, width: u16) -> Operand
|
||||||
|
codegen_allocate_place:
|
||||||
|
push rbp
|
||||||
|
mov rbp, rsp
|
||||||
|
|
||||||
|
xor rdx, rdx
|
||||||
|
mov edx, dword [rdi + 0] ; current_stack_size
|
||||||
|
add edx, esi ; width
|
||||||
|
mov dword [rdi + 0], edx ; current_stack_size += width
|
||||||
|
|
||||||
|
mov eax, dword [rdi + 4] ; max_stack_size
|
||||||
|
cmp eax, edx
|
||||||
|
cmovb eax, edx
|
||||||
|
mov dword [rdi + 4], eax ; max_stack_size = max(max_stack_size, current_stack_size)
|
||||||
|
|
||||||
|
; construct Operand
|
||||||
|
xor rax, rax
|
||||||
|
mov eax, 0 ; Operand.len = 0
|
||||||
|
shl eax, 16
|
||||||
|
or eax, esi ; Operand.width
|
||||||
|
shl eax, 4
|
||||||
|
; or eax, 0 ; Operand.register = undef
|
||||||
|
shl eax, 8
|
||||||
|
or eax, OPERAND_RBP_OFFSET ; Operand.kind
|
||||||
|
neg rdx ; Operand.value = -current_stack_size
|
||||||
|
|
||||||
|
.done:
|
||||||
|
pop rbp
|
||||||
|
ret
|
||||||
|
|
||||||
;; rdi: *FunctionCtx
|
;; rdi: *FunctionCtx
|
||||||
;; rsi: width
|
;; rsi: width
|
||||||
;; define-fn: fn codegen_allocate_value(ctx: *mut FunctionCtx, width: u16) -> Operand
|
;; define-fn: fn codegen_allocate_value(ctx: *mut FunctionCtx, width: u16) -> Operand
|
||||||
|
|
@ -365,21 +398,7 @@ codegen_allocate_value:
|
||||||
jmp .done
|
jmp .done
|
||||||
|
|
||||||
.alloc_stack:
|
.alloc_stack:
|
||||||
mov rdi, [rsp] ; ctx
|
call codegen_allocate_place
|
||||||
mov rdx, [rdi + 0] ; current_stack_size
|
|
||||||
add rdx, [rsp + 8] ; width
|
|
||||||
mov [rdi + 0], rdx ; current_stack_size += width
|
|
||||||
|
|
||||||
; construct Operand
|
|
||||||
xor rax, rax
|
|
||||||
mov eax, 0 ; Operand.len = 0
|
|
||||||
shl eax, 16
|
|
||||||
mov rsi, [rsp + 8] ; width
|
|
||||||
or eax, esi ; Operand.width
|
|
||||||
shl eax, 4
|
|
||||||
; or eax, 0 ; Operand.register = undef
|
|
||||||
shl eax, 8
|
|
||||||
or eax, OPERAND_RBP_OFFSET ; Operand.kind
|
|
||||||
|
|
||||||
.done:
|
.done:
|
||||||
add rsp, 16
|
add rsp, 16
|
||||||
|
|
@ -407,16 +426,17 @@ codegen_free_operand:
|
||||||
jmp .done
|
jmp .done
|
||||||
|
|
||||||
.free_stack:
|
.free_stack:
|
||||||
mov rbx, [rdi + 0] ; current_stack_size
|
xor rbx, rbx
|
||||||
|
mov ebx, dword [rdi + 0] ; current_stack_size
|
||||||
mov rax, [rsi + 8] ; Operand.value
|
mov rax, [rsi + 8] ; Operand.value
|
||||||
cmp rbx, rax
|
cmp rbx, rax
|
||||||
jne .done ; operand not at top of stack, can't free
|
jne .done ; operand not at top of stack, can't free
|
||||||
|
|
||||||
mov al, byte [rsi + 1] ; Operand.width
|
mov al, byte [rsi + 1] ; Operand.width
|
||||||
shl al, 4
|
shr al, 4
|
||||||
movzx rax, al
|
movzx rax, al
|
||||||
sub rbx, rax
|
sub rbx, rax
|
||||||
mov [rdi + 0], rbx ; current_stack_size -= width
|
mov dword [rdi + 0], ebx ; current_stack_size -= width
|
||||||
jmp .done
|
jmp .done
|
||||||
|
|
||||||
.free_reg:
|
.free_reg:
|
||||||
|
|
@ -452,7 +472,8 @@ codegen_function:
|
||||||
; dirtied-register-bitset [76..80] [a,b,c,d,si,di,bp,sp,8,9,10,11,12,13,14,15]
|
; dirtied-register-bitset [76..80] [a,b,c,d,si,di,bp,sp,8,9,10,11,12,13,14,15]
|
||||||
; register-bitset [72..76] [a,b,c,d,si,di,bp,sp,8,9,10,11,12,13,14,15]
|
; register-bitset [72..76] [a,b,c,d,si,di,bp,sp,8,9,10,11,12,13,14,15]
|
||||||
; stack-vars: Vec<(index, offset)> [32..72]
|
; stack-vars: Vec<(index, offset)> [32..72]
|
||||||
; current_stack_size: [24..32]
|
; max_stack_size: [28..32]
|
||||||
|
; current_stack_size: [24..28]
|
||||||
; func_idx [16..24]
|
; func_idx [16..24]
|
||||||
; ast [8..16]
|
; ast [8..16]
|
||||||
; ctx [0..8]
|
; ctx [0..8]
|
||||||
|
|
@ -461,7 +482,7 @@ codegen_function:
|
||||||
mov rax, [rdi]
|
mov rax, [rdi]
|
||||||
mov [rsp + 8], rax ; ast
|
mov [rsp + 8], rax ; ast
|
||||||
mov [rsp + 16], rsi ; func_idx
|
mov [rsp + 16], rsi ; func_idx
|
||||||
mov qword [rsp + 24], 0 ; current_stack_size = 0
|
mov qword [rsp + 24], 0 ; current_stack_size = 0, max_stack_size = 0
|
||||||
|
|
||||||
lea rdi, [rsp + 32] ; stack-vars
|
lea rdi, [rsp + 32] ; stack-vars
|
||||||
mov rsi, 16 ; size_of::<(u64, u64)>
|
mov rsi, 16 ; size_of::<(u64, u64)>
|
||||||
|
|
@ -469,10 +490,12 @@ codegen_function:
|
||||||
mov rcx, 16 ; initial capacity
|
mov rcx, 16 ; initial capacity
|
||||||
call vec_init_with
|
call vec_init_with
|
||||||
|
|
||||||
bts word [rsp + 72], 7 ; mark rsp as used
|
bts word [rsp + 72], 7 ; mark rsp as used
|
||||||
bts word [rsp + 72], 6 ; mark rbp as used
|
bts word [rsp + 72], 6 ; mark rbp as used
|
||||||
bts word [rsp + 72], 0 ; mark rax as used
|
bts word [rsp + 72], 0 ; mark rax as used
|
||||||
mov word [rsp + 76], 0 ; dirtied_register_bitset = 0
|
mov word [rsp + 76], 0 ; dirtied_register_bitset = 0
|
||||||
|
|
||||||
|
mov word [rsp + 72], -1 ; reserve all registers (test)
|
||||||
|
|
||||||
; push "section .text\n"
|
; push "section .text\n"
|
||||||
mov rdi, [rsp] ; ctx
|
mov rdi, [rsp] ; ctx
|
||||||
|
|
@ -554,11 +577,18 @@ codegen_function:
|
||||||
lea rsi, [rax + r14 * 8] ;
|
lea rsi, [rax + r14 * 8] ;
|
||||||
mov rsi, [rsi] ; AstFunction.args[i]
|
mov rsi, [rsi] ; AstFunction.args[i]
|
||||||
|
|
||||||
mov [rsp + 104], rsi ; scratch
|
mov [rsp + 104], rsi ; &(index, _)
|
||||||
mov rax, [rsp + 24] ; current_stack_size
|
|
||||||
add rax, 8 ; size_of::<u64>
|
lea rdi, [rsp + 24] ; &function_ctx
|
||||||
mov [rsp + 24], rax ; current_stack_size += size_of::<u64>
|
; TODO: get arg type size
|
||||||
mov [rsp + 112], rax
|
mov rsi, 8 ; size_of::<u64>
|
||||||
|
call codegen_allocate_place
|
||||||
|
; rdx = stack offset
|
||||||
|
mov [rsp + 80], rax ; Operand
|
||||||
|
mov [rsp + 88], rdx ; Operand.value
|
||||||
|
neg rdx
|
||||||
|
mov [rsp + 112], rdx ; &(_, offset)
|
||||||
|
|
||||||
lea rdi, [rsp + 32] ; stack-vars
|
lea rdi, [rsp + 32] ; stack-vars
|
||||||
lea rsi, [rsp + 104] ; &scratch: &(index, offset)
|
lea rsi, [rsp + 104] ; &scratch: &(index, offset)
|
||||||
mov rdx, stackvar_cmp
|
mov rdx, stackvar_cmp
|
||||||
|
|
@ -567,17 +597,16 @@ codegen_function:
|
||||||
|
|
||||||
; spill arg from register to newly allocated stack slot
|
; spill arg from register to newly allocated stack slot
|
||||||
; get source Operand
|
; get source Operand
|
||||||
mov r13, [rsp + 112] ; current_stack_size before increment
|
mov rdi, r14 ; arg index
|
||||||
mov rdi, [rsp + 104] ; arg index
|
|
||||||
call codegen_arg_to_operand
|
call codegen_arg_to_operand
|
||||||
mov [rsp + 104], rax
|
mov [rsp + 104], rax
|
||||||
mov [rsp + 112], rdx
|
mov [rsp + 112], rdx
|
||||||
mov rdx, r13 ; offset
|
|
||||||
neg rdx
|
|
||||||
mov rdi, [rsp] ; ctx
|
mov rdi, [rsp] ; ctx
|
||||||
lea rdi, [rdi + 8] ; &ctx.text
|
lea rdi, [rdi + 8] ; &ctx.text
|
||||||
lea rsi, [rsp + 104] ; src
|
lea rsi, [rsp + 104] ; src
|
||||||
call codegen_move_rbp_slot_src
|
lea rdx, [rsp + 80] ; dst
|
||||||
|
call codegen_move_dst_src
|
||||||
|
|
||||||
inc r14
|
inc r14
|
||||||
jmp .arg_loop
|
jmp .arg_loop
|
||||||
|
|
@ -614,7 +643,7 @@ codegen_function:
|
||||||
mov rdx, 1 ; pop = true
|
mov rdx, 1 ; pop = true
|
||||||
call codegen_push_pop_dirtied_registers
|
call codegen_push_pop_dirtied_registers
|
||||||
|
|
||||||
; "add rsp, {current_stack_size}\n"
|
; "add rsp, {max_stack_size}\n"
|
||||||
mov rdi, [rsp] ; ctx
|
mov rdi, [rsp] ; ctx
|
||||||
lea rdi, [rdi + 8] ; &ctx.text
|
lea rdi, [rdi + 8] ; &ctx.text
|
||||||
lea rsi, [rel ADD_RSP]
|
lea rsi, [rel ADD_RSP]
|
||||||
|
|
@ -622,7 +651,7 @@ codegen_function:
|
||||||
call vec_extend
|
call vec_extend
|
||||||
|
|
||||||
lea rdi, [rsp + 24] ; &function_ctx
|
lea rdi, [rsp + 24] ; &function_ctx
|
||||||
mov rdi, [rdi + 0] ; current_stack_size
|
mov edi, dword [rdi + 4] ; max_stack_size
|
||||||
lea rsi, [rsp + 104] ; scratch
|
lea rsi, [rsp + 104] ; scratch
|
||||||
mov rdx, 16 ; buffer length
|
mov rdx, 16 ; buffer length
|
||||||
mov rcx, 10 ; radix
|
mov rcx, 10 ; radix
|
||||||
|
|
@ -658,7 +687,7 @@ codegen_function:
|
||||||
mov rdx, DOT_PROLOGUE_LEN
|
mov rdx, DOT_PROLOGUE_LEN
|
||||||
call vec_extend
|
call vec_extend
|
||||||
|
|
||||||
; "sub rsp, {current_stack_size}\n"
|
; "sub rsp, {max_stack_size}\n"
|
||||||
mov rdi, [rsp] ; ctx
|
mov rdi, [rsp] ; ctx
|
||||||
lea rdi, [rdi + 8] ; &ctx.text
|
lea rdi, [rdi + 8] ; &ctx.text
|
||||||
lea rsi, [rel SUB_RSP]
|
lea rsi, [rel SUB_RSP]
|
||||||
|
|
@ -666,7 +695,7 @@ codegen_function:
|
||||||
call vec_extend
|
call vec_extend
|
||||||
|
|
||||||
lea rdi, [rsp + 24] ; &function_ctx
|
lea rdi, [rsp + 24] ; &function_ctx
|
||||||
mov rdi, [rdi + 0] ; current_stack_size
|
mov edi, dword [rdi + 4] ; max_stack_size
|
||||||
lea rsi, [rsp + 104] ; scratch
|
lea rsi, [rsp + 104] ; scratch
|
||||||
mov rdx, 16 ; buffer length
|
mov rdx, 16 ; buffer length
|
||||||
mov rcx, 10 ; radix
|
mov rcx, 10 ; radix
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ unsafe extern "C" {
|
||||||
pub unsafe fn get_register_name(reg_idx: u8, width: u8, buffer: *mut u8) -> FFISlice;
|
pub unsafe fn get_register_name(reg_idx: u8, width: u8, buffer: *mut u8) -> FFISlice;
|
||||||
pub unsafe fn stackvar_cmp(a: *const (u64, u64), b: *const (u64, u64)) -> i32;
|
pub unsafe fn stackvar_cmp(a: *const (u64, u64), b: *const (u64, u64)) -> i32;
|
||||||
pub unsafe fn codegen_allocate_register(ctx: *mut FunctionCtx) -> u8;
|
pub unsafe fn codegen_allocate_register(ctx: *mut FunctionCtx) -> u8;
|
||||||
|
pub unsafe fn codegen_allocate_place(ctx: *mut FunctionCtx, width: u16) -> Operand;
|
||||||
pub unsafe fn codegen_allocate_value(ctx: *mut FunctionCtx, width: u16) -> Operand;
|
pub unsafe fn codegen_allocate_value(ctx: *mut FunctionCtx, width: u16) -> Operand;
|
||||||
pub unsafe fn codegen_free_operand(ctx: *mut FunctionCtx, operand: *const Operand) -> ();
|
pub unsafe fn codegen_free_operand(ctx: *mut FunctionCtx, operand: *const Operand) -> ();
|
||||||
pub unsafe fn codegen_function(ast: *const CodegenCtx, func_idx: u64) -> ();
|
pub unsafe fn codegen_function(ast: *const CodegenCtx, func_idx: u64) -> ();
|
||||||
|
|
@ -216,7 +217,8 @@ pub struct CodegenCtx {
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FunctionCtx {
|
pub struct FunctionCtx {
|
||||||
pub current_stack_size: u64,
|
pub current_stack_size: u32,
|
||||||
|
pub max_stack_size: u32,
|
||||||
pub stack_vars: Vec<(u64, u64)>,
|
pub stack_vars: Vec<(u64, u64)>,
|
||||||
pub register_bitset: u16,
|
pub register_bitset: u16,
|
||||||
pub dirtied_register_bitset: u16,
|
pub dirtied_register_bitset: u16,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue