diff options
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/pcc/ccom/cgram.y | 101 | ||||
-rw-r--r-- | usr.bin/pcc/ccom/pass1.h | 5 | ||||
-rw-r--r-- | usr.bin/pcc/ccom/trees.c | 17 | ||||
-rw-r--r-- | usr.bin/pcc/hppa/code.c | 25 | ||||
-rw-r--r-- | usr.bin/pcc/i386/code.c | 25 | ||||
-rw-r--r-- | usr.bin/pcc/m16c/code.c | 31 | ||||
-rw-r--r-- | usr.bin/pcc/mips/code.c | 25 | ||||
-rw-r--r-- | usr.bin/pcc/nova/code.c | 25 | ||||
-rw-r--r-- | usr.bin/pcc/pdp10/code.c | 26 | ||||
-rw-r--r-- | usr.bin/pcc/powerpc/code.c | 21 | ||||
-rw-r--r-- | usr.bin/pcc/vax/code.c | 14 |
11 files changed, 144 insertions, 171 deletions
diff --git a/usr.bin/pcc/ccom/cgram.y b/usr.bin/pcc/ccom/cgram.y index 10961e47eae..7cec014fb61 100644 --- a/usr.bin/pcc/ccom/cgram.y +++ b/usr.bin/pcc/ccom/cgram.y @@ -1,4 +1,4 @@ -/* $OpenBSD: cgram.y,v 1.5 2007/11/18 17:39:55 ragge Exp $ */ +/* $OpenBSD: cgram.y,v 1.6 2007/11/22 15:06:43 stefan Exp $ */ /* * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). @@ -169,7 +169,8 @@ static void swend(void); static void addcase(NODE *p); static void adddef(void); static void savebc(void); -static void swstart(int); +static void swstart(int, TWORD); +static void genswitch(int, TWORD, struct swents **, int); static NODE * structref(NODE *p, int f, char *name); static char *mkpstr(char *str); static struct symtab *clbrace(NODE *); @@ -863,23 +864,24 @@ forprefix: C_FOR '(' .e ';' .e ';' { switchpart: C_SWITCH '(' e ')' { NODE *p; int num; + TWORD t; savebc(); brklab = getlab(); - if ($3->n_type != INT) { - /* must cast to integer */ - p = block(NAME, NIL, NIL, INT, 0, MKSUE(INT)); - p = buildtree(CAST, p, $3); - $3 = p->n_right; - nfree(p->n_left); - nfree(p); + if (($3->n_type != BOOL && $3->n_type > ULONGLONG) || + $3->n_type < CHAR) { + uerror("switch expression must have integer " + "type"); + t = INT; + } else { + $3 = intprom($3); + t = $3->n_type; } -// ecomp( buildtree( FORCE, $3, NIL ) ); - p = tempnode(0, INT, 0, MKSUE(INT)); + p = tempnode(0, t, 0, MKSUE(t)); num = p->n_lval; ecomp(buildtree(ASSIGN, p, $3)); branch( $$ = getlab()); - swstart(num); + swstart(num, t); reached = 0; } ; @@ -1145,6 +1147,7 @@ struct swdef { struct swents *ents; /* Linked sorted list of case entries */ int nents; /* # of entries in list */ int num; /* Node value will end up in */ + TWORD type; /* Type of switch expression */ } *swpole; /* @@ -1154,6 +1157,7 @@ static void addcase(NODE *p) { struct swents **put, *w, *sw = tmpalloc(sizeof(struct swents)); + CONSZ val; p = optim(p); /* change enum to ints */ if (p->n_op != ICON || p->n_sp != NULL) { @@ -1165,19 +1169,35 @@ addcase(NODE *p) return; } + val = p->n_lval; + p = makety(p, swpole->type, 0, 0, MKSUE(swpole->type)); + if (p->n_op != ICON) + cerror("could not cast case value to type of switch " + "expression"); + if (p->n_lval != val) + werror("case expression truncated"); + sw->sval = p->n_lval; + tfree(p); put = &swpole->ents; - for (w = swpole->ents; w != NULL && w->sval < sw->sval; w = w->next) - put = &w->next; - if (w != NULL && w->sval == sw->sval) + if (ISUNSIGNED(swpole->type)) { + for (w = swpole->ents; + w != NULL && (U_CONSZ)w->sval < (U_CONSZ)sw->sval; + w = w->next) + put = &w->next; + } else { + for (w = swpole->ents; w != NULL && w->sval < sw->sval; + w = w->next) + put = &w->next; + } + if (w != NULL && w->sval == sw->sval) { uerror("duplicate case in switch"); - else { - plabel(sw->slab = getlab()); - *put = sw; - sw->next = w; - swpole->nents++; + return; } - tfree(p); + plabel(sw->slab = getlab()); + *put = sw; + sw->next = w; + swpole->nents++; } /* @@ -1195,7 +1215,7 @@ adddef(void) } static void -swstart(int num) +swstart(int num, TWORD type) { struct swdef *sw = tmpalloc(sizeof(struct swdef)); @@ -1203,6 +1223,7 @@ swstart(int num) sw->ents = NULL; sw->next = swpole; sw->num = num; + sw->type = type; swpole = sw; } @@ -1225,12 +1246,46 @@ swend(void) swp[i] = swpole->ents; swpole->ents = swpole->ents->next; } - genswitch(swpole->num, swp, swpole->nents); + genswitch(swpole->num, swpole->type, swp, swpole->nents); swpole = swpole->next; } /* + * num: tempnode the value of the switch expression is in + * type: type of the switch expression + * + * p points to an array of structures, each consisting + * of a constant value and a label. + * The first is >=0 if there is a default label; + * its value is the label number + * The entries p[1] to p[n] are the nontrivial cases + * n is the number of case statements (length of list) + */ +static void +genswitch(int num, TWORD type, struct swents **p, int n) +{ + NODE *r, *q; + int i; + + if (mygenswitch(num, type, p, n)) + return; + + /* simple switch code */ + for (i = 1; i <= n; ++i) { + /* already in 1 */ + r = tempnode(num, type, 0, MKSUE(type)); + q = block(ICON, NIL, NIL, type, 0, MKSUE(type)); + q->n_sp = NULL; + q->n_lval = p[i]->sval; + r = buildtree(NE, r, clocal(q)); + cbranch(buildtree(NOT, r, NIL), bcon(p[i]->slab)); + } + if (p[0]->slab > 0) + branch(p[0]->slab); +} + +/* * Declare a variable or prototype. */ static struct symtab * diff --git a/usr.bin/pcc/ccom/pass1.h b/usr.bin/pcc/ccom/pass1.h index c736b681043..052673848d2 100644 --- a/usr.bin/pcc/ccom/pass1.h +++ b/usr.bin/pcc/ccom/pass1.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pass1.h,v 1.4 2007/11/18 17:39:55 ragge Exp $ */ +/* $OpenBSD: pass1.h,v 1.5 2007/11/22 15:06:43 stefan Exp $ */ /* * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. * @@ -177,7 +177,7 @@ struct swents { /* switch table */ CONSZ sval; /* case value */ int slab; /* associated label */ }; -void genswitch(int, struct swents **, int); +int mygenswitch(int, TWORD, struct swents **, int); extern int blevel; extern int instruct, got_type; @@ -254,6 +254,7 @@ extern NODE *btsize(TWORD, union dimfun *, struct suedef *), *tempnode(int, TWORD type, union dimfun *df, struct suedef *sue), *doacall(NODE *f, NODE *a); +NODE *intprom(NODE *); OFFSZ tsize(TWORD, union dimfun *, struct suedef *), psize(NODE *); NODE * typenode(NODE *new); diff --git a/usr.bin/pcc/ccom/trees.c b/usr.bin/pcc/ccom/trees.c index 1fa2ecc9c74..7d93e4a97d2 100644 --- a/usr.bin/pcc/ccom/trees.c +++ b/usr.bin/pcc/ccom/trees.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trees.c,v 1.9 2007/11/18 17:39:55 ragge Exp $ */ +/* $OpenBSD: trees.c,v 1.10 2007/11/22 15:06:43 stefan Exp $ */ /* * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). * All rights reserved. @@ -2398,3 +2398,18 @@ plabel(int label) reached = 1; /* Will this always be correct? */ send_passt(IP_DEFLAB, label); } + +/* + * Perform integer promotion on node n. + */ +NODE * +intprom(NODE *n) +{ + if ((n->n_type >= CHAR && n->n_type < INT) || n->n_type == BOOL) { + if ((n->n_type == UCHAR && MAX_UCHAR > MAX_INT) || + (n->n_type == USHORT && MAX_USHORT > MAX_INT)) + return makety(n, UNSIGNED, 0, 0, MKSUE(UNSIGNED)); + return makety(n, INT, 0, 0, MKSUE(INT)); + } + return n; +} diff --git a/usr.bin/pcc/hppa/code.c b/usr.bin/pcc/hppa/code.c index 66300335515..a3fa3381345 100644 --- a/usr.bin/pcc/hppa/code.c +++ b/usr.bin/pcc/hppa/code.c @@ -1,4 +1,4 @@ -/* $OpenBSD: code.c,v 1.1 2007/11/16 08:36:23 otto Exp $ */ +/* $OpenBSD: code.c,v 1.2 2007/11/22 15:06:43 stefan Exp $ */ /* * Copyright (c) 2007 Michael Shalayeff @@ -195,28 +195,13 @@ fldty(struct symtab *p) { } -/* p points to an array of structures, each consisting - * of a constant value and a label. - * The first is >=0 if there is a default label; - * its value is the label number - * The entries p[1] to p[n] are the nontrivial cases +/* * XXX - fix genswitch. */ -void -genswitch(int num, struct swents **p, int n) +int +mygenswitch(int num, TWORD type, struct swents **p, int n) { - NODE *r; - int i; - - /* simple switch code */ - for (i = 1; i <= n; ++i) { - /* already in 1 */ - r = tempnode(num, INT, 0, MKSUE(INT)); - r = buildtree(NE, r, bcon(p[i]->sval)); - cbranch(buildtree(NOT, r, NIL), bcon(p[i]->slab)); - } - if (p[0]->slab > 0) - branch(p[0]->slab); + return 0; } /* * Called with a function call with arguments as argument. diff --git a/usr.bin/pcc/i386/code.c b/usr.bin/pcc/i386/code.c index faed14036bc..6e51e853f84 100644 --- a/usr.bin/pcc/i386/code.c +++ b/usr.bin/pcc/i386/code.c @@ -1,4 +1,4 @@ -/* $OpenBSD: code.c,v 1.4 2007/11/18 17:39:55 ragge Exp $ */ +/* $OpenBSD: code.c,v 1.5 2007/11/22 15:06:43 stefan Exp $ */ /* * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). * All rights reserved. @@ -248,26 +248,11 @@ fldty(struct symtab *p) { } -/* p points to an array of structures, each consisting - * of a constant value and a label. - * The first is >=0 if there is a default label; - * its value is the label number - * The entries p[1] to p[n] are the nontrivial cases +/* * XXX - fix genswitch. */ -void -genswitch(int num, struct swents **p, int n) +int +mygenswitch(int num, TWORD type, struct swents **p, int n) { - NODE *r; - int i; - - /* simple switch code */ - for (i = 1; i <= n; ++i) { - /* already in 1 */ - r = tempnode(num, INT, 0, MKSUE(INT)); - r = buildtree(NE, r, bcon(p[i]->sval)); - cbranch(buildtree(NOT, r, NIL), bcon(p[i]->slab)); - } - if (p[0]->slab > 0) - branch(p[0]->slab); + return 0; } diff --git a/usr.bin/pcc/m16c/code.c b/usr.bin/pcc/m16c/code.c index 2ec7f3802f8..80bcdd70cef 100644 --- a/usr.bin/pcc/m16c/code.c +++ b/usr.bin/pcc/m16c/code.c @@ -1,4 +1,4 @@ -/* $OpenBSD: code.c,v 1.2 2007/11/16 09:00:12 otto Exp $ */ +/* $OpenBSD: code.c,v 1.3 2007/11/22 15:06:43 stefan Exp $ */ /* * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). * All rights reserved. @@ -345,34 +345,13 @@ fldty(struct symtab *p) { } -/* p points to an array of structures, each consisting - * of a constant value and a label. - * The first is >=0 if there is a default label; - * its value is the label number - * The entries p[1] to p[n] are the nontrivial cases +/* * XXX - fix genswitch. */ -void -genswitch(struct swents **p, int n) +int +mygenswitch(int num, TWORD type, struct swents **p, int n) { - uerror("switch() statements unsopported"); -#if 0 - int i; - char *s; - - /* simple switch code */ - for (i = 1; i <= n; ++i) { - /* already in 1 */ - s = (isinlining ? permalloc(40) : tmpalloc(40)); - sprintf(s, " cmpl $%lld,%%eax", p[i]->sval); - send_passt(IP_ASM, s); - s = (isinlining ? permalloc(40) : tmpalloc(40)); - sprintf(s, " je " LABFMT, p[i]->slab); - send_passt(IP_ASM, s); - } - if (p[0]->slab > 0) - branch(p[0]->slab); -#endif + return 0; } /* * Called with a function call with arguments as argument. diff --git a/usr.bin/pcc/mips/code.c b/usr.bin/pcc/mips/code.c index bbeecd96146..99847602da6 100644 --- a/usr.bin/pcc/mips/code.c +++ b/usr.bin/pcc/mips/code.c @@ -1,4 +1,4 @@ -/* $OpenBSD: code.c,v 1.2 2007/11/16 08:34:55 otto Exp $ */ +/* $OpenBSD: code.c,v 1.3 2007/11/22 15:06:43 stefan Exp $ */ /* * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). * All rights reserved. @@ -216,28 +216,13 @@ fldty(struct symtab *p) { } -/* p points to an array of structures, each consisting - * of a constant value and a label. - * The first is >=0 if there is a default label; - * its value is the label number - * The entries p[1] to p[n] are the nontrivial cases +/* * XXX - fix genswitch. */ -void -genswitch(int num, struct swents **p, int n) +int +mygenswitch(int num, TWORD type, struct swents **p, int n) { - NODE *r; - int i; - - /* simple switch code */ - for (i = 1; i <= n; ++i) { - /* already in 1 */ - r = tempnode(num, INT, 0, MKSUE(INT)); - r = buildtree(NE, r, bcon(p[i]->sval)); - cbranch(buildtree(NOT, r, NIL), bcon(p[i]->slab)); - } - if (p[0]->slab > 0) - branch(p[0]->slab); + return 0; } static void diff --git a/usr.bin/pcc/nova/code.c b/usr.bin/pcc/nova/code.c index dfc364011da..ee390ac99a2 100644 --- a/usr.bin/pcc/nova/code.c +++ b/usr.bin/pcc/nova/code.c @@ -1,4 +1,4 @@ -/* $OpenBSD: code.c,v 1.2 2007/11/16 09:00:13 otto Exp $ */ +/* $OpenBSD: code.c,v 1.3 2007/11/22 15:06:43 stefan Exp $ */ /* * Copyright (c) 2006 Anders Magnusson (ragge@ludd.luth.se). * All rights reserved. @@ -187,28 +187,13 @@ fldty(struct symtab *p) { } -/* p points to an array of structures, each consisting - * of a constant value and a label. - * The first is >=0 if there is a default label; - * its value is the label number - * The entries p[1] to p[n] are the nontrivial cases +/* * XXX - fix genswitch. */ -void -genswitch(int num, struct swents **p, int n) +int +mygenswitch(int num, TWORD type, struct swents **p, int n) { - NODE *r; - int i; - - /* simple switch code */ - for (i = 1; i <= n; ++i) { - /* already in 1 */ - r = tempnode(num, INT, 0, MKSUE(INT)); - r = buildtree(NE, r, bcon(p[i]->sval)); - cbranch(buildtree(NOT, r, NIL), bcon(p[i]->slab)); - } - if (p[0]->slab > 0) - branch(p[0]->slab); + return 0; } /* * Called with a function call with arguments as argument. diff --git a/usr.bin/pcc/pdp10/code.c b/usr.bin/pcc/pdp10/code.c index d7bdcbf760d..f52f41d48f7 100644 --- a/usr.bin/pcc/pdp10/code.c +++ b/usr.bin/pcc/pdp10/code.c @@ -1,4 +1,4 @@ -/* $OpenBSD: code.c,v 1.2 2007/11/16 09:00:13 otto Exp $ */ +/* $OpenBSD: code.c,v 1.3 2007/11/22 15:06:43 stefan Exp $ */ /* * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). * All rights reserved. @@ -250,27 +250,11 @@ fldty(struct symtab *p) { } -/* p points to an array of structures, each consisting - * of a constant value and a label. - * The first is >=0 if there is a default label; - * its value is the label number - * The entries p[1] to p[n] are the nontrivial cases +/* * XXX - fix genswitch. */ -void -genswitch(int num, struct swents **p, int n) +int +mygenswitch(int num, TWORD type, struct swents **p, int n) { - NODE *r; - int i; - - /* simple switch code */ - for (i = 1; i <= n; ++i) { - /* already in 1 */ - r = tempnode(num, INT, 0, MKSUE(INT)); - r = buildtree(NE, r, bcon(p[i]->sval)); - cbranch(buildtree(NOT, r, NIL), bcon(p[i]->slab)); - } - if (p[0]->slab > 0) - branch(p[0]->slab); - + return 0; } diff --git a/usr.bin/pcc/powerpc/code.c b/usr.bin/pcc/powerpc/code.c index 5f927ffd959..0f2338da659 100644 --- a/usr.bin/pcc/powerpc/code.c +++ b/usr.bin/pcc/powerpc/code.c @@ -1,4 +1,4 @@ -/* $OpenBSD: code.c,v 1.4 2007/11/16 09:00:13 otto Exp $ */ +/* $OpenBSD: code.c,v 1.5 2007/11/22 15:06:43 stefan Exp $ */ /* * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). * All rights reserved. @@ -32,10 +32,12 @@ #include "pass1.h" #include "pass2.h" +#if 0 static void genswitch_simple(int num, struct swents **p, int n); static void genswitch_bintree(int num, struct swents **p, int n); static void genswitch_table(int num, struct swents **p, int n); static void genswitch_mrst(int num, struct swents **p, int n); +#endif /* * cause the alignment to become a multiple of n @@ -317,17 +319,14 @@ fldty(struct symtab *p) { } -/* p points to an array of structures, each consisting - * of a constant value and a label. - * The first is >=0 if there is a default label; - * its value is the label number - * The entries p[1] to p[n] are the nontrivial cases +/* * XXX - fix genswitch. - * n is the number of case statemens (length of list) */ -void -genswitch(int num, struct swents **p, int n) +int +mygenswitch(int num, TWORD type, struct swents **p, int n) { + return 0; +#if 0 if (n == 0) { if (p[0]->sval != 0) branch(p[0]->sval); @@ -347,8 +346,10 @@ genswitch(int num, struct swents **p, int n) if (0) genswitch_bintree(num, p, n); genswitch_mrst(num, p, n); +#endif } +#if 0 static void genswitch_simple(int num, struct swents **p, int n) { @@ -808,6 +809,8 @@ mrst_find_window(struct swents **p, int n, int *state, int lab, int *len, int *l return Wmax; } +#endif + /* * Called with a function call with arguments as argument. * This is done early in buildtree() and only done once. diff --git a/usr.bin/pcc/vax/code.c b/usr.bin/pcc/vax/code.c index 8e041b69e55..a4096fd9f13 100644 --- a/usr.bin/pcc/vax/code.c +++ b/usr.bin/pcc/vax/code.c @@ -1,4 +1,4 @@ -/* $OpenBSD: code.c,v 1.3 2007/11/16 09:00:13 otto Exp $ */ +/* $OpenBSD: code.c,v 1.4 2007/11/22 15:06:43 stefan Exp $ */ /* * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. * @@ -202,17 +202,13 @@ fldty( p ) struct symtab *p; { /* fix up type of field p */ ; } -/* p points to an array of structures, each consisting - * of a constant value and a label. - * The first is >=0 if there is a default label; - * its value is the label number - * The entries p[1] to p[n] are the nontrivial cases +/* * XXX - fix genswitch. */ -void -genswitch(int num, struct swents **p, int n) +int +mygenswitch(int num, TWORD type, struct swents **p, int n) { - cerror("genswitch"); + return 0; } #ifdef notyet |