Trying to do some ir stuff

This commit is contained in:
Krzosa Karol
2022-06-24 21:56:21 +02:00
parent dfd848bced
commit 6dd904346e
2 changed files with 196 additions and 1 deletions

194
bytecode_codegen.cpp Normal file
View File

@@ -0,0 +1,194 @@
typedef S32 Register_Index;
union Register{
F64 f64;
S64 s64;
S64 *pointer_s64;
F64 *pointer_f64;
U8 *pointer;
U64 *pointer64;
U64 *pointer_u64;
U32 *pointer_u32;
U16 *pointer_u16;
U8 *pointer_u8;
U64 u64;
U32 u32;
U16 u16;
U8 u8;
};
static_assert(sizeof(Register) == 8, "not 8 bytes");
enum Ir_Storage_Kind{
STORAGE_NULL,
STORAGE_GLOBAL,
STORAGE_CONSTANT,
STORAGE_REGISTER,
STORAGE_STACK,
};
struct Ir_Storage{
Ast_Type *type;
Ir_Storage *next;
Ir_Storage_Kind kind;
union{ S64 register_index; S64 offset; Register constant; };
};
enum Ir_Instruction_Kind{
IR_NOOP,
IR_STORE,
IR_LOAD,
IR_ADD,
IR_SUB,
IR_MUL,
IR_DIV,
};
struct Ir_Instruction{
Ir_Instruction_Kind kind;
Ir_Storage *a;
Ir_Storage *b;
Ir_Storage *c;
};
struct Ir_Block{
Simple_Bucket_Array<Ir_Instruction, 64> instructions;
};
struct Ir_Call;
struct Ir_Var{
Ast_Decl *decl;
Ir_Storage storage;
Ir_Call *call;
Simple_Bucket_Array<Ir_Block, 16> blocks;
};
struct Ir_Call{
Ast_Decl *decl;
Array<Register_Index> used_registers;
Array<Register_Index> free_registers;
Register_Index register_ids;
Ir_Storage return_value;
Simple_Bucket_Array<Ir_Var, 4> args;
Simple_Bucket_Array<Ir_Block, 8> blocks;
};
struct Ir_Builder{
#define IR_NEW(T) exp_alloc_type(ir->arena, T, AF_ZeroMemory)
Arena _arena;
Arena *arena;
Simple_Bucket_Array<Ir_Var, 32> global_variables;
Simple_Bucket_Array<Ir_Call, 64> calls;
};
function Register_Index
allocate_register(Ir_Call *call){
Register_Index result = -1;
if(call->free_registers.len > 0){
result = call->free_registers.pop();
}
else{
result = call->register_ids++;
}
assert(result != -1);
call->used_registers.add(result);
return result;
}
function void
release_register(Ir_Call *call, Register_Index index){
if(index == -1) return;
B32 found = false;
For(call->used_registers){
if(index == it){
call->used_registers.unordered_remove(&it);
found = true;
break;
}
}
assert_msg(found, "Internal compiler error: releasing register that is not marked as used");
call->free_registers.add(index);
}
function void
build_bytecode(){
Ir_Builder ir_builder = {};
arena_init(&ir_builder._arena, "Ir builder arena"_s);
ir_builder.arena = &ir_builder._arena;
Ir_Builder *ir = &ir_builder;
For_Named(pctx->ordered_decls, ast){
switch(ast->kind){
CASE(LAMBDA, Decl){
Ir_Call *call = ir->calls.allocate(ir->arena);
call->decl = node;
// @todo multiple return values
call->return_value.type = node->lambda->ret[0]->resolved_type;
call->free_registers = array_make<Register_Index>(ir->arena, 32);
call->used_registers = array_make<Register_Index>(ir->arena, 32);
For_It(node->lambda->args){
Ir_Var *arg = call->args.allocate(ir->arena);
arg->decl = *it.it;
arg->call = call;
arg->storage.kind = STORAGE_REGISTER;
arg->storage.register_index = allocate_register(call);
}
// @todo: Allocate all variables in function
//
//
For(node->lambda->scope->stmts){
CASE(VAR, Decl){
BREAK();
}
}
BREAK();
}
CASE(VAR, Decl){
if(is_flag_set(node->flags, AST_FOREIGN)){
break; // @todo
}
if(!is_flag_set(node->flags, AST_VAR_IS_CONST)){
compiler_error(node->pos, "Global variable has value assigned that is not constant and requires computation");
}
Ir_Var *v = ir->global_variables.allocate(ir->arena);
v->decl = node;
v->storage.kind = STORAGE_GLOBAL;
v->storage.type = node->type;
if(node->type->size <= 8){
switch(node->type->kind){
CASE_UINT: v->storage.constant.u64 = bigint_as_unsigned(&node->big_int_val); break;
CASE_SINT: v->storage.constant.s64 = bigint_as_signed(&node->big_int_val); break;
CASE_FLOAT: v->storage.constant.f64 = node->f64_val; break;
invalid_default_case;
}
}
else {
// Doesn't fit in register
invalid_codepath;
}
BREAK();
}
default: {};
}
}
}

View File

@@ -171,7 +171,7 @@ want to export all the symbols, we can namespace them optionally.
#include "c_language_codegen.cpp"
#include "intermediate_representation.cpp"
// #include "bytecode_interpreter.cpp"
// #include "bytecode_codegen.cpp"
#include "bytecode_codegen.cpp"
int main(int argument_count, char **arguments){
@@ -236,6 +236,7 @@ int main(int argument_count, char **arguments){
arena_clear(&pctx->stage_arena);
build_bytecode();
// compile_to_bc();
// __debugbreak();
String result = get_compilation_result();