allocate/free operand methods
This commit is contained in:
parent
ea4611111b
commit
ecb4a83153
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue