get-register-name from width and index
This commit is contained in:
parent
d793a3251f
commit
da2a298baf
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) },
|
||||
// );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue