diff options
Diffstat (limited to 'src/ssa')
-rw-r--r-- | src/ssa/ssa.c | 144 |
1 files changed, 133 insertions, 11 deletions
diff --git a/src/ssa/ssa.c b/src/ssa/ssa.c index f5187af..1b5ed3d 100644 --- a/src/ssa/ssa.c +++ b/src/ssa/ssa.c @@ -4,12 +4,21 @@ #include "../../include/ast.h" #include <assert.h> +#define throw(result) do { longjmp(context->env, (result)); } while(0) +#define throw_if_error(result) \ +do { \ + int return_if_result; \ + return_if_result = (result); \ + if((return_if_result) != 0) \ + throw(return_if_result); \ +} while(0) + static int compare_number(const void *a, const void *b) { const SsaNumber *lhs; const SsaNumber *rhs; lhs = a; rhs = b; - if(rhs->type == lhs->type && rhs->value == lhs->value) + if(rhs->type == lhs->type && rhs->value.integer == lhs->value.integer) return 0; return 1; } @@ -18,13 +27,20 @@ static usize hash_number(const u8 *data, usize size) { SsaNumber number; assert(size == sizeof(SsaNumber)); am_memcpy(&number, data, size); - return number.value; + return number.value.integer; +} + +SsaNumber create_ssa_integer(i64 value) { + SsaNumber result; + result.value.integer = value; + result.type = SSA_NUMBER_TYPE_INTEGER; + return result; } -SsaNumber create_ssa_number(i64 value, SsaNumberType type) { +SsaNumber create_ssa_float(f64 value) { SsaNumber result; - result.value = value; - result.type = type; + result.value.floating = value; + result.type = SSA_NUMBER_TYPE_FLOAT; return result; } @@ -45,13 +61,11 @@ int ssa_get_unique_reg(Ssa *self, SsaRegister *result) { return 0; } -static CHECK_RESULT int ssa_try_add_intermediate(Ssa *self, i64 intermediate, SsaNumberType number_type, SsaIntermediateIndex *result_index) { - SsaNumber number; +static CHECK_RESULT int ssa_try_add_intermediate(Ssa *self, SsaNumber number, SsaIntermediateIndex *result_index) { bool exists; BufferView key; assert(result_index); - number = create_ssa_number(intermediate, number_type); key = create_buffer_view((const char*)&number, sizeof(number)); exists = hash_map_get(&self->intermediates, key, result_index); @@ -64,6 +78,16 @@ static CHECK_RESULT int ssa_try_add_intermediate(Ssa *self, i64 intermediate, Ss *result_index = self->intermediate_counter; ++self->intermediate_counter; + switch(number.type) { + case SSA_NUMBER_TYPE_INTEGER: { + amal_log_debug("i%u = %lld", *result_index, number.value.integer); + break; + } + case SSA_NUMBER_TYPE_FLOAT: { + amal_log_debug("i%u = %f", *result_index, number.value.floating); + break; + } + } return hash_map_insert(&self->intermediates, key, result_index); } @@ -99,7 +123,7 @@ static CHECK_RESULT int ssa_add_ins_form2(Ssa *self, SsaInstructionType ins_type int ssa_ins_assign_inter(Ssa *self, SsaRegister dest, SsaNumber number) { SsaIntermediateIndex index; - return_if_error(ssa_try_add_intermediate(self, number.value, number.type, &index)); + return_if_error(ssa_try_add_intermediate(self, number, &index)); amal_log_debug("r%u = i%u", dest, index); return ssa_add_ins_form1(self, SSA_ASSIGN_INTER, dest, index); } @@ -165,10 +189,108 @@ int ssa_ins_call(Ssa *self, SsaFuncIndex func, SsaRegister *result) { return 0; } -static void ast_generate_ssa(Ast *self, SsaCompilerContext *context) { +static CHECK_RESULT SsaRegister ast_generate_ssa(Ast *self, SsaCompilerContext *context); + +static CHECK_RESULT SsaRegister number_generate_ssa(Number *self, SsaCompilerContext *context) { + SsaRegister reg; + SsaNumber number; + if(self->is_integer) { + number = create_ssa_integer(self->value.integer); + throw_if_error(ssa_get_unique_reg(&context->ssa, ®)); + throw_if_error(ssa_ins_assign_inter(&context->ssa, reg, number)); + } else { + number = create_ssa_float(self->value.floating); + throw_if_error(ssa_get_unique_reg(&context->ssa, ®)); + throw_if_error(ssa_ins_assign_inter(&context->ssa, reg, number)); + } + return reg; +} + +static CHECK_RESULT SsaRegister funcdecl_generate_ssa(FunctionDecl *self, SsaCompilerContext *context) { + /* TODO: Implement */ + scope_generate_ssa(&self->body, context); + return 0; +} + +static CHECK_RESULT SsaRegister funccall_generate_ssa(FunctionCall *self, SsaCompilerContext *context) { + /* TODO: Implement */ + (void)self; + (void)context; + return 0; +} + +static CHECK_RESULT SsaRegister lhs_generate_ssa(LhsExpr *self, SsaCompilerContext *context) { + /* TODO: Implement */ + SsaRegister rhs_reg; + amal_log_debug("lhs_generate_ssa"); + rhs_reg = ast_generate_ssa(&self->rhs_expr, context); + return rhs_reg; +} + +static CHECK_RESULT SsaRegister string_generate_ssa(String *self, SsaCompilerContext *context) { /* TODO: Implement */ (void)self; (void)context; + return 0; +} + +static CHECK_RESULT SsaRegister variable_generate_ssa(Variable *self, SsaCompilerContext *context) { + /* TODO: Implement */ + (void)self; + (void)context; + return 0; +} + +static SsaInstructionType binop_type_to_ssa_type(BinopType binop_type) { + switch(binop_type) { + case BINOP_ADD: + return SSA_ADD; + case BINOP_SUB: + return SSA_SUB; + case BINOP_MUL: + return SSA_MUL; + case BINOP_DIV: + return SSA_DIV; + case BINOP_DOT: + assert(bool_false && "TODO: Implement dot access"); + return 0; + } + return 0; +} + +static CHECK_RESULT SsaRegister binop_generate_ssa(Binop *self, SsaCompilerContext *context) { + SsaRegister lhs_reg; + SsaRegister rhs_reg; + SsaRegister reg; + 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, ®)); + return reg; +} + +CHECK_RESULT SsaRegister ast_generate_ssa(Ast *self, SsaCompilerContext *context) { + switch(self->type) { + case AST_NONE: + return 0; + case AST_NUMBER: + return number_generate_ssa(self->value.number, context); + case AST_FUNCTION_DECL: + return funcdecl_generate_ssa(self->value.func_decl, context); + case AST_FUNCTION_CALL: + return funccall_generate_ssa(self->value.func_call, context); + case AST_LHS: + return lhs_generate_ssa(self->value.lhs_expr, context); + case AST_IMPORT: + /* TODO: When @import(...).data syntax is added, implement the generate ssa for it */ + return 0; + case AST_STRING: + return string_generate_ssa(self->value.string, context); + case AST_VARIABLE: + return variable_generate_ssa(self->value.variable, context); + case AST_BINOP: + return binop_generate_ssa(self->value.binop, context); + } + return 0; } void scope_generate_ssa(Scope *self, SsaCompilerContext *context) { @@ -177,6 +299,6 @@ void scope_generate_ssa(Scope *self, SsaCompilerContext *context) { ast = buffer_start(&self->ast_objects); ast_end = buffer_end(&self->ast_objects); for(; ast != ast_end; ++ast) { - ast_generate_ssa(ast, context); + ignore_result_int(ast_generate_ssa(ast, context)); } } |