aboutsummaryrefslogtreecommitdiff
path: root/src/bytecode
diff options
context:
space:
mode:
Diffstat (limited to 'src/bytecode')
-rw-r--r--src/bytecode/bytecode.c237
1 files changed, 24 insertions, 213 deletions
diff --git a/src/bytecode/bytecode.c b/src/bytecode/bytecode.c
index 8daa4ce..80cc95b 100644
--- a/src/bytecode/bytecode.c
+++ b/src/bytecode/bytecode.c
@@ -23,49 +23,9 @@ int bytecode_init(Bytecode *self, ArenaAllocator *allocator) {
return buffer_init(&self->data, allocator);
}
-static CHECK_RESULT usize ssa_extract_form1(u8 *instruction_data, SsaInsForm1 *result) {
- am_memcpy(&result->lhs, instruction_data, sizeof(result->lhs));
- am_memcpy(&result->rhs, instruction_data + sizeof(result->lhs), sizeof(result->rhs));
- return sizeof(result->lhs) + sizeof(result->rhs);
-}
-
-static CHECK_RESULT usize ssa_extract_form2(u8 *instruction_data, SsaInsForm2 *result) {
- am_memcpy(&result->result, instruction_data, sizeof(result->result));
- am_memcpy(&result->lhs, instruction_data + sizeof(result->result), sizeof(result->lhs));
- am_memcpy(&result->rhs, instruction_data + sizeof(result->result) + sizeof(result->lhs), sizeof(result->rhs));
- return sizeof(result->result) + sizeof(result->lhs) + sizeof(result->rhs);
-}
-
-static CHECK_RESULT usize ssa_extract_func_start(u8 *instruction_data, SsaInsFuncStart *result) {
- am_memcpy(&result->func_index, instruction_data, sizeof(result->func_index));
- am_memcpy(&result->num_params_regs, instruction_data + sizeof(result->func_index), sizeof(result->num_params_regs));
- am_memcpy(&result->num_local_vars_regs, instruction_data + sizeof(result->func_index) + sizeof(result->num_params_regs), sizeof(result->num_local_vars_regs));
- return sizeof(result->func_index) + sizeof(result->num_params_regs) + sizeof(result->num_local_vars_regs);
-}
-
-static CHECK_RESULT usize ssa_extract_func_call(u8 *instruction_data, SsaInsFuncCall *result) {
- result->num_args = instruction_data[0];
- am_memcpy(&result->result, instruction_data + 1, sizeof(result->result));
- am_memcpy(&result->func_decl, instruction_data + 1 + sizeof(result->result), sizeof(result->func_decl));
- return sizeof(u8) + sizeof(result->result) + sizeof(result->func_decl);
-}
-
-static CHECK_RESULT usize ssa_extract_func_call_extern(u8 *instruction_data, SsaInsFuncCallExtern *result) {
- result->num_args = instruction_data[0];
- am_memcpy(&result->result, instruction_data + 1, sizeof(result->result));
- am_memcpy(&result->extern_func_index, instruction_data + 1 + sizeof(result->result), sizeof(result->extern_func_index));
- return sizeof(u8) + sizeof(result->result) + sizeof(result->extern_func_index);
-}
-
-static CHECK_RESULT usize ssa_extract_jump_zero(u8 *instruction_data, SsaInsJumpZero *result) {
- am_memcpy(&result->condition_reg, instruction_data, sizeof(result->condition_reg));
- am_memcpy(&result->jump_offset, instruction_data + sizeof(result->condition_reg), sizeof(result->jump_offset));
- return sizeof(result->condition_reg) + sizeof(result->jump_offset);
-}
-
-static CHECK_RESULT usize ssa_extract_jump(u8 *instruction_data, SsaInsJump *result) {
- am_memcpy(&result->jump_offset, instruction_data, sizeof(result->jump_offset));
- return sizeof(result->jump_offset);
+static CHECK_RESULT usize ssa_extract_data(u8 *instruction_data, void *result, usize size) {
+ am_memcpy(result, instruction_data, size);
+ return size;
}
static void add_intermediates(BytecodeCompilerContext *self) {
@@ -328,10 +288,6 @@ static void add_instructions(BytecodeCompilerContext *self) {
|Instruction|Instructions data|The instructions data. Each instructions begins with an opcode, see #Opcode|
*/
- Ssa *ssa;
- u8 *instruction;
- u8 *instructions_end;
-
SsaInsForm1 ssa_ins_form1;
SsaInsForm2 ssa_ins_form2;
SsaInsFuncStart ssa_ins_func_start;
@@ -340,210 +296,69 @@ static void add_instructions(BytecodeCompilerContext *self) {
SsaInsJumpZero ssa_ins_jump_zero;
SsaInsJump ssa_ins_jump;
- FILE *file;
- char *filename;
+ Ssa *ssa = self->parser->ssa;
+ u8 *instruction = buffer_begin(&ssa->instructions);
+ u8 *instructions_end = buffer_end(&ssa->instructions);
- u32 num_instructions_index;
- num_instructions_index = self->bytecode.data.size;
+ u32 num_instructions_index = self->bytecode.data.size;
throw_if_error(buffer_append_empty(&self->bytecode.data, sizeof(num_instructions_index)));
- #ifdef COMPILE_TO_C
- LhsExpr *reg_types[NUM_MAX_REGS]; /* TODO: Remove this. Encode this data in the register itself */
- SsaRegister func_arg_stack[NUM_MAX_FUNC_ARGS]; /* TODO: Remove this? */
- int func_arg_index;
- #endif
-
- ssa = self->parser->ssa;
- instruction = buffer_begin(&ssa->instructions);
- instructions_end = buffer_end(&ssa->instructions);
- /*#warning "dont forget to remove this" */
- filename = malloc(self->parser->tokenizer.code_name.size + 3);
- filename[0] = '\0';
- strcat(filename, self->parser->tokenizer.code_name.data);
- strcat(filename, ".z");
- file = fopen(filename, "wb");
- free(filename);
- #ifdef COMPILE_TO_C
- #ifdef DEBUG
- am_memset(reg_types, 0, sizeof(reg_types));
- #endif
- func_arg_index = 0;
-
- fputs("typedef i64 signed long long;\n", file);
- fputs("typedef f64 double;\n", file);
-
- #define ARITH_OP(op) do {\
- const char *rhs_type_name; \
- instruction += ssa_extract_form2(instruction, &ssa_ins_form2); \
- assert(ssa_ins_form2.result < NUM_MAX_REGS); \
- assert(ssa_ins_form2.lhs < NUM_MAX_REGS); \
- rhs_type_name = lhs_expr_get_c_name(self, reg_types[ssa_ins_form2.lhs]); \
- fprintf(file, "%s r%d = r%d %s r%d;\n", rhs_type_name, ssa_ins_form2.result, ssa_ins_form2.lhs, (op), ssa_ins_form2.rhs); \
- reg_types[ssa_ins_form2.result] = reg_types[ssa_ins_form2.lhs]; \
- } while(0)
-
- while(instruction != instructions_end) {
- switch((SsaInstruction)*instruction++) {
- case SSA_ASSIGN_INTER: {
- SsaNumber number;
- instruction += ssa_extract_form1(instruction, &ssa_ins_form1);
- number = ssa_get_intermediate(ssa, ssa_ins_form1.rhs);
- assert(ssa_ins_form1.lhs < NUM_MAX_REGS);
- if(number.type == SSA_NUMBER_TYPE_INTEGER) {
- fprintf(file, "i64 r%d = %zu;\n", ssa_ins_form1.lhs, number.value.integer);
- reg_types[ssa_ins_form1.lhs] = self->parser->compiler->default_types.i64;
- } else if(number.type == SSA_NUMBER_TYPE_FLOAT) {
- fprintf(file, "f64 r%d = %f;\n", ssa_ins_form1.lhs, number.value.floating);
- reg_types[ssa_ins_form1.lhs] = self->parser->compiler->default_types.f64;
- } else {
- assert(bool_false && "TODO: Implement");
- }
- break;
- }
- case SSA_ASSIGN_STRING: {
- BufferView str;
- instruction += ssa_extract_form1(instruction, &ssa_ins_form1);
- str = ssa_get_string(ssa, ssa_ins_form1.rhs);
- fprintf(file, "const char* r%d = \"%.*s\";\n", ssa_ins_form1.lhs, (int)str.size, str.data);
- assert(ssa_ins_form1.lhs < NUM_MAX_REGS);
- reg_types[ssa_ins_form1.lhs] = self->parser->compiler->default_types.str;
- break;
- }
- case SSA_ASSIGN_REG: {
- const char *rhs_type_name;
- instruction += ssa_extract_form1(instruction, &ssa_ins_form1);
- assert(ssa_ins_form1.rhs < NUM_MAX_REGS);
- rhs_type_name = lhs_expr_get_c_name(self, reg_types[ssa_ins_form1.rhs]);
- fprintf(file, "%s r%d = r%d;\n", rhs_type_name, ssa_ins_form1.lhs, ssa_ins_form1.rhs);
- reg_types[ssa_ins_form1.lhs] = reg_types[ssa_ins_form1.rhs];
- break;
- }
- case SSA_ADD: {
- ARITH_OP("+");
- break;
- }
- case SSA_SUB: {
- ARITH_OP("-");
- break;
- }
- case SSA_MUL: {
- ARITH_OP("*");
- break;
- }
- case SSA_DIV: {
- ARITH_OP("/");
- break;
- }
- case SSA_EQUALS: {
- ARITH_OP("==");
- break;
- }
- case SSA_FUNC_START: {
- int i;
- instruction += ssa_extract_func_start(instruction, &ssa_ins_func_start);
- fprintf(file, "void f%zu(", ssa_ins_func_start.func_index);
- fputs(") {\n", file);
- for(i = 0; i < ssa_ins_func_start.num_args; ++i) {
- if(i > 0)
- fputs(", ", file);
- fprintf(file, "p%d", i);
- }
- break;
- }
- case SSA_FUNC_END:
- fputs("}\n", file);
- break;
- case SSA_PUSH: {
- SsaRegister reg;
- am_memcpy(&reg, instruction, sizeof(SsaRegister));
- instruction += sizeof(SsaRegister);
- assert(func_arg_index < NUM_MAX_FUNC_ARGS);
- func_arg_stack[func_arg_index++] = reg;
- break;
- }
- case SSA_CALL: {
- int i;
- instruction += ssa_extract_func_call(instruction, &ssa_ins_func_call);
- fprintf(file, "r%d = f%p(", ssa_ins_func_call.result, ssa_ins_func_call.func_decl);
- for(i = 0; i < func_arg_index; ++i) {
- if(i > 0)
- fputs(", ", file);
- fprintf(file, "r%d", func_arg_stack[i]);
- }
- func_arg_index = 0;
- fputs(");\n", file);
- break;
- }
- case SSA_JUMP_ZERO: {
- assert(bool_false && "Not implemented!");
- instruction += ssa_extract_jump_zero(instruction, &ssa_ins_jump_zero);
- break;
- }
- case SSA_JUMP: {
- assert(bool_false && "Not implemented!");
- instruction += ssa_extract_jump(instruction, &ssa_ins_jump);
- break;
- }
- }
- }
- #else
/* TODO: Keep all registers under 256 */
-
while(instruction != instructions_end) {
SsaInstruction ins = (SsaInstruction)*instruction++;
switch(ins) {
case SSA_ASSIGN_INTER: {
- instruction += ssa_extract_form1(instruction, &ssa_ins_form1);
+ instruction += ssa_extract_data(instruction, &ssa_ins_form1, sizeof(ssa_ins_form1));
add_ins6(self, AMAL_OP_MOVI, ssa_ins_form1.lhs, ssa_ins_form1.rhs, "movi r%d, i%d");
break;
}
case SSA_ASSIGN_STRING: {
- instruction += ssa_extract_form1(instruction, &ssa_ins_form1);
+ instruction += ssa_extract_data(instruction, &ssa_ins_form1, sizeof(ssa_ins_form1));
add_ins6(self, AMAL_OP_MOVD, ssa_ins_form1.lhs, ssa_ins_form1.rhs, "movd r%d, s%d");
break;
}
case SSA_ASSIGN_REG: {
- instruction += ssa_extract_form1(instruction, &ssa_ins_form1);
+ instruction += ssa_extract_data(instruction, &ssa_ins_form1, sizeof(ssa_ins_form1));
add_ins3(self, AMAL_OP_MOV, ssa_ins_form1.lhs, ssa_ins_form1.rhs, "mov r%d, r%d");
break;
}
case SSA_ADD: {
- instruction += ssa_extract_form2(instruction, &ssa_ins_form2);
+ instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
add_ins5(self, AMAL_OP_ADD, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "add r%d, r%d, r%d");
break;
}
case SSA_SUB: {
- instruction += ssa_extract_form2(instruction, &ssa_ins_form2);
+ instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
add_ins5(self, AMAL_OP_SUB, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "sub r%d, r%d, r%d");
break;
}
case SSA_IMUL: {
- instruction += ssa_extract_form2(instruction, &ssa_ins_form2);
+ instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
add_ins5(self, AMAL_OP_IMUL, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "imul r%d, r%d, r%d");
break;
}
case SSA_MUL: {
- instruction += ssa_extract_form2(instruction, &ssa_ins_form2);
+ instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
add_ins5(self, AMAL_OP_MUL, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "mul r%d, r%d, r%d");
break;
}
case SSA_IDIV: {
- instruction += ssa_extract_form2(instruction, &ssa_ins_form2);
+ instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
add_ins5(self, AMAL_OP_IDIV, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "idiv r%d, r%d, r%d");
break;
}
case SSA_DIV: {
- instruction += ssa_extract_form2(instruction, &ssa_ins_form2);
+ instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
add_ins5(self, AMAL_OP_DIV, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "div r%d, r%d, r%d");
break;
}
case SSA_EQUALS: {
- instruction += ssa_extract_form2(instruction, &ssa_ins_form2);
+ instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
add_ins5(self, AMAL_OP_CMP, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "cmp r%d, r%d, r%d");
break;
}
case SSA_FUNC_START: {
- instruction += ssa_extract_func_start(instruction, &ssa_ins_func_start);
+ instruction += ssa_extract_data(instruction, &ssa_ins_func_start, sizeof(ssa_ins_func_start));
add_ins6(self, AMAL_OP_FUNC_START, ssa_ins_func_start.num_params_regs, ssa_ins_func_start.num_local_vars_regs, "func_start %d, %u");
break;
}
@@ -567,22 +382,22 @@ static void add_instructions(BytecodeCompilerContext *self) {
the function indices can be increased by their block index (ssa_func_index + block index), where block index
is defined as the size of all previous files' number of functions.
*/
- instruction += ssa_extract_func_call(instruction, &ssa_ins_func_call);
+ instruction += ssa_extract_data(instruction, &ssa_ins_func_call, sizeof(ssa_ins_func_call));
add_ins7(self, AMAL_OP_CALL, ssa_ins_func_call.func_decl->ssa_func_index, ssa_ins_func_call.num_args, ssa_ins_func_call.result, "call f%d, %d, r%d");
break;
}
case SSA_CALL_EXTERN: {
- instruction += ssa_extract_func_call_extern(instruction, &ssa_ins_func_call_extern);
+ instruction += ssa_extract_data(instruction, &ssa_ins_func_call_extern, sizeof(ssa_ins_func_call_extern));
add_ins7(self, AMAL_OP_CALLE, ssa_ins_func_call_extern.extern_func_index, ssa_ins_func_call_extern.num_args, ssa_ins_func_call_extern.result, "calle ef%d, %d, r%d");
break;
}
case SSA_JUMP_ZERO: {
- instruction += ssa_extract_jump_zero(instruction, &ssa_ins_jump_zero);
+ instruction += ssa_extract_data(instruction, &ssa_ins_jump_zero, sizeof(ssa_ins_jump_zero));
add_ins6(self, AMAL_OP_JZ, ssa_ins_jump_zero.condition_reg, ssa_ins_jump_zero.jump_offset, "jz r%d, %d");
break;
}
case SSA_JUMP: {
- instruction += ssa_extract_jump(instruction, &ssa_ins_jump);
+ instruction += ssa_extract_data(instruction, &ssa_ins_jump, sizeof(ssa_ins_jump));
add_ins4(self, AMAL_OP_JMP, ssa_ins_jump.jump_offset, "jmp %d");
break;
}
@@ -598,14 +413,10 @@ static void add_instructions(BytecodeCompilerContext *self) {
/* Prepend instructions with its size */
{
- u32 instructions_size;
/* -sizeof to Remove the count itself from the size of the instructions size */
- instructions_size = self->bytecode.data.size - num_instructions_index - sizeof(instructions_size);
- am_memcpy(&self->bytecode.data.data[num_instructions_index], &instructions_size, sizeof(instructions_size));
+ const u32 instructions_size = self->bytecode.data.size - num_instructions_index - sizeof(instructions_size);
+ am_memcpy(self->bytecode.data.data + num_instructions_index, &instructions_size, sizeof(instructions_size));
}
-
- #endif /* COMPILE_TO_C */
- fclose(file);
}
void generate_bytecode_from_ssa(BytecodeCompilerContext *self) {