OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

[/] [eco32/] [trunk/] [lcc/] [src/] [init.c] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 hellwig
#include "c.h"
2
 
3
static char rcsid[] = "$Id: init.c,v 1.1 2002/08/28 23:12:43 drh Exp $";
4
 
5
static int curseg;              /* current segment */
6
 
7
/* defpointer - initialize a pointer to p or to 0 if p==0 */
8
void defpointer(Symbol p) {
9
        if (p) {
10
                (*IR->defaddress)(p);
11
                p->ref++;
12
        } else {
13
                static Value v;
14
                (*IR->defconst)(P, voidptype->size, v);
15
        }
16
}
17
 
18
/* genconst - generate/check constant expression e; return size */
19
static int genconst(Tree e, int def) {
20
        for (;;)
21
                switch (generic(e->op)) {
22
                case ADDRG:
23
                        if (def)
24
                                (*IR->defaddress)(e->u.sym);
25
                        return e->type->size;
26
                case CNST:
27
                        if (e->op == CNST+P && isarray(e->type)) {
28
                                e = cvtconst(e);
29
                                continue;
30
                        }
31
                        if (def)
32
                                (*IR->defconst)(e->type->op, e->type->size, e->u.v);
33
                        return e->type->size;
34
                case RIGHT:
35
                        assert(e->kids[0] || e->kids[1]);
36
                        if (e->kids[1] && e->kids[0])
37
                                error("initializer must be constant\n");
38
                        e = e->kids[1] ? e->kids[1] : e->kids[0];
39
                        continue;
40
                case CVP:
41
                        if (isarith(e->type))
42
                                error("cast from `%t' to `%t' is illegal in constant expressions\n",
43
                                        e->kids[0]->type, e->type);
44
                        /* fall thru */
45
                case CVI: case CVU: case CVF:
46
                        e = e->kids[0];
47
                        continue;
48
                default:
49
                        error("initializer must be constant\n");
50
                        if (def)
51
                                genconst(consttree(0, inttype), def);
52
                        return inttype->size;
53
                }
54
}
55
 
56
/* initvalue - evaluate a constant expression for a value of integer type ty */
57
static Tree initvalue(Type ty) {
58
        Type aty;
59
        Tree e;
60
 
61
        needconst++;
62
        e = expr1(0);
63
        if ((aty = assign(ty, e)) != NULL)
64
                e = cast(e, aty);
65
        else {
66
                error("invalid initialization type; found `%t' expected `%t'\n",
67
                        e->type,  ty);
68
                e = retype(consttree(0, inttype), ty);
69
        }
70
        needconst--;
71
        if (generic(e->op) != CNST) {
72
                error("initializer must be constant\n");
73
                e = retype(consttree(0, inttype), ty);
74
        }
75
        return e;
76
}
77
 
78
/* initarray - initialize array of ty of <= len bytes; if len == 0, go to } */
79
static int initarray(int len, Type ty, int lev) {
80
        int n = 0;
81
 
82
        do {
83
                initializer(ty, lev);
84
                n += ty->size;
85
                if (len > 0 && n >= len || t != ',')
86
                        break;
87
                t = gettok();
88
        } while (t != '}');
89
        return n;
90
}
91
 
92
/* initchar - initialize array of <= len ty characters; if len == 0, go to } */
93
static int initchar(int len, Type ty) {
94
        int n = 0;
95
        char buf[16], *s = buf;
96
 
97
        do {
98
                *s++ = initvalue(ty)->u.v.i;
99
                if (++n%inttype->size == 0) {
100
                        (*IR->defstring)(inttype->size, buf);
101
                        s = buf;
102
                }
103
                if (len > 0 && n >= len || t != ',')
104
                        break;
105
                t = gettok();
106
        } while (t != '}');
107
        if (s > buf)
108
                (*IR->defstring)(s - buf, buf);
109
        return n;
110
}
111
 
112
/* initend - finish off an initialization at level lev; accepts trailing comma */
113
static void initend(int lev, char follow[]) {
114
        if (lev == 0 && t == ',')
115
                t = gettok();
116
        test('}', follow);
117
}
118
 
119
/* initfields - initialize <= an unsigned's worth of bit fields in fields p to q */
120
static int initfields(Field p, Field q) {
121
        unsigned int bits = 0;
122
        int i, n = 0;
123
 
124
        do {
125
                i = initvalue(inttype)->u.v.i;
126
                if (fieldsize(p) < 8*p->type->size) {
127
                        if (p->type == inttype &&
128
                           (i < -(int)(fieldmask(p)>>1)-1 || i > (int)(fieldmask(p)>>1))
129
                        ||  p->type == unsignedtype && (i&~fieldmask(p)) !=  0)
130
                                warning("initializer exceeds bit-field width\n");
131
                        i &= fieldmask(p);
132
                }
133
                bits |= i<<fieldright(p);
134
                if (IR->little_endian) {
135
                        if (fieldsize(p) + fieldright(p) > n)
136
                                n = fieldsize(p) + fieldright(p);
137
                } else {
138
                        if (fieldsize(p) + fieldleft(p) > n)
139
                                n = fieldsize(p) + fieldleft(p);
140
                }
141
                if (p->link == q)
142
                        break;
143
                p = p->link;
144
        } while (t == ',' && (t = gettok()) != 0);
145
        n = (n + 7)/8;
146
        for (i = 0; i < n; i++) {
147
                Value v;
148
                if (IR->little_endian) {
149
                        v.u = (unsigned char)bits;
150
                        bits >>= 8;
151
                } else {        /* a big endian */
152
                        v.u = (unsigned char)(bits>>(8*(unsignedtype->size - 1)));
153
                        bits <<= 8;
154
                }
155
                (*IR->defconst)(U, unsignedchar->size, v);
156
        }
157
        return n;
158
}
159
 
160
/* initstruct - initialize a struct ty of <= len bytes; if len == 0, go to } */
161
static int initstruct(int len, Type ty, int lev) {
162
        int a, n = 0;
163
        Field p = ty->u.sym->u.s.flist;
164
 
165
        do {
166
                if (p->offset > n) {
167
                        (*IR->space)(p->offset - n);
168
                        n += p->offset - n;
169
                }
170
                if (p->lsb) {
171
                        Field q = p;
172
                        while (q->link && q->link->offset == p->offset)
173
                                q = q->link;
174
                        n += initfields(p, q->link);
175
                        p = q;
176
                } else {
177
                        initializer(p->type, lev);
178
                        n += p->type->size;
179
                }
180
                if (p->link) {
181
                        p = p->link;
182
                        a = p->type->align;
183
                } else
184
                        a = ty->align;
185
                if (a && n%a) {
186
                        (*IR->space)(a - n%a);
187
                        n = roundup(n, a);
188
                }
189
                if (len > 0 && n >= len || t != ',')
190
                        break;
191
                t = gettok();
192
        } while (t != '}');
193
        return n;
194
}
195
 
196
/* initializer - constexpr | { constexpr ( , constexpr )* [ , ] } */
197
Type initializer(Type ty, int lev) {
198
        int n = 0;
199
        Tree e;
200
        Type aty = NULL;
201
        static char follow[] = { IF, CHAR, STATIC, 0 };
202
 
203
        ty = unqual(ty);
204
        if (isscalar(ty)) {
205
                needconst++;
206
                if (t == '{') {
207
                        t = gettok();
208
                        e = expr1(0);
209
                        initend(lev, follow);
210
                } else
211
                        e = expr1(0);
212
                e = pointer(e);
213
                if ((aty = assign(ty, e)) != NULL)
214
                        e = cast(e, aty);
215
                else
216
                        error("invalid initialization type; found `%t' expected `%t'\n",
217
                                e->type, ty);
218
                n = genconst(e, 1);
219
                deallocate(STMT);
220
                needconst--;
221
        }
222
        if ((isunion(ty) || isstruct(ty)) && ty->size == 0) {
223
                static char follow[] = { CHAR, STATIC, 0 };
224
                error("cannot initialize undefined `%t'\n", ty);
225
                skipto(';', follow);
226
                return ty;
227
        } else if (isunion(ty)) {
228
                if (t == '{') {
229
                        t = gettok();
230
                        n = initstruct(ty->u.sym->u.s.flist->type->size, ty, lev + 1);
231
                        initend(lev, follow);
232
                } else {
233
                        if (lev == 0)
234
                                error("missing { in initialization of `%t'\n", ty);
235
                        n = initstruct(ty->u.sym->u.s.flist->type->size, ty, lev + 1);
236
                }
237
        } else if (isstruct(ty)) {
238
                if (t == '{') {
239
                        t = gettok();
240
                        n = initstruct(0, ty, lev + 1);
241
                        test('}', follow);
242
                } else if (lev > 0)
243
                        n = initstruct(ty->size, ty, lev + 1);
244
                else {
245
                        error("missing { in initialization of `%t'\n", ty);
246
                        n = initstruct(ty->u.sym->u.s.flist->type->size, ty, lev + 1);
247
                }
248
        }
249
        if (isarray(ty))
250
                aty = unqual(ty->type);
251
        if (isarray(ty) && ischar(aty)) {
252
                if (t == SCON) {
253
                        if (ty->size > 0 && ty->size == tsym->type->size - 1)
254
                                tsym->type = array(chartype, ty->size, 0);
255
                        n = tsym->type->size;
256
                        (*IR->defstring)(tsym->type->size, tsym->u.c.v.p);
257
                        t = gettok();
258
                } else if (t == '{') {
259
                        t = gettok();
260
                        if (t == SCON) {
261
                                ty = initializer(ty, lev + 1);
262
                                initend(lev, follow);
263
                                return ty;
264
                        }
265
                        n = initchar(0, aty);
266
                        test('}', follow);
267
                } else if (lev > 0 && ty->size > 0)
268
                        n = initchar(ty->size, aty);
269
                else {  /* eg, char c[] = 0; */
270
                        error("missing { in initialization of `%t'\n", ty);
271
                        n = initchar(1, aty);
272
                }
273
        } else if (isarray(ty)) {
274
                if (t == SCON && aty == widechar) {
275
                        int i;
276
                        unsigned int *s = tsym->u.c.v.p;
277
                        if (ty->size > 0 && ty->size == tsym->type->size - widechar->size)
278
                                tsym->type = array(widechar, ty->size/widechar->size, 0);
279
                        n = tsym->type->size;
280
                        for (i = 0; i < n; i += widechar->size) {
281
                                Value v;
282
                                v.u = *s++;
283
                                (*IR->defconst)(widechar->op, widechar->size, v);
284
                        }
285
                        t = gettok();
286
                } else if (t == '{') {
287
                        t = gettok();
288
                        if (t == SCON && aty == widechar) {
289
                                ty = initializer(ty, lev + 1);
290
                                initend(lev, follow);
291
                                return ty;
292
                        }
293
                        n = initarray(0, aty, lev + 1);
294
                        test('}', follow);
295
                } else if (lev > 0 && ty->size > 0)
296
                        n = initarray(ty->size, aty, lev + 1);
297
                else {
298
                        error("missing { in initialization of `%t'\n", ty);
299
                        n = initarray(aty->size, aty, lev + 1);
300
                }
301
        }
302
        if (ty->size) {
303
                if (n > ty->size)
304
                        error("too many initializers\n");
305
                else if (n < ty->size)
306
                        (*IR->space)(ty->size - n);
307
        } else if (isarray(ty) && ty->type->size > 0)
308
                ty = array(ty->type, n/ty->type->size, 0);
309
        else
310
                ty->size = n;
311
        return ty;
312
}
313
 
314
/* swtoseg - switch to segment seg, if necessary */
315
void swtoseg(int seg) {
316
        if (curseg != seg)
317
                (*IR->segment)(seg);
318
        curseg = seg;
319
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.