aboutsummaryrefslogtreecommitdiff
path: root/include/ssa/ssa.h
blob: a21b45ac44b27dd18ca6ef850ca00ca3fcdd551e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#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 <setjmp.h>

typedef enum {
    SSA_ASSIGN_INTER,
    SSA_ASSIGN_REG,
    SSA_ADD,
    SSA_SUB,
    SSA_MUL,
    SSA_DIV,
    SSA_FUNC_START,
    SSA_FUNC_END,
    SSA_PUSH,
    SSA_CALL
} SsaInstructionType;

typedef enum {
    SSA_NUMBER_TYPE_INTEGER,
    SSA_NUMBER_TYPE_FLOAT
} SsaNumberType;

typedef struct {
    i64 value;
    SsaNumberType type;
} SsaNumber;

typedef u16 SsaRegister;
typedef u16 SsaIntermediateIndex;
typedef u32 SsaFuncIndex;

typedef struct {
    Buffer/*instruction data*/ instructions;
    HashMap/*<SsaNumberType, IntermediateIndex>*/ intermediates;
    SsaIntermediateIndex intermediate_counter;
    SsaRegister reg_counter;
    SsaFuncIndex func_counter;
} Ssa;

/* None of these functions are thread-safe */
SsaNumber create_ssa_number(i64 value, SsaNumberType type);

CHECK_RESULT int ssa_init(Ssa *self, ScopedAllocator *allocator);
CHECK_RESULT int ssa_get_unique_reg(Ssa *self, SsaRegister *result);
CHECK_RESULT int ssa_ins_assign_inter(Ssa *self, SsaRegister dest, SsaNumber number);
CHECK_RESULT int ssa_ins_assign_reg(Ssa *self, SsaRegister dest, SsaRegister src);
CHECK_RESULT int ssa_ins_binop(Ssa *self, SsaInstructionType binop_type, SsaRegister lhs, SsaRegister rhs, SsaRegister *result);
CHECK_RESULT int ssa_ins_func_start(Ssa *self, u8 num_args, SsaFuncIndex *result);
CHECK_RESULT int ssa_ins_func_end(Ssa *self);
CHECK_RESULT int ssa_ins_push(Ssa *self, SsaRegister reg);
CHECK_RESULT int ssa_ins_call(Ssa *self, SsaFuncIndex func, SsaRegister *result);


typedef struct {
    jmp_buf env;
    Parser *parser;
    Ssa ssa;
} SsaCompilerContext;

/* longjump to compiler env on failure */
void scope_generate_ssa(Scope *self, SsaCompilerContext *context);

#endif