diff options
-rw-r--r-- | usr.bin/pcc/ccom/Makefile.inc | 4 | ||||
-rw-r--r-- | usr.bin/pcc/ccom/cgram.y | 37 | ||||
-rw-r--r-- | usr.bin/pcc/ccom/pass1.h | 4 | ||||
-rw-r--r-- | usr.bin/pcc/ccom/pftn.c | 25 | ||||
-rw-r--r-- | usr.bin/pcc/ccom/scan.l | 56 | ||||
-rw-r--r-- | usr.bin/pcc/ccom/trees.c | 17 |
6 files changed, 122 insertions, 21 deletions
diff --git a/usr.bin/pcc/ccom/Makefile.inc b/usr.bin/pcc/ccom/Makefile.inc index c08dff221d9..f0f0608d934 100644 --- a/usr.bin/pcc/ccom/Makefile.inc +++ b/usr.bin/pcc/ccom/Makefile.inc @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.inc,v 1.1 2007/10/07 17:58:51 otto Exp $ +# $OpenBSD: Makefile.inc,v 1.2 2007/10/07 18:34:41 otto Exp $ # # Makefile for the ccom part of pcc. # @@ -41,5 +41,7 @@ mkext: mkext.c table.c common.c external.h external.c: mkext ./mkext +pftn.o: cgram.c + cleandepend: rm -f .depend ${.CURDIR}/tags cgram.h diff --git a/usr.bin/pcc/ccom/cgram.y b/usr.bin/pcc/ccom/cgram.y index d77193c2c8e..19622c53bbf 100644 --- a/usr.bin/pcc/ccom/cgram.y +++ b/usr.bin/pcc/ccom/cgram.y @@ -1,4 +1,4 @@ -/* $OpenBSD: cgram.y,v 1.1 2007/10/07 17:58:51 otto Exp $ */ +/* $OpenBSD: cgram.y,v 1.2 2007/10/07 18:34:41 otto Exp $ */ /* * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). @@ -118,6 +118,13 @@ %token C_ASM /* + * These tokens are only used for pragmas; let yacc handle syntax check. + */ +%token PRAG_PACKED +%token PRAG_ALIGNED +%token PRAG_RENAMED + +/* * Precedence */ %left ',' @@ -190,7 +197,7 @@ struct savbc { %start ext_def_list %type <intval> con_e ifelprefix ifprefix whprefix forprefix doprefix switchpart - type_qualifier_list + type_qualifier_list str_attr %type <nodep> e .e term enum_dcl struct_dcl cast_type funct_idn declarator direct_declarator elist type_specifier merge_attribs parameter_declaration abstract_declarator initializer @@ -199,12 +206,14 @@ struct savbc { specifier_qualifier_list merge_specifiers nocon_e identifier_list arg_param_list arg_declaration arg_dcl_list designator_list designator -%type <strp> string wstring C_STRING C_WSTRING +%type <strp> string wstring C_STRING C_WSTRING PRAG_RENAMED %type <rp> enum_head str_head %type <symp> xnfdeclarator clbrace %type <intval> C_CLASS C_STRUCT C_RELOP C_DIVOP C_SHIFTOP C_ANDAND C_OROR C_STROP C_INCOP C_UNOP C_ASOP C_EQUOP + PRAG_PACKED PRAG_ALIGNED + %type <nodep> C_TYPE C_QUALIFIER C_ICON C_FCON %type <strp> C_NAME C_TYPENAME @@ -476,7 +485,7 @@ init_declarator_list: | init_declarator_list ',' { $<nodep>$ = $<nodep>0; } init_declarator ; -enum_dcl: enum_head '{' moe_list optcomma '}' { $$ = dclstruct($1); } +enum_dcl: enum_head '{' moe_list optcomma '}' { $$ = dclstruct($1, 0); } | C_ENUM C_NAME { $$ = rstruct($2,0); } | C_ENUM C_TYPENAME { $$ = rstruct($2,0); } ; @@ -494,17 +503,24 @@ moe: C_NAME { moedef( $1 ); } | C_NAME '=' con_e { strucoff = $3; moedef( $1 ); } ; -struct_dcl: str_head '{' struct_dcl_list '}' { $$ = dclstruct($1); } +struct_dcl: str_head '{' struct_dcl_list '}' str_attr { + $$ = dclstruct($1, $5); + } | C_STRUCT C_NAME { $$ = rstruct($2,$1); } | C_STRUCT C_TYPENAME { $$ = rstruct($2,$1); } | str_head '{' '}' { #ifndef GCC_COMPAT werror("gcc extension"); #endif - $$ = dclstruct($1); + $$ = dclstruct($1, 0); } ; +str_attr: { $$ = 0; /* nothing */ } + | PRAG_PACKED { $$ = PRAG_PACKED; } + | PRAG_ALIGNED { $$ = PRAG_ALIGNED; } + ; + str_head: C_STRUCT { $$ = bstruct(NULL, $1); } | C_STRUCT C_NAME { $$ = bstruct($2,$1); } | C_STRUCT C_TYPENAME { $$ = bstruct($2,$1); } @@ -573,6 +589,10 @@ xnfdeclarator: declarator { $$ = xnf = init_declarator($<nodep>0, $1, 1); } * Returns nothing. */ init_declarator: declarator { init_declarator($<nodep>0, $1, 0); } + | declarator PRAG_RENAMED { + renname = $2; /* XXX ugly */ + init_declarator($<nodep>0, $1, 0); + } | declarator C_ASM '(' string ')' { #ifdef GCC_COMPAT renname = $4; @@ -949,7 +969,7 @@ term: term C_INCOP { $$ = buildtree( $2, $1, bcon(1) ); } $$ = buildtree(CAST, $2, $4); nfree($$->n_left); nfree($$); - $$ = $$->n_right; + $$ = $$->n_right; /* XXX use after free */ } | C_SIZEOF '(' cast_type ')' %prec C_SIZEOF { $$ = doszof($3); @@ -1331,7 +1351,8 @@ structref(NODE *p, int f, char *name) p = buildtree(ADDROF, p, NIL); r = block(NAME, NIL, NIL, INT, 0, MKSUE(INT)); r->n_name = name; - return buildtree(STREF, p, r); + r = buildtree(STREF, p, r); + return r; } static void diff --git a/usr.bin/pcc/ccom/pass1.h b/usr.bin/pcc/ccom/pass1.h index d93f51dbee0..22a5d729344 100644 --- a/usr.bin/pcc/ccom/pass1.h +++ b/usr.bin/pcc/ccom/pass1.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pass1.h,v 1.1 2007/10/07 17:58:51 otto Exp $ */ +/* $OpenBSD: pass1.h,v 1.2 2007/10/07 18:34:41 otto Exp $ */ /* * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. * @@ -231,7 +231,7 @@ extern NODE *buildtree(int, NODE *l, NODE *r), *mkty(unsigned, union dimfun *, struct suedef *), *rstruct(char *, int), - *dclstruct(struct rstack *), + *dclstruct(struct rstack *, int), *strend(char *), *wstrend(char *), *tymerge(NODE *typ, NODE *idp), diff --git a/usr.bin/pcc/ccom/pftn.c b/usr.bin/pcc/ccom/pftn.c index c8f4dd49e2e..9d2ddef2a2c 100644 --- a/usr.bin/pcc/ccom/pftn.c +++ b/usr.bin/pcc/ccom/pftn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pftn.c,v 1.1 2007/10/07 17:58:51 otto Exp $ */ +/* $OpenBSD: pftn.c,v 1.2 2007/10/07 18:34:41 otto Exp $ */ /* * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). * All rights reserved. @@ -69,6 +69,8 @@ #include <string.h> /* XXX - for strcmp */ +#include "cgram.h" + struct symtab *spname; struct symtab *cftnsp; static int strunem; /* currently parsed member type */ @@ -761,13 +763,13 @@ bstruct(char *name, int soru) * Called after a struct is declared to restore the environment. */ NODE * -dclstruct(struct rstack *r) +dclstruct(struct rstack *r, int pa) { NODE *n; struct params *l, *m; struct suedef *sue; struct symtab *p; - int al, sa, sz; + int al, sa, sz, coff; TWORD temp; int i, high, low; @@ -800,6 +802,10 @@ dclstruct(struct rstack *r) i++; sue->suelem = permalloc(sizeof(struct symtab *) * i); + coff = 0; + if (pa == PRAG_PACKED || pa == PRAG_ALIGNED) + strucoff = 0; /* must recount it */ + for (i = 0; l != NULL; l = l->next) { sue->suelem[i++] = p = l->sym; @@ -814,11 +820,20 @@ dclstruct(struct rstack *r) continue; } sa = talign(p->stype, p->ssue); - if (p->sclass & FIELD) { + if (p->sclass & FIELD) sz = p->sclass&FLDSIZ; - } else { + else sz = tsize(p->stype, p->sdf, p->ssue); + + if (pa == PRAG_PACKED || pa == PRAG_ALIGNED) { + p->soffset = coff; + if (pa == PRAG_ALIGNED) + coff += ALLDOUBLE; + else + coff += sz; + strucoff = coff; } + if (sz > strucoff) strucoff = sz; /* for use with unions */ /* diff --git a/usr.bin/pcc/ccom/scan.l b/usr.bin/pcc/ccom/scan.l index 93240ae4805..782fb31bae4 100644 --- a/usr.bin/pcc/ccom/scan.l +++ b/usr.bin/pcc/ccom/scan.l @@ -1,5 +1,5 @@ %{ -/* $OpenBSD: scan.l,v 1.1 2007/10/07 17:58:51 otto Exp $ */ +/* $OpenBSD: scan.l,v 1.2 2007/10/07 18:34:41 otto Exp $ */ /* * Copyright (c) 2002 Anders Magnusson. All rights reserved. @@ -48,11 +48,11 @@ IS (u|U|l|L)* static NODE *cvtdig(int radix); static NODE *charcon(void); static void control(int); +static int pragma(void); static NODE *floatcon(void); static NODE *fhexcon(void); int notype, parbal; -#define CPP_PRAGMA 1 #define CPP_IDENT 2 #define CPP_LINE 3 #define CPP_HASH 4 @@ -225,7 +225,7 @@ L?\"(\\.|[^\\"])*\" { "^" { return('^'); } "|" { return('|'); } "?" { return('?'); } -^#pragma[ \t].* { control(CPP_PRAGMA); } +^#pragma[ \t].* { int rv; if ((rv = pragma())) return rv; } ^#ident[ \t].* { control(CPP_IDENT); } ^#line[ \t].* { control(CPP_LINE); } ^#.* { control(CPP_HASH); } @@ -432,7 +432,6 @@ control(int t) wr++; /* Skip initial '#' */ switch (t) { - case CPP_PRAGMA: case CPP_IDENT: return; /* Just skip these for now. */ @@ -465,3 +464,52 @@ control(int t) bad: werror("%s: illegal control", yytext); } + +static char * +nextkw(char **ptr) +{ + char *rc; + + while (**ptr == ' ' || **ptr == '\t') + (*ptr)++; + if (**ptr == 0) + return 0; + rc = *ptr; + while (**ptr && **ptr != ' ' && **ptr != '\t') + (*ptr)++; + if (**ptr != 0) { + **ptr = 0; + (*ptr)++; + } + return rc; +} + +/* + * got a full pragma line. Split it up here. + */ +static int +pragma() +{ + int rv; + char *c, *ptr = yytext; + + rv = 0; + ptr += strlen("#pragma"); + if ((c = nextkw(&ptr)) == NULL) + goto bad; + if (strcmp(c, "packed") == 0) { + rv = PRAG_PACKED; + } else if (strcmp(c, "aligned") == 0) { + rv = PRAG_ALIGNED; + } else if (strcmp(c, "rename") == 0) { + if ((c = nextkw(&ptr)) == NULL) + goto bad; + /* XXX may loose memory if blevel > 0 */ + yylval.strp = newstring(c, strlen(c)); + rv = PRAG_RENAMED; + } +bad: + if (rv == 0) + werror("unknown pragma"); + return rv; +} diff --git a/usr.bin/pcc/ccom/trees.c b/usr.bin/pcc/ccom/trees.c index 077d4b9d743..805d8895e7a 100644 --- a/usr.bin/pcc/ccom/trees.c +++ b/usr.bin/pcc/ccom/trees.c @@ -1,4 +1,4 @@ -/* $Id: trees.c,v 1.1 2007/10/07 17:58:51 otto Exp $ */ +/* $OpenBSD: trees.c,v 1.2 2007/10/07 18:34:41 otto Exp $ */ /* * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). * All rights reserved. @@ -868,6 +868,21 @@ stref(NODE *p) off = s->soffset; dsc = s->sclass; +#ifndef CAN_UNALIGN + /* + * If its a packed struct, and the target cannot do unaligned + * accesses, then split it up in two bitfield operations. + * LHS and RHS accesses are different, so must delay + * it until we know. Do the bitfield construct here though. + */ + if ((dsc & FIELD) == 0 && (off % talign(s->stype, s->ssue))) { +// int sz = tsize(s->stype, s->sdf, s->ssue); +// int al = talign(s->stype, s->ssue); +// int sz1 = al - (off % al); + + } +#endif + if (dsc & FIELD) { /* make fields look like ints */ off = (off/ALINT)*ALINT; sue = MKSUE(INT); |