diff options
-rw-r--r-- | 05/codegen.b | 44 | ||||
-rw-r--r-- | 05/main.c | 10 | ||||
-rw-r--r-- | README.md | 1 |
3 files changed, 46 insertions, 9 deletions
diff --git a/05/codegen.b b/05/codegen.b index ec5d511..579c225 100644 --- a/05/codegen.b +++ b/05/codegen.b @@ -283,6 +283,12 @@ function emit_push_rax code_output += 1 return +function emit_pop_rax + ; 58 + *1code_output = 0x58 + code_output += 1 + return + function emit_syscall ; 0f 05 *2code_output = 0x050f @@ -967,8 +973,9 @@ function generate_stack_sub function generate_stack_dereference argument statement ; for errors argument type - + local p local size + local c size = type_sizeof(type) emit_mov_rax_qword_rsp() ; mov rax, [rsp] @@ -978,10 +985,20 @@ function generate_stack_dereference if size == 4 goto gen_deref4 if size == 8 goto gen_deref8 - byte 0xcc ; @TODO + emit_pop_rax() ; pop rax + emit_mov_reg(REG_RSI, REG_RAX) ; mov rsi, rax + c = round_up_to_8(size) + emit_sub_rsp_imm32(c) ; sub rsp, (size) + emit_mov_reg(REG_RDI, REG_RSP) ; mov rdi, rsp + emit_mov_rax_imm64(size) ; mov rax, (size) + emit_mov_reg(REG_RCX, REG_RAX) ; mov rcx, rax + emit_rep_movsb() ; rep movsb + return :gen_deref_cast - emit_push_rax() + emit_mov_qword_rsp_rax() + p = types + type + if *1p >= TYPE_LONG goto return_0 generate_cast_top_of_stack(statement, TYPE_UNSIGNED_LONG, type) return :gen_deref1 @@ -1087,6 +1104,9 @@ function generate_push_expression if c == EXPRESSION_DEREFERENCE goto generate_dereference if c == EXPRESSION_SUBSCRIPT goto generate_subscript if c == EXPRESSION_ADDRESS_OF goto generate_address_of + if c == EXPRESSION_DOT goto generate_dot_or_arrow + if c == EXPRESSION_ARROW goto generate_dot_or_arrow + if c == EXPRESSION_COMMA goto generate_comma die(.str_genpushexprNI) :str_genpushexprNI @@ -1227,6 +1247,13 @@ function generate_push_expression generate_stack_add(statement, c, d, c) generate_stack_dereference(statement, type) return expr + :generate_dot_or_arrow + ; @NONSTANDARD: we require that the 1st operand to . be an lvalue + ; e.g. int thing = function_which_returns_struct().x; + ; is not allowed + expr = generate_push_address_of_expression(statement, expr) + generate_stack_dereference(statement, type) + return expr :generate_local_variable expr += 8 d = sign_extend_32_to_64(*4expr) ; rbp offset @@ -1273,7 +1300,16 @@ function generate_push_expression emit_push_rax() expr += 8 return expr - + :generate_comma + expr += 8 + c = expr + 4 ; type of 1st expression + c = *4c + expr = generate_push_expression(statement, expr) + c = type_sizeof(c) + c = round_up_to_8(c) + emit_add_rsp_imm32(c) ; add rsp, (size of expression value on stack) + expr = generate_push_expression(statement, expr) + return expr function generate_statement argument statement local dat1 @@ -3,13 +3,13 @@ static char x = -2; typedef struct { int x; char y; - int z; + long z; + long q; } Structure; long main(int argc, char **argv) { -Structure s[] = {3, 5, -88,6,9,12}; - Structure *ps = s; - int *p = &ps->z; - return *p; + Structure s[] = {3, 5, -88,6,9,12,88,33}; + Structure t = s[0]; + return t.z; } @@ -148,6 +148,7 @@ ax bx cx dx sp bp si di | movsq | 48 a5 | copy 8 bytes from rsi to rdi | | rep movsb | f3 a4 | copy rcx bytes from rsi to rdi | │ push rax │ 50 │ push rax onto the stack │ +│ pop rax │ 58 │ pop a value off the stack into rax │ │ neg rax │ 48 f7 d8 │ set rax to -rax │ │ add rax, rbx │ 48 01 d8 │ add rbx to rax │ │ sub rax, rbx │ 48 29 d8 │ subtract rbx from rax │ |