From b69bd8be29a53d8801387d09043de5bd75ca9e26 Mon Sep 17 00:00:00 2001 From: pommicket Date: Sat, 12 Feb 2022 11:37:40 -0500 Subject: codegen for global variables --- 04/README.md | 2 +- 04a/in04 | 3 +- 05/codegen.b | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 05/main.c | 4 ++- 05/parse.b | 7 +++++ 5 files changed, 104 insertions(+), 4 deletions(-) diff --git a/04/README.md b/04/README.md index 68cd81d..6840080 100644 --- a/04/README.md +++ b/04/README.md @@ -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! 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). diff --git a/04a/in04 b/04a/in04 index 8c0d2cc..5bd955c 100644 --- a/04a/in04 +++ b/04a/in04 @@ -6,11 +6,10 @@ byte 40 byte 0 byte 0 byte 0 +goto main global output_fd -goto main - global defines global defines_end diff --git a/05/codegen.b b/05/codegen.b index 0d70f37..ff4687a 100644 --- a/05/codegen.b +++ b/05/codegen.b @@ -150,6 +150,62 @@ function emit_mov_eax_eax code_output += 2 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 argument imm32 ; 48 89 84 24 IMM32 @@ -889,6 +945,7 @@ function generate_stack_sub function generate_push_expression argument statement argument expr + local b local c local d local p @@ -906,6 +963,7 @@ function generate_push_expression if c == EXPRESSION_LOGICAL_NOT goto generate_unary_logical_not if c == EXPRESSION_ADD goto generate_add if c == EXPRESSION_SUB goto generate_sub + if c == EXPRESSION_GLOBAL_VARIABLE goto generate_global_variable die(.str_genpushexprNI) :str_genpushexprNI @@ -991,6 +1049,40 @@ function generate_push_expression emit_movq_xmm0_rax() ; movq xmm0, rax emit_comisd_xmm0_xmm1() ; comisd xmm0, xmm1 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 expr += 8 emit_mov_rax_imm64(*8expr) diff --git a/05/main.c b/05/main.c index d156c52..b2a0001 100644 --- a/05/main.c +++ b/05/main.c @@ -1,3 +1,5 @@ +static int x = -2; + long main(int argc, char **argv) { - return (double*)808 - (double*)792; + return x + 17.3; } diff --git a/05/parse.b b/05/parse.b index 476d503..a6dd81d 100644 --- a/05/parse.b +++ b/05/parse.b @@ -24,6 +24,13 @@ function token_is_type if b != 0 goto return_1 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 argument ftype local type -- cgit v1.2.3