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

Subversion Repositories eco32

[/] [eco32/] [tags/] [eco32-0.23/] [lcc/] [src/] [init.c] - Diff between revs 4 and 157

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 4 Rev 157
#include "c.h"
#include "c.h"
 
 
static char rcsid[] = "$Id: init.c,v 1.1 2002/08/28 23:12:43 drh Exp $";
static char rcsid[] = "$Id: init.c,v 1.1 2002/08/28 23:12:43 drh Exp $";
 
 
static int curseg;              /* current segment */
static int curseg;              /* current segment */
 
 
/* defpointer - initialize a pointer to p or to 0 if p==0 */
/* defpointer - initialize a pointer to p or to 0 if p==0 */
void defpointer(Symbol p) {
void defpointer(Symbol p) {
        if (p) {
        if (p) {
                (*IR->defaddress)(p);
                (*IR->defaddress)(p);
                p->ref++;
                p->ref++;
        } else {
        } else {
                static Value v;
                static Value v;
                (*IR->defconst)(P, voidptype->size, v);
                (*IR->defconst)(P, voidptype->size, v);
        }
        }
}
}
 
 
/* genconst - generate/check constant expression e; return size */
/* genconst - generate/check constant expression e; return size */
static int genconst(Tree e, int def) {
static int genconst(Tree e, int def) {
        for (;;)
        for (;;)
                switch (generic(e->op)) {
                switch (generic(e->op)) {
                case ADDRG:
                case ADDRG:
                        if (def)
                        if (def)
                                (*IR->defaddress)(e->u.sym);
                                (*IR->defaddress)(e->u.sym);
                        return e->type->size;
                        return e->type->size;
                case CNST:
                case CNST:
                        if (e->op == CNST+P && isarray(e->type)) {
                        if (e->op == CNST+P && isarray(e->type)) {
                                e = cvtconst(e);
                                e = cvtconst(e);
                                continue;
                                continue;
                        }
                        }
                        if (def)
                        if (def)
                                (*IR->defconst)(e->type->op, e->type->size, e->u.v);
                                (*IR->defconst)(e->type->op, e->type->size, e->u.v);
                        return e->type->size;
                        return e->type->size;
                case RIGHT:
                case RIGHT:
                        assert(e->kids[0] || e->kids[1]);
                        assert(e->kids[0] || e->kids[1]);
                        if (e->kids[1] && e->kids[0])
                        if (e->kids[1] && e->kids[0])
                                error("initializer must be constant\n");
                                error("initializer must be constant\n");
                        e = e->kids[1] ? e->kids[1] : e->kids[0];
                        e = e->kids[1] ? e->kids[1] : e->kids[0];
                        continue;
                        continue;
                case CVP:
                case CVP:
                        if (isarith(e->type))
                        if (isarith(e->type))
                                error("cast from `%t' to `%t' is illegal in constant expressions\n",
                                error("cast from `%t' to `%t' is illegal in constant expressions\n",
                                        e->kids[0]->type, e->type);
                                        e->kids[0]->type, e->type);
                        /* fall thru */
                        /* fall thru */
                case CVI: case CVU: case CVF:
                case CVI: case CVU: case CVF:
                        e = e->kids[0];
                        e = e->kids[0];
                        continue;
                        continue;
                default:
                default:
                        error("initializer must be constant\n");
                        error("initializer must be constant\n");
                        if (def)
                        if (def)
                                genconst(consttree(0, inttype), def);
                                genconst(consttree(0, inttype), def);
                        return inttype->size;
                        return inttype->size;
                }
                }
}
}
 
 
/* initvalue - evaluate a constant expression for a value of integer type ty */
/* initvalue - evaluate a constant expression for a value of integer type ty */
static Tree initvalue(Type ty) {
static Tree initvalue(Type ty) {
        Type aty;
        Type aty;
        Tree e;
        Tree e;
 
 
        needconst++;
        needconst++;
        e = expr1(0);
        e = expr1(0);
        if ((aty = assign(ty, e)) != NULL)
        if ((aty = assign(ty, e)) != NULL)
                e = cast(e, aty);
                e = cast(e, aty);
        else {
        else {
                error("invalid initialization type; found `%t' expected `%t'\n",
                error("invalid initialization type; found `%t' expected `%t'\n",
                        e->type,  ty);
                        e->type,  ty);
                e = retype(consttree(0, inttype), ty);
                e = retype(consttree(0, inttype), ty);
        }
        }
        needconst--;
        needconst--;
        if (generic(e->op) != CNST) {
        if (generic(e->op) != CNST) {
                error("initializer must be constant\n");
                error("initializer must be constant\n");
                e = retype(consttree(0, inttype), ty);
                e = retype(consttree(0, inttype), ty);
        }
        }
        return e;
        return e;
}
}
 
 
/* initarray - initialize array of ty of <= len bytes; if len == 0, go to } */
/* initarray - initialize array of ty of <= len bytes; if len == 0, go to } */
static int initarray(int len, Type ty, int lev) {
static int initarray(int len, Type ty, int lev) {
        int n = 0;
        int n = 0;
 
 
        do {
        do {
                initializer(ty, lev);
                initializer(ty, lev);
                n += ty->size;
                n += ty->size;
                if (len > 0 && n >= len || t != ',')
                if (len > 0 && n >= len || t != ',')
                        break;
                        break;
                t = gettok();
                t = gettok();
        } while (t != '}');
        } while (t != '}');
        return n;
        return n;
}
}
 
 
/* initchar - initialize array of <= len ty characters; if len == 0, go to } */
/* initchar - initialize array of <= len ty characters; if len == 0, go to } */
static int initchar(int len, Type ty) {
static int initchar(int len, Type ty) {
        int n = 0;
        int n = 0;
        char buf[16], *s = buf;
        char buf[16], *s = buf;
 
 
        do {
        do {
                *s++ = initvalue(ty)->u.v.i;
                *s++ = initvalue(ty)->u.v.i;
                if (++n%inttype->size == 0) {
                if (++n%inttype->size == 0) {
                        (*IR->defstring)(inttype->size, buf);
                        (*IR->defstring)(inttype->size, buf);
                        s = buf;
                        s = buf;
                }
                }
                if (len > 0 && n >= len || t != ',')
                if (len > 0 && n >= len || t != ',')
                        break;
                        break;
                t = gettok();
                t = gettok();
        } while (t != '}');
        } while (t != '}');
        if (s > buf)
        if (s > buf)
                (*IR->defstring)(s - buf, buf);
                (*IR->defstring)(s - buf, buf);
        return n;
        return n;
}
}
 
 
/* initend - finish off an initialization at level lev; accepts trailing comma */
/* initend - finish off an initialization at level lev; accepts trailing comma */
static void initend(int lev, char follow[]) {
static void initend(int lev, char follow[]) {
        if (lev == 0 && t == ',')
        if (lev == 0 && t == ',')
                t = gettok();
                t = gettok();
        test('}', follow);
        test('}', follow);
}
}
 
 
/* initfields - initialize <= an unsigned's worth of bit fields in fields p to q */
/* initfields - initialize <= an unsigned's worth of bit fields in fields p to q */
static int initfields(Field p, Field q) {
static int initfields(Field p, Field q) {
        unsigned int bits = 0;
        unsigned int bits = 0;
        int i, n = 0;
        int i, n = 0;
 
 
        do {
        do {
                i = initvalue(inttype)->u.v.i;
                i = initvalue(inttype)->u.v.i;
                if (fieldsize(p) < 8*p->type->size) {
                if (fieldsize(p) < 8*p->type->size) {
                        if (p->type == inttype &&
                        if (p->type == inttype &&
                           (i < -(int)(fieldmask(p)>>1)-1 || i > (int)(fieldmask(p)>>1))
                           (i < -(int)(fieldmask(p)>>1)-1 || i > (int)(fieldmask(p)>>1))
                        ||  p->type == unsignedtype && (i&~fieldmask(p)) !=  0)
                        ||  p->type == unsignedtype && (i&~fieldmask(p)) !=  0)
                                warning("initializer exceeds bit-field width\n");
                                warning("initializer exceeds bit-field width\n");
                        i &= fieldmask(p);
                        i &= fieldmask(p);
                }
                }
                bits |= i<<fieldright(p);
                bits |= i<<fieldright(p);
                if (IR->little_endian) {
                if (IR->little_endian) {
                        if (fieldsize(p) + fieldright(p) > n)
                        if (fieldsize(p) + fieldright(p) > n)
                                n = fieldsize(p) + fieldright(p);
                                n = fieldsize(p) + fieldright(p);
                } else {
                } else {
                        if (fieldsize(p) + fieldleft(p) > n)
                        if (fieldsize(p) + fieldleft(p) > n)
                                n = fieldsize(p) + fieldleft(p);
                                n = fieldsize(p) + fieldleft(p);
                }
                }
                if (p->link == q)
                if (p->link == q)
                        break;
                        break;
                p = p->link;
                p = p->link;
        } while (t == ',' && (t = gettok()) != 0);
        } while (t == ',' && (t = gettok()) != 0);
        n = (n + 7)/8;
        n = (n + 7)/8;
        for (i = 0; i < n; i++) {
        for (i = 0; i < n; i++) {
                Value v;
                Value v;
                if (IR->little_endian) {
                if (IR->little_endian) {
                        v.u = (unsigned char)bits;
                        v.u = (unsigned char)bits;
                        bits >>= 8;
                        bits >>= 8;
                } else {        /* a big endian */
                } else {        /* a big endian */
                        v.u = (unsigned char)(bits>>(8*(unsignedtype->size - 1)));
                        v.u = (unsigned char)(bits>>(8*(unsignedtype->size - 1)));
                        bits <<= 8;
                        bits <<= 8;
                }
                }
                (*IR->defconst)(U, unsignedchar->size, v);
                (*IR->defconst)(U, unsignedchar->size, v);
        }
        }
        return n;
        return n;
}
}
 
 
/* initstruct - initialize a struct ty of <= len bytes; if len == 0, go to } */
/* initstruct - initialize a struct ty of <= len bytes; if len == 0, go to } */
static int initstruct(int len, Type ty, int lev) {
static int initstruct(int len, Type ty, int lev) {
        int a, n = 0;
        int a, n = 0;
        Field p = ty->u.sym->u.s.flist;
        Field p = ty->u.sym->u.s.flist;
 
 
        do {
        do {
                if (p->offset > n) {
                if (p->offset > n) {
                        (*IR->space)(p->offset - n);
                        (*IR->space)(p->offset - n);
                        n += p->offset - n;
                        n += p->offset - n;
                }
                }
                if (p->lsb) {
                if (p->lsb) {
                        Field q = p;
                        Field q = p;
                        while (q->link && q->link->offset == p->offset)
                        while (q->link && q->link->offset == p->offset)
                                q = q->link;
                                q = q->link;
                        n += initfields(p, q->link);
                        n += initfields(p, q->link);
                        p = q;
                        p = q;
                } else {
                } else {
                        initializer(p->type, lev);
                        initializer(p->type, lev);
                        n += p->type->size;
                        n += p->type->size;
                }
                }
                if (p->link) {
                if (p->link) {
                        p = p->link;
                        p = p->link;
                        a = p->type->align;
                        a = p->type->align;
                } else
                } else
                        a = ty->align;
                        a = ty->align;
                if (a && n%a) {
                if (a && n%a) {
                        (*IR->space)(a - n%a);
                        (*IR->space)(a - n%a);
                        n = roundup(n, a);
                        n = roundup(n, a);
                }
                }
                if (len > 0 && n >= len || t != ',')
                if (len > 0 && n >= len || t != ',')
                        break;
                        break;
                t = gettok();
                t = gettok();
        } while (t != '}');
        } while (t != '}');
        return n;
        return n;
}
}
 
 
/* initializer - constexpr | { constexpr ( , constexpr )* [ , ] } */
/* initializer - constexpr | { constexpr ( , constexpr )* [ , ] } */
Type initializer(Type ty, int lev) {
Type initializer(Type ty, int lev) {
        int n = 0;
        int n = 0;
        Tree e;
        Tree e;
        Type aty = NULL;
        Type aty = NULL;
        static char follow[] = { IF, CHAR, STATIC, 0 };
        static char follow[] = { IF, CHAR, STATIC, 0 };
 
 
        ty = unqual(ty);
        ty = unqual(ty);
        if (isscalar(ty)) {
        if (isscalar(ty)) {
                needconst++;
                needconst++;
                if (t == '{') {
                if (t == '{') {
                        t = gettok();
                        t = gettok();
                        e = expr1(0);
                        e = expr1(0);
                        initend(lev, follow);
                        initend(lev, follow);
                } else
                } else
                        e = expr1(0);
                        e = expr1(0);
                e = pointer(e);
                e = pointer(e);
                if ((aty = assign(ty, e)) != NULL)
                if ((aty = assign(ty, e)) != NULL)
                        e = cast(e, aty);
                        e = cast(e, aty);
                else
                else
                        error("invalid initialization type; found `%t' expected `%t'\n",
                        error("invalid initialization type; found `%t' expected `%t'\n",
                                e->type, ty);
                                e->type, ty);
                n = genconst(e, 1);
                n = genconst(e, 1);
                deallocate(STMT);
                deallocate(STMT);
                needconst--;
                needconst--;
        }
        }
        if ((isunion(ty) || isstruct(ty)) && ty->size == 0) {
        if ((isunion(ty) || isstruct(ty)) && ty->size == 0) {
                static char follow[] = { CHAR, STATIC, 0 };
                static char follow[] = { CHAR, STATIC, 0 };
                error("cannot initialize undefined `%t'\n", ty);
                error("cannot initialize undefined `%t'\n", ty);
                skipto(';', follow);
                skipto(';', follow);
                return ty;
                return ty;
        } else if (isunion(ty)) {
        } else if (isunion(ty)) {
                if (t == '{') {
                if (t == '{') {
                        t = gettok();
                        t = gettok();
                        n = initstruct(ty->u.sym->u.s.flist->type->size, ty, lev + 1);
                        n = initstruct(ty->u.sym->u.s.flist->type->size, ty, lev + 1);
                        initend(lev, follow);
                        initend(lev, follow);
                } else {
                } else {
                        if (lev == 0)
                        if (lev == 0)
                                error("missing { in initialization of `%t'\n", ty);
                                error("missing { in initialization of `%t'\n", ty);
                        n = initstruct(ty->u.sym->u.s.flist->type->size, ty, lev + 1);
                        n = initstruct(ty->u.sym->u.s.flist->type->size, ty, lev + 1);
                }
                }
        } else if (isstruct(ty)) {
        } else if (isstruct(ty)) {
                if (t == '{') {
                if (t == '{') {
                        t = gettok();
                        t = gettok();
                        n = initstruct(0, ty, lev + 1);
                        n = initstruct(0, ty, lev + 1);
                        test('}', follow);
                        test('}', follow);
                } else if (lev > 0)
                } else if (lev > 0)
                        n = initstruct(ty->size, ty, lev + 1);
                        n = initstruct(ty->size, ty, lev + 1);
                else {
                else {
                        error("missing { in initialization of `%t'\n", ty);
                        error("missing { in initialization of `%t'\n", ty);
                        n = initstruct(ty->u.sym->u.s.flist->type->size, ty, lev + 1);
                        n = initstruct(ty->u.sym->u.s.flist->type->size, ty, lev + 1);
                }
                }
        }
        }
        if (isarray(ty))
        if (isarray(ty))
                aty = unqual(ty->type);
                aty = unqual(ty->type);
        if (isarray(ty) && ischar(aty)) {
        if (isarray(ty) && ischar(aty)) {
                if (t == SCON) {
                if (t == SCON) {
                        if (ty->size > 0 && ty->size == tsym->type->size - 1)
                        if (ty->size > 0 && ty->size == tsym->type->size - 1)
                                tsym->type = array(chartype, ty->size, 0);
                                tsym->type = array(chartype, ty->size, 0);
                        n = tsym->type->size;
                        n = tsym->type->size;
                        (*IR->defstring)(tsym->type->size, tsym->u.c.v.p);
                        (*IR->defstring)(tsym->type->size, tsym->u.c.v.p);
                        t = gettok();
                        t = gettok();
                } else if (t == '{') {
                } else if (t == '{') {
                        t = gettok();
                        t = gettok();
                        if (t == SCON) {
                        if (t == SCON) {
                                ty = initializer(ty, lev + 1);
                                ty = initializer(ty, lev + 1);
                                initend(lev, follow);
                                initend(lev, follow);
                                return ty;
                                return ty;
                        }
                        }
                        n = initchar(0, aty);
                        n = initchar(0, aty);
                        test('}', follow);
                        test('}', follow);
                } else if (lev > 0 && ty->size > 0)
                } else if (lev > 0 && ty->size > 0)
                        n = initchar(ty->size, aty);
                        n = initchar(ty->size, aty);
                else {  /* eg, char c[] = 0; */
                else {  /* eg, char c[] = 0; */
                        error("missing { in initialization of `%t'\n", ty);
                        error("missing { in initialization of `%t'\n", ty);
                        n = initchar(1, aty);
                        n = initchar(1, aty);
                }
                }
        } else if (isarray(ty)) {
        } else if (isarray(ty)) {
                if (t == SCON && aty == widechar) {
                if (t == SCON && aty == widechar) {
                        int i;
                        int i;
                        unsigned int *s = tsym->u.c.v.p;
                        unsigned int *s = tsym->u.c.v.p;
                        if (ty->size > 0 && ty->size == tsym->type->size - widechar->size)
                        if (ty->size > 0 && ty->size == tsym->type->size - widechar->size)
                                tsym->type = array(widechar, ty->size/widechar->size, 0);
                                tsym->type = array(widechar, ty->size/widechar->size, 0);
                        n = tsym->type->size;
                        n = tsym->type->size;
                        for (i = 0; i < n; i += widechar->size) {
                        for (i = 0; i < n; i += widechar->size) {
                                Value v;
                                Value v;
                                v.u = *s++;
                                v.u = *s++;
                                (*IR->defconst)(widechar->op, widechar->size, v);
                                (*IR->defconst)(widechar->op, widechar->size, v);
                        }
                        }
                        t = gettok();
                        t = gettok();
                } else if (t == '{') {
                } else if (t == '{') {
                        t = gettok();
                        t = gettok();
                        if (t == SCON && aty == widechar) {
                        if (t == SCON && aty == widechar) {
                                ty = initializer(ty, lev + 1);
                                ty = initializer(ty, lev + 1);
                                initend(lev, follow);
                                initend(lev, follow);
                                return ty;
                                return ty;
                        }
                        }
                        n = initarray(0, aty, lev + 1);
                        n = initarray(0, aty, lev + 1);
                        test('}', follow);
                        test('}', follow);
                } else if (lev > 0 && ty->size > 0)
                } else if (lev > 0 && ty->size > 0)
                        n = initarray(ty->size, aty, lev + 1);
                        n = initarray(ty->size, aty, lev + 1);
                else {
                else {
                        error("missing { in initialization of `%t'\n", ty);
                        error("missing { in initialization of `%t'\n", ty);
                        n = initarray(aty->size, aty, lev + 1);
                        n = initarray(aty->size, aty, lev + 1);
                }
                }
        }
        }
        if (ty->size) {
        if (ty->size) {
                if (n > ty->size)
                if (n > ty->size)
                        error("too many initializers\n");
                        error("too many initializers\n");
                else if (n < ty->size)
                else if (n < ty->size)
                        (*IR->space)(ty->size - n);
                        (*IR->space)(ty->size - n);
        } else if (isarray(ty) && ty->type->size > 0)
        } else if (isarray(ty) && ty->type->size > 0)
                ty = array(ty->type, n/ty->type->size, 0);
                ty = array(ty->type, n/ty->type->size, 0);
        else
        else
                ty->size = n;
                ty->size = n;
        return ty;
        return ty;
}
}
 
 
/* swtoseg - switch to segment seg, if necessary */
/* swtoseg - switch to segment seg, if necessary */
void swtoseg(int seg) {
void swtoseg(int seg) {
        if (curseg != seg)
        if (curseg != seg)
                (*IR->segment)(seg);
                (*IR->segment)(seg);
        curseg = seg;
        curseg = seg;
}
}
 
 

powered by: WebSVN 2.1.0

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