diff options
Diffstat (limited to 'src/ir.c')
-rw-r--r-- | src/ir.c | 115 |
1 files changed, 1 insertions, 114 deletions
@@ -1,121 +1,8 @@ | |||
1 | typedef enum Operator { | 1 | #include "ir.h" |
2 | // Arithmetic ops. | ||
3 | OP_ADD, | ||
4 | OP_SUB, | ||
5 | OP_MUL, | ||
6 | OP_DIV, | ||
7 | OP_MOD, | ||
8 | |||
9 | // Load/store/copy operations. | ||
10 | OP_LD8, | ||
11 | OP_LD16, | ||
12 | OP_LD32, | ||
13 | OP_LD64, | ||
14 | OP_ST8, | ||
15 | OP_ST16, | ||
16 | OP_ST32, | ||
17 | OP_ST64, | ||
18 | OP_CP8, | ||
19 | OP_CP16, | ||
20 | OP_CP32, | ||
21 | OP_CP64, | ||
22 | |||
23 | // Bit fiddling operations. | ||
24 | OP_NOT, | ||
25 | OP_AND, | ||
26 | OP_OR, | ||
27 | OP_XOR, | ||
28 | OP_LSHIFT, | ||
29 | OP_RSHIFT, | ||
30 | OP_LROT, | ||
31 | OP_RROT, | ||
32 | |||
33 | // (Un)conditional jump operations. | ||
34 | OP_LABEL, | ||
35 | OP_JMP, | ||
36 | OP_JMP_EQ, | ||
37 | OP_JMP_NEQ, | ||
38 | OP_JMP_GT, | ||
39 | OP_JMP_LT, | ||
40 | OP_JMP_GE, | ||
41 | OP_JMP_LE, | ||
42 | } Operator; | ||
43 | |||
44 | typedef enum OperandType { | ||
45 | OP_TYPE_REG, | ||
46 | OP_TYPE_CONST, | ||
47 | OP_TYPE_LABEL, | ||
48 | } OperandType; | ||
49 | 2 | ||
50 | static size_t reg_gen_id = 0; | 3 | static size_t reg_gen_id = 0; |
51 | static size_t lab_gen_id = 0; | 4 | static size_t lab_gen_id = 0; |
52 | 5 | ||
53 | #define NEW_REG() (Operand){ .type = OP_TYPE_REG, .id = reg_gen_id++ } | ||
54 | #define NEW_LAB() (Operand){ .type = OP_TYPE_LABEL, .id = lab_gen_id++ } | ||
55 | #define NEW_S64(C) (Operand){ .type = OP_TYPE_CONST, .constant.sval = (C) } | ||
56 | #define EMIT_0(PROGRAM, LINE, OP, DST) do { \ | ||
57 | Instruction inst = (Instruction){ \ | ||
58 | .op = (OP), \ | ||
59 | .dst = (DST), \ | ||
60 | }; \ | ||
61 | array_push((PROGRAM)->inst, inst); \ | ||
62 | array_push((PROGRAM)->lines, (LINE)); \ | ||
63 | } while(false); | ||
64 | #define EMIT_1(PROGRAM, LINE, OP, DST, A) do { \ | ||
65 | Instruction inst = (Instruction){ \ | ||
66 | .op = (OP), \ | ||
67 | .dst = (DST), \ | ||
68 | .src_a = (A), \ | ||
69 | }; \ | ||
70 | array_push((PROGRAM)->inst, inst); \ | ||
71 | array_push((PROGRAM)->lines, (LINE)); \ | ||
72 | } while(false); | ||
73 | #define EMIT_2(PROGRAM, LINE, OP, DST, A, B) do { \ | ||
74 | Instruction inst = (Instruction){ \ | ||
75 | .op = (OP), \ | ||
76 | .dst = (DST), \ | ||
77 | .src_a = (A), \ | ||
78 | .src_b = (B), \ | ||
79 | }; \ | ||
80 | array_push((PROGRAM)->inst, inst); \ | ||
81 | array_push((PROGRAM)->lines, (LINE)); \ | ||
82 | } while(false); | ||
83 | |||
84 | typedef struct Operand { | ||
85 | OperandType type; | ||
86 | union { | ||
87 | // REG/LABEL | ||
88 | size_t id; | ||
89 | |||
90 | // s64 constant; | ||
91 | struct { | ||
92 | union { | ||
93 | u64 uval; | ||
94 | s64 sval; | ||
95 | }; | ||
96 | } constant; | ||
97 | }; | ||
98 | } Operand; | ||
99 | |||
100 | typedef struct Instruction { | ||
101 | Operator op; | ||
102 | Operand dst; | ||
103 | Operand src_a; | ||
104 | Operand src_b; | ||
105 | } Instruction; | ||
106 | |||
107 | typedef struct LineInfo { | ||
108 | size_t line; | ||
109 | size_t col; | ||
110 | } LineInfo; | ||
111 | |||
112 | typedef struct ProgramBASM { | ||
113 | Instruction *inst; | ||
114 | LineInfo *lines; | ||
115 | } ProgramBASM; | ||
116 | |||
117 | Operand emit_basm(ProgramBASM *program, Node *node); | ||
118 | |||
119 | Operand | 6 | Operand |
120 | emit_arith(ProgramBASM *program, Node *node, Operator op) { | 7 | emit_arith(ProgramBASM *program, Node *node, Operator op) { |
121 | LineInfo line = (LineInfo){ | 8 | LineInfo line = (LineInfo){ |