summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--05/codegen.b208
-rw-r--r--05/constants.b1
-rw-r--r--05/main.c5
3 files changed, 212 insertions, 2 deletions
diff --git a/05/codegen.b b/05/codegen.b
index 51dce21..7dd7f37 100644
--- a/05/codegen.b
+++ b/05/codegen.b
@@ -1476,6 +1476,16 @@ function generate_push_expression
if c == EXPRESSION_LSHIFT goto generate_lshift
if c == EXPRESSION_RSHIFT goto generate_rshift
if c == EXPRESSION_ASSIGN goto generate_assign
+ if c == EXPRESSION_ASSIGN_ADD goto generate_assign_add
+ if c == EXPRESSION_ASSIGN_SUB goto generate_assign_sub
+ if c == EXPRESSION_ASSIGN_MUL goto generate_assign_mul
+ if c == EXPRESSION_ASSIGN_DIV goto generate_assign_div
+ if c == EXPRESSION_ASSIGN_REMAINDER goto generate_assign_remainder
+ if c == EXPRESSION_ASSIGN_LSHIFT goto generate_assign_lshift
+ if c == EXPRESSION_ASSIGN_RSHIFT goto generate_assign_rshift
+ if c == EXPRESSION_ASSIGN_AND goto generate_assign_and
+ if c == EXPRESSION_ASSIGN_OR goto generate_assign_or
+ if c == EXPRESSION_ASSIGN_XOR goto generate_assign_xor
if c == EXPRESSION_DEREFERENCE goto generate_dereference
if c == EXPRESSION_SUBSCRIPT goto generate_subscript
if c == EXPRESSION_ADDRESS_OF goto generate_address_of
@@ -1581,6 +1591,196 @@ function generate_push_expression
:str_exprend_wrong
string Internal compiler error: expression_get_end disagrees with generate_push_expression.
byte 0
+ :generate_assign_add
+ expr += 8
+ p = expression_get_end(expr)
+ p = generate_push_expression_casted(statement, p, type)
+ generate_push_address_of_expression(statement, expr)
+ expr = p
+ emit_mov_rax_qword_rsp() ; mov rax, [rsp] (address)
+ emit_push_rax() ; push rax
+ generate_stack_dereference(statement, type)
+ emit_mov_rax_qword_rsp_plus_imm32(16) ; mov rax, [rsp+16] (addend)
+ emit_push_rax() ; push rax
+ generate_stack_add(statement, type, type, type)
+ emit_mov_rax_qword_rsp_plus_imm32(8) ; mov rax, [rsp+8] (address)
+ emit_push_rax() ; push rax
+ generate_stack_assign(statement, type)
+ emit_mov_rax_qword_rsp() ; mov rax, [rsp] (result)
+ emit_add_rsp_imm32(16) ; add rsp, 16 (pop address, addend)
+ emit_mov_qword_rsp_rax() ; mov [rsp], rax
+ return expr
+ :generate_assign_sub
+ expr += 8
+ p = expression_get_end(expr)
+ p = generate_push_expression_casted(statement, p, type)
+ generate_push_address_of_expression(statement, expr)
+ expr = p
+ emit_mov_rax_qword_rsp() ; mov rax, [rsp] (address)
+ emit_push_rax() ; push rax
+ generate_stack_dereference(statement, type)
+ emit_mov_rax_qword_rsp_plus_imm32(16) ; mov rax, [rsp+16] (2nd operand)
+ emit_push_rax() ; push rax
+ generate_stack_sub(statement, type, type, type)
+ emit_mov_rax_qword_rsp_plus_imm32(8) ; mov rax, [rsp+8] (address)
+ emit_push_rax() ; push rax
+ generate_stack_assign(statement, type)
+ emit_mov_rax_qword_rsp() ; mov rax, [rsp] (result)
+ emit_add_rsp_imm32(16) ; add rsp, 16 (pop address, 2nd operand)
+ emit_mov_qword_rsp_rax() ; mov [rsp], rax
+ return expr
+ :generate_assign_mul
+ expr += 8
+ p = expression_get_end(expr)
+ p = generate_push_expression_casted(statement, p, type)
+ generate_push_address_of_expression(statement, expr)
+ expr = p
+ emit_mov_rax_qword_rsp() ; mov rax, [rsp] (address)
+ emit_push_rax() ; push rax
+ generate_stack_dereference(statement, type)
+ emit_mov_rax_qword_rsp_plus_imm32(16) ; mov rax, [rsp+16] (2nd operand)
+ emit_push_rax() ; push rax
+ generate_stack_mul(statement, type)
+ emit_mov_rax_qword_rsp_plus_imm32(8) ; mov rax, [rsp+8] (address)
+ emit_push_rax() ; push rax
+ generate_stack_assign(statement, type)
+ emit_mov_rax_qword_rsp() ; mov rax, [rsp] (result)
+ emit_add_rsp_imm32(16) ; add rsp, 16 (pop address, 2nd operand)
+ emit_mov_qword_rsp_rax() ; mov [rsp], rax
+ return expr
+ :generate_assign_div
+ expr += 8
+ p = expression_get_end(expr)
+ p = generate_push_expression_casted(statement, p, type)
+ generate_push_address_of_expression(statement, expr)
+ expr = p
+ emit_mov_rax_qword_rsp() ; mov rax, [rsp] (address)
+ emit_push_rax() ; push rax
+ generate_stack_dereference(statement, type)
+ emit_mov_rax_qword_rsp_plus_imm32(16) ; mov rax, [rsp+16] (2nd operand)
+ emit_push_rax() ; push rax
+ generate_stack_div(statement, type)
+ emit_mov_rax_qword_rsp_plus_imm32(8) ; mov rax, [rsp+8] (address)
+ emit_push_rax() ; push rax
+ generate_stack_assign(statement, type)
+ emit_mov_rax_qword_rsp() ; mov rax, [rsp] (result)
+ emit_add_rsp_imm32(16) ; add rsp, 16 (pop address, 2nd operand)
+ emit_mov_qword_rsp_rax() ; mov [rsp], rax
+ return expr
+ :generate_assign_remainder
+ expr += 8
+ p = expression_get_end(expr)
+ p = generate_push_expression_casted(statement, p, type)
+ generate_push_address_of_expression(statement, expr)
+ expr = p
+ emit_mov_rax_qword_rsp() ; mov rax, [rsp] (address)
+ emit_push_rax() ; push rax
+ generate_stack_dereference(statement, type)
+ emit_mov_rax_qword_rsp_plus_imm32(16) ; mov rax, [rsp+16] (2nd operand)
+ emit_push_rax() ; push rax
+ generate_stack_remainder(statement, type)
+ emit_mov_rax_qword_rsp_plus_imm32(8) ; mov rax, [rsp+8] (address)
+ emit_push_rax() ; push rax
+ generate_stack_assign(statement, type)
+ emit_mov_rax_qword_rsp() ; mov rax, [rsp] (result)
+ emit_add_rsp_imm32(16) ; add rsp, 16 (pop address, 2nd operand)
+ emit_mov_qword_rsp_rax() ; mov [rsp], rax
+ return expr
+ :generate_assign_and
+ expr += 8
+ p = expression_get_end(expr)
+ p = generate_push_expression_casted(statement, p, type)
+ generate_push_address_of_expression(statement, expr)
+ expr = p
+ emit_mov_rax_qword_rsp() ; mov rax, [rsp] (address)
+ emit_push_rax() ; push rax
+ generate_stack_dereference(statement, type)
+ emit_mov_rax_qword_rsp_plus_imm32(16) ; mov rax, [rsp+16] (2nd operand)
+ emit_push_rax() ; push rax
+ generate_stack_bitwise_and(statement, type)
+ emit_mov_rax_qword_rsp_plus_imm32(8) ; mov rax, [rsp+8] (address)
+ emit_push_rax() ; push rax
+ generate_stack_assign(statement, type)
+ emit_mov_rax_qword_rsp() ; mov rax, [rsp] (result)
+ emit_add_rsp_imm32(16) ; add rsp, 16 (pop address, 2nd operand)
+ emit_mov_qword_rsp_rax() ; mov [rsp], rax
+ return expr
+ :generate_assign_or
+ expr += 8
+ p = expression_get_end(expr)
+ p = generate_push_expression_casted(statement, p, type)
+ generate_push_address_of_expression(statement, expr)
+ expr = p
+ emit_mov_rax_qword_rsp() ; mov rax, [rsp] (address)
+ emit_push_rax() ; push rax
+ generate_stack_dereference(statement, type)
+ emit_mov_rax_qword_rsp_plus_imm32(16) ; mov rax, [rsp+16] (2nd operand)
+ emit_push_rax() ; push rax
+ generate_stack_bitwise_or(statement, type)
+ emit_mov_rax_qword_rsp_plus_imm32(8) ; mov rax, [rsp+8] (address)
+ emit_push_rax() ; push rax
+ generate_stack_assign(statement, type)
+ emit_mov_rax_qword_rsp() ; mov rax, [rsp] (result)
+ emit_add_rsp_imm32(16) ; add rsp, 16 (pop address, 2nd operand)
+ emit_mov_qword_rsp_rax() ; mov [rsp], rax
+ return expr
+ :generate_assign_xor
+ expr += 8
+ p = expression_get_end(expr)
+ p = generate_push_expression_casted(statement, p, type)
+ generate_push_address_of_expression(statement, expr)
+ expr = p
+ emit_mov_rax_qword_rsp() ; mov rax, [rsp] (address)
+ emit_push_rax() ; push rax
+ generate_stack_dereference(statement, type)
+ emit_mov_rax_qword_rsp_plus_imm32(16) ; mov rax, [rsp+16] (2nd operand)
+ emit_push_rax() ; push rax
+ generate_stack_bitwise_xor(statement, type)
+ emit_mov_rax_qword_rsp_plus_imm32(8) ; mov rax, [rsp+8] (address)
+ emit_push_rax() ; push rax
+ generate_stack_assign(statement, type)
+ emit_mov_rax_qword_rsp() ; mov rax, [rsp] (result)
+ emit_add_rsp_imm32(16) ; add rsp, 16 (pop address, 2nd operand)
+ emit_mov_qword_rsp_rax() ; mov [rsp], rax
+ return expr
+ :generate_assign_lshift
+ expr += 8
+ p = expression_get_end(expr)
+ p = generate_push_expression_casted(statement, p, type)
+ generate_push_address_of_expression(statement, expr)
+ expr = p
+ emit_mov_rax_qword_rsp() ; mov rax, [rsp] (address)
+ emit_push_rax() ; push rax
+ generate_stack_dereference(statement, type)
+ emit_mov_rax_qword_rsp_plus_imm32(16) ; mov rax, [rsp+16] (2nd operand)
+ emit_push_rax() ; push rax
+ generate_stack_lshift(statement, type)
+ emit_mov_rax_qword_rsp_plus_imm32(8) ; mov rax, [rsp+8] (address)
+ emit_push_rax() ; push rax
+ generate_stack_assign(statement, type)
+ emit_mov_rax_qword_rsp() ; mov rax, [rsp] (result)
+ emit_add_rsp_imm32(16) ; add rsp, 16 (pop address, 2nd operand)
+ emit_mov_qword_rsp_rax() ; mov [rsp], rax
+ return expr
+ :generate_assign_rshift
+ expr += 8
+ p = expression_get_end(expr)
+ p = generate_push_expression_casted(statement, p, type)
+ generate_push_address_of_expression(statement, expr)
+ expr = p
+ emit_mov_rax_qword_rsp() ; mov rax, [rsp] (address)
+ emit_push_rax() ; push rax
+ generate_stack_dereference(statement, type)
+ emit_mov_rax_qword_rsp_plus_imm32(16) ; mov rax, [rsp+16] (2nd operand)
+ emit_push_rax() ; push rax
+ generate_stack_rshift(statement, type)
+ emit_mov_rax_qword_rsp_plus_imm32(8) ; mov rax, [rsp+8] (address)
+ emit_push_rax() ; push rax
+ generate_stack_assign(statement, type)
+ emit_mov_rax_qword_rsp() ; mov rax, [rsp] (result)
+ emit_add_rsp_imm32(16) ; add rsp, 16 (pop address, 2nd operand)
+ emit_mov_qword_rsp_rax() ; mov [rsp], rax
+ return expr
:generate_add
expr += 8
c = expr + 4 ; type of 1st operand
@@ -2141,9 +2341,12 @@ function generate_code
local p_func
+ local end_addr
code_output = output_file_data + FUNCTIONS_ADDR
codegen_second_pass = 0
generate_functions()
+ end_addr = code_output - output_file_data
+ if end_addr ] FUNCTIONS_END goto too_much_code
code_output = output_file_data + FUNCTIONS_ADDR
codegen_second_pass = 1
generate_functions()
@@ -2187,3 +2390,8 @@ function generate_code
:str_no_main_function
string Error: No main function.
byte 0
+ :too_much_code
+ die(.str_too_much_code)
+ :str_too_much_code
+ string Too much code for executable.
+ byte 0
diff --git a/05/constants.b b/05/constants.b
index ec11033..f02ffaf 100644
--- a/05/constants.b
+++ b/05/constants.b
@@ -8,6 +8,7 @@
; you should be able to change these constants (in a way that's consistent) without breaking anything:
#define ENTRY_ADDR 0x200000
#define FUNCTIONS_ADDR 0x400000
+#define FUNCTIONS_END 0x800000
#define TOTAL_CODE_SIZE 0x600000
#define RODATA_ADDR 0x800000
#define RODATA_SIZE 0x400000
diff --git a/05/main.c b/05/main.c
index 65cb111..b5c3e12 100644
--- a/05/main.c
+++ b/05/main.c
@@ -12,7 +12,8 @@ long fibonacci(long x) {
}
int main(int argc, char **argv) {
- long (*fp)(long) = factorial;
- return (*fp)(6);
+ int x = 104;
+ x >>= 3;
+ return x;
}