aboutsummaryrefslogtreecommitdiffstats
path: root/src/ir.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir.c')
-rw-r--r--src/ir.c115
1 files changed, 1 insertions, 114 deletions
diff --git a/src/ir.c b/src/ir.c
index 075ebe3..f1b7eb9 100644
--- a/src/ir.c
+++ b/src/ir.c
@@ -1,121 +1,8 @@
1typedef 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
44typedef enum OperandType {
45 OP_TYPE_REG,
46 OP_TYPE_CONST,
47 OP_TYPE_LABEL,
48} OperandType;
49 2
50static size_t reg_gen_id = 0; 3static size_t reg_gen_id = 0;
51static size_t lab_gen_id = 0; 4static 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
84typedef 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
100typedef struct Instruction {
101 Operator op;
102 Operand dst;
103 Operand src_a;
104 Operand src_b;
105} Instruction;
106
107typedef struct LineInfo {
108 size_t line;
109 size_t col;
110} LineInfo;
111
112typedef struct ProgramBASM {
113 Instruction *inst;
114 LineInfo *lines;
115} ProgramBASM;
116
117Operand emit_basm(ProgramBASM *program, Node *node);
118
119Operand 6Operand
120emit_arith(ProgramBASM *program, Node *node, Operator op) { 7emit_arith(ProgramBASM *program, Node *node, Operator op) {
121 LineInfo line = (LineInfo){ 8 LineInfo line = (LineInfo){