aboutsummaryrefslogtreecommitdiff
path: root/src/ssa
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2019-07-31 01:25:05 +0200
committerdec05eba <dec05eba@protonmail.com>2020-07-25 14:36:46 +0200
commit1f28c3c733ea3ae4234bff91e1c55e61b1ee3e96 (patch)
tree0ab52e362da03fde741ce8159ef8a4110cd1fb6a /src/ssa
parentec1a48e7b86fcd00127dd5a88d56c42083af1d78 (diff)
Starting on asm, implementing extern function call so progress is visible
Diffstat (limited to 'src/ssa')
-rw-r--r--src/ssa/ssa.c56
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, &reg));
+ 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, &reg));
+ }
+
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, &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, &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);