diff options
Diffstat (limited to 'src/ssa')
-rw-r--r-- | src/ssa/ssa.c | 56 |
1 files changed, 34 insertions, 22 deletions
diff --git a/src/ssa/ssa.c b/src/ssa/ssa.c index 6e61bf1..b95cd10 100644 --- a/src/ssa/ssa.c +++ b/src/ssa/ssa.c @@ -50,7 +50,7 @@ SsaNumber create_ssa_float(f64 value) { return result; } -int ssa_init(Ssa *self, ScopedAllocator *allocator) { +int ssa_init(Ssa *self, ArenaAllocator *allocator) { return_if_error(buffer_init(&self->instructions, allocator)); return_if_error(hash_map_init(&self->intermediates_map, allocator, sizeof(SsaIntermediateIndex), compare_number, hash_number)); return_if_error(buffer_init(&self->intermediates, allocator)); @@ -207,7 +207,7 @@ static CHECK_RESULT int ssa_ins_binop(Ssa *self, SsaInstruction binop_type, SsaR return ssa_add_ins_form2(self, binop_type, lhs, rhs, result); } -static CHECK_RESULT int ssa_ins_func_start(Ssa *self, u8 num_args, SsaFuncIndex *result) { +static CHECK_RESULT int ssa_ins_func_start(Ssa *self, SsaFuncIndex *result, usize *func_metadata_index) { usize index; index = self->instructions.size; @@ -215,12 +215,13 @@ static CHECK_RESULT int ssa_ins_func_start(Ssa *self, u8 num_args, SsaFuncIndex if(self->func_counter + 1 < self->func_counter) return -1; - return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(SsaFuncIndex) + sizeof(u8))); + return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(SsaFuncIndex) + sizeof(u16))); *result = self->func_counter++; self->instructions.data[index + 0] = SSA_FUNC_START; am_memcpy(self->instructions.data + index + 1, result, sizeof(SsaFuncIndex)); - self->instructions.data[index + 1 + sizeof(SsaFuncIndex)] = num_args; - amal_log_debug("FUNC_START f%u(%u)", *result, num_args); + *func_metadata_index = index + 1 + sizeof(SsaFuncIndex); + /* No need to add data to instructions.data here, it can contain undefined data until we set it (@ the caller) */ + amal_log_debug("FUNC_START f%u", *result); return 0; } @@ -363,9 +364,9 @@ static CHECK_RESULT SsaRegister lhsexpr_generate_ssa(Ast *self, SsaCompilerConte } else { /* TODO: Do not assign if we dont want default value */ SsaNumber number; - if(self->resolve_data.type == context->compiler->default_types.i64) + if(self->resolve_data.type == (LhsExpr*)context->compiler->default_types.i64) number = create_ssa_integer(0); - else if(self->resolve_data.type == context->compiler->default_types.f64) + else if(self->resolve_data.type == (LhsExpr*)context->compiler->default_types.f64) number = create_ssa_float(0.0); else assert(bool_false && "TODO: assign default value to reg depending on LhsExpr type"); @@ -399,23 +400,24 @@ static CHECK_RESULT SsaRegister funcdecl_generate_ssa(FunctionDecl *self, SsaCom that is reset after function end */ SsaRegister prev_reg_counter; + usize func_metadata_index; prev_reg_counter = context->ssa->reg_counter; context->ssa->reg_counter = 0; amal_log_debug("SSA funcdecl %p", self); - throw_if_error(ssa_ins_func_start(context->ssa, 0, &self->ssa_func_index)); + throw_if_error(ssa_ins_func_start(context->ssa, &self->ssa_func_index, &func_metadata_index)); scope_generate_ssa(&self->body, context); throw_if_error(ssa_ins_func_end(context->ssa)); + /* Add the number of registers used to the function metadata (FUNC_START) */ + am_memcpy(&context->ssa->instructions.data[func_metadata_index], &context->ssa->reg_counter, sizeof(u16)); context->ssa->reg_counter = prev_reg_counter; - /*assert(bool_false);*/ return 0; } static CHECK_RESULT SsaRegister funccall_generate_ssa(Ast *self, SsaCompilerContext *context) { /* TODO: Implement */ FunctionCall *func_call; - FunctionDecl *func_to_call; Ast **ast; Ast **ast_end; SsaRegister reg; @@ -430,14 +432,19 @@ static CHECK_RESULT SsaRegister funccall_generate_ssa(Ast *self, SsaCompilerCont throw_if_error(ssa_ins_push(context->ssa, arg_reg)); } - assert(self->resolve_data.type->rhs_expr->type == AST_FUNCTION_DECL); - func_to_call = self->resolve_data.type->rhs_expr->value.func_decl; - /* - TODO: Implement func reference instead of using 0. Perhaps the best way is to use function declaration pointer value? - then there is no need for mutex locks. - */ - amal_log_debug("SSA funccall %.*s, func index ptr: %p", func_call->func.name.size, func_call->func.name.data, func_to_call); - throw_if_error(ssa_ins_call(context->ssa, func_to_call, ®)); + assert((self->resolve_data.type->rhs_expr && self->resolve_data.type->rhs_expr->type == AST_FUNCTION_DECL) || + self->resolve_data.type->type.type == VARIABLE_TYPE_SIGNATURE); + if(self->resolve_data.type->is_extern) { + amal_log_error("TODO: Implement extern function call (extern function %.*s was called)", func_call->func.name.size, func_call->func.name.data); + reg = 0; + assert(bool_false && "TODO: Implement extern function call!"); + } else { + FunctionDecl *func_to_call; + func_to_call = self->resolve_data.type->rhs_expr->value.func_decl; + amal_log_debug("SSA funccall %.*s, func index ptr: %p", func_call->func.name.size, func_call->func.name.data, func_to_call); + throw_if_error(ssa_ins_call(context->ssa, func_to_call, ®)); + } + return reg; } @@ -470,16 +477,16 @@ static CHECK_RESULT SsaRegister variable_generate_ssa(Variable *self, SsaCompile return ast_generate_ssa(self->resolved_var, context); } -static SsaInstruction binop_type_to_ssa_type(BinopType binop_type) { +static SsaInstruction binop_type_to_ssa_type(BinopType binop_type, amal_default_type *type) { switch(binop_type) { case BINOP_ADD: return SSA_ADD; case BINOP_SUB: return SSA_SUB; case BINOP_MUL: - return SSA_MUL; + return type->is_signed ? SSA_IMUL : SSA_MUL; case BINOP_DIV: - return SSA_DIV; + return type->is_signed ? SSA_IDIV : SSA_DIV; case BINOP_DOT: assert(bool_false && "Binop dot not valid for arithmetic operation and requires special functionality"); return 0; @@ -494,18 +501,23 @@ static CHECK_RESULT SsaRegister binop_generate_ssa(Binop *self, SsaCompilerConte SsaRegister rhs_reg; SsaRegister reg; + /* + const std = @import("std.amal"); + std.printf + */ if(self->type == BINOP_DOT && self->rhs->resolve_data.type->rhs_expr->type == AST_FUNCTION_DECL) { reg = ast_generate_ssa(self->rhs, context); } else { lhs_reg = ast_generate_ssa(self->lhs, context); rhs_reg = ast_generate_ssa(self->rhs, context); - throw_if_error(ssa_ins_binop(context->ssa, binop_type_to_ssa_type(self->type), lhs_reg, rhs_reg, ®)); + throw_if_error(ssa_ins_binop(context->ssa, binop_type_to_ssa_type(self->type, (amal_default_type*)self->lhs->resolve_data.type), lhs_reg, rhs_reg, ®)); } return reg; } static void else_if_statement_generate_ssa(ElseIfStatement *else_if_stmt, SsaCompilerContext *context) { usize jump_ins_index; + jump_ins_index = 0; if(else_if_stmt->condition) { SsaRegister condition_reg; condition_reg = ast_generate_ssa(else_if_stmt->condition, context); |