aboutsummaryrefslogtreecommitdiff
path: root/ir.c
blob: 9d28e2fabb6314b827cc3c96938daebb4c284838 (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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
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++);
}