local variables
This commit is contained in:
parent
b69bd8be29
commit
0a14c8ca2a
4 changed files with 96 additions and 15 deletions
81
05/codegen.b
81
05/codegen.b
|
@ -300,6 +300,29 @@ function emit_lea_rax_rbp_plus_imm32
|
||||||
code_output += 4
|
code_output += 4
|
||||||
return
|
return
|
||||||
|
|
||||||
|
function emit_lea_rsp_rbp_plus_imm32
|
||||||
|
; 48 8d a5 IMM32
|
||||||
|
argument imm32
|
||||||
|
*2code_output = 0x8d48
|
||||||
|
code_output += 2
|
||||||
|
*1code_output = 0xa5
|
||||||
|
code_output += 1
|
||||||
|
*4code_output = imm32
|
||||||
|
code_output += 4
|
||||||
|
return
|
||||||
|
|
||||||
|
function emit_mov_rax_qword_rbp_plus_imm32
|
||||||
|
; 48 8b 85 IMM32
|
||||||
|
argument imm32
|
||||||
|
*2code_output = 0x8b48
|
||||||
|
code_output += 2
|
||||||
|
*1code_output = 0x85
|
||||||
|
code_output += 1
|
||||||
|
*4code_output = imm32
|
||||||
|
code_output += 4
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
function emit_rep_movsb
|
function emit_rep_movsb
|
||||||
; f3 a4
|
; f3 a4
|
||||||
*2code_output = 0xa4f3
|
*2code_output = 0xa4f3
|
||||||
|
@ -964,6 +987,7 @@ function generate_push_expression
|
||||||
if c == EXPRESSION_ADD goto generate_add
|
if c == EXPRESSION_ADD goto generate_add
|
||||||
if c == EXPRESSION_SUB goto generate_sub
|
if c == EXPRESSION_SUB goto generate_sub
|
||||||
if c == EXPRESSION_GLOBAL_VARIABLE goto generate_global_variable
|
if c == EXPRESSION_GLOBAL_VARIABLE goto generate_global_variable
|
||||||
|
if c == EXPRESSION_LOCAL_VARIABLE goto generate_local_variable
|
||||||
|
|
||||||
die(.str_genpushexprNI)
|
die(.str_genpushexprNI)
|
||||||
:str_genpushexprNI
|
:str_genpushexprNI
|
||||||
|
@ -1083,6 +1107,39 @@ function generate_push_expression
|
||||||
emit_mov_rax_imm64(d) ; mov rax, (address)
|
emit_mov_rax_imm64(d) ; mov rax, (address)
|
||||||
emit_push_rax() ; push rax
|
emit_push_rax() ; push rax
|
||||||
return expr
|
return expr
|
||||||
|
:generate_local_variable
|
||||||
|
expr += 8
|
||||||
|
d = *8expr ; rbp offset
|
||||||
|
expr += 8
|
||||||
|
b = type_is_array(type)
|
||||||
|
if b != 0 goto local_var_array
|
||||||
|
c = type_sizeof(type)
|
||||||
|
if c > 8 goto local_var_large
|
||||||
|
emit_mov_rax_qword_rbp_plus_imm32(d) ; mov rax, [rbp+X]
|
||||||
|
emit_push_rax() ; push rax
|
||||||
|
p = types + type
|
||||||
|
if *1p < TYPE_LONG goto local_var_needs_cast
|
||||||
|
return expr
|
||||||
|
:local_var_needs_cast
|
||||||
|
generate_cast_top_of_stack(statement, TYPE_UNSIGNED_LONG, type)
|
||||||
|
return expr
|
||||||
|
:local_var_large
|
||||||
|
; @TODO: test this
|
||||||
|
c = round_up_to_8(c)
|
||||||
|
emit_sub_rsp_imm32(c) ; sub rsp, (size)
|
||||||
|
emit_mov_reg(REG_RDI, REG_RSP) ; mov rdi, rsp
|
||||||
|
emit_lea_rax_rbp_plus_imm32(d) ; lea rax, [rbp+X]
|
||||||
|
emit_mov_reg(REG_RSI, REG_RAX) ; mov rsi, rax
|
||||||
|
emit_mov_rax_imm64(c) ; mov rax, (size)
|
||||||
|
emit_mov_reg(REG_RCX, REG_RAX) ; mov rcx, rax
|
||||||
|
emit_rep_movsb() ; rep movsb
|
||||||
|
return expr
|
||||||
|
:local_var_array
|
||||||
|
; push address of array instead of array
|
||||||
|
emit_lea_rax_rbp_plus_imm32(d) ; lea rax, [rbp+X]
|
||||||
|
emit_push_rax() ; push rax
|
||||||
|
return expr
|
||||||
|
byte 0xcc
|
||||||
:generate_float
|
:generate_float
|
||||||
expr += 8
|
expr += 8
|
||||||
emit_mov_rax_imm64(*8expr)
|
emit_mov_rax_imm64(*8expr)
|
||||||
|
@ -1120,6 +1177,7 @@ function generate_statement
|
||||||
|
|
||||||
if c == STATEMENT_BLOCK goto gen_block
|
if c == STATEMENT_BLOCK goto gen_block
|
||||||
if c == STATEMENT_RETURN goto gen_return
|
if c == STATEMENT_RETURN goto gen_return
|
||||||
|
if c == STATEMENT_LOCAL_DECLARATION goto gen_local_decl
|
||||||
; @TODO
|
; @TODO
|
||||||
die(.str_genstmtNI)
|
die(.str_genstmtNI)
|
||||||
:str_genstmtNI
|
:str_genstmtNI
|
||||||
|
@ -1145,7 +1203,28 @@ function generate_statement
|
||||||
:gen_return_noexpr
|
:gen_return_noexpr
|
||||||
generate_return()
|
generate_return()
|
||||||
return
|
return
|
||||||
|
:gen_local_decl
|
||||||
|
c = type_sizeof(dat2)
|
||||||
|
c = round_up_to_8(c)
|
||||||
|
if dat3 != 0 goto gen_local_decl_initializer
|
||||||
|
; move the stack pointer to the start of the variable
|
||||||
|
dat1 += c
|
||||||
|
dat1 = 0 - dat1
|
||||||
|
emit_lea_rsp_rbp_plus_imm32(dat1)
|
||||||
|
if dat2 != 0 goto gen_local_decl_data_initializer
|
||||||
|
return
|
||||||
|
|
||||||
|
:gen_local_decl_initializer
|
||||||
|
dat1 = 0 - dat1
|
||||||
|
; move the stack pointer to the end of the variable
|
||||||
|
emit_lea_rsp_rbp_plus_imm32(dat1)
|
||||||
|
; push the expression
|
||||||
|
generate_push_expression_casted(statement, dat3, dat2)
|
||||||
|
return
|
||||||
|
:gen_local_decl_data_initializer
|
||||||
|
byte 0xcc ; @TODO
|
||||||
|
|
||||||
|
|
||||||
function generate_function
|
function generate_function
|
||||||
argument function_name
|
argument function_name
|
||||||
argument function_statement
|
argument function_statement
|
||||||
|
|
|
@ -271,7 +271,7 @@
|
||||||
; a type of 0 indicates the end of the block.
|
; a type of 0 indicates the end of the block.
|
||||||
; data layout for particular statements:
|
; data layout for particular statements:
|
||||||
; - STATEMENT_EXPRESSION - data1 is a pointer to expression data; data2,3,4 are unused
|
; - STATEMENT_EXPRESSION - data1 is a pointer to expression data; data2,3,4 are unused
|
||||||
; - STATEMENT_LOCAL_DECLARATION - declaring a local variable, data1 = rbp offset, data2 = size of type (ignored if dat4 is 0), data3 = initializer expression or 0, data4 = initializer memory address to copy from (for braced initializers) or 0
|
; - STATEMENT_LOCAL_DECLARATION - declaring a local variable, data1 = rbp - rsp BEFORE variable is pushed, data2 = type, data3 = initializer expression or 0, data4 = initializer memory address to copy from (for braced initializers) or 0
|
||||||
; - STATEMENT_LABEL - data1 is a pointer to the name of the label; data2,3,4 are unused
|
; - STATEMENT_LABEL - data1 is a pointer to the name of the label; data2,3,4 are unused
|
||||||
; - STATEMENT_BLOCK - data1 is a pointer to an array of statements; data2,3,4 are unused
|
; - STATEMENT_BLOCK - data1 is a pointer to an array of statements; data2,3,4 are unused
|
||||||
; - STATEMENT_IF - data1 is a pointer to the condition, data2 is a pointer to the `if' branch statement, data3 is a pointer to the `else' branch statement, or 0 if there is none; data4 is unused
|
; - STATEMENT_IF - data1 is a pointer to the condition, data2 is a pointer to the `if' branch statement, data3 is a pointer to the `else' branch statement, or 0 if there is none; data4 is unused
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
static int x = -2;
|
static char x = -2;
|
||||||
|
|
||||||
long main(int argc, char **argv) {
|
long main(int argc, char **argv) {
|
||||||
return x + 17.3;
|
int y = 38;
|
||||||
|
int z = y + x;
|
||||||
|
return z + x;
|
||||||
}
|
}
|
||||||
|
|
22
05/parse.b
22
05/parse.b
|
@ -704,18 +704,18 @@ function parse_statement
|
||||||
; we need to calculate the size of the type here, because of stuff like
|
; we need to calculate the size of the type here, because of stuff like
|
||||||
; int x[] = {1,2,3};
|
; int x[] = {1,2,3};
|
||||||
n = type_sizeof(l_type)
|
n = type_sizeof(l_type)
|
||||||
; advance
|
|
||||||
local_var_rbp_offset += n
|
|
||||||
; align
|
|
||||||
local_var_rbp_offset += 7
|
|
||||||
local_var_rbp_offset >= 3
|
|
||||||
local_var_rbp_offset <= 3
|
|
||||||
write_statement_header(out, STATEMENT_LOCAL_DECLARATION, token)
|
write_statement_header(out, STATEMENT_LOCAL_DECLARATION, token)
|
||||||
out += 8
|
out += 8
|
||||||
*8out = local_var_rbp_offset
|
*8out = local_var_rbp_offset
|
||||||
out += 8
|
out += 8
|
||||||
*8out = n
|
*8out = l_type
|
||||||
out += 24
|
out += 24
|
||||||
|
|
||||||
|
; advance
|
||||||
|
local_var_rbp_offset += n
|
||||||
|
; align
|
||||||
|
local_var_rbp_offset = round_up_to_8(local_var_rbp_offset)
|
||||||
|
|
||||||
p = local_variables
|
p = local_variables
|
||||||
p += block_depth < 3
|
p += block_depth < 3
|
||||||
; local variables are stored below rbp
|
; local variables are stored below rbp
|
||||||
|
@ -1102,8 +1102,8 @@ function print_statement_with_depth
|
||||||
:print_stmt_local_decl
|
:print_stmt_local_decl
|
||||||
puts(.str_local_decl)
|
puts(.str_local_decl)
|
||||||
putn(dat1)
|
putn(dat1)
|
||||||
puts(.str_local_size)
|
puts(.str_local_type)
|
||||||
putn(dat2)
|
print_type(dat2)
|
||||||
if dat3 != 0 goto print_stmt_local_initializer
|
if dat3 != 0 goto print_stmt_local_initializer
|
||||||
if dat4 != 0 goto print_stmt_local_copy_address
|
if dat4 != 0 goto print_stmt_local_copy_address
|
||||||
:stmt_local_decl_finish
|
:stmt_local_decl_finish
|
||||||
|
@ -1122,8 +1122,8 @@ function print_statement_with_depth
|
||||||
:str_local_decl
|
:str_local_decl
|
||||||
string local variable at rbp-
|
string local variable at rbp-
|
||||||
byte 0
|
byte 0
|
||||||
:str_local_size
|
:str_local_type
|
||||||
string size
|
string type
|
||||||
byte 32
|
byte 32
|
||||||
byte 0
|
byte 0
|
||||||
:str_local_copyfrom
|
:str_local_copyfrom
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue