summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/pcc/ccom/Makefile.inc4
-rw-r--r--usr.bin/pcc/ccom/cgram.y37
-rw-r--r--usr.bin/pcc/ccom/pass1.h4
-rw-r--r--usr.bin/pcc/ccom/pftn.c25
-rw-r--r--usr.bin/pcc/ccom/scan.l56
-rw-r--r--usr.bin/pcc/ccom/trees.c17
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);