summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/pcc/ccom/cgram.y101
-rw-r--r--usr.bin/pcc/ccom/pass1.h5
-rw-r--r--usr.bin/pcc/ccom/trees.c17
-rw-r--r--usr.bin/pcc/hppa/code.c25
-rw-r--r--usr.bin/pcc/i386/code.c25
-rw-r--r--usr.bin/pcc/m16c/code.c31
-rw-r--r--usr.bin/pcc/mips/code.c25
-rw-r--r--usr.bin/pcc/nova/code.c25
-rw-r--r--usr.bin/pcc/pdp10/code.c26
-rw-r--r--usr.bin/pcc/powerpc/code.c21
-rw-r--r--usr.bin/pcc/vax/code.c14
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