#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 /* Important: The number of fields in this enum can't exceed 255 */ 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_AND, SSA_FUNC_START, SSA_FUNC_END, SSA_PUSH, SSA_PUSH_RET, SSA_CALL_START, SSA_CALL, SSA_CALL_EXTERN, SSA_JUMP_ZERO, SSA_JUMP, SSA_RET, SSA_LABEL } 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 struct { FunctionSignature *func_sig; BufferView name; } SsaExportFunc; typedef struct { FunctionSignature *func_sig; } SsaFunc; typedef i16 JumpOffset; typedef i16 SsaRegister; typedef u16 SsaIntermediateIndex; typedef u16 SsaStringIndex; typedef u16 SsaExternFuncIndex; typedef u16 SsaExportFuncIndex; typedef u16 SsaFuncIndex; typedef u16 SsaLabelIndex; 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; Buffer/*SsaExportFunc*/ export_funcs; Buffer/*SsaFunc*/ funcs; SsaIntermediateIndex intermediate_counter; SsaStringIndex string_counter; SsaExternFuncIndex extern_func_counter; SsaExportFuncIndex export_func_counter; SsaFuncIndex func_counter; SsaRegister reg_counter; SsaRegister param_counter; SsaLabelIndex label_counter; Parser *parser; /* Borrowed */ } Ssa; typedef struct { SsaRegister lhs; u16 rhs; } SsaInsForm1; typedef struct { SsaRegister result; SsaRegister lhs; SsaRegister rhs; } SsaInsForm2; typedef struct { u8 flags; u16 num_local_vars_regs; } SsaInsFuncStart; typedef struct { FunctionDecl *func_decl; u8 import_index; } SsaInsFuncCall; typedef struct { LhsExpr *func_decl_lhs; int import_index; } SsaInsFuncCallExtern; typedef struct { u8 num_args; } SsaInsCallStart; typedef struct { SsaRegister condition_reg; SsaLabelIndex target_label; } SsaInsJumpZero; typedef struct { SsaLabelIndex target_label; } 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; /* 0 if the current scope belongs to the file, otherwise ParserFileScopeReference's import_index (the import file that contains the scope) */ u8 import_index; } SsaCompilerContext; /* longjump to context->env on failure */ void scope_generate_ssa(Scope *self, SsaCompilerContext *context); #endif