get-register-name from width and index

This commit is contained in:
janis 2025-10-31 17:14:20 +01:00
parent d793a3251f
commit da2a298baf
Signed by: janis
SSH key fingerprint: SHA256:bB1qbbqmDXZNT0KKD5c2Dfjg53JGhj7B3CFcLIzSqq8
3 changed files with 224 additions and 19 deletions

View file

@ -5,9 +5,11 @@ default rel
extern panic
extern vec_extend
extern vec_get
extern vec_push
extern vec_init_with
global codegen_function
global get_register_name
section .rdata
SECTION_TEXT db "section .text", 10
@ -20,10 +22,132 @@ section .rdata
RET_NL_LEN equ $ - RET_NL
PROLOGUE db "push rbp", 10, "mov rbp, rsp", 10
PROLOGUE_LEN equ $ - PROLOGUE
EPILOGUE db "mov rsp, rbp", 10, "pop rbp", 10, "ret", 10
EPILOGUE_LEN equ $ - EPILOGUE
REGISTER_NAMES db "abcdsidibpspr8r9r10r11r12r13r14r15"
WIDTHS db "erxliwdbp"
section .text
;; ```rust
;; use super::FFISlice;
;; ```
;; rdi: register index
;; rsi: register width (1=byte,2=word,4=dword,8=qword)
;; rdx: *mut u8 (buffer, at least 4 bytes)
;; define-fn: fn get_register_name(reg_idx: u8, width: u8, buffer: *mut u8) -> FFISlice
get_register_name:
push rbp
mov rbp, rsp
push rdx
push rdi
cmp rdi, 8
jge .skip_prefix
mov rcx, 0
cmp rsi, 8
mov rax, 'r'
cmove rcx, rax
cmp rsi, 4
mov rax, 'e'
cmove rcx, rax
cmp cl, 0
je .skip_prefix
mov byte [rdx], cl
inc rdx
.skip_prefix:
push rsi
call write_register_name
pop rsi
mov rdi, [rsp]
cmp rdi, 4
jge .check81
cmp rsi, 2
jl .check81
mov byte [rdx], 'x'
inc rdx
jmp .done
.check81:
cmp rdi, 8
jge .ext_suffix
cmp rsi, 1
jne .done
mov byte [rdx], 'l'
inc rdx
jmp .done
.ext_suffix:
mov rcx, 0
cmp rsi, 4
mov rax, 'd'
cmove rcx, rax
cmp rsi, 2
mov rax, 'w'
cmove rcx, rax
cmp rsi, 1
mov rax, 'b'
cmove rcx, rax
cmp rcx, 0
je .done
mov byte [rdx], cl
inc rdx
.done:
pop rdi
pop rax
xchg rax, rdx
sub rax, rdx
xchg rax, rdx
pop rbp
ret
.panic:
call panic
;; rdi: register index
;; rdx: *mut u8 (buffer, at least 2 bytes)
write_register_name:
cmp rdi, 4
jl .abcd
cmp rdi, 10
jl .two_digit
; 10,11,12,13,14,15
lea rsi, [rel REGISTER_NAMES + 16]
sub rdi, 10
lea rsi, [rsi + rdi * 2]
add rsi, rdi
mov al, [rsi + 0]
mov [rdx], al
inc rdx
mov al, [rsi + 1]
mov [rdx], al
inc rdx
mov al, [rsi + 2]
mov [rdx], al
inc rdx
jmp .done
.two_digit:
lea rsi, [rel REGISTER_NAMES + 4]
sub rdi, 4
lea rsi, [rsi + rdi * 2]
mov al, [rsi + 0]
mov [rdx], al
inc rdx
mov al, [rsi + 1]
mov [rdx], al
inc rdx
jmp .done
.abcd:
lea rsi, [rel REGISTER_NAMES + 0]
lea rsi, [rsi + rdi * 1]
mov al, [rsi + 0]
mov [rdx], al
inc rdx
.done:
ret
;; rdi: ctx
;; rsi: a: *const (index, offset)
;; rdx: b: *const (index, offset)
@ -63,19 +187,22 @@ codegen_function:
push rbp
mov rbp, rsp
push rbx
push r15
push r14
; register-bitset [72..88] [a,b,c,d,di,si,sp,bp,8,9,10,11,12,13,14,15]
; scratch [88..104]
; register-bitset [72..88] [a,b,c,d,si,di,bp,sp,8,9,10,11,12,13,14,15]
; stack-vars: Vec<(index, offset)> [32..72]
; current_stack_size: [24..32]
; func_idx [16..24]
; ast [8..16]
; ctx [0..8]
sub rsp, 88
sub rsp, 104
mov [rsp], rdi ; ctx
mov rax, [rdi]
mov [rsp + 8], rax ; ast
mov [rsp + 16], rsi ; func_idx
mov [rsp + 24], 0 ; current_stack_size = 0
mov qword [rsp + 24], 0 ; current_stack_size = 0
lea rdi, [rsp + 32] ; stack-vars
mov rsi, 16 ; size_of::<(u64, u64)>
@ -83,8 +210,8 @@ codegen_function:
mov rcx, 16 ; initial capacity
call vec_init_with
bts qword [rsp + 72], 7 ; mark rbp as used
bts qword [rsp + 72], 6 ; mark rsp as used
bts qword [rsp + 72], 7 ; mark rsp as used
bts qword [rsp + 72], 6 ; mark rbp as used
; push "section .text\n"
mov rdi, [rsp] ; ctx
@ -139,6 +266,36 @@ codegen_function:
mov rdx, PROLOGUE_LEN
call vec_extend
; allocate args on stack
; rbx = *AstFunction
mov r15, [rbx + 24] ; AstFunction.args_len
xor r14, r14 ; arg index
.arg_loop:
cmp r14, r15
jge .arg_loop_done
mov rax, [rbx + 16] ; AstFunction.args
lea rsi, [rax + r14 * 8] ;
mov rsi, [rsi] ; AstFunction.args[i]
mov [rsp + 88], rsi
mov rax, [rsp + 24] ; current_stack_size
mov [rsp + 96], rax
add rax, 8 ; size_of::<u64>
mov [rsp + 24], rax ; current_stack_size += size_of::<u64>
lea rdi, [rsp + 32] ; stack-vars
lea rsi, [rsp + 88] ; &(index, offset)
call vec_push
inc r14
jmp .arg_loop
.arg_loop_done:
mov rdi, [rsp] ; ctx
lea rsi, [rsp + 24] ; &function_ctx
call codegen_block
; TODO: generate function body
; push "ret\n"
@ -148,10 +305,17 @@ codegen_function:
mov rdx, RET_NL_LEN
call vec_extend
add rsp, 88
add rsp, 104
pop r15
pop r14
pop rbx
pop rbp
ret
.panic:
call panic
;; rdi: ctx
;; rsi: &function_ctx
codegen_block:
ret

View file

@ -19,8 +19,45 @@ fn main() {
bump_init();
}
println!("Bump allocator initialized.");
let src = b"3 + 4";
unsafe {
let mut buf = [0u8; 4];
assert_eq!(
util::defs::get_register_name(0, 4, buf.as_mut_ptr()).as_str(),
"eax"
);
assert_eq!(
util::defs::get_register_name(7, 8, buf.as_mut_ptr()).as_str(),
"rsp"
);
assert_eq!(
util::defs::get_register_name(7, 4, buf.as_mut_ptr()).as_str(),
"esp"
);
assert_eq!(
util::defs::get_register_name(7, 2, buf.as_mut_ptr()).as_str(),
"sp"
);
assert_eq!(
util::defs::get_register_name(7, 1, buf.as_mut_ptr()).as_str(),
"spl"
);
assert_eq!(
util::defs::get_register_name(9, 1, buf.as_mut_ptr()).as_str(),
"r9b"
);
assert_eq!(
util::defs::get_register_name(12, 1, buf.as_mut_ptr()).as_str(),
"r12b"
);
assert_eq!(
util::defs::get_register_name(12, 4, buf.as_mut_ptr()).as_str(),
"r12d"
);
assert_eq!(
util::defs::get_register_name(8, 2, buf.as_mut_ptr()).as_str(),
"r8w"
);
}
fn print_ast(src: &[u8], parser: impl FnOnce(&mut Ast) -> u64) {
unsafe {
@ -51,15 +88,15 @@ fn main() {
};
}
print_ast(
b"fn main(a: u32) -> void {
let y: u32 = a + 4;
{
let y: u32 = 10;
}
let y: *u32 = &y;
return *y;
}",
|ast| unsafe { parse_func(ast) },
);
// print_ast(
// b"fn main(a: u32) -> void {
// let y: u32 = a + 4;
// {
// let y: u32 = 10;
// }
// let y: *u32 = &y;
// return *y;
// }",
// |ast| unsafe { parse_func(ast) },
// );
}

View file

@ -17,6 +17,8 @@ unsafe extern "C" {
pub unsafe fn ast_build_symtable(ast: *mut Ast, root_index: u64, symtable: *mut core::mem::MaybeUninit<SymbolTable>);
pub unsafe fn ast_walk_for_each(ast: *mut Ast, start_index: u64, ctx: *mut (), for_each: unsafe extern "C" fn(ctx: *mut (), *mut Ast, node_index: u64, scope: u64));
pub unsafe fn ast_resolve_var_refs(ast: *mut Ast, ctx: *mut SymbolTable, root_index: u64);
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 codegen_function(ast: *const CodegenCtx, func_idx: u64) -> ();
pub unsafe fn vec_extend(vec: *mut BlobVec, elements: *const u8, count: usize) -> ();
}
@ -210,3 +212,5 @@ pub struct BlobVec {
}
use super::vec::Vec;
use super::FFISlice;