aboutsummaryrefslogtreecommitdiff
path: root/ir.h
blob: b359d00dda8bfb8a6cd7cd54502c3266c2297fcb (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
#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);