aboutsummaryrefslogtreecommitdiff
path: root/src/ssa/ssa.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ssa/ssa.c')
-rw-r--r--src/ssa/ssa.c144
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, &reg));
+ 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, &reg));
+ 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, &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));
}
}