many small fixes
This commit is contained in:
parent
e43424b780
commit
a25dcdabbb
|
|
@ -7,7 +7,9 @@ extern vec_extend
|
|||
extern vec_get
|
||||
extern vec_push
|
||||
extern vec_insert_sorted
|
||||
extern vec_insert_many
|
||||
extern vec_init_with
|
||||
extern int_to_str2
|
||||
|
||||
global codegen_function
|
||||
global get_register_name
|
||||
|
|
@ -29,9 +31,27 @@ section .rdata
|
|||
MOV_RAX_LEN equ $ - MOV_RAX
|
||||
JMP_EPILOGUE db 10, "jmp .epilogue", 10
|
||||
JMP_EPILOGUE_LEN equ $ - JMP_EPILOGUE
|
||||
DOT_ARGS db ".args:", 10
|
||||
DOT_ARGS_LEN equ $ - DOT_ARGS
|
||||
DOT_BODY db ".body:", 10
|
||||
DOT_BODY_LEN equ $ - DOT_BODY
|
||||
DOT_PROLOGUE db ".prologue:", 10
|
||||
DOT_PROLOGUE_LEN equ $ - DOT_PROLOGUE
|
||||
DOT_EPILOGUE db ".epilogue:", 10
|
||||
DOT_EPILOGUE_LEN equ $ - DOT_EPILOGUE
|
||||
JMP_ARGS db 10, "jmp .args", 10
|
||||
JMP_ARGS_LEN equ $ - JMP_ARGS
|
||||
JMP_BODY db 10, "jmp .body", 10
|
||||
JMP_BODY_LEN equ $ - JMP_BODY
|
||||
JMP_PROLOGUE db 10, "jmp .prologue", 10
|
||||
JMP_PROLOGUE_LEN equ $ - JMP_PROLOGUE
|
||||
SUB_RSP db "sub rsp, "
|
||||
SUB_RSP_LEN equ $ - SUB_RSP
|
||||
ADD_RSP db "add rsp, "
|
||||
ADD_RSP_LEN equ $ - ADD_RSP
|
||||
|
||||
|
||||
REGISTER_NAMES db "abcdsidibpspr8r9r10r11r12r13r14r15"
|
||||
WIDTHS db "erxliwdbp"
|
||||
|
||||
section .text
|
||||
|
||||
|
|
@ -153,6 +173,73 @@ write_register_name:
|
|||
ret
|
||||
|
||||
|
||||
;; rdi: arg index
|
||||
;; Returns the `Operand` for the given argument index
|
||||
codegen_arg_to_operand:
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
|
||||
cmp rdi, 6
|
||||
jge .stack_arg
|
||||
|
||||
; register args in sysV make this strange movement through the canonical register indices:
|
||||
; 3 2 1 0 4 5
|
||||
; [a,b,c,d,si,di,bp,sp,8,9,10,11,12,13,14,15]
|
||||
; at least there's 6 register args and not 4 line on win64..
|
||||
|
||||
cmp rdi, 2
|
||||
jge .rdx
|
||||
mov rax, 5
|
||||
sub rax, rdi
|
||||
jmp .reg_arg
|
||||
|
||||
.rdx:
|
||||
cmp rdi, 4
|
||||
jge .r8
|
||||
mov rax, 5
|
||||
sub rax, rdi
|
||||
jmp .reg_arg
|
||||
|
||||
.r8:
|
||||
add rdi, 4 ; offset to r8
|
||||
mov rax, rdi
|
||||
|
||||
.reg_arg:
|
||||
mov rdi, rax
|
||||
|
||||
xor rax, rax
|
||||
mov eax, 0 ; Operand.len = 0
|
||||
shl eax, 16
|
||||
or eax, 8 ; Operand.width = 8
|
||||
shl eax, 4
|
||||
or eax, edi ; Operand.register
|
||||
shl eax, 8
|
||||
or eax, OPERAND_REGISTER ; Operand.kind
|
||||
mov rdx, 0 ; Operand.value = 0
|
||||
jmp .epilogue
|
||||
|
||||
.stack_arg:
|
||||
sub rdi, 6
|
||||
mov rax, 8
|
||||
mul rdi
|
||||
add rax, 16 ; return address + old rbp
|
||||
|
||||
; construct Operand
|
||||
mov rdx, rax ; Operand.value = offset
|
||||
|
||||
xor rax, rax
|
||||
mov eax, 0 ; Operand.len = 0
|
||||
shl eax, 16
|
||||
or eax, 8 ; Operand.width = 8
|
||||
shl eax, 4
|
||||
; or eax, 0 ; Operand.register = undef
|
||||
shl eax, 8
|
||||
or eax, OPERAND_RBP_OFFSET ; Operand.kind
|
||||
|
||||
.epilogue:
|
||||
pop rbp
|
||||
ret
|
||||
|
||||
;; rdi: ctx
|
||||
;; rsi: a: *const (index, offset)
|
||||
;; rdx: b: *const (index, offset)
|
||||
|
|
@ -259,6 +346,7 @@ codegen_function:
|
|||
push rbx
|
||||
push r15
|
||||
push r14
|
||||
push r13
|
||||
|
||||
; scratch [104..120]
|
||||
; dirtied-register-bitset [88..104] [a,b,c,d,si,di,bp,sp,8,9,10,11,12,13,14,15]
|
||||
|
|
@ -340,6 +428,21 @@ codegen_function:
|
|||
; allocate args on stack
|
||||
; rbx = *AstFunction
|
||||
|
||||
|
||||
; "jmp .prologue\n"
|
||||
mov rdi, [rsp] ; ctx
|
||||
lea rdi, [rdi + 8] ; &ctx.text
|
||||
lea rsi, [rel JMP_PROLOGUE]
|
||||
mov rdx, JMP_PROLOGUE_LEN
|
||||
call vec_extend
|
||||
|
||||
; ".args:\n"
|
||||
mov rdi, [rsp] ; ctx
|
||||
lea rdi, [rdi + 8] ; &ctx.text
|
||||
lea rsi, [rel DOT_ARGS]
|
||||
mov rdx, DOT_ARGS_LEN
|
||||
call vec_extend
|
||||
|
||||
mov r15, [rbx + 24] ; AstFunction.args_len
|
||||
xor r14, r14 ; arg index
|
||||
.arg_loop:
|
||||
|
|
@ -359,28 +462,126 @@ codegen_function:
|
|||
mov rdx, stackvar_cmp
|
||||
mov rcx, 0
|
||||
call vec_insert_sorted
|
||||
|
||||
; spill arg from register to newly allocated stack slot
|
||||
; get source Operand
|
||||
mov r13, [rsp + 112] ; current_stack_size before increment
|
||||
mov rdi, [rsp + 104] ; arg index
|
||||
call codegen_arg_to_operand
|
||||
mov [rsp + 104], rax
|
||||
mov [rsp + 112], rdx
|
||||
mov rdx, r13 ; offset
|
||||
neg rdx
|
||||
mov rdi, [rsp] ; ctx
|
||||
lea rdi, [rdi + 8] ; &ctx.text
|
||||
lea rsi, [rsp + 104] ; src
|
||||
call codegen_move_rbp_slot_src
|
||||
|
||||
inc r14
|
||||
jmp .arg_loop
|
||||
|
||||
.arg_loop_done:
|
||||
|
||||
; "jmp .body\n"
|
||||
; ".body:\n"
|
||||
|
||||
mov rdi, [rsp] ; ctx
|
||||
lea rsi, [rsp + 24] ; &function_ctx
|
||||
mov rdx, [rbx + 48] ; AstFunction.body
|
||||
call codegen_block
|
||||
call codegen_expr
|
||||
|
||||
; TODO: generate function body
|
||||
|
||||
; push "ret\n"
|
||||
; ".epilogue:\n"
|
||||
mov rdi, [rsp] ; ctx
|
||||
lea rdi, [rdi + 8] ; &ctx.text
|
||||
lea rsi, [rel DOT_EPILOGUE]
|
||||
mov rdx, DOT_EPILOGUE_LEN
|
||||
call vec_extend
|
||||
|
||||
; "pop {dirtied registers}\n"
|
||||
mov rdi, [rsp] ; ctx
|
||||
lea rdi, [rdi + 8] ; &ctx.text
|
||||
mov rsi, [rsp + 24] ; &function_ctx
|
||||
mov rdx, 0 ; push = false
|
||||
call codegen_push_pop_dirtied_registers
|
||||
|
||||
; "add rsp, {current_stack_size}\n"
|
||||
mov rdi, [rsp] ; ctx
|
||||
lea rdi, [rdi + 8] ; &ctx.text
|
||||
lea rsi, [rel ADD_RSP]
|
||||
mov rdx, ADD_RSP_LEN
|
||||
call vec_extend
|
||||
|
||||
mov rdi, [rsp + 24] ; &function_ctx
|
||||
mov rdi, [rdi + 0] ; current_stack_size
|
||||
lea rsi, [rsp + 104] ; scratch
|
||||
mov rdx, 16 ; buffer length
|
||||
mov rcx, 10 ; radix
|
||||
call int_to_str2
|
||||
|
||||
mov rdi, [rsp] ; ctx
|
||||
lea rdi, [rdi + 8] ; &ctx.text
|
||||
lea rsi, [rax + rdx]
|
||||
mov byte [rsi], 10 ; add newline
|
||||
mov rsi, rax
|
||||
mov rdx, rdx ; length from int_to_str2
|
||||
call vec_extend
|
||||
|
||||
; "ret\n"
|
||||
mov rdi, [rsp] ; ctx
|
||||
lea rdi, [rdi + 8] ; &ctx.text
|
||||
lea rsi, [rel RET_NL]
|
||||
mov rdx, RET_NL_LEN
|
||||
call vec_extend
|
||||
|
||||
; ".prologue:\n"
|
||||
mov rdi, [rsp] ; ctx
|
||||
lea rdi, [rdi + 8] ; &ctx.text
|
||||
lea rsi, [rel DOT_PROLOGUE]
|
||||
mov rdx, DOT_PROLOGUE_LEN
|
||||
call vec_extend
|
||||
|
||||
; "sub rsp, {current_stack_size}\n"
|
||||
mov rdi, [rsp] ; ctx
|
||||
lea rdi, [rdi + 8] ; &ctx.text
|
||||
lea rsi, [rel SUB_RSP]
|
||||
mov rdx, SUB_RSP_LEN
|
||||
call vec_extend
|
||||
|
||||
mov rdi, [rsp + 24] ; &function_ctx
|
||||
mov rdi, [rdi + 0] ; current_stack_size
|
||||
lea rsi, [rsp + 104] ; scratch
|
||||
mov rdx, 16 ; buffer length
|
||||
mov rcx, 10 ; radix
|
||||
call int_to_str2
|
||||
|
||||
mov rdi, [rsp] ; ctx
|
||||
lea rdi, [rdi + 8] ; &ctx.text
|
||||
lea rsi, [rax + rdx]
|
||||
mov byte [rsi], 10 ; add newline
|
||||
mov rsi, rax
|
||||
mov rdx, rdx ; length from int_to_str2
|
||||
call vec_extend
|
||||
|
||||
; "push{dirtied registers}\n"
|
||||
mov rdi, [rsp] ; ctx
|
||||
lea rdi, [rdi + 8] ; &ctx.text
|
||||
mov rsi, [rsp + 24] ; &function_ctx
|
||||
mov rdx, 1 ; push = false
|
||||
call codegen_push_pop_dirtied_registers
|
||||
|
||||
; "jmp .args\n"
|
||||
mov rdi, [rsp] ; ctx
|
||||
lea rdi, [rdi + 8] ; &ctx.text
|
||||
lea rsi, [rel JMP_ARGS]
|
||||
mov rdx, JMP_ARGS_LEN
|
||||
call vec_extend
|
||||
|
||||
add rsp, 120
|
||||
pop r15
|
||||
pop r14
|
||||
push r13
|
||||
push r14
|
||||
push r15
|
||||
pop rbx
|
||||
pop rbp
|
||||
ret
|
||||
|
|
@ -388,6 +589,116 @@ codegen_function:
|
|||
.panic:
|
||||
call panic
|
||||
|
||||
;; rdi: *text
|
||||
;; rsi: &function_ctx
|
||||
;; rdx: push: bool
|
||||
codegen_push_pop_dirtied_registers:
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
push rbx
|
||||
push r15
|
||||
push r14
|
||||
|
||||
sub rsp, 32
|
||||
mov [rsp], rdi
|
||||
mov [rsp + 8], rsi
|
||||
|
||||
mov byte [rsp + 29 + 3], 10 ; newline
|
||||
mov qword [rsp + 16], -1
|
||||
mov rax, ' hsup'
|
||||
mov qword [rsp + 24], rax
|
||||
test rdx, rdx
|
||||
jz .skip_setup_pop
|
||||
mov rax, ' pop'
|
||||
mov qword [rsp + 24], rax
|
||||
|
||||
mov rdi, [rsp] ; text
|
||||
mov rax, [rdi + 8] ; text.len()
|
||||
mov [rsp + 16], rax
|
||||
.skip_setup_pop:
|
||||
|
||||
; low: 0b01000000 high: 0b00001111
|
||||
; preserved registers:
|
||||
mov rax, [rsi + 48 + 16] ; dirtied_register_bitset low
|
||||
mov rbx, 0b01000000
|
||||
and rax, rbx
|
||||
test rax, rax
|
||||
jz .skip_rbp
|
||||
|
||||
mov rdi, 2
|
||||
mov rsi, 8
|
||||
lea rdx, [rsp + 29]
|
||||
call get_register_name
|
||||
|
||||
mov rax, -1
|
||||
cmp [rsp + 16], rax
|
||||
jne .rbx_pop
|
||||
|
||||
mov rdi, [rsp] ; text
|
||||
lea rsi, [rsp + 24]
|
||||
mov rdx, 9
|
||||
call vec_extend
|
||||
jmp .skip_rbp
|
||||
.rbx_pop:
|
||||
|
||||
mov rdi, [rsp] ; text
|
||||
lea rsi, [rsp + 24]
|
||||
mov rdx, 9
|
||||
mov rcx, [rsp + 16] ; text.len()
|
||||
call vec_insert_many
|
||||
|
||||
.skip_rbp:
|
||||
mov rax, [rsi + 48 + 16 + 8] ; dirtied_register_bitset high
|
||||
mov rbx, 0b00001111
|
||||
and rax, rbx
|
||||
test rax, rax
|
||||
jz .done
|
||||
|
||||
mov r15, 8
|
||||
xor r14, r14
|
||||
.reg_loop:
|
||||
cmp r14, r15
|
||||
jge .done
|
||||
bt rax, r14
|
||||
jnc .next_reg
|
||||
|
||||
mov rdi, 8
|
||||
add rdi, r14
|
||||
mov rsi, 8
|
||||
lea rdx, [rsp + 29]
|
||||
call get_register_name
|
||||
|
||||
mov rax, -1
|
||||
cmp [rsp + 16], rax
|
||||
jne .reg_pop
|
||||
|
||||
mov rdi, [rsp] ; text
|
||||
lea rsi, [rsp + 24]
|
||||
mov rdx, 9
|
||||
call vec_extend
|
||||
jmp .next_reg
|
||||
.reg_pop:
|
||||
|
||||
mov rdi, [rsp] ; text
|
||||
lea rsi, [rsp + 24]
|
||||
mov rdx, 9
|
||||
mov rcx, [rsp + 16] ; text.len()
|
||||
call vec_insert_many
|
||||
|
||||
|
||||
.next_reg:
|
||||
inc r14
|
||||
jmp .reg_loop
|
||||
|
||||
.done:
|
||||
add rsp, 32
|
||||
pop r14
|
||||
pop r15
|
||||
pop rbx
|
||||
pop rbp
|
||||
ret
|
||||
|
||||
|
||||
;; rdi: ctx
|
||||
;; rsi: &function_ctx
|
||||
;; rdx: block index
|
||||
|
|
@ -405,17 +716,17 @@ codegen_block:
|
|||
mov rdi, [rdi] ; ast
|
||||
mov rsi, rdx ; block index
|
||||
call vec_get
|
||||
mov 15, [rax + 8] ; AstNode.extra
|
||||
mov rbx, [rax + 0] ; AstNode.data
|
||||
mov r15, [rax + 8] ; AstNode.extra
|
||||
mov rbx, [rax + 0] ; AstNode.data
|
||||
|
||||
xor r14, r14 ; statement index
|
||||
.stmt_loop:
|
||||
cmp r14, r15
|
||||
jge .stmt_loop_done
|
||||
mov rdi, [rsp] ; ctx
|
||||
lea mov, [rsp + 8] ; &function_ctx
|
||||
lea rbx, [rsp + 8] ; &function_ctx
|
||||
mov rdx, [rbx + r14 * 8] ; statements[i]
|
||||
call codegen_statement
|
||||
call codegen_expr
|
||||
inc r14
|
||||
jmp .stmt_loop
|
||||
|
||||
|
|
@ -436,11 +747,13 @@ codegen_expr:
|
|||
push rbp
|
||||
mov rbp, rsp
|
||||
push rbx
|
||||
push r15
|
||||
push r14
|
||||
|
||||
; scratch [16..32]
|
||||
; scratch [16..48]
|
||||
; function_ctx: [8..16]
|
||||
; ctx [0..8]
|
||||
sub rsp, 32
|
||||
sub rsp, 48
|
||||
mov [rsp], rdi ; ctx
|
||||
mov [rsp + 8], rsi ; &function_ctx
|
||||
|
||||
|
|
@ -475,52 +788,112 @@ codegen_expr:
|
|||
je .address_of
|
||||
jmp .panic
|
||||
|
||||
.block:
|
||||
mov rbx, [rax + 8] ; AstNode.data
|
||||
mov r15, [rax + 16] ; AstNode.extra
|
||||
|
||||
xor r14, r14 ; statement index
|
||||
.stmt_loop:
|
||||
cmp r14, r15
|
||||
jge .stmt_loop_done
|
||||
mov rdi, [rsp] ; ctx
|
||||
mov rsi, [rsp + 8] ; &function_ctx
|
||||
mov rdx, [rbx + r14 * 8] ; statements[i]
|
||||
call codegen_expr
|
||||
inc r14
|
||||
jmp .stmt_loop
|
||||
.stmt_loop_done:
|
||||
xor rax, rax
|
||||
xor rdx, rdx
|
||||
jmp .done
|
||||
|
||||
.return:
|
||||
; codegen inner expr
|
||||
mov rdi, [rsp] ; ctx
|
||||
mov rsi, [rsp + 8] ; &function_ctx
|
||||
mov rdx, [rax + 8] ; AstNode.data
|
||||
call codegen_expr
|
||||
mov rbx, rax
|
||||
|
||||
; mov rax, {inner expr result}
|
||||
mov [rsp + 16], rax
|
||||
mov [rsp + 24], rdx
|
||||
mov rax, qword [rel OPERAND_RAX]
|
||||
mov rdx, qword [rel OPERAND_RAX + 8]
|
||||
mov [rsp + 32], rax
|
||||
mov [rsp + 40], rdx
|
||||
|
||||
mov rdi, [rsp] ; ctx
|
||||
mov rdi, [rdi + 8] ; &ctx.text
|
||||
lea rsi, [rel MOV_RAX]
|
||||
mov rdx, MOV_RAX_LEN
|
||||
call vec_extend
|
||||
|
||||
mov rdi, rbx
|
||||
mov rsi, 8
|
||||
lea rdx, [rsp + 16] ; scratch
|
||||
call get_register_name
|
||||
|
||||
mov rdi, [rsp] ; ctx
|
||||
mov rdi, [rdi + 8] ; &ctx.text
|
||||
mov rsi, rax
|
||||
call vec_extend
|
||||
lea rsi, [rsp + 32] ; dst
|
||||
lea rdx, [rsp + 16] ; src
|
||||
call codegen_move_dst_src
|
||||
|
||||
; push "jmp .epilogue\n"
|
||||
mov rdi, [rsp] ; ctx
|
||||
mov rdi, [rdi + 8] ; &ctx.text
|
||||
lea rsi, [rel JMP_EPILOGUE]
|
||||
mov rdx, JMP_EPILOGUE_LEN
|
||||
call vec_extend
|
||||
|
||||
mov rax, 0
|
||||
; construct return operand
|
||||
; Operand { kind: REGISTER, register_and_width: (register | (width << 4)), len: 0, value: 0 }
|
||||
mov eax, 0 ; len = 0
|
||||
shl eax, 16
|
||||
or eax, 8 ; width = 8
|
||||
shl eax, 4
|
||||
or eax, 0 ; register = rax
|
||||
shl eax, 8
|
||||
or eax, OPERAND_REGISTER ; kind
|
||||
mov rdx, 0 ; value = 0
|
||||
jmp .done
|
||||
|
||||
.number:
|
||||
; rax = *AstNode
|
||||
mov [rsp + 16], rax ; scratch = *AstNode
|
||||
mov rbx, [rax + 8] ; AstNode.data = value
|
||||
mov [rsp + 40], rbx ; Operand.value
|
||||
mov rdi, [rsp + 8] ; &function_ctx
|
||||
call codegen_allocate_register
|
||||
|
||||
|
||||
xor rbx, rbx
|
||||
or rbx, 8 ; width = 8
|
||||
shl rbx, 4
|
||||
or rbx, rax ; register
|
||||
shl rbx, 8
|
||||
or rbx, OPERAND_REGISTER ; kind
|
||||
mov [rsp + 16], rbx ;
|
||||
mov qword [rsp + 24], 0 ; value = 0
|
||||
|
||||
mov byte [rsp + 32], OPERAND_IMMEDIATE ; Operand.kind
|
||||
mov bl, 8 ; width = 8
|
||||
shl bl, 4 ; register = undef
|
||||
mov byte [rsp + 33], bl ; Operand.register_and_width
|
||||
mov word [rsp + 34], 0 ; Operand.len = 0
|
||||
|
||||
mov rdi, [rsp] ; ctx
|
||||
mov rdi, [rdi + 8] ; &ctx.text
|
||||
lea rsi, [rsp + 16] ; dst
|
||||
lea rdx, [rsp + 16] ; src
|
||||
call codegen_move_dst_src
|
||||
|
||||
mov rax, qword [rsp + 16]
|
||||
mov rdx, qword [rsp + 24]
|
||||
jmp .done
|
||||
|
||||
.var_decl:
|
||||
.var_ref:
|
||||
.binary_op:
|
||||
.assignment:
|
||||
.place_to_value:
|
||||
.value_to_place:
|
||||
.deref:
|
||||
.address_of:
|
||||
; TODO
|
||||
|
||||
.done:
|
||||
add rsp, 32
|
||||
add rsp, 48
|
||||
pop r14
|
||||
pop r15
|
||||
pop rbx
|
||||
pop rbp
|
||||
ret
|
||||
|
|
@ -539,19 +912,21 @@ codegen_expr:
|
|||
;; or: register: u4, width: u4
|
||||
section .rdata
|
||||
;; start-consts
|
||||
OPERAND_REGISTER db 1 ; e.g. rax, rbx
|
||||
OPERAND_RBP_OFFSET db 2 ; e.g. [rbp - 8]
|
||||
OPERAND_RSP_OFFSET db 3 ; e.g. [rsp + 16]
|
||||
OPERAND_ADDRESS db 4 ; e.g. [rel OPERAND_ADDRESS]
|
||||
OPERAND_IMMEDIATE db 5 ; e.g. 0x10
|
||||
OPERAND_CONSTANT db 6 ; e.g. OPERAND_CONSTANT
|
||||
OPERAND_LABEL db 7 ; e.g. label_1234
|
||||
OPERAND_REGISTER equ 1 ; e.g. rax, rbx
|
||||
OPERAND_RBP_OFFSET equ 2 ; e.g. [rbp - 8]
|
||||
OPERAND_RSP_OFFSET equ 3 ; e.g. [rsp + 16]
|
||||
OPERAND_ADDRESS equ 4 ; e.g. [rel OPERAND_ADDRESS]
|
||||
OPERAND_IMMEDIATE equ 5 ; e.g. 0x10
|
||||
OPERAND_CONSTANT equ 6 ; e.g. OPERAND_CONSTANT
|
||||
OPERAND_LABEL equ 7 ; e.g. label_1234
|
||||
;; end-consts
|
||||
WIDTH_BYTE db 'byte '
|
||||
WIDTH_WORD db 'word '
|
||||
WIDTH_DWORD db 'dword '
|
||||
WIDTH_QWORD db 'qword '
|
||||
|
||||
section .text
|
||||
|
||||
;; rdi: *text
|
||||
;; rsi: op: *Operand
|
||||
codegen_write_operand:
|
||||
|
|
@ -587,7 +962,7 @@ codegen_write_operand:
|
|||
mov rbx, rsi
|
||||
mov rdi, [rbx + 1] ; register_and_width
|
||||
mov rsi, rdi
|
||||
mov dil, dil ; low 4 bits = register
|
||||
and dil, 0x0F ; low 4 bits = register
|
||||
shr rsi, 4 ; high 4 bits = width
|
||||
lea rdx, [rsp + 16] ; buffer
|
||||
call get_register_name
|
||||
|
|
@ -601,7 +976,7 @@ codegen_write_operand:
|
|||
.rsp_offset:
|
||||
; {width} [rbp {+/-} offset]
|
||||
mov rsi, [rsp + 8] ; op
|
||||
mov sil, byte [rsi + 1] ; register_and_width
|
||||
mov sil, byte [rsi + 1] ; Operand.register_and_width
|
||||
shr sil, 4 ; width
|
||||
mov rdi, [rsp] ; *text
|
||||
call codegen_write_width
|
||||
|
|
@ -614,10 +989,10 @@ codegen_write_operand:
|
|||
|
||||
; if op.kind == OPERAND_RBP_OFFSET
|
||||
mov rax, [rsp + 8] ; op
|
||||
mov al, byte [rax + 0] ; op.kind
|
||||
mov al, byte [rax + 0] ; Operand.kind
|
||||
cmp al, OPERAND_RBP_OFFSET
|
||||
jne .rsp_offset_write
|
||||
mov qword [rsp + 16], ' pbr'
|
||||
mov qword [rsp + 16], 'rbp '
|
||||
mov rdi, [rsp] ; *text
|
||||
lea rsi, [rsp + 16]
|
||||
mov rdx, 4
|
||||
|
|
@ -625,7 +1000,7 @@ codegen_write_operand:
|
|||
jmp .check_sign
|
||||
|
||||
.rsp_offset_write:
|
||||
mov qword [rsp + 16], ' psr'
|
||||
mov qword [rsp + 16], 'rsp '
|
||||
mov rdi, [rsp] ; *text
|
||||
lea rsi, [rsp + 16]
|
||||
mov rdx, 4
|
||||
|
|
@ -637,11 +1012,12 @@ codegen_write_operand:
|
|||
mov rdi, [rax + 8] ; op.value
|
||||
cmp rdi, 0
|
||||
jl .skip_plus
|
||||
mov qword [rsp + 16], ' + '
|
||||
mov qword [rsp + 16], ' + '
|
||||
mov rdi, [rsp] ; *text
|
||||
lea rsi, [rsp + 16]
|
||||
mov rdx, 3
|
||||
call vec_extend
|
||||
nop
|
||||
.skip_plus:
|
||||
|
||||
; write offset
|
||||
|
|
@ -668,7 +1044,7 @@ codegen_write_operand:
|
|||
lea rsi, [rsp + 16]
|
||||
call vec_push
|
||||
|
||||
mov qword [rsp + 16], ' ler'
|
||||
mov qword [rsp + 16], 'rel '
|
||||
mov rdi, [rsp] ; *text
|
||||
lea rsi, [rsp + 16]
|
||||
mov rdx, 4
|
||||
|
|
@ -678,7 +1054,7 @@ codegen_write_operand:
|
|||
mov rax, [rsp + 8] ; op
|
||||
mov rdi, [rsp] ; *text
|
||||
mov rsi, [rax + 8] ; op.value
|
||||
mov rdx, [rax + 4] ; op.len
|
||||
mov rdx, [rax + 2] ; op.len
|
||||
mov dx, dx ; low 16 bits
|
||||
call vec_extend
|
||||
|
||||
|
|
@ -707,11 +1083,14 @@ codegen_write_operand:
|
|||
mov rax, [rsp + 8] ; op
|
||||
mov rdi, [rsp] ; *text
|
||||
mov rsi, [rax + 8] ; op.value
|
||||
mov rdx, [rax + 4] ; op.len
|
||||
mov rdx, [rax + 2] ; op.len
|
||||
mov dx, dx ; low 16 bits
|
||||
call vec_extend
|
||||
jmp .epilogue
|
||||
|
||||
.label:
|
||||
jmp .panic
|
||||
|
||||
.epilogue:
|
||||
add rsp, 40
|
||||
pop rbx
|
||||
|
|
@ -745,7 +1124,33 @@ codegen_write_width:
|
|||
call vec_extend
|
||||
pop rax ; length written
|
||||
ret
|
||||
.panic:
|
||||
call panic
|
||||
|
||||
;; rdi: *text
|
||||
;; rsi: src: *Operand
|
||||
;; rdx: rbp offset
|
||||
codegen_move_rbp_slot_src:
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
|
||||
sub rsp, 16
|
||||
|
||||
; construct dst Operand
|
||||
|
||||
mov byte [rsp + 0], OPERAND_RBP_OFFSET ; Operand.kind
|
||||
mov byte [rsp + 1], 0x80 ; Operand.register_and_width (width=8)
|
||||
mov word [rsp + 2], 0 ; Operand.len = 0
|
||||
mov dword [rsp + 4], 0 ; padding
|
||||
mov qword [rsp + 8], rdx ; Operand.value = rbp offset
|
||||
|
||||
mov rdx, rsi
|
||||
lea rsi, [rsp + 0] ; dst
|
||||
call codegen_move_dst_src
|
||||
|
||||
add rsp, 16
|
||||
pop rbp
|
||||
ret
|
||||
|
||||
;; rdi: *text
|
||||
;; rsi: dst: *Operand
|
||||
|
|
@ -764,8 +1169,8 @@ codegen_move_dst_src:
|
|||
jg .panic ; unsupported dst kind
|
||||
|
||||
; if dst.width != src.width
|
||||
mov cl, byte [rsi + 2] ; dst.register_and_width
|
||||
mov bl, byte [rdx + 2] ; src.register_and_width
|
||||
mov cl, byte [rsi + 1] ; dst.register_and_width
|
||||
mov bl, byte [rdx + 1] ; src.register_and_width
|
||||
shr cl, 4
|
||||
shr bl, 4
|
||||
cmp cl, bl
|
||||
|
|
@ -788,13 +1193,80 @@ codegen_move_dst_src:
|
|||
; xchg rax, [src]
|
||||
; mov [dst], rax
|
||||
; xchg rax, [src]
|
||||
|
||||
mov rdi, [rsp] ; *text
|
||||
lea rsi, [rel XCHG_RAX]
|
||||
mov rdx, XCHG_RAX_LEN
|
||||
call vec_extend
|
||||
|
||||
mov rdi, [rsp] ; *text
|
||||
mov rsi, [rsp + 16] ; src
|
||||
call codegen_write_operand
|
||||
|
||||
mov rdi, [rsp] ; *text
|
||||
lea rsi, [rel COMMA_RAX]
|
||||
mov rdx, COMMA_RAX_LEN
|
||||
call vec_extend
|
||||
|
||||
mov rdi, [rsp] ; *text
|
||||
lea rsi, [rel MOV_RAX_COMMA]
|
||||
mov rdx, 4
|
||||
call vec_extend
|
||||
|
||||
mov rdi, [rsp] ; *text
|
||||
mov rsi, [rsp + 8] ; dst
|
||||
call codegen_write_operand
|
||||
|
||||
mov rdi, [rsp] ; *text
|
||||
lea rsi, [rel COMMA_RAX]
|
||||
mov rdx, COMMA_RAX_LEN
|
||||
call vec_extend
|
||||
|
||||
mov rdi, [rsp] ; *text
|
||||
lea rsi, [rel XCHG_RAX]
|
||||
mov rdx, XCHG_RAX_LEN
|
||||
call vec_extend
|
||||
|
||||
mov rdi, [rsp] ; *text
|
||||
mov rsi, [rsp + 16] ; src
|
||||
call codegen_write_operand
|
||||
jmp .epilogue
|
||||
|
||||
.do_move:
|
||||
mov rdi, [rsp] ; *text
|
||||
lea rsi, [rel MOV_RAX_COMMA]
|
||||
mov rdx, 4
|
||||
call vec_extend
|
||||
|
||||
mov rdi, [rsp] ; *text
|
||||
mov rsi, [rsp + 8] ; dst
|
||||
call codegen_write_operand
|
||||
|
||||
mov rdi, [rsp] ; *text
|
||||
lea rsi, [rel COMMA_RAX]
|
||||
mov rdx, 2
|
||||
call vec_extend
|
||||
|
||||
mov rdi, [rsp] ; *text
|
||||
mov rsi, [rsp + 16] ; src
|
||||
call codegen_write_operand
|
||||
|
||||
.epilogue:
|
||||
add rsp, 24
|
||||
pop rbx
|
||||
pop rbp
|
||||
ret
|
||||
|
||||
.panic:
|
||||
call panic
|
||||
|
||||
section .rdata
|
||||
XCHG_RAX db "xchg rax, "
|
||||
XCHG_RAX_LEN equ $ - XCHG_RAX
|
||||
MOV_RAX_COMMA db "mov rax, "
|
||||
MOV_RAX_COMMA_LEN equ $ - MOV_RAX_COMMA
|
||||
COMMA_RAX db ", rax"
|
||||
COMMA_RAX_LEN equ $ - COMMA_RAX
|
||||
|
||||
; Operand { kind: REGISTER, register: 0, width: 8, len: 0, padding: 0, value: 0 }
|
||||
align 8
|
||||
OPERAND_RAX dq 0x0000_8001, 0
|
||||
|
|
|
|||
|
|
@ -90,12 +90,7 @@ 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;
|
||||
return 4;
|
||||
}",
|
||||
|ast| unsafe { parse_func(ast) },
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue