aboutsummaryrefslogtreecommitdiff
path: root/src/ssa
diff options
context:
space:
mode:
Diffstat (limited to 'src/ssa')
-rw-r--r--src/ssa/ssa.c117
1 files changed, 56 insertions, 61 deletions
diff --git a/src/ssa/ssa.c b/src/ssa/ssa.c
index 01c4f0f..39b5a80 100644
--- a/src/ssa/ssa.c
+++ b/src/ssa/ssa.c
@@ -193,12 +193,11 @@ static CHECK_RESULT int ssa_try_add_extern_func(Ssa *self, FunctionSignature *fu
}
static CHECK_RESULT int ssa_add_ins_form1(Ssa *self, SsaInstruction ins_type, SsaRegister lhs, u16 rhs) {
- const usize index = self->instructions.size;
- return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(SsaRegister) + sizeof(u16)));
- self->instructions.data[index + 0] = ins_type;
- am_memcpy(self->instructions.data + index + 1, &lhs, sizeof(lhs));
- am_memcpy(self->instructions.data + index + 3, &rhs, sizeof(rhs));
- return 0;
+ SsaInsForm1 ins_form_1;
+ ins_form_1.lhs = lhs;
+ ins_form_1.rhs = rhs;
+ return_if_error(buffer_append(&self->instructions, &ins_type, 1));
+ return buffer_append(&self->instructions, &ins_form_1, sizeof(ins_form_1));
}
static const char* binop_type_to_string(SsaInstruction binop_type) {
@@ -214,15 +213,14 @@ static const char* binop_type_to_string(SsaInstruction binop_type) {
}
static CHECK_RESULT int ssa_add_ins_form2(Ssa *self, SsaInstruction ins_type, SsaRegister lhs, SsaRegister rhs, SsaRegister *result) {
- const usize index = self->instructions.size;
+ SsaInsForm2 ins_form_2;
return_if_error(ssa_get_unique_reg(self, result));
- return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(SsaRegister) + sizeof(SsaRegister) + sizeof(SsaRegister)));
- self->instructions.data[index + 0] = ins_type;
- am_memcpy(self->instructions.data + index + 1, result, sizeof(SsaRegister));
- am_memcpy(self->instructions.data + index + 3, &lhs, sizeof(lhs));
- am_memcpy(self->instructions.data + index + 5, &rhs, sizeof(rhs));
+ ins_form_2.result = *result;
+ ins_form_2.lhs = lhs;
+ ins_form_2.rhs = rhs;
amal_log_debug("r%d = r%d %s r%d", *result, lhs, binop_type_to_string(ins_type), rhs);
- return 0;
+ return_if_error(buffer_append(&self->instructions, &ins_type, 1));
+ return buffer_append(&self->instructions, &ins_form_2, sizeof(ins_form_2));
}
static CHECK_RESULT int ssa_ins_assign_inter(Ssa *self, SsaRegister dest, SsaNumber number) {
@@ -250,7 +248,8 @@ static CHECK_RESULT int ssa_ins_binop(Ssa *self, SsaInstruction binop_type, SsaR
}
static CHECK_RESULT int ssa_ins_func_start(Ssa *self, SsaRegister num_reg_params, SsaFuncIndex *result, usize *func_metadata_index) {
- const usize index = self->instructions.size;
+ const u8 ins_type = SSA_FUNC_START;
+ SsaInsFuncStart ins_func_start;
/* Overflow */
if(self->func_counter + 1 <= self->func_counter) {
@@ -258,86 +257,82 @@ static CHECK_RESULT int ssa_ins_func_start(Ssa *self, SsaRegister num_reg_params
return -1;
}
- return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(SsaFuncIndex) + sizeof(SsaRegister) + sizeof(u16)));
*result = self->func_counter++;
- self->instructions.data[index + 0] = SSA_FUNC_START;
- am_memcpy(self->instructions.data + index + 1, result, sizeof(SsaFuncIndex));
- am_memcpy(self->instructions.data + index + 1 + sizeof(SsaFuncIndex), &num_reg_params, sizeof(SsaRegister));
- *func_metadata_index = index + 1 + sizeof(SsaFuncIndex) + sizeof(num_reg_params);
- /* No need to add data to instructions.data here, it can contain undefined data until we set it (@ the caller) */
+ ins_func_start.func_index = *result;
+ ins_func_start.num_params_regs = num_reg_params;
+ /* Dont set number of local registers yet. That will be set by @func_metadata_index later when it's known */
+ /*ins_func_start.num_local_vars_regs = ---*/
+ return_if_error(buffer_append(&self->instructions, &ins_type, 1));
+ return_if_error(buffer_append(&self->instructions, &ins_func_start, sizeof(ins_func_start)));
+ *func_metadata_index = self->instructions.size - sizeof(ins_func_start.num_local_vars_regs);
amal_log_debug("FUNC_START f%u, %d", *result, num_reg_params);
return 0;
}
static CHECK_RESULT int ssa_ins_func_end(Ssa *self) {
- const u8 ins = SSA_FUNC_END;
+ const u8 ins_type = SSA_FUNC_END;
amal_log_debug("FUNC_END");
- return buffer_append(&self->instructions, &ins, 1);
+ return buffer_append(&self->instructions, &ins_type, 1);
}
static CHECK_RESULT int ssa_ins_push(Ssa *self, SsaRegister reg) {
- const usize index = self->instructions.size;
- return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(SsaRegister)));
- self->instructions.data[index + 0] = SSA_PUSH;
- am_memcpy(self->instructions.data + index + 1, &reg, sizeof(SsaRegister));
+ const u8 ins_type = SSA_PUSH;
amal_log_debug("PUSH r%d", reg);
- return 0;
+ return_if_error(buffer_append(&self->instructions, &ins_type, 1));
+ return buffer_append(&self->instructions, &reg, sizeof(reg));
}
static CHECK_RESULT int ssa_ins_call(Ssa *self, FunctionDecl *func_decl, u8 num_args, SsaRegister *result) {
- const usize index = self->instructions.size;
+ const u8 ins_type = SSA_CALL;
+ SsaInsFuncCall ins_func_call;
return_if_error(ssa_get_unique_reg(self, result));
- return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(u8) + sizeof(SsaRegister) + sizeof(func_decl)));
- self->instructions.data[index + 0] = SSA_CALL;
- self->instructions.data[index + 1] = num_args;
- am_memcpy(self->instructions.data + index + 2, result, sizeof(SsaRegister));
- am_memcpy(self->instructions.data + index + 2 + sizeof(SsaRegister), &func_decl, sizeof(func_decl));
+ ins_func_call.num_args = num_args;
+ ins_func_call.result = *result;
+ ins_func_call.func_decl = func_decl;
amal_log_debug("r%d = CALL %d, %p", *result, num_args, func_decl);
- return 0;
+ return_if_error(buffer_append(&self->instructions, &ins_type, 1));
+ return buffer_append(&self->instructions, &ins_func_call, sizeof(ins_func_call));
}
static CHECK_RESULT int ssa_ins_call_extern(Ssa *self, SsaExternFuncIndex extern_func_index, u8 num_args, SsaRegister *result) {
- const usize index = self->instructions.size;
- assert(extern_func_index < self->extern_func_counter);
+ const u8 ins_type = SSA_CALL_EXTERN;
+ SsaInsFuncCallExtern ins_func_call_extern;
return_if_error(ssa_get_unique_reg(self, result));
- return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(u8) + sizeof(SsaRegister) + sizeof(extern_func_index)));
- self->instructions.data[index + 0] = SSA_CALL_EXTERN;
- self->instructions.data[index + 1] = num_args;
- am_memcpy(self->instructions.data + index + 2, result, sizeof(SsaRegister));
- am_memcpy(self->instructions.data + index + 2 + sizeof(SsaRegister), &extern_func_index, sizeof(extern_func_index));
+ assert(extern_func_index < self->extern_func_counter);
+ ins_func_call_extern.num_args = num_args;
+ ins_func_call_extern.result = *result;
+ ins_func_call_extern.extern_func_index = extern_func_index;
amal_log_debug("r%d = CALL_EXTERN %d, %d", *result, num_args, extern_func_index);
- return 0;
+ return_if_error(buffer_append(&self->instructions, &ins_type, 1));
+ return buffer_append(&self->instructions, &ins_func_call_extern, sizeof(ins_func_call_extern));
}
static CHECK_RESULT int ssa_ins_jumpzero(Ssa *self, SsaRegister condition_reg, JumpOffset jump_offset) {
- const usize index = self->instructions.size;
-
- return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(SsaRegister) + sizeof(JumpOffset)));
- self->instructions.data[index + 0] = SSA_JUMP_ZERO;
- am_memcpy(self->instructions.data + index + 1, &condition_reg, sizeof(SsaRegister));
- am_memcpy(self->instructions.data + index + 1 + sizeof(SsaRegister), &jump_offset, sizeof(JumpOffset));
+ const u8 ins_type = SSA_JUMP_ZERO;
+ SsaInsJumpZero ins_jump_zero;
+ ins_jump_zero.condition_reg = condition_reg;
+ ins_jump_zero.jump_offset = jump_offset;
if(jump_offset == 0)
amal_log_debug("JUMP_ZERO r%d, DUMMY", condition_reg);
else
amal_log_debug("JUMP_ZERO r%d, %d", condition_reg, jump_offset);
- return 0;
+ return_if_error(buffer_append(&self->instructions, &ins_type, 1));
+ return buffer_append(&self->instructions, &ins_jump_zero, sizeof(ins_jump_zero));
}
static CHECK_RESULT int ssa_ins_jump(Ssa *self, JumpOffset jump_offset) {
- const usize index = self->instructions.size;
- return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(JumpOffset)));
- self->instructions.data[index + 0] = SSA_JUMP;
- am_memcpy(self->instructions.data + index + 1, &jump_offset, sizeof(JumpOffset));
+ const u8 ins_type = SSA_JUMP;
+ SsaInsJump ins_jump;
+ ins_jump.jump_offset = jump_offset;
amal_log_debug("JUMP %d", jump_offset);
- return 0;
+ return_if_error(buffer_append(&self->instructions, &ins_type, 1));
+ return buffer_append(&self->instructions, &ins_jump, sizeof(ins_jump));
}
static CHECK_RESULT int ssa_ins_return(Ssa *self, SsaRegister reg) {
- const usize index = self->instructions.size;
- return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(SsaRegister)));
- self->instructions.data[index + 0] = SSA_RET;
- am_memcpy(self->instructions.data + index + 1, &reg, sizeof(SsaRegister));
- return 0;
+ const u8 ins_type = SSA_RET;
+ return_if_error(buffer_append(&self->instructions, &ins_type, 1));
+ return buffer_append(&self->instructions, &reg, sizeof(reg));
}
static usize ssa_ins_get_index(Ssa *self) {
@@ -352,9 +347,9 @@ static CHECK_RESULT int ssa_ins_jump_set_target(Ssa *self, usize jump_ins_index)
/* TODO: Should something be done about this? */
if(jump_offset < -0x7FFF || jump_offset > 0x7FFF) {
amal_log_error("Unexpected error. Jump offset has to be less than +-32767, was %d", jump_offset);
- return 1;
+ return -1;
}
- am_memcpy(self->instructions.data + jump_ins_index + 1 + sizeof(SsaRegister), &jump_offset, sizeof(JumpOffset));
+ am_memcpy(self->instructions.data + jump_ins_index + 1 + offsetof(SsaInsJumpZero, jump_offset), &jump_offset, sizeof(JumpOffset));
break;
}
default: