diff options
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/pcc/i386/code.c | 95 | ||||
-rw-r--r-- | usr.bin/pcc/i386/local.c | 238 | ||||
-rw-r--r-- | usr.bin/pcc/i386/local2.c | 8 |
3 files changed, 132 insertions, 209 deletions
diff --git a/usr.bin/pcc/i386/code.c b/usr.bin/pcc/i386/code.c index e2225f63a99..0e0a6bb7cbc 100644 --- a/usr.bin/pcc/i386/code.c +++ b/usr.bin/pcc/i386/code.c @@ -1,4 +1,4 @@ -/* $OpenBSD: code.c,v 1.6 2007/12/09 18:54:39 ragge Exp $ */ +/* $OpenBSD: code.c,v 1.7 2008/01/12 17:29:09 ragge Exp $ */ /* * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). * All rights reserved. @@ -30,36 +30,43 @@ # include "pass1.h" /* - * cause the alignment to become a multiple of n - * never called for text segment. + * Define everything needed to print out some data (or text). + * This means segment, alignment, visibility, etc. */ void -defalign(int n) +defloc(struct symtab *sp) { - n /= SZCHAR; - if (n == 1) + extern char *nextsect; + static char *loctbl[] = { "text", "data", "section .rodata" }; + static int lastloc = -1; + TWORD t; + int s; + + if (sp == NULL) { + lastloc = -1; return; - printf(" .align %d\n", n); -} - -/* - * define the current location as the name p->sname - * never called for text segment. - */ -void -defnam(struct symtab *p) -{ - char *c = p->sname; - -#ifdef GCC_COMPAT - c = gcc_findname(p); -#endif - if (p->sclass == EXTDEF) - printf(" .globl %s\n", c); - printf("%s:\n", c); + } + t = sp->stype; + s = ISFTN(t) ? PROG : ISCON(cqual(t, sp->squal)) ? RDATA : DATA; + if (nextsect) { + printf(" .section %s\n", nextsect); + nextsect = NULL; + s = -1; + } else if (s != lastloc) + printf(" .%s\n", loctbl[s]); + lastloc = s; + while (ISARY(t)) + t = DECREF(t); + if (t > UCHAR) + printf(" .align %d\n", t > USHORT ? 4 : 2); + if (sp->sclass == EXTDEF) + printf(" .globl %s\n", sp->soname); + if (sp->slevel == 0) + printf("%s:\n", sp->soname); + else + printf(LABFMT ":\n", sp->soffset); } - /* * code for the end of a function * deals with struct return here @@ -105,7 +112,7 @@ bfcode(struct symtab **sp, int cnt) n = block(REG, NIL, NIL, INT, 0, MKSUE(INT)); n->n_rval = EBX; p = tempnode(0, INT, 0, MKSUE(INT)); - gotnr = p->n_lval; + gotnr = regno(p); ecomp(buildtree(ASSIGN, p, n)); } if (xtemps == 0) @@ -119,7 +126,7 @@ bfcode(struct symtab **sp, int cnt) spname = sp[i]; n = tempnode(0, sp[i]->stype, sp[i]->sdf, sp[i]->ssue); n = buildtree(ASSIGN, n, buildtree(NAME, 0, 0)); - sp[i]->soffset = n->n_left->n_lval; + sp[i]->soffset = regno(n->n_left); sp[i]->sflags |= STNODE; ecomp(n); } @@ -189,40 +196,6 @@ funcode(NODE *p) } /* - * Print character t at position i in one string, until t == -1. - * Locctr & label is already defined. - */ -void -bycode(int t, int i) -{ - static int lastoctal = 0; - - /* put byte i+1 in a string */ - - if (t < 0) { - if (i != 0) - puts("\""); - } else { - if (i == 0) - printf("\t.ascii \""); - if (t == '\\' || t == '"') { - lastoctal = 0; - putchar('\\'); - putchar(t); - } else if (t < 040 || t >= 0177) { - lastoctal++; - printf("\\%o",t); - } else if (lastoctal && '0' <= t && t <= '9') { - lastoctal = 0; - printf("\"\n\t.ascii \"%c", t); - } else { - lastoctal = 0; - putchar(t); - } - } -} - -/* * return the alignment of field of type t */ int 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 diff --git a/usr.bin/pcc/i386/local2.c b/usr.bin/pcc/i386/local2.c index b79e32f07c0..a2e02a69ec6 100644 --- a/usr.bin/pcc/i386/local2.c +++ b/usr.bin/pcc/i386/local2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: local2.c,v 1.6 2007/12/22 22:56:31 stefan Exp $ */ +/* $OpenBSD: local2.c,v 1.7 2008/01/12 17:29:09 ragge Exp $ */ /* * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). * All rights reserved. @@ -119,10 +119,12 @@ prologue(struct interpass_prolog *ipp) int addto; ftype = ipp->ipp_type; +#if 0 if (ipp->ipp_vis) printf(" .globl %s\n", ipp->ipp_name); printf(" .align 4\n"); printf("%s:\n", ipp->ipp_name); +#endif /* * We here know what register to save and how much to * add to the stack. @@ -288,10 +290,10 @@ fldexpand(NODE *p, int cookie, char **cp) break; case 'M': case 'N': - val = 1 << UPKFSZ(p->n_rval); + val = (CONSZ)1 << UPKFSZ(p->n_rval); --val; val <<= UPKFOFF(p->n_rval); - printf("0x%llx", (**cp == 'M' ? val : ~val) & 0xffffffff); + printf("0x%llx", (**cp == 'M' ? val : ~val) & 0xffffffff); break; default: comperr("fldexpand"); |