diff options
Diffstat (limited to 'usr.bin/pcc/i386/local.c')
-rw-r--r-- | usr.bin/pcc/i386/local.c | 238 |
1 files changed, 93 insertions, 145 deletions
diff --git a/usr.bin/pcc/i386/local.c b/usr.bin/pcc/i386/local.c index cb35c3bd679..4643c7adbe1 100644 --- a/usr.bin/pcc/i386/local.c +++ b/usr.bin/pcc/i386/local.c @@ -1,4 +1,4 @@ -/* $OpenBSD: local.c,v 1.5 2007/12/09 18:54:39 ragge Exp $ */ +/* $OpenBSD: local.c,v 1.6 2008/01/12 17:29:09 ragge Exp $ */ /* * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). * All rights reserved. @@ -68,9 +68,9 @@ picsymtab(char *s, char *s2) struct symtab *sp = IALLOC(sizeof(struct symtab)); size_t len = strlen(s) + strlen(s2) + 1; - sp->sname = IALLOC(len); - strlcpy(sp->sname, s, len); - strlcat(sp->sname, s2, len); + sp->sname = sp->soname = IALLOC(len); + strlcpy(sp->soname, s, len); + strlcat(sp->soname, s2, len); sp->sclass = EXTERN; sp->sflags = sp->slevel = 0; return sp; @@ -84,10 +84,11 @@ static NODE * picext(NODE *p) { NODE *q, *r; + struct symtab *sp; q = tempnode(gotnr, PTR|VOID, 0, MKSUE(VOID)); - r = bcon(0); - r->n_sp = picsymtab(gcc_findname(p->n_sp), "@GOT"); + sp = picsymtab(p->n_sp->soname, "@GOT"); + r = xbcon(0, sp, INT); q = buildtree(PLUS, q, r); q = block(UMUL, q, 0, PTR|VOID, 0, MKSUE(VOID)); q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_sue); @@ -103,17 +104,18 @@ static NODE * picstatic(NODE *p) { NODE *q, *r; + struct symtab *sp; q = tempnode(gotnr, PTR|VOID, 0, MKSUE(VOID)); - r = bcon(0); if (p->n_sp->slevel > 0 || p->n_sp->sclass == ILABEL) { char buf[32]; snprintf(buf, 32, LABFMT, (int)p->n_sp->soffset); - r->n_sp = picsymtab(buf, "@GOTOFF"); + sp = picsymtab(buf, "@GOTOFF"); } else - r->n_sp = picsymtab(gcc_findname(p->n_sp), "@GOTOFF"); - r->n_sp->sclass = STATIC; - r->n_sp->stype = p->n_sp->stype; + sp = picsymtab(p->n_sp->soname, "@GOTOFF"); + sp->sclass = STATIC; + sp->stype = p->n_sp->stype; + r = xbcon(0, sp, INT); q = buildtree(PLUS, q, r); q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_sue); q->n_sp = p->n_sp; /* for init */ @@ -475,7 +477,7 @@ fixnames(NODE *p) sp->sclass != EXTDEF) cerror("fixnames"); - if ((c = strstr(sp->sname, "@GOT")) == NULL) + if ((c = strstr(sp->soname, "@GOT")) == NULL) cerror("fixnames2"); if (isu) { memcpy(c, "@PLT", sizeof("@PLT")); @@ -494,8 +496,35 @@ fixnames(NODE *p) void myp2tree(NODE *p) { + struct symtab *sp; + if (kflag) - walkf(p, fixnames); + walkf(p, fixnames); /* XXX walkf not needed */ + if (p->n_op != FCON) + return; + +#if 0 + /* put floating constants in memory */ + setloc1(RDATA); + defalign(ALLDOUBLE); + deflab1(i = getlab()); + ninval(0, btdims[p->n_type].suesize, p); +#endif + + sp = IALLOC(sizeof(struct symtab)); + sp->sclass = STATIC; + sp->slevel = 1; /* fake numeric label */ + sp->soffset = getlab(); + sp->sflags = 0; + sp->stype = p->n_type; + sp->squal = (CON >> TSHIFT); + + defloc(sp); + ninval(0, btdims[p->n_type].suesize, p); + + p->n_op = NAME; + p->n_lval = 0; + p->n_sp = sp; } /*ARGSUSED*/ @@ -576,39 +605,18 @@ spalloc(NODE *t, NODE *p, OFFSZ off) } -#if 0 -/* - * Print out an integer constant of size size. - * can only be sizes <= SZINT. - */ -void -indata(CONSZ val, int size) -{ - switch (size) { - case SZCHAR: - printf("\t.byte %d\n", (int)val & 0xff); - break; - case SZSHORT: - printf("\t.word %d\n", (int)val & 0xffff); - break; - case SZINT: - printf("\t.long %d\n", (int)val & 0xffffffff); - break; - default: - cerror("indata"); - } -} -#endif - /* * Print out a string of characters. * Assume that the assembler understands C-style escape - * sequences. Location is already set. + * sequences. */ void -instring(char *str) +instring(struct symtab *sp) { - char *s; + char *s, *str; + + defloc(sp); + str = sp->sname; /* be kind to assemblers and avoid long strings */ printf("\t.ascii \""); @@ -616,7 +624,7 @@ instring(char *str) if (*s++ == '\\') { (void)esccon(&s); } - if (s - str > 64) { + if (s - str > 60) { fwrite(str, 1, s - str, stdout); printf("\"\n\t.ascii \""); str = s; @@ -626,6 +634,28 @@ instring(char *str) printf("\\0\"\n"); } +/* + * Print out a wide string by calling ninval(). + */ +void +inwstring(struct symtab *sp) +{ + char *s = sp->sname; + NODE *p; + + defloc(sp); + p = bcon(0); + do { + if (*s++ == '\\') + p->n_lval = esccon(&s); + else + p->n_lval = (unsigned char)s[-1]; + ninval(0, (MKSUE(WCHAR_TYPE))->suesize, p); + } while (s[-1] != 0); + nfree(p); +} + + static int inbits, inval; /* @@ -712,7 +742,7 @@ ninval(CONSZ off, int fsz, NODE *p) p = p->n_left; p = p->n_right; q = p->n_sp; - if ((c = strstr(q->sname, "@GOT")) != NULL) + if ((c = strstr(q->soname, "@GOT")) != NULL) *c = 0; /* ignore GOT ref here */ } if (p->n_op != ICON && p->n_op != FCON) @@ -739,7 +769,7 @@ ninval(CONSZ off, int fsz, NODE *p) q->sclass == ILABEL) { printf("+" LABFMT, q->soffset); } else - printf("+%s", exname(q->sname)); + printf("+%s", exname(q->soname)); } printf("\n"); break; @@ -773,42 +803,6 @@ ninval(CONSZ off, int fsz, NODE *p) } } -#if 0 -/* - * print out an integer. - */ -void -inval(CONSZ word) -{ - word &= 0xffffffff; - printf(" .long 0x%llx\n", word); -} - -/* output code to initialize a floating point value */ -/* the proper alignment has been obtained */ -void -finval(NODE *p) -{ - union { float f; double d; long double l; int i[3]; } u; - - switch (p->n_type) { - case LDOUBLE: - u.i[2] = 0; - u.l = (long double)p->n_dcon; - printf("\t.long\t0x%x,0x%x,0x%x\n", u.i[0], u.i[1], u.i[2]); - break; - case DOUBLE: - u.d = (double)p->n_dcon; - printf("\t.long\t0x%x,0x%x\n", u.i[0], u.i[1]); - break; - case FLOAT: - u.f = (float)p->n_dcon; - printf("\t.long\t0x%x\n", u.i[0]); - break; - } -} -#endif - /* make a name look like an external name in the local machine */ char * exname(char *p) @@ -848,84 +842,38 @@ extdec(struct symtab *q) /* make a common declaration for id, if reasonable */ void -commdec(struct symtab *q) +defzero(struct symtab *sp) { int off; - off = tsize(q->stype, q->sdf, q->ssue); + off = tsize(sp->stype, sp->sdf, sp->ssue); off = (off+(SZCHAR-1))/SZCHAR; -#ifdef GCC_COMPAT - printf(" .comm %s,0%o\n", gcc_findname(q), off); -#else - printf(" .comm %s,0%o\n", exname(q->sname), off); -#endif + printf(" .%scomm ", sp->sclass == STATIC ? "l" : ""); + if (sp->slevel == 0) + printf("%s,0%o\n", exname(sp->soname), off); + else + printf(LABFMT ",0%o\n", sp->soffset, off); } -/* make a local common declaration for id, if reasonable */ -void -lcommdec(struct symtab *q) -{ - int off; +char *nextsect; - off = tsize(q->stype, q->sdf, q->ssue); - off = (off+(SZCHAR-1))/SZCHAR; - if (q->slevel == 0) -#ifdef GCC_COMPAT - printf(" .lcomm %s,0%o\n", gcc_findname(q), off); -#else - printf(" .lcomm %s,0%o\n", exname(q->sname), off); -#endif - else - printf(" .lcomm " LABFMT ",0%o\n", q->soffset, off); -} +#define SSECTION 010000 -/* - * print a (non-prog) label. +/* * Give target the opportunity of handling pragmas. */ -void -deflab1(int label) +int +mypragma(char **ary) { - printf(LABFMT ":\n", label); + if (strcmp(ary[1], "section") || ary[2] == NULL) + return 0; + nextsect = newstring(ary[2], strlen(ary[2])); + return 1; } -static char *loctbl[] = { "text", "data", "section .rodata", "section .rodata" }; - +/* + * Called when a identifier has been declared. + */ void -setloc1(int locc) -{ - if (locc == lastloc) - return; - lastloc = locc; - printf(" .%s\n", loctbl[locc]); -} - -#if 0 -int -ftoint(NODE *p, CONSZ **c) +fixdef(struct symtab *sp) { - static CONSZ cc[3]; - union { float f; double d; long double l; int i[3]; } u; - int n; - - switch (p->n_type) { - case LDOUBLE: - u.i[2] = 0; - u.l = (long double)p->n_dcon; - n = SZLDOUBLE; - break; - case DOUBLE: - u.d = (double)p->n_dcon; - n = SZDOUBLE; - break; - case FLOAT: - u.f = (float)p->n_dcon; - n = SZFLOAT; - break; - } - cc[0] = u.i[0]; - cc[1] = u.i[1]; - cc[2] = u.i[2]; - *c = cc; - return n; } -#endif |