-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathgen.c
129 lines (108 loc) · 2.95 KB
/
gen.c
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
127
128
129
#include "cc.h"
static unsigned int freemask[2];
struct symbol *mkreg(const char *name, int index, int kind)
{
struct symbol *s;
s = NEWS0(struct symbol, PERM);
s->name = s->x.name = name;
s->x.reg.index = index;
s->x.reg.kind = kind;
s->x.reg.mask = 1<<index;
return s;
}
struct symbol *mksreg(const char *name)
{
struct symbol *s;
s = NEWS0(struct symbol, PERM);
s->name = s->x.name = name;
return s;
}
static void rewrite(void)
{
}
void gen(struct symbol *s)
{
}
void emit(struct symbol *s)
{
}
static void geninit_struct(struct symbol *s)
{
// TODO:
}
static void geninit_array(struct symbol *s)
{
// TODO:
struct tree *init = s->u.init;
struct type *ty = s->type;
size_t size = TYPE_SIZE(ty);
if (isstring(ty) && issliteral(init)) {
IR->defstring(init->s.sym->name, size);
} else {
error_at(s->src, "illegal %s initializer for '%s'",
TYPE_NAME(ty), s->name);
IR->defzero(size);
}
}
static void geninit_ptr(struct symbol *s)
{
struct tree *init = s->u.init;
if (OPKIND(init->op) == CNST) {
IR->defconst(OPTYPE(init->op), TYPE_SIZE(s->type), &init->s.value);
} else if (opid(init->op) == ADDRG+P) {
IR->defaddress(init->s.sym->x.name, 0);
} else if (opid(init->op) == ADD+P &&
opid(init->kids[0]->op) == ADDRG+P &&
OPKIND(init->kids[1]->op) == CNST) {
IR->defaddress(init->kids[0]->s.sym->x.name,
init->kids[1]->s.value.i);
} else if (opid(init->op) == SUB+P &&
opid(init->kids[0]->op) == ADDRG+P &&
OPKIND(init->kids[1]->op) == CNST) {
IR->defaddress(init->kids[0]->s.sym->x.name,
-init->kids[1]->s.value.i);
} else {
if (debug['v'])
intal_at(s->src, "illegal initializer for '%s'", s->name);
IR->defzero(TYPE_SIZE(s->type));
}
}
static void geninit_arith(struct symbol *s)
{
struct tree *init = s->u.init;
if (OPKIND(init->op) == CNST) {
IR->defconst(OPTYPE(init->op), TYPE_SIZE(s->type), &init->s.value);
} else {
if (debug['v'])
intal_at(s->src, "illegal initializer for '%s'", s->name);
IR->defzero(TYPE_SIZE(s->type));
}
}
void genglobal(struct symbol *s)
{
int seg = s->u.init ? DATA : BSS;
if (seg == DATA && s->sclass != STATIC)
IR->export(s);
else if (seg == BSS && s->sclass == STATIC)
IR->local(s);
IR->segment(seg);
IR->defvar(s);
if (s->u.init) {
if (isarith(s->type))
geninit_arith(s);
else if (isptr(s->type))
geninit_ptr(s);
else if (isarray(s->type))
geninit_array(s);
else if (isstruct(s->type))
geninit_struct(s);
else
CC_UNAVAILABLE();
}
}
void genstring(struct symbol *s)
{
IR->segment(RODATA);
IR->defvar(s);
IR->defstring(s->name, -1);
}