codegen for address of

This commit is contained in:
pommicket 2022-02-12 14:12:01 -05:00
parent 0ee06ac2c4
commit 864b23702a
3 changed files with 79 additions and 4 deletions

View file

@ -997,6 +997,68 @@ function generate_stack_dereference
emit_mov_rax_qword_rbx() emit_mov_rax_qword_rbx()
goto gen_deref_cast 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 ; `statement` is used for errors
; returns pointer to end of expression ; returns pointer to end of expression
function generate_push_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_LOCAL_VARIABLE goto generate_local_variable
if c == EXPRESSION_DEREFERENCE goto generate_dereference if c == EXPRESSION_DEREFERENCE goto generate_dereference
if c == EXPRESSION_SUBSCRIPT goto generate_subscript if c == EXPRESSION_SUBSCRIPT goto generate_subscript
if c == EXPRESSION_ADDRESS_OF goto generate_address_of
die(.str_genpushexprNI) die(.str_genpushexprNI)
:str_genpushexprNI :str_genpushexprNI
@ -1065,6 +1128,10 @@ function generate_push_expression
emit_mov_qword_rsp_rax() ; mov [rsp], rax emit_mov_qword_rsp_rax() ; mov [rsp], rax
generate_cast_top_of_stack(statement, TYPE_UNSIGNED_LONG, type) generate_cast_top_of_stack(statement, TYPE_UNSIGNED_LONG, type)
return expr return expr
:generate_address_of
expr += 8
expr = generate_push_address_of_expression(statement, expr)
return expr
:generate_add :generate_add
expr += 8 expr += 8
c = expr + 4 ; type of 1st operand c = expr + 4 ; type of 1st operand

View file

@ -160,7 +160,6 @@
; - for casts, the operand (type is given by type member) ; - for casts, the operand (type is given by type member)
; - for binary operators, the first operand followed by the second ; - 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. ; - 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 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 ; - 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. ; File/line number are not stored in expressions.

View file

@ -1,6 +1,15 @@
static char x = -2; static char x = -2;
typedef struct {
int x;
char y;
int z;
} Structure;
long main(int argc, char **argv) { long main(int argc, char **argv) {
int y[] = {38, 55, -22}; Structure s[] = {3, 5, -88,6,9,12};
int *z = (y+2)[-1]; Structure *ps = s;
return *z; int *p = &ps->z;
return *p;
} }