codegen for global variables

This commit is contained in:
pommicket 2022-02-12 11:37:40 -05:00
parent 3db0956b19
commit b69bd8be29
5 changed files with 104 additions and 4 deletions

View file

@ -271,4 +271,4 @@ you need to use a lot of labels, and that means their names can get quite long.
the 03 language, you'll get an error if you use the same label name twice! the 03 language, you'll get an error if you use the same label name twice!
Overall, though, this language ended up being surprisingly powerful. With any luck, stage `05` will Overall, though, this language ended up being surprisingly powerful. With any luck, stage `05` will
finally be a C compiler... But first, it's time to make [something that's not a compiler](../04a/README.html). finally be a C compiler... But first, it's time to make [something that's not a compiler](../04a/README.md).

View file

@ -6,11 +6,10 @@ byte 40
byte 0 byte 0
byte 0 byte 0
byte 0 byte 0
goto main
global output_fd global output_fd
goto main
global defines global defines
global defines_end global defines_end

View file

@ -150,6 +150,62 @@ function emit_mov_eax_eax
code_output += 2 code_output += 2
return return
function emit_mov_al_byte_rbx
; 8a 03
*2code_output = 0x038a
code_output += 2
return
function emit_mov_byte_rbx_al
; 88 03
*2code_output = 0x0388
code_output += 2
return
function emit_mov_ax_word_rbx
; 66 8b 03
*2code_output = 0x8b66
code_output += 2
*1code_output = 0x03
code_output += 1
return
function emit_mov_word_rbx_ax
; 66 89 03
*2code_output = 0x8966
code_output += 2
*1code_output = 0x03
code_output += 1
return
function emit_mov_eax_dword_rbx
; 8b 03
*2code_output = 0x038b
code_output += 2
return
function emit_mov_dword_rbx_eax
; 89 03
*2code_output = 0x0389
code_output += 2
return
function emit_mov_rax_qword_rbx
; 48 8b 03
*2code_output = 0x8b48
code_output += 2
*1code_output = 0x03
code_output += 1
return
function emit_mov_qword_rbx_rax
; 48 89 03
*2code_output = 0x8948
code_output += 2
*1code_output = 0x03
code_output += 1
return
function emit_mov_qword_rsp_plus_imm32_rax function emit_mov_qword_rsp_plus_imm32_rax
argument imm32 argument imm32
; 48 89 84 24 IMM32 ; 48 89 84 24 IMM32
@ -889,6 +945,7 @@ function generate_stack_sub
function generate_push_expression function generate_push_expression
argument statement argument statement
argument expr argument expr
local b
local c local c
local d local d
local p local p
@ -906,6 +963,7 @@ function generate_push_expression
if c == EXPRESSION_LOGICAL_NOT goto generate_unary_logical_not if c == EXPRESSION_LOGICAL_NOT goto generate_unary_logical_not
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
die(.str_genpushexprNI) die(.str_genpushexprNI)
:str_genpushexprNI :str_genpushexprNI
@ -991,6 +1049,40 @@ function generate_push_expression
emit_movq_xmm0_rax() ; movq xmm0, rax emit_movq_xmm0_rax() ; movq xmm0, rax
emit_comisd_xmm0_xmm1() ; comisd xmm0, xmm1 emit_comisd_xmm0_xmm1() ; comisd xmm0, xmm1
goto generate_logical_not_cont goto generate_logical_not_cont
:generate_global_variable
expr += 8
d = *8expr ; address
expr += 8
b = type_is_array(type)
if b != 0 goto global_var_array
c = type_sizeof(type)
if c > 8 goto global_var_large
emit_mov_rbx_imm64(d) ; mov rbx, (address)
emit_mov_rax_qword_rbx() ; mov rax, [rbx]
emit_push_rax() ; push rax
p = types + type
if *1p < TYPE_LONG goto global_var_needs_cast
return expr
:global_var_needs_cast
; we need to sign extend 8/16/32-bit signed global variables to 64 bits
generate_cast_top_of_stack(statement, TYPE_UNSIGNED_LONG, type)
return expr
:global_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_mov_rax_imm64(d) ; mov rax, (address)
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
:global_var_array
; just push the address of the array
emit_mov_rax_imm64(d) ; mov rax, (address)
emit_push_rax() ; push rax
return expr
:generate_float :generate_float
expr += 8 expr += 8
emit_mov_rax_imm64(*8expr) emit_mov_rax_imm64(*8expr)

View file

@ -1,3 +1,5 @@
static int x = -2;
long main(int argc, char **argv) { long main(int argc, char **argv) {
return (double*)808 - (double*)792; return x + 17.3;
} }

View file

@ -24,6 +24,13 @@ function token_is_type
if b != 0 goto return_1 if b != 0 goto return_1
goto return_0 goto return_0
function type_is_array
argument type
local p
p = types + type
if *1p == TYPE_ARRAY goto return_1
return 0
function functype_return_type function functype_return_type
argument ftype argument ftype
local type local type