aboutsummaryrefslogtreecommitdiff
path: root/ir.c
diff options
context:
space:
mode:
Diffstat (limited to 'ir.c')
-rw-r--r--ir.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/ir.c b/ir.c
new file mode 100644
index 0000000..9d28e2f
--- /dev/null
+++ b/ir.c
@@ -0,0 +1,110 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "ir.h"
+
+
+struct ir* ir_make(void) {
+ struct ir *ir = malloc(sizeof(struct ir));
+ ir->cap = 32;
+ ir->len = 0;
+ ir->inss = malloc(ir->cap * sizeof(struct irins*));
+ ir->globspace = 0;
+ return ir;
+}
+
+void ir_delete(struct ir *ir) {
+ for (int i = 0; i < ir->len; i++) {
+ irins_delete(ir->inss[i]);
+ }
+ free(ir->inss);
+ free(ir);
+}
+
+struct ref ir_reserve_global(struct ir *ir, int size) {
+ int offset = ir->globspace;
+ ir->globspace += size;
+ return ref_mem(-1, offset, true);
+}
+
+void ir_append(struct ir *ir, struct irins *ins) {
+ if (ir->len == ir->cap) {
+ ir->cap *= 2;
+ ir->inss = realloc(ir->inss, ir->cap * sizeof(struct irins*));
+ }
+ ir->inss[ir->len++] = ins;
+}
+
+struct irins* irins_make(enum instype type) {
+ struct irins *ins = malloc(sizeof(struct irins));
+ ins->type = type;
+ ins->name = NULL;
+ return ins;
+}
+
+struct irins* irins_make_name(enum instype type, char *name) {
+ struct irins *ins = irins_make(type);
+ ins->name = name;
+ return ins;
+}
+
+struct irins* irins_make_01(enum instype type, struct ref r0, struct ref r1) {
+ struct irins *ins = irins_make(type);
+ ins->r0 = r0;
+ ins->r1 = r1;
+ return ins;
+}
+
+struct irins* irins_make_012(enum instype type, struct ref r0, struct ref r1, struct ref r2) {
+ struct irins *ins = irins_make_01(type, r0, r1);
+ ins->r2 = r2;
+ return ins;
+}
+
+struct irins* irins_make_1(enum instype type, struct ref r1) {
+ struct irins *ins = irins_make(type);
+ ins->r1 = r1;
+ return ins;
+}
+
+struct irins* irins_make_12(enum instype type, struct ref r1, struct ref r2) {
+ struct irins *ins = irins_make(type);
+ ins->r1 = r1;
+ ins->r2 = r2;
+ return ins;
+}
+
+struct irins* irins_make_jcc(char *name, enum condcode condcode) {
+ struct irins *ins = irins_make(INS_JCC);
+ ins->name = name;
+ ins->condcode = condcode;
+ return ins;
+}
+
+void irins_delete(struct irins *ins) {
+ if (ins->name) free(ins->name);
+ free(ins);
+}
+
+char* gen_label_name(void) {
+ static int next = 0;
+ char *buf = malloc(16);
+ sprintf(buf, "L%d", next++);
+ return buf;
+}
+
+struct ref ref_reg(int reg) {
+ return (struct ref){REF_REG, reg, 0, false, 0};
+}
+
+struct ref ref_mem(int reg, int offset, bool rel_heap) {
+ return (struct ref){REF_MEM, reg, offset, rel_heap, 0};
+}
+
+struct ref ref_imm(int imm) {
+ return (struct ref){REF_IMM, -1, 0, false, imm};
+}
+
+struct ref ref_next_register(void) {
+ static int next = 0;
+ return ref_reg(next++);
+}