diff options
author | pommicket <pommicket@gmail.com> | 2022-02-12 14:12:01 -0500 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2022-02-12 14:12:01 -0500 |
commit | 864b23702a8e867d6361acd3cef7b505cfedf552 (patch) | |
tree | 97567ee4328a67e0fac13e54db304478c3ee9298 | |
parent | 0ee06ac2c466149097ed411cb648dfbe17ff4098 (diff) |
codegen for address of
-rw-r--r-- | 05/codegen.b | 67 | ||||
-rw-r--r-- | 05/constants.b | 1 | ||||
-rw-r--r-- | 05/main.c | 15 |
3 files changed, 79 insertions, 4 deletions
diff --git a/05/codegen.b b/05/codegen.b index 7701391..ec5d511 100644 --- a/05/codegen.b +++ b/05/codegen.b @@ -996,7 +996,69 @@ function generate_stack_dereference :gen_deref8 emit_mov_rax_qword_rbx() goto gen_deref_cast + +; returns pointer to end of expr +function generate_push_address_of_expression + argument statement ; for errors + argument expr + + local c + local d + + c = *1expr + + if c == EXPRESSION_GLOBAL_VARIABLE goto addrof_global_var + if c == EXPRESSION_LOCAL_VARIABLE goto addrof_local_var + if c == EXPRESSION_DEREFERENCE goto addrof_dereference + if c == EXPRESSION_SUBSCRIPT goto addrof_subscript + if c == EXPRESSION_DOT goto addrof_dot + if c == EXPRESSION_ARROW goto addrof_arrow + statement_error(statement, .str_bad_lvalue) + :str_bad_lvalue + string Bad l-value. + byte 0 + :addrof_global_var + expr += 8 + emit_mov_rax_imm64(*4expr) + emit_push_rax() + expr += 8 + return expr + :addrof_local_var + expr += 8 + emit_lea_rax_rbp_plus_imm32(*4expr) + emit_push_rax() + expr += 8 + return expr + :addrof_dereference + expr += 8 + return generate_push_expression(statement, expr) + :addrof_subscript + expr += 8 + c = expr + 4 ; type 1 + c = *4c + expr = generate_push_expression(statement, expr) + d = expr + 4 ; type 2 + d = *4d + expr = generate_push_expression(statement, expr) + generate_stack_add(statement, c, d, c) + return expr + :addrof_dot + expr += 8 + expr = generate_push_address_of_expression(statement, expr) + goto addrof_dot_cont + :addrof_arrow + expr += 8 + expr = generate_push_expression(statement, expr) + :addrof_dot_cont + emit_mov_rax_qword_rsp() ; mov rax, [rsp] + emit_mov_reg(REG_RBX, REG_RAX) ; mov rbx, rax + emit_mov_rax_imm64(*8expr) ; mov rax, (offset to member) + emit_add_rax_rbx() ; add rax, rbx + emit_mov_qword_rsp_rax() ; mov [rsp], rax + expr += 8 + return expr + ; `statement` is used for errors ; returns pointer to end of expression function generate_push_expression @@ -1024,6 +1086,7 @@ function generate_push_expression if c == EXPRESSION_LOCAL_VARIABLE goto generate_local_variable if c == EXPRESSION_DEREFERENCE goto generate_dereference if c == EXPRESSION_SUBSCRIPT goto generate_subscript + if c == EXPRESSION_ADDRESS_OF goto generate_address_of die(.str_genpushexprNI) :str_genpushexprNI @@ -1065,6 +1128,10 @@ function generate_push_expression emit_mov_qword_rsp_rax() ; mov [rsp], rax generate_cast_top_of_stack(statement, TYPE_UNSIGNED_LONG, type) return expr + :generate_address_of + expr += 8 + expr = generate_push_address_of_expression(statement, expr) + return expr :generate_add expr += 8 c = expr + 4 ; type of 1st operand diff --git a/05/constants.b b/05/constants.b index 9a39ecd..ec11033 100644 --- a/05/constants.b +++ b/05/constants.b @@ -160,7 +160,6 @@ ; - for casts, the operand (type is given by type member) ; - for binary operators, the first operand followed by the second ; - for the operators . and ->, the first argument is the expression on the left-hand side, and the second argument is a 64-bit offset. -; we could use a 32-bit offset but that would cause things to be unaligned. ; - for the ternary operator ? :, the first followed by the second followed by the third ; - for function calls, the function, followed by each of the arguments to the function, followed by 8 bytes of zeros ; File/line number are not stored in expressions. @@ -1,6 +1,15 @@ static char x = -2; + +typedef struct { + int x; + char y; + int z; +} Structure; + + long main(int argc, char **argv) { - int y[] = {38, 55, -22}; - int *z = (y+2)[-1]; - return *z; +Structure s[] = {3, 5, -88,6,9,12}; + Structure *ps = s; + int *p = &ps->z; + return *p; } |