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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
#include "call.h"
#include "cgen.h"
#include "cgen/prv.h"
#include "qbe.h"
#include <stdio.h>
#if 0
static int gettmp(char *tmp, size_t n)
{
size_t j;
for (j = 0; j < n; j++)
{
char c = tmp[j];
if (!c)
return tmp[j] = 'a';
else if (c != 'z')
return ++(tmp[j]);
}
return EOF;
}
static int param_lit(const struct lit *lit, struct cgen *c)
{
printf("l $%s", lit->name);
return 0;
}
static int param_id(const struct stentry *e, struct cgen *c, char *tmp,
size_t n)
{
const char *name = e->tk->s;
const struct type *t = e->t;
printf("%s ", cgen_sz(t->sz));
if (cgen_global(c->fn, e))
printf("$%s", name);
else if (cgen_abity(t))
{
if (gettmp(tmp, n) == EOF)
return -1;
printf("%%%s", tmp);
}
else
printf("%%%s_", name);
return 0;
}
static int param_c(const struct type *t, struct cgen *cg)
{
const union c *c = &t->u.c;
/* TODO: adapt type to expected param size */
fputs("l ", stdout);
if (t->sign)
printf("%lld", c->v);
else
printf("%llu", c->uv);
return 0;
}
static int param_num(const struct callparam *cp, struct cgen *c)
{
const union callv *u = &cp->u;
/* TODO: adapt type to expected param size */
fputs("w ", stdout);
if (cp->sign)
printf("%lld", u->v);
else
printf("%llu", u->uv);
return 0;
}
static int param_load(const struct call *m, struct cgen *c)
{
char tmp[sizeof "abcdefghijklmnopqrstuvwxyz"] = {0};
for (size_t i = 0; i < m->nparams; i++)
{
const struct callparam *cp = &m->params[i];
const struct stentry *e = cp->entry;
if (!e || cgen_global(c->fn, e) || !cgen_abity(e->t))
continue;
else if (gettmp(tmp, sizeof tmp - 1) == EOF)
{
fprintf(stderr, "%s: exhausted temporaries\n", __func__);
return -1;
}
printf("%%%s =%s load%s %%%s_\n", tmp, cgen_sz(e->t->sz),
cgen_load(e->t), e->tk->s);
}
return 0;
}
int call_cgen(const struct call *m, struct cgen *c)
{
char tmps[sizeof "abcdefghijklmnopqrstuvwxyz"] = {0};
const struct stentry *ret = m->ret;
const char *tmp;
size_t sz;
if (param_load(m, c))
return -1;
else if (ret)
{
tmp = cgen_tmp((sz = ret->t->sz));
printf("%%%s =%s ", tmp, cgen_sz(sz));
}
printf("call $%s(", m->tk->s);
for (size_t i = 0; i < m->nparams; i++)
{
const struct callparam *cp = &m->params[i];
int var = m->pr->variadic;
if (cp->lit)
param_lit(cp->lit, c);
else if (cp->entry)
param_id(cp->entry, c, tmps, sizeof tmps - 1);
else if (cp->t)
param_c(cp->t, c);
else
param_num(cp, c);
if (var && i + 1 == var - 1)
fputs(", ...", stdout);
if (i + 1 < m->nparams)
fputs(", ", stdout);
}
puts(")");
if (ret)
{
printf("store%s %%%s, ", cgen_sz(sz), tmp);
cgen_printvar(c->fn, ret);
putchar('\n');
}
return 0;
}
#endif
int qbe_call(const struct call *m, struct cgen *c)
{
fprintf(stderr, "%s: TODO\n", __func__);
return -1;
}
|