allocate/free operand methods

This commit is contained in:
janis 2025-11-01 16:18:01 +01:00
parent ea4611111b
commit ecb4a83153
Signed by: janis
SSH key fingerprint: SHA256:bB1qbbqmDXZNT0KKD5c2Dfjg53JGhj7B3CFcLIzSqq8

View file

@ -301,7 +301,7 @@ codegen_allocate_register:
; flip bits
not ax
test ax, ax
jz .panic
jz .no_regs
; find first set bit
bsf cx, ax
@ -313,14 +313,127 @@ codegen_allocate_register:
mov ax, word [rdi + 52] ; dirtied_register_bitset
bts ax, cx
mov word [rdi + 52], ax ; update dirtied_register_bitset
jmp .done
.no_regs:
; return -1u64 to indicate no free registers
; the caller should panic or allocate a stack slot instead
mov rbx, -1
.done:
mov rax, rbx
pop rbx
pop rbp
ret
;; rdi: *FunctionCtx
;; rsi: width
;; define-fn: fn codegen_allocate_value(ctx: *mut FunctionCtx, width: u16) -> Operand
codegen_allocate_value:
push rbp
mov rbp, rsp
push rbx
; width [8..16]
; *FunctionCtx [0..8]
sub rsp, 16
mov [rsp], rdi ; ctx
mov [rsp + 8], rsi ; width
cmp rsi, 8
jg .alloc_stack
.alloc_reg:
call codegen_allocate_register
cmp rax, -1
je .alloc_stack
mov rbx, rax
; 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, rbx ; Operand.register
shl eax, 8
or eax, OPERAND_REGISTER ; Operand.kind
mov rdx, 0 ; Operand.value = 0
jmp .done
.alloc_stack:
mov rdi, [rsp] ; ctx
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:
add rsp, 16
pop rbx
pop rbp
ret
;; rdi: *FunctionCtx
;; rsi: *Operand
;; define-fn: fn codegen_free_operand(ctx: *mut FunctionCtx, operand: *const Operand) -> ()
codegen_free_operand:
push rbp
mov rbp, rsp
push rbx
sub rsp, 16
mov [rsp], rdi ; ctx
mov [rsp + 8], rsi ; operand
mov al, byte [rsi] ; Operand.kind
cmp al, OPERAND_REGISTER
je .free_reg
cmp al, OPERAND_RBP_OFFSET
je .free_stack
jmp .done
.free_stack:
mov rbx, [rdi + 0] ; current_stack_size
mov rax, [rsi + 8] ; Operand.value
cmp rbx, rax
jne .done ; operand not at top of stack, can't free
mov al, byte [rsi + 1] ; Operand.width
shl al, 4
movzx rax, al
sub rbx, rax
mov [rdi + 0], rbx ; current_stack_size -= width
jmp .done
.free_reg:
xor rax, rax
mov al, byte [rsi + 1] ; Operand.register_and_width
and al, 0x0F ; get register index
mov bx, word [rdi + 48] ; register_bitset
btr bx, ax
jnc .panic ; trying to free unallocated register
mov word [rdi + 48], bx ; update register_bitset
.done:
add rsp, 16
pop rbx
pop rbp
ret
.panic:
; no free registers!
call panic
;; rdi: *Ctx