aboutsummaryrefslogtreecommitdiff
path: root/ir.h
diff options
context:
space:
mode:
Diffstat (limited to 'ir.h')
-rw-r--r--ir.h83
1 files changed, 83 insertions, 0 deletions
diff --git a/ir.h b/ir.h
new file mode 100644
index 0000000..b359d00
--- /dev/null
+++ b/ir.h
@@ -0,0 +1,83 @@
+#pragma once
+
+#include <stdbool.h>
+
+
+// IR uses an unlimited number of registers. This will later be fixed by a regalloc.
+
+enum instype {
+ INS_ADD, // r0 = r1 + r2
+ INS_SUB, // r0 = r1 - r2
+ INS_MUL, // r0 = r1 * r2
+ INS_DIV, // r0 = r1 / r2
+ INS_MOD, // r0 = r1 % r2
+ INS_NEG, // r0 = -r1
+ INS_NOT, // r0 = !r1
+ INS_TEST, // r1 & r2 (flags)
+ INS_PUSH, // push r1
+ INS_POP, // r0 = pop
+ INS_CMP, // r1 - r2 (flags)
+ INS_LBL, // label name
+ INS_JMP, // jmp name
+ INS_JCC, // if condcode, jmp name
+ INS_CALL, // call name
+ INS_RET, // return
+ INS_RETV, // return r1
+ INS_MOV, // r0 = r1
+};
+
+enum condcode {
+ CCZ, CCNZ, CCL, CCG, CCLE, CCGE
+};
+
+enum reftype {
+ REF_REG, // reg
+ REF_MEM, // [reg + offset + (rel_heap ? heap_base : 0)]
+ REF_IMM, // imm
+};
+
+struct ref {
+ enum reftype type;
+ int reg; // if -1 in a REF_MEM, unused
+ int offset;
+ bool rel_heap; // whether the heap base address should be added to the offset
+ int imm;
+};
+
+struct irins {
+ enum instype type;
+ struct ref r0, r1, r2;
+ char *name;
+ enum condcode condcode;
+};
+
+struct ir {
+ int cap, len;
+ struct irins **inss;
+ int globspace;
+};
+
+
+struct ir* ir_make(void);
+void ir_delete(struct ir *ir);
+
+// returns offset
+struct ref ir_reserve_global(struct ir *ir, int size);
+
+void ir_append(struct ir *ir, struct irins *ins);
+
+struct irins* irins_make(enum instype type);
+struct irins* irins_make_name(enum instype type, char *name);
+struct irins* irins_make_01(enum instype type, struct ref r0, struct ref r1);
+struct irins* irins_make_012(enum instype type, struct ref r0, struct ref r1, struct ref r2);
+struct irins* irins_make_1(enum instype type, struct ref r1);
+struct irins* irins_make_12(enum instype type, struct ref r1, struct ref r2);
+struct irins* irins_make_jcc(char *name, enum condcode condcode);
+void irins_delete(struct irins *ins);
+
+char* gen_label_name(void);
+
+struct ref ref_reg(int reg);
+struct ref ref_mem(int reg, int offset, bool rel_heap);
+struct ref ref_imm(int imm);
+struct ref ref_next_register(void);