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);
|