#ifndef AMALGAM_SSA_H #define AMALGAM_SSA_H #include "../std/buffer.h" #include "../std/hash_map.h" #include "../std/defs.h" #include "../defs.h" #include #define SSA_ERR_EXTERN_FUNC_SIG_MISMATCH -20 typedef enum { SSA_ASSIGN_INTER, SSA_ASSIGN_STRING, SSA_ASSIGN_REG, SSA_ADD, SSA_SUB, SSA_IMUL, SSA_MUL, SSA_IDIV, SSA_DIV, SSA_EQUALS, SSA_FUNC_START, SSA_FUNC_END, SSA_PUSH, SSA_CALL, SSA_CALL_EXTERN, SSA_JUMP_ZERO, SSA_JUMP, SSA_RET } SsaInstruction; typedef enum { SSA_NUMBER_TYPE_INTEGER, SSA_NUMBER_TYPE_FLOAT } SsaNumberType; typedef struct { union { i64 integer; f64 floating; } value; SsaNumberType type; } SsaNumber; typedef struct { FunctionSignature *func_sig; BufferView name; } SsaExternFunc; typedef i16 JumpOffset; typedef i16 SsaRegister; typedef u16 SsaIntermediateIndex; typedef u16 SsaStringIndex; typedef u16 SsaExternFuncIndex; typedef u16 SsaFuncIndex; typedef struct { Buffer/*instruction data*/ instructions; HashMapType(SsaNumber, SsaIntermediateIndex) intermediates_map; Buffer/*SsaNumber*/ intermediates; HashMapType(BufferView, SsaStringIndex) strings_map; Buffer/*BufferView*/ strings; HashMapType(BufferView, SsaExternFuncIndex) extern_funcs_map; Buffer/*SsaExternFunc*/ extern_funcs; SsaIntermediateIndex intermediate_counter; SsaStringIndex string_counter; SsaExternFuncIndex extern_func_counter; SsaRegister reg_counter; SsaRegister param_counter; SsaFuncIndex func_counter; Parser *parser; /* Borrowed */ } Ssa; typedef struct { SsaRegister lhs; u16 rhs; } SsaInsForm1; typedef struct { SsaRegister result; SsaRegister lhs; SsaRegister rhs; } SsaInsForm2; typedef struct { SsaFuncIndex func_index; u16 num_params_regs; u16 num_local_vars_regs; } SsaInsFuncStart; typedef struct { u8 num_args; SsaRegister result; FunctionDecl *func_decl; } SsaInsFuncCall; typedef struct { u8 num_args; SsaRegister result; SsaExternFuncIndex extern_func_index; } SsaInsFuncCallExtern; typedef struct { SsaRegister condition_reg; JumpOffset jump_offset; } SsaInsJumpZero; typedef struct { JumpOffset jump_offset; } SsaInsJump; /* None of these functions are thread-safe */ SsaNumber create_ssa_integer(i64 value); SsaNumber create_ssa_float(f64 value); SsaNumber ssa_get_intermediate(Ssa *self, SsaIntermediateIndex index); BufferView ssa_get_string(Ssa *self, SsaStringIndex index); CHECK_RESULT int ssa_init(Ssa *self, Parser *parser); typedef struct { jmp_buf env; Ssa *ssa; amal_compiler *compiler; } SsaCompilerContext; /* longjump to context->env on failure */ void scope_generate_ssa(Scope *self, SsaCompilerContext *context); #endif