diff options
Diffstat (limited to 'src/bytecode')
-rw-r--r-- | src/bytecode/bytecode.c | 237 |
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(®, 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) { |