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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
#include "common.h"
enum irclass {
KXXX,
KI4, KI8, KPTR,
KF4, KF8,
};
#define kisint(k) in_range((k), KI4, KIP)
#define kisflt(k) in_range((k), KF4, KF8)
union irtype {
struct { ushort isagg : 1, cls : 15; };
struct { ushort _ : 1, dat : 15; };
ushort bits;
};
struct irdat {
uchar align : 7, mut : 1;
uint siz;
union {
vec_of(uchar) dat;
uchar sdat[8];
};
struct symref {
struct symref *next;
const char *sym;
uint off;
vlong addend;
} *syms;
};
struct xcon {
bool issym;
uchar cls;
union {
const char *sym;
int i4;
vlong i8;
float fs;
double fd;
};
};
struct call {
short narg;
short vararg; /* first variadic arg or -1 */
union irtype *typs;
union ref *args;
};
struct phi {
struct block **blk;
union ref *ref;
int n, cap;
};
enum refkind {
RNONE, RTMP, RARG, RICON, RXCON, RSYM, REXT
};
union ref {
struct { uint t : 3, idx : 29; };
struct { signed _0: 3, i : 29; }; /* RICON */
uint bits;
};
enum op {
Oxxx,
#define _(o,...) O##o,
#include "op.def"
#undef _
};
struct instr {
uchar op;
uchar cls;
union ref l, r;
};
enum jumpkind {
JXXX, Jb, Jbcnd, Jret, Jrets,
};
struct block {
int id;
struct block *s1, *s2;
struct { uchar t; union ref arg; } jmp;
vec_of(ushort) phi;
vec_of(ushort) ins;
struct block *lprev, *lnext;
};
struct function {
struct arena *arena;
const char *name;
struct block *entry, *curblk;
union type fnty, retty, *paramty;
uint nblk;
uint nparam;
bool globl;
};
extern uchar type2cls[];
extern uchar cls2siz[];
extern const uchar siz2intcls[];
void irinit(struct function *);
#define NOREF ((union ref) {0})
#define mkref(t, x) ((union ref) {{ (t), (x) }})
#define mkzerocon() ((union irref){ RICON, 0 })
union irtype mkirtype(union type);
union ref mkintcon(struct function *, enum irclass, vlong);
union ref mkfltcon(struct function *, enum irclass, double);
union ref mksymref(struct function *, const char *);
void conputdat(struct irdat *, uint off, enum typetag t, const void *dat);
union ref mkcall(struct function *, union type fnty, uint narg, union ref *, union irtype *);
union ref addinstr(struct function *, struct instr);
union ref addphi2(struct function *, enum irclass cls,
struct block *b1, union ref r1, struct block *b2, union ref r2);
union ref addphi(struct function *, enum irclass cls, struct block **blk, union ref *ref, uint n);
struct block *newblk(struct function *);
void useblk(struct function *, struct block *);
void putjump(struct function *, enum jumpkind, union ref arg, struct block *t, struct block *f);
void irdump(struct function *, const char *fname);
/* vim:set ts=3 sw=3 expandtab: */
|