summaryrefslogtreecommitdiff
path: root/usr.bin/pcc
diff options
context:
space:
mode:
authorStefan Kempf <stefan@cvs.openbsd.org>2007-12-22 22:56:32 +0000
committerStefan Kempf <stefan@cvs.openbsd.org>2007-12-22 22:56:32 +0000
commit6ca4d0c856b7b95130215d2f95e092898ad991db (patch)
tree4ee33bbf29471bebe47a5c23a88285aafafb9440 /usr.bin/pcc
parentb575ace5a68441ce83385134f42dfd60c88a1d2c (diff)
Sync with main repo.
Diffstat (limited to 'usr.bin/pcc')
-rw-r--r--usr.bin/pcc/arm/local2.c8
-rw-r--r--usr.bin/pcc/arm/macdefs.h2
-rw-r--r--usr.bin/pcc/ccom/init.c8
-rw-r--r--usr.bin/pcc/ccom/pass1.h3
-rw-r--r--usr.bin/pcc/ccom/pftn.c9
-rw-r--r--usr.bin/pcc/ccom/trees.c21
-rw-r--r--usr.bin/pcc/hppa/local2.c8
-rw-r--r--usr.bin/pcc/i386/local2.c106
-rw-r--r--usr.bin/pcc/i386/table.c42
-rw-r--r--usr.bin/pcc/m16c/local2.c8
-rw-r--r--usr.bin/pcc/mip/match.c13
-rw-r--r--usr.bin/pcc/mip/protos.h4
-rw-r--r--usr.bin/pcc/mips/code.c212
-rw-r--r--usr.bin/pcc/mips/local.c64
-rw-r--r--usr.bin/pcc/mips/local2.c96
-rw-r--r--usr.bin/pcc/mips/macdefs.h4
-rw-r--r--usr.bin/pcc/mips/order.c7
-rw-r--r--usr.bin/pcc/mips/table.c524
-rw-r--r--usr.bin/pcc/nova/local2.c8
-rw-r--r--usr.bin/pcc/pdp10/local2.c8
-rw-r--r--usr.bin/pcc/powerpc/local2.c8
-rw-r--r--usr.bin/pcc/vax/local2.c8
22 files changed, 802 insertions, 369 deletions
diff --git a/usr.bin/pcc/arm/local2.c b/usr.bin/pcc/arm/local2.c
index 4f0f2e6748d..36182094d41 100644
--- a/usr.bin/pcc/arm/local2.c
+++ b/usr.bin/pcc/arm/local2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: local2.c,v 1.2 2007/12/22 12:38:56 stefan Exp $ */
+/* $OpenBSD: local2.c,v 1.3 2007/12/22 22:56:31 stefan Exp $ */
/*
* Copyright (c) 2007 Gregory McGarry (g.mcgarry@ieee.org).
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
@@ -169,6 +169,12 @@ twollcomp(NODE *p)
deflab(s);
}
+int
+fldexpand(NODE *P, int cookie, char **cp)
+{
+ return 0;
+}
+
#if 0
/*
* Assign to a bitfield.
diff --git a/usr.bin/pcc/arm/macdefs.h b/usr.bin/pcc/arm/macdefs.h
index c125945eb43..df8db2007db 100644
--- a/usr.bin/pcc/arm/macdefs.h
+++ b/usr.bin/pcc/arm/macdefs.h
@@ -1,4 +1,4 @@
-/* $Id: macdefs.h,v 1.1 2007/11/25 18:45:06 otto Exp $ */
+/* $OpenBSD: macdefs.h,v 1.2 2007/12/22 22:56:31 stefan Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
diff --git a/usr.bin/pcc/ccom/init.c b/usr.bin/pcc/ccom/init.c
index 6b2ff1e96f1..ee85a716e32 100644
--- a/usr.bin/pcc/ccom/init.c
+++ b/usr.bin/pcc/ccom/init.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: init.c,v 1.4 2007/12/09 18:49:06 ragge Exp $ */
+/* $OpenBSD: init.c,v 1.5 2007/12/22 22:56:31 stefan Exp $ */
/*
* Copyright (c) 2004, 2007 Anders Magnusson (ragge@ludd.ltu.se).
@@ -455,7 +455,9 @@ setscl(struct symtab *sp)
{
int ro = DATA;
- if (BTYPE(sp->stype) == sp->stype && sp->squal == (CON >> TSHIFT))
+ if (BTYPE(sp->stype) == sp->stype && sp->squal & (CON >> TSHIFT))
+ ro = RDATA;
+ else if (ISPTR(sp->stype) && ISCON(sp->squal))
ro = RDATA;
/* XXX - readonly pointers */
setloc1(ro);
@@ -813,7 +815,7 @@ desinit(NODE *p)
mkstack(p); /* Setup for assignment */
/* pop one step if SOU, ilbrace will push */
- if (op == NAME)
+ if (op == NAME || op == LB)
pstk = pstk->in_prev;
#ifdef PCC_DEBUG
diff --git a/usr.bin/pcc/ccom/pass1.h b/usr.bin/pcc/ccom/pass1.h
index 052673848d2..c23e2b8d1f9 100644
--- a/usr.bin/pcc/ccom/pass1.h
+++ b/usr.bin/pcc/ccom/pass1.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pass1.h,v 1.5 2007/11/22 15:06:43 stefan Exp $ */
+/* $OpenBSD: pass1.h,v 1.6 2007/12/22 22:56:31 stefan Exp $ */
/*
* Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
*
@@ -325,6 +325,7 @@ NODE *funcode(NODE *);
struct symtab *enumhd(char *);
NODE *enumdcl(struct symtab *);
NODE *enumref(char *);
+CONSZ icons(NODE *);
#ifdef GCC_COMPAT
void gcc_init(void);
diff --git a/usr.bin/pcc/ccom/pftn.c b/usr.bin/pcc/ccom/pftn.c
index 0e68d40b469..a648525d508 100644
--- a/usr.bin/pcc/ccom/pftn.c
+++ b/usr.bin/pcc/ccom/pftn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pftn.c,v 1.9 2007/12/09 18:47:07 ragge Exp $ */
+/* $OpenBSD: pftn.c,v 1.10 2007/12/22 22:56:31 stefan Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
@@ -1779,7 +1779,7 @@ tymerge(NODE *typ, NODE *idp)
#endif
idp->n_type = typ->n_type;
- idp->n_qual = typ->n_qual;
+ idp->n_qual |= typ->n_qual;
tylkp = &tylnk;
tylkp->next = NULL;
@@ -1804,7 +1804,6 @@ tymerge(NODE *typ, NODE *idp)
/* now idp is a single node: fix up type */
idp->n_type = ctype(idp->n_type);
-// idp->n_qual = DECQAL(idp->n_qual);
/* in case ctype has rewritten things */
if ((t = BTYPE(idp->n_type)) != STRTY && t != UNIONTY)
@@ -1921,8 +1920,10 @@ tyreduce(NODE *p, struct tylnk **tylkp, int *ntdim)
TWORD t, q;
o = p->n_op;
- if (o == NAME)
+ if (o == NAME) {
+ p->n_qual = DECQAL(p->n_qual);
return;
+ }
t = INCREF(p->n_type);
q = p->n_qual;
diff --git a/usr.bin/pcc/ccom/trees.c b/usr.bin/pcc/ccom/trees.c
index d7c697843bb..09f71974633 100644
--- a/usr.bin/pcc/ccom/trees.c
+++ b/usr.bin/pcc/ccom/trees.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trees.c,v 1.11 2007/12/09 18:45:07 ragge Exp $ */
+/* $OpenBSD: trees.c,v 1.12 2007/12/22 22:56:31 stefan Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
@@ -1296,20 +1296,21 @@ block(int o, NODE *l, NODE *r, TWORD t, union dimfun *d, struct suedef *sue)
return(p);
}
-int
-icons(p) register NODE *p; {
+/*
+ * Return the constant value from an ICON.
+ */
+CONSZ
+icons(NODE *p)
+{
/* if p is an integer constant, return its value */
- int val;
+ CONSZ val;
- if( p->n_op != ICON ){
+ if (p->n_op != ICON || p->n_sp != NULL) {
uerror( "constant expected");
val = 1;
- }
- else {
+ } else
val = p->n_lval;
- if( val != p->n_lval ) uerror( "constant too big for cross-compiler" );
- }
- tfree( p );
+ tfree(p);
return(val);
}
diff --git a/usr.bin/pcc/hppa/local2.c b/usr.bin/pcc/hppa/local2.c
index a76693ce6de..feec2e85ccc 100644
--- a/usr.bin/pcc/hppa/local2.c
+++ b/usr.bin/pcc/hppa/local2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: local2.c,v 1.2 2007/12/19 20:19:54 otto Exp $ */
+/* $OpenBSD: local2.c,v 1.3 2007/12/22 22:56:31 stefan Exp $ */
/*
* Copyright (c) 2007 Michael Shalayeff
@@ -391,6 +391,12 @@ canaddr(NODE *p)
return(0);
}
+int
+fldexpand(NODE *p, int cookie, char **cp)
+{
+ return 0;
+}
+
/*
* Does the bitfield shape match?
*/
diff --git a/usr.bin/pcc/i386/local2.c b/usr.bin/pcc/i386/local2.c
index 4c8b0637fef..b79e32f07c0 100644
--- a/usr.bin/pcc/i386/local2.c
+++ b/usr.bin/pcc/i386/local2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: local2.c,v 1.5 2007/12/09 18:54:39 ragge Exp $ */
+/* $OpenBSD: local2.c,v 1.6 2007/12/22 22:56:31 stefan Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
@@ -272,58 +272,64 @@ twollcomp(NODE *p)
deflab(s);
}
-/*
- * Assign to a bitfield.
- * Clumsy at least, but what to do?
- */
-static void
-bfasg(NODE *p)
+int
+fldexpand(NODE *p, int cookie, char **cp)
{
- NODE *fn = p->n_left;
- int shift = UPKFOFF(fn->n_rval);
- int fsz = UPKFSZ(fn->n_rval);
- int andval, tch = 0;
-
- /* get instruction size */
- switch (p->n_type) {
- case CHAR: case UCHAR: tch = 'b'; break;
- case SHORT: case USHORT: tch = 'w'; break;
- case INT: case UNSIGNED: tch = 'l'; break;
- default: comperr("bfasg");
+ CONSZ val;
+
+ if (p->n_op == ASSIGN)
+ p = p->n_left;
+ switch (**cp) {
+ case 'S':
+ printf("%d", UPKFSZ(p->n_rval));
+ break;
+ case 'H':
+ printf("%d", UPKFOFF(p->n_rval));
+ break;
+ case 'M':
+ case 'N':
+ val = 1 << UPKFSZ(p->n_rval);
+ --val;
+ val <<= UPKFOFF(p->n_rval);
+ printf("0x%llx", (**cp == 'M' ? val : ~val) & 0xffffffff);
+ break;
+ default:
+ comperr("fldexpand");
}
+ return 1;
+}
- /* put src into a temporary reg */
- fprintf(stdout, " mov%c ", tch);
- adrput(stdout, getlr(p, 'R'));
- fprintf(stdout, ",");
- adrput(stdout, getlr(p, '1'));
- fprintf(stdout, "\n");
-
- /* AND away the bits from dest */
- andval = ~(((1 << fsz) - 1) << shift);
- fprintf(stdout, " and%c $%d,", tch, andval);
- adrput(stdout, fn->n_left);
- fprintf(stdout, "\n");
-
- /* AND away unwanted bits from src */
- andval = ((1 << fsz) - 1);
- fprintf(stdout, " and%c $%d,", tch, andval);
- adrput(stdout, getlr(p, '1'));
- fprintf(stdout, "\n");
-
- /* SHIFT left src number of bits */
- if (shift) {
- fprintf(stdout, " sal%c $%d,", tch, shift);
- adrput(stdout, getlr(p, '1'));
- fprintf(stdout, "\n");
+static void
+bfext(NODE *p)
+{
+ int ch = 0, sz = 0;
+
+ if (ISUNSIGNED(p->n_right->n_type))
+ return;
+ switch (p->n_right->n_type) {
+ case CHAR:
+ ch = 'b';
+ sz = 8;
+ break;
+ case SHORT:
+ ch = 'w';
+ sz = 16;
+ break;
+ case INT:
+ case LONG:
+ ch = 'l';
+ sz = 32;
+ break;
+ default:
+ comperr("bfext");
}
- /* OR in src to dest */
- fprintf(stdout, " or%c ", tch);
- adrput(stdout, getlr(p, '1'));
- fprintf(stdout, ",");
- adrput(stdout, fn->n_left);
- fprintf(stdout, "\n");
+ sz -= UPKFSZ(p->n_left->n_rval);
+ printf("\tshl%c $%d,", ch, sz);
+ adrput(stdout, getlr(p, 'D'));
+ printf("\n\tsar%c $%d,", ch, sz);
+ adrput(stdout, getlr(p, 'D'));
+ printf("\n");
}
/*
@@ -461,8 +467,8 @@ zzzcode(NODE *p, int c)
twollcomp(p);
break;
- case 'E': /* Assign to bitfield */
- bfasg(p);
+ case 'E': /* Perform bitfield sign-extension */
+ bfext(p);
break;
case 'F': /* Structure argument */
diff --git a/usr.bin/pcc/i386/table.c b/usr.bin/pcc/i386/table.c
index 6991920b141..81c4ccb47af 100644
--- a/usr.bin/pcc/i386/table.c
+++ b/usr.bin/pcc/i386/table.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: table.c,v 1.4 2007/12/16 19:27:33 ragge Exp $ */
+/* $OpenBSD: table.c,v 1.5 2007/12/22 22:56:31 stefan Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
@@ -930,20 +930,40 @@ struct optab table[] = {
{ ASSIGN, FOREFF|INBREG,
SFLD, TCHAR|TUCHAR,
SBREG|SCON, TCHAR|TUCHAR,
- NBREG, RDEST,
- "ZE", },
+ NAREG|NBREG, RDEST,
+ " movb AR,A2\n"
+ " movzbl A2,A1\n"
+ " andl $N,AL\n"
+ " sall $H,A1\n"
+ " andl $M,A1\n"
+ " orl A1,AL\n"
+ "F movb AR,AD\n"
+ "FZE", },
{ ASSIGN, FOREFF|INAREG,
- SFLD, TANY,
- SAREG, TANY,
+ SFLD, TSHORT|TUSHORT,
+ SAREG|SCON, TSHORT|TUSHORT,
NAREG, RDEST,
- "ZE", },
+ " movw AR,A1\n"
+ " movzwl A1,ZN\n"
+ " andl $N,AL\n"
+ " sall $H,ZN\n"
+ " andl $M,ZN\n"
+ " orl ZN,AL\n"
+ "F movw AR,AD\n"
+ "FZE", },
-{ ASSIGN, FOREFF,
- SFLD, TANY,
- SAREG|SNAME|SOREG|SCON, TANY,
- NAREG, 0,
- "ZE", },
+{ ASSIGN, FOREFF|INAREG,
+ SFLD, TWORD,
+ SAREG|SNAME|SOREG|SCON, TWORD,
+ NAREG, RDEST,
+ " movl AR,A1\n"
+ " andl $N,AL\n"
+ " sall $H,A1\n"
+ " andl $M,A1\n"
+ " orl A1,AL\n"
+ "F movl AR,AD\n"
+ "FZE", },
{ ASSIGN, INDREG|FOREFF,
SHFL, TFLOAT|TDOUBLE|TLDOUBLE,
diff --git a/usr.bin/pcc/m16c/local2.c b/usr.bin/pcc/m16c/local2.c
index 25335cafaa0..d19b7243440 100644
--- a/usr.bin/pcc/m16c/local2.c
+++ b/usr.bin/pcc/m16c/local2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: local2.c,v 1.2 2007/12/22 12:48:52 stefan Exp $ */
+/* $OpenBSD: local2.c,v 1.3 2007/12/22 22:56:31 stefan Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
@@ -310,6 +310,12 @@ canaddr(NODE *p)
return(0);
}
+int
+fldexpand(NODE *p, int cookie, char **cp)
+{
+ return 0;
+}
+
/*
* Does the bitfield shape match?
*/
diff --git a/usr.bin/pcc/mip/match.c b/usr.bin/pcc/mip/match.c
index a37ed55427d..fe7d0603a77 100644
--- a/usr.bin/pcc/mip/match.c
+++ b/usr.bin/pcc/mip/match.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: match.c,v 1.6 2007/12/09 18:42:42 ragge Exp $ */
+/* $OpenBSD: match.c,v 1.7 2007/12/22 22:56:31 stefan Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
@@ -275,19 +275,28 @@ expand(NODE *p, int cookie, char *cp)
continue;
case 'F': /* this line deleted if FOREFF is active */
- if( cookie & FOREFF ) while( *++cp != '\n' ) ; /* VOID */
+ if (cookie & FOREFF) {
+ while (*++cp != '\n' && *(cp - 1) != '\0')
+ continue;
+ }
continue;
case 'S': /* field size */
+ if (fldexpand(p, cookie, &cp))
+ continue;
printf("%d", FLDSZ(p->n_rval));
continue;
case 'H': /* field shift */
+ if (fldexpand(p, cookie, &cp))
+ continue;
printf("%d", FLDSHF(p->n_rval));
continue;
case 'M': /* field mask */
case 'N': /* complement of field mask */
+ if (fldexpand(p, cookie, &cp))
+ continue;
val = 1;
val <<= FLDSZ(p->n_rval);
--val;
diff --git a/usr.bin/pcc/mip/protos.h b/usr.bin/pcc/mip/protos.h
index 88e0811b667..a5f8674110a 100644
--- a/usr.bin/pcc/mip/protos.h
+++ b/usr.bin/pcc/mip/protos.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: protos.h,v 1.5 2007/12/09 18:38:49 ragge Exp $ */
+/* $OpenBSD: protos.h,v 1.6 2007/12/22 22:56:31 stefan Exp $ */
struct optab;
struct symtab;
@@ -36,6 +36,7 @@ void dclargs(void);
void cendarg(void);
void defalign(int);
int fldal(unsigned int);
+int fldexpand(NODE *, int, char **);
void putbyte(int v);
void ecomp(NODE *p);
void bccode(void);
@@ -54,7 +55,6 @@ void oreg2(NODE *p);
int notoff(TWORD, int, CONSZ, char *);
void bycode(int, int);
int notlval(NODE *);
-int icons(NODE *);
void ecode(NODE *p);
int yylex(void);
void yyerror(char *s);
diff --git a/usr.bin/pcc/mips/code.c b/usr.bin/pcc/mips/code.c
index be0598d4ae1..be0830362ac 100644
--- a/usr.bin/pcc/mips/code.c
+++ b/usr.bin/pcc/mips/code.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: code.c,v 1.4 2007/12/22 14:12:26 stefan Exp $ */
+/* $OpenBSD: code.c,v 1.5 2007/12/22 22:56:31 stefan Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
@@ -42,10 +42,10 @@
void
defalign(int n)
{
- n /= SZCHAR;
- if (n == 1)
- return;
- printf("\t.align %d\n", n);
+ n = ispow2(n / SZCHAR);
+ if (n == -1)
+ cerror("defalign: n != 2^i");
+ printf("\t.p2align %d\n", n);
}
/*
@@ -179,39 +179,36 @@ param_64bit(struct symtab *sym, int *regp, int dotemps)
int reg = *regp;
NODE *p, *q;
int navail;
- int sz;
/* alignment */
++reg;
reg &= ~1;
navail = nargregs - (reg - A0);
- sz = szty(sym->stype);
- if (sz > navail) {
+ if (navail < 2) {
/* would have appeared half in registers/half
* on the stack, but alignment ensures it
* appears on the stack */
if (dotemps)
putintemp(sym);
- } else {
- q = block(REG, NIL, NIL,
- sym->stype, sym->sdf, sym->ssue);
- q->n_rval = A0A1 + (reg - A0);
- if (dotemps) {
- p = tempnode(0, sym->stype, sym->sdf, sym->ssue);
- sym->soffset = p->n_lval;
- sym->sflags |= STNODE;
- } else {
- spname = sym;
- p = buildtree(NAME, 0, 0);
- }
- p = buildtree(ASSIGN, p, q);
- ecomp(p);
- reg += 2;
+ *regp = reg;
+ return;
}
- *regp = reg;
+ q = block(REG, NIL, NIL, sym->stype, sym->sdf, sym->ssue);
+ q->n_rval = A0A1 + (reg - A0);
+ if (dotemps) {
+ p = tempnode(0, sym->stype, sym->sdf, sym->ssue);
+ sym->soffset = p->n_lval;
+ sym->sflags |= STNODE;
+ } else {
+ spname = sym;
+ p = buildtree(NAME, 0, 0);
+ }
+ p = buildtree(ASSIGN, p, q);
+ ecomp(p);
+ *regp = reg + 2;
}
/* setup a 32-bit param on the stack
@@ -236,6 +233,85 @@ param_32bit(struct symtab *sym, int *regp, int dotemps)
}
/*
+ * XXX This is a hack. We cannot have (l)doubles in more than one
+ * register class. So we bounce them in and out of temps to
+ * move them in and out of the right registers.
+ */
+static void
+param_double(struct symtab *sym, int *regp, int dotemps)
+{
+ int reg = *regp;
+ NODE *p, *q, *t;
+ int navail;
+ int tmpnr;
+
+ /* alignment */
+ ++reg;
+ reg &= ~1;
+
+ navail = nargregs - (reg - A0);
+
+ if (navail < 2) {
+ /* would have appeared half in registers/half
+ * on the stack, but alignment ensures it
+ * appears on the stack */
+ if (dotemps)
+ putintemp(sym);
+ *regp = reg;
+ return;
+ }
+
+ t = tempnode(0, LONGLONG, 0, MKSUE(LONGLONG));
+ tmpnr = t->n_lval;
+ q = block(REG, NIL, NIL, LONGLONG, 0, MKSUE(LONGLONG));
+ q->n_rval = A0A1 + (reg - A0);
+ p = buildtree(ASSIGN, t, q);
+ ecomp(p);
+
+ if (dotemps) {
+ sym->soffset = tmpnr;
+ sym->sflags |= STNODE;
+ } else {
+ q = tempnode(tmpnr, sym->stype, sym->sdf, sym->ssue);
+ spname = sym;
+ p = buildtree(NAME, 0, 0);
+ p = buildtree(ASSIGN, p, q);
+ ecomp(p);
+ }
+ *regp = reg + 2;
+}
+
+/*
+ * XXX This is a hack. We cannot have floats in more than one
+ * register class. So we bounce them in and out of temps to
+ * move them in and out of the right registers.
+ */
+static void
+param_float(struct symtab *sym, int *regp, int dotemps)
+{
+ NODE *p, *q, *t;
+ int tmpnr;
+
+ t = tempnode(0, INT, 0, MKSUE(INT));
+ tmpnr = t->n_lval;
+ q = block(REG, NIL, NIL, INT, 0, MKSUE(INT));
+ q->n_rval = (*regp)++;
+ p = buildtree(ASSIGN, t, q);
+ ecomp(p);
+
+ if (dotemps) {
+ sym->soffset = tmpnr;
+ sym->sflags |= STNODE;
+ } else {
+ q = tempnode(tmpnr, sym->stype, sym->sdf, sym->ssue);
+ spname = sym;
+ p = buildtree(NAME, 0, 0);
+ p = buildtree(ASSIGN, p, q);
+ ecomp(p);
+ }
+}
+
+/*
* code for the beginning of a function; a is an array of
* indices in symtab for the arguments; n is the number
*/
@@ -277,9 +353,12 @@ bfcode(struct symtab **sp, int cnt)
putintemp(sp[i]);
else if (sp[i]->stype == STRTY || sp[i]->stype == UNIONTY)
param_struct(sp[i], &reg);
- else if (sp[i]->stype == DOUBLE || sp[i]->stype == LDOUBLE ||
- DEUNSIGN(sp[i]->stype) == LONGLONG)
+ else if (DEUNSIGN(sp[i]->stype) == LONGLONG)
param_64bit(sp[i], &reg, xtemps && !saveallargs);
+ else if (sp[i]->stype == DOUBLE || sp[i]->stype == LDOUBLE)
+ param_double(sp[i], &reg, xtemps && !saveallargs);
+ else if (sp[i]->stype == FLOAT)
+ param_float(sp[i], &reg, xtemps && !saveallargs);
else
param_32bit(sp[i], &reg, xtemps && !saveallargs);
}
@@ -340,16 +419,18 @@ bycode(int t, int i)
if (t < 0) {
if (i != 0)
- puts("\"");
+ puts("\\000\"");
} else {
if (i == 0)
- printf("\t.asciiz \"");
+ printf("\t.ascii \"");
if (t == 0)
return;
else if (t == '\\' || t == '"') {
lastoctal = 0;
putchar('\\');
putchar(t);
+ } else if (t == 011) {
+ printf("\\t");
} else if (t == 012) {
printf("\\n");
} else if (t < 040 || t >= 0177) {
@@ -357,7 +438,7 @@ bycode(int t, int i)
printf("\\%o",t);
} else if (lastoctal && '0' <= t && t <= '9') {
lastoctal = 0;
- printf("\"\n\t.asciiz \"%c", t);
+ printf("\"\n\t.ascii \"%c", t);
} else {
lastoctal = 0;
putchar(t);
@@ -397,25 +478,34 @@ static NODE *
movearg_struct(NODE *p, NODE *parent, int *regp)
{
int reg = *regp;
- NODE *q, *t, *r;
+ NODE *l, *q, *t, *r;
+ int tmpnr;
int navail;
int off;
int num;
int sz;
+ int ty;
int i;
navail = nargregs - (reg - A0);
sz = tsize(p->n_type, p->n_df, p->n_sue) / SZINT;
num = sz > navail ? navail : sz;
- if (p != parent)
+ l = p->n_left;
+ nfree(p);
+ ty = l->n_type;
+ t = tempnode(0, l->n_type, l->n_df, l->n_sue);
+ tmpnr = t->n_lval;
+ l = buildtree(ASSIGN, t, l);
+
+ if (p != parent) {
q = parent->n_left;
- else
+ } else
q = NULL;
/* copy structure into registers */
for (i = 0; i < num; i++) {
- t = tcopy(p->n_left);
+ t = tempnode(tmpnr, ty, 0, MKSUE(PTR+ty));
t = block(SCONV, t, NIL, PTR+INT, 0, MKSUE(PTR+INT));
t = block(PLUS, t, bcon(4*i), PTR+INT, 0, MKSUE(PTR+INT));
t = buildtree(UMUL, t, NIL);
@@ -426,12 +516,12 @@ movearg_struct(NODE *p, NODE *parent, int *regp)
r = buildtree(ASSIGN, r, t);
if (q == NULL)
q = r;
- else
+ else
q = block(CM, q, r, INT, 0, MKSUE(INT));
}
off = ARGINIT/SZINT + nargregs;
for (i = num; i < sz; i++) {
- t = tcopy(p->n_left);
+ t = tempnode(tmpnr, ty, 0, MKSUE(PTR+ty));
t = block(SCONV, t, NIL, PTR+INT, 0, MKSUE(PTR+INT));
t = block(PLUS, t, bcon(4*i), PTR+INT, 0, MKSUE(PTR+INT));
t = buildtree(UMUL, t, NIL);
@@ -447,13 +537,12 @@ movearg_struct(NODE *p, NODE *parent, int *regp)
else
q = block(CM, q, r, INT, 0, MKSUE(INT));
}
- tfree(p);
if (parent->n_op == CM) {
- parent->n_left = q->n_left;
- t = q;
- q = q->n_right;
- nfree(t);
+ parent->n_left = q;
+ q = l;
+ } else {
+ q = block(CM, q, l, INT, 0, MKSUE(INT));
}
*regp = reg;
@@ -467,16 +556,23 @@ movearg_64bit(NODE *p, int *regp)
{
int reg = *regp;
NODE *q;
+ int lastarg;
/* alignment */
++reg;
reg &= ~1;
+ lastarg = A0 + nargregs - 1;
+ if (reg > lastarg) {
+ *regp = reg;
+ return block(FUNARG, p, NIL, p->n_type, p->n_df, p->n_sue);
+ }
+
q = block(REG, NIL, NIL, p->n_type, p->n_df, p->n_sue);
- q->n_rval = A0A1 + (reg++ - A0);
+ q->n_rval = A0A1 + (reg - A0);
q = buildtree(ASSIGN, q, p);
- *regp = reg;
+ *regp = reg + 2;
return q;
}
@@ -519,11 +615,37 @@ moveargs(NODE *p, int *regp)
*rp = block(FUNARG, r, NIL, r->n_type, r->n_df, r->n_sue);
else if (r->n_op == STARG) {
*rp = movearg_struct(r, p, regp);
- } else if (DEUNSIGN(r->n_type) == LONGLONG || r->n_type == DOUBLE ||
- r->n_type == LDOUBLE)
+ } else if (DEUNSIGN(r->n_type) == LONGLONG) {
*rp = movearg_64bit(r, regp);
- else
+ } else if (r->n_type == DOUBLE || r->n_type == LDOUBLE) {
+ /* XXX bounce in and out of temporary to change to longlong */
+ NODE *t1 = tempnode(0, LONGLONG, 0, MKSUE(LONGLONG));
+ int tmpnr = t1->n_lval;
+ NODE *t2 = tempnode(tmpnr, r->n_type, r->n_df, r->n_sue);
+ t1 = movearg_64bit(t1, regp);
+ r = block(ASSIGN, t2, r, r->n_type, r->n_df, r->n_sue);
+ if (p->n_op == CM) {
+ p->n_left = buildtree(CM, p->n_left, t1);
+ p->n_right = r;
+ } else {
+ p = buildtree(CM, t1, r);
+ }
+ } else if (r->n_type == FLOAT) {
+ /* XXX bounce in and out of temporary to change to int */
+ NODE *t1 = tempnode(0, INT, 0, MKSUE(INT));
+ int tmpnr = t1->n_lval;
+ NODE *t2 = tempnode(tmpnr, r->n_type, r->n_df, r->n_sue);
+ t1 = movearg_32bit(t1, regp);
+ r = block(ASSIGN, t2, r, r->n_type, r->n_df, r->n_sue);
+ if (p->n_op == CM) {
+ p->n_left = buildtree(CM, p->n_left, t1);
+ p->n_right = r;
+ } else {
+ p = buildtree(CM, t1, r);
+ }
+ } else {
*rp = movearg_32bit(r, regp);
+ }
return p;
}
diff --git a/usr.bin/pcc/mips/local.c b/usr.bin/pcc/mips/local.c
index e821be7ed2c..4c8a43f0f47 100644
--- a/usr.bin/pcc/mips/local.c
+++ b/usr.bin/pcc/mips/local.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: local.c,v 1.4 2007/12/22 14:12:26 stefan Exp $ */
+/* $OpenBSD: local.c,v 1.5 2007/12/22 22:56:31 stefan Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
@@ -260,6 +260,9 @@ clocal(NODE *p)
if (!ISPTR(m)) /* Pointers don't need to be conv'd */
switch (m) {
+ case BOOL:
+ l->n_lval = l->n_lval != 0;
+ break;
case CHAR:
l->n_lval = (char)val;
break;
@@ -404,31 +407,23 @@ void
spalloc(NODE *t, NODE *p, OFFSZ off)
{
NODE *sp;
+ int nbytes = off / SZCHAR;
- if ((off % SZINT) == 0)
- p = buildtree(MUL, p, bcon(off/SZINT));
- else if ((off % SZSHORT) == 0) {
- p = buildtree(MUL, p, bcon(off/SZSHORT));
- p = buildtree(PLUS, p, bcon(1));
- p = buildtree(RS, p, bcon(1));
- } else if ((off % SZCHAR) == 0) {
- p = buildtree(MUL, p, bcon(off/SZCHAR));
- p = buildtree(PLUS, p, bcon(3));
- p = buildtree(RS, p, bcon(2));
- } else
- cerror("roundsp");
-
- /* save the address of sp */
- sp = block(REG, NIL, NIL, PTR+INT, t->n_df, t->n_sue);
- sp->n_rval = SP;
- t->n_type = sp->n_type;
- ecomp(buildtree(ASSIGN, t, sp)); /* Emit! */
+ p = buildtree(MUL, p, bcon(nbytes));
+ p = buildtree(PLUS, p, bcon(7));
+ p = buildtree(AND, p, bcon(~7));
/* subtract the size from sp */
sp = block(REG, NIL, NIL, p->n_type, 0, 0);
sp->n_lval = 0;
sp->n_rval = SP;
ecomp(buildtree(MINUSEQ, sp, p));
+
+ /* save the address of sp */
+ sp = block(REG, NIL, NIL, PTR+INT, t->n_df, t->n_sue);
+ sp->n_rval = SP;
+ t->n_type = sp->n_type;
+ ecomp(buildtree(ASSIGN, t, sp)); /* Emit! */
}
/*
@@ -438,7 +433,7 @@ spalloc(NODE *t, NODE *p, OFFSZ off)
void
ninval(CONSZ off, int fsz, NODE *p)
{
- union { float f; double d; long double l; int i[3]; } u;
+ union { float f; double d; int i[2]; } u;
struct symtab *q;
TWORD t;
#ifndef USE_GAS
@@ -459,7 +454,7 @@ ninval(CONSZ off, int fsz, NODE *p)
case LONGLONG:
case ULONGLONG:
#ifdef USE_GAS
- printf("\t.dword 0x%llx\n", (long long)p->n_lval);
+ printf("\t.dword %lld\n", (long long)p->n_lval);
#else
i = p->n_lval >> 32;
j = p->n_lval & 0xffffffff;
@@ -483,7 +478,7 @@ ninval(CONSZ off, int fsz, NODE *p)
/* FALLTHROUGH */
case INT:
case UNSIGNED:
- printf("\t.word 0x%x", (int)p->n_lval);
+ printf("\t.word " CONFMT, (CONSZ)p->n_lval);
if ((q = p->n_sp) != NULL) {
if ((q->sclass == STATIC && q->slevel > 0) ||
q->sclass == ILABEL) {
@@ -495,7 +490,7 @@ ninval(CONSZ off, int fsz, NODE *p)
break;
case SHORT:
case USHORT:
- printf("\t.half 0x%x\n", (int)p->n_lval & 0xffff);
+ printf("\t.half %d\n", (int)p->n_lval & 0xffff);
break;
case CHAR:
case UCHAR:
@@ -505,11 +500,11 @@ ninval(CONSZ off, int fsz, NODE *p)
case DOUBLE:
u.d = (double)p->n_dcon;
if (bigendian) {
- printf("\t.word\t0x%x\n", u.i[0]);
- printf("\t.word\t0x%x\n", u.i[1]);
+ printf("\t.word\t%d\n", u.i[0]);
+ printf("\t.word\t%d\n", u.i[1]);
} else {
- printf("\t.word\t0x%x\n", u.i[1]);
- printf("\t.word\t0x%x\n", u.i[0]);
+ printf("\t.word\t%d\n", u.i[1]);
+ printf("\t.word\t%d\n", u.i[0]);
}
break;
case FLOAT:
@@ -617,11 +612,18 @@ static char *loctbl[] = { "text", "data", "rdata", "rdata" };
void
setloc1(int locc)
{
- if ((locc == lastloc) || (lastloc == DATA && locc == STRNG) ||
- (locc == STRNG && lastloc == DATA))
+ if (locc == lastloc && locc != STRNG)
return;
- lastloc = locc;
- printf("\t.%s\n", loctbl[locc]);
+ if (locc == DATA && lastloc == STRNG)
+ return;
+
+ if (locc != lastloc) {
+ lastloc = locc;
+ printf("\t.%s\n", loctbl[locc]);
+ }
+
+ if (locc == STRNG)
+ printf("\t.align 2\n");
}
/*
diff --git a/usr.bin/pcc/mips/local2.c b/usr.bin/pcc/mips/local2.c
index 1a1dcb0d71e..9ff1ed1eafc 100644
--- a/usr.bin/pcc/mips/local2.c
+++ b/usr.bin/pcc/mips/local2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: local2.c,v 1.3 2007/12/22 14:12:26 stefan Exp $ */
+/* $OpenBSD: local2.c,v 1.4 2007/12/22 22:56:31 stefan Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
@@ -46,7 +46,7 @@ int bigendian = 0;
int nargregs = MIPS_O32_NARGREGS;
-static int argsiz(NODE * p);
+static int argsiz(NODE *p);
void
deflab(int label)
@@ -112,6 +112,21 @@ prologue(struct interpass_prolog * ipp)
printf("\tsw %s,4(%s)\n", rnames[RA], rnames[SP]);
printf("\tsw %s,(%s)\n", rnames[FP], rnames[SP]);
printf("\tmove %s,%s\n", rnames[FP], rnames[SP]);
+
+#ifdef notyet
+ /* profiling */
+ if (pflag) {
+ printf("\t.set noat\n");
+ printf("\tmove %s,%s\t# save current return address\n",
+ rnames[AT], rnames[RA]);
+ printf("\tsubu %s,%s,8\t# _mcount pops 2 words from stack\n",
+ rnames[SP], rnames[SP]);
+ printf("\tjal %s\n", exname("_mcount"));
+ printf("\tnop\n");
+ printf("\t.set at\n");
+ }
+#endif
+
if (addto)
printf("\tsubu %s,%s,%d\n", rnames[SP], rnames[SP], addto);
@@ -119,6 +134,7 @@ prologue(struct interpass_prolog * ipp)
if (i & 1)
fprintf(stdout, "\tsw %s,-%d(%s) # save permanent\n",
rnames[j], regoff[j], rnames[FP]);
+
}
void
@@ -367,7 +383,7 @@ shiftop(NODE *p)
expand(p, INBREG, "\tsrl U1,UL,AR\n");
} else if (p->n_op == RS && r->n_op == ICON && r->n_lval < 64) {
if (ty == LONGLONG) {
- expand(p, INBREG, "\tli U1,-1\t# 64-bit right-shift\n");
+ expand(p, INBREG, "\tsra U1,UL,31\t# 64-bit right-shift\n");
expand(p, INBREG, "\tsra A1,UL,");
}else {
expand(p, INBREG, "\tli U1,0\t# 64-bit right-shift\n");
@@ -377,6 +393,8 @@ shiftop(NODE *p)
} else if (p->n_op == LS && r->n_op == ICON) {
expand(p, INBREG, "\tli A1,0\t# 64-bit right-shift\n");
expand(p, INBREG, "\tli U1,0\n");
+ } else {
+ comperr("shiftop");
}
}
@@ -721,6 +739,33 @@ rewfld(NODE * p)
return (1);
}
+int
+fldexpand(NODE *p, int cookie, char **cp)
+{
+ CONSZ val;
+
+ if (p->n_op == ASSIGN)
+ p = p->n_left;
+ switch (**cp) {
+ case 'S':
+ printf("%d", UPKFSZ(p->n_rval));
+ break;
+ case 'H':
+ printf("%d", UPKFOFF(p->n_rval));
+ break;
+ case 'M':
+ case 'N':
+ val = 1 << UPKFSZ(p->n_rval);
+ --val;
+ val <<= UPKFOFF(p->n_rval);
+ printf("0x%llx", (**cp == 'M' ? val : ~val) & 0xffffffff);
+ break;
+ default:
+ comperr("fldexpand");
+ }
+ return 1;
+}
+
/*
* Does the bitfield shape match?
*/
@@ -1106,11 +1151,8 @@ gclass(TWORD t)
* Calculate argument sizes.
*/
void
-lastcall(NODE * p)
+lastcall(NODE *p)
{
- NODE *op = p;
- int size = 0;
-
#ifdef PCC_DEBUG
if (x2debug)
printf("lastcall:\n");
@@ -1119,26 +1161,36 @@ lastcall(NODE * p)
p->n_qual = 0;
if (p->n_op != CALL && p->n_op != FORTCALL && p->n_op != STCALL)
return;
- for (p = p->n_right; p->n_op == CM; p = p->n_left)
- size += argsiz(p->n_right);
- size += argsiz(p);
- op->n_qual = size; /* XXX */
+ p->n_qual = argsiz(p->n_right); /* XXX */
}
-static int
-argsiz(NODE * p)
+int
+argsiz(NODE *p)
{
- TWORD t = p->n_type;
+ TWORD t;
+ int size = 0;
+ int sz;
+
+ if (p->n_op == CM) {
+ size = argsiz(p->n_left);
+ p = p->n_right;
+ }
+ t = p->n_type;
if (t < LONGLONG || t == FLOAT || t > BTMASK)
- return 4;
- if (t == LONGLONG || t == ULONGLONG ||
- t == DOUBLE || t == LDOUBLE)
- return 8;
- if (t == STRTY || t == UNIONTY)
- return p->n_stsize;
- comperr("argsiz");
- return 0;
+ sz = 4;
+ else if (DEUNSIGN(LONGLONG) || t == DOUBLE || t == LDOUBLE)
+ sz = 8;
+ else if (t == STRTY || t == UNIONTY)
+ sz = p->n_stsize;
+
+ if (p->n_type == STRTY || p->n_type == UNIONTY || sz == 4)
+ return (size + sz);
+
+ if ((size < 4*nargregs) && (sz == 8) && ((size & 7) != 0))
+ sz += 4;
+
+ return (size + sz);
}
/*
diff --git a/usr.bin/pcc/mips/macdefs.h b/usr.bin/pcc/mips/macdefs.h
index 7474f6d8a06..c892c6e5faf 100644
--- a/usr.bin/pcc/mips/macdefs.h
+++ b/usr.bin/pcc/mips/macdefs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: macdefs.h,v 1.3 2007/12/22 14:12:26 stefan Exp $ */
+/* $OpenBSD: macdefs.h,v 1.4 2007/12/22 22:56:31 stefan Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
@@ -69,7 +69,7 @@
#define ALCHAR 8
#define ALBOOL 32
#define ALINT 32
-#define ALFLOAT 64
+#define ALFLOAT 32
#define ALDOUBLE 64
#define ALLDOUBLE 64
#define ALLONG 32
diff --git a/usr.bin/pcc/mips/order.c b/usr.bin/pcc/mips/order.c
index 940d43a9a20..29c28ec5e64 100644
--- a/usr.bin/pcc/mips/order.c
+++ b/usr.bin/pcc/mips/order.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: order.c,v 1.3 2007/12/22 14:12:26 stefan Exp $ */
+/* $OpenBSD: order.c,v 1.4 2007/12/22 22:56:31 stefan Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
@@ -40,7 +40,10 @@
int
notoff(TWORD t, int r, CONSZ off, char *cp)
{
- if (off > 65535) return 1;
+ /*
+ * although the hardware doesn't permit offsets greater
+ * than +/- 32K, the assembler fixes it for us.
+ */
return 0; /* YES */
}
diff --git a/usr.bin/pcc/mips/table.c b/usr.bin/pcc/mips/table.c
index b293a2614a4..48c2f3f9872 100644
--- a/usr.bin/pcc/mips/table.c
+++ b/usr.bin/pcc/mips/table.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: table.c,v 1.3 2007/12/22 14:12:26 stefan Exp $ */
+/* $OpenBSD: table.c,v 1.4 2007/12/22 22:56:31 stefan Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
@@ -41,10 +41,6 @@
#include "pass2.h"
-#define TLL TLONGLONG|TULONGLONG
-#define ANYSIGNED TINT|TLONG|TSHORT|TCHAR
-#define ANYUSIGNED TUNSIGNED|TULONG|TUSHORT|TUCHAR
-#define ANYFIXED ANYSIGNED|ANYUSIGNED
#define TUWORD TUNSIGNED|TULONG
#define TSWORD TINT|TLONG
#define TWORD TUWORD|TSWORD
@@ -53,45 +49,55 @@ struct optab table[] = {
/* First entry must be an empty entry */
{ -1, FOREFF, SANY, TANY, SANY, TANY, 0, 0, "", },
+/* PCONVs are usually not necessary */
+{ PCONV, INAREG,
+ SAREG, TWORD|TPOINT,
+ SAREG, TWORD|TPOINT,
+ 0, RLEFT,
+ " # convert between word and pointer", },
+
/*
* Conversions of integral<->integral types
*/
-/* convert char to (u)short */
{ SCONV, INAREG,
SOREG, TCHAR,
- SAREG, TWORD|TSHORT|TUSHORT,
+ SAREG, TSWORD|TSHORT,
NAREG, RESC1,
- " lb A1,AL # convert oreg char to (u)short/word\n"
+ " lb A1,AL # convert oreg char to short/int\n"
+ " nop\n", },
+
+{ SCONV, INAREG,
+ SOREG, TCHAR,
+ SAREG, TUWORD|TUSHORT|TUCHAR,
+ NAREG, RESC1,
+ " lbu A1,AL # conver oreg char to uchar/ushort/uint\n"
" nop\n", },
-/* convert uchar to (u)short */
{ SCONV, INAREG,
SOREG, TUCHAR,
SAREG, TWORD|TSHORT|TUSHORT,
NAREG, RESC1,
- " lbu A1,AL # convert oreg uchar to (u)short\n"
+ " lbu A1,AL # convert oreg uchar to (u)short/(u)int\n"
" nop\n", },
-/* convert char to (u)long long - big endian*/
{ SCONV, INBREG,
SOREG, TCHAR,
- SBREG, TLL,
+ SBREG, TLONGLONG,
NBREG, RESC1,
- " lb U1,AL # convert oreg char to (u)longlong\n"
+ " lb A1,AL # convert oreg char to longlong\n"
" nop\n"
- " sra A1,U1,31\n"
- " sub A1,$zero,A1\n", },
+ " sra U1,A1,31\n", },
+
+/* chor -> ulonglong handled later */
-/* convert uchar to (u)long long */
{ SCONV, INBREG,
SOREG, TUCHAR,
- SBREG, TLL,
+ SBREG, TLONGLONG|TULONGLONG,
NBREG, RESC1,
- " lbu U1,AL # convert oreg uchar to (u)longlong\n"
- " move A1,$zero\n", },
+ " lbu A1,AL # convert oreg uchar to (u)longlong\n"
+ " move U1,$zero\n", },
-/* convert (u)short to char */
{ SCONV, INAREG,
SOREG, TSHORT|TUSHORT,
SAREG, TCHAR,
@@ -99,7 +105,6 @@ struct optab table[] = {
" lb A1,AL # convert oreg (u)short to char (endianness problem?)\n"
" nop\n", },
-/* convert (u)short to uchar */
{ SCONV, INAREG,
SOREG, TSHORT|TUSHORT,
SAREG, TUCHAR,
@@ -107,15 +112,20 @@ struct optab table[] = {
" lbu A1,AL # convert oreg (u)short to uchar (endianness problem?)\n"
" nop\n", },
-/* convert short to (u)long */
{ SCONV, INAREG,
SOREG, TSHORT,
- SAREG, TWORD,
+ SAREG, TSWORD,
NAREG, RESC1,
- " lh A1,AL # convert oreg short to (u)int\n"
+ " lh A1,AL # convert oreg short to int\n"
+ " nop\n", },
+
+{ SCONV, INAREG,
+ SOREG, TSHORT,
+ SAREG, TUWORD,
+ NAREG, RESC1,
+ " lhu A1,AL # convert oreg short to uint\n"
" nop\n", },
-/* convert ushort to (u)long */
{ SCONV, INAREG,
SOREG, TUSHORT,
SAREG, TWORD,
@@ -123,25 +133,29 @@ struct optab table[] = {
" lhu A1,AL # convert oreg ushort to (u)int\n"
" nop\n", },
-/* convert short to (u)long long */
{ SCONV, INBREG,
SOREG, TSHORT,
- SBREG, TLL,
+ SBREG, TLONGLONG,
+ NBREG, RESC1,
+ " lh A1,AL # convert oreg short to longlong\n"
+ " nop\n"
+ " sra U1,A1,31\n", },
+
+{ SCONV, INBREG,
+ SOREG, TSHORT,
+ SBREG, TULONGLONG,
NBREG, RESC1,
- " lh U1,AL # convert oreg short to (u)longlong\n"
+ " lhu A1,AL # convert oreg short to ulonglong\n"
" nop\n"
- " sra A1,U1,31\n"
- " sub A1,$zero,A1\n", },
+ " move U1,$zero\n", },
-/* convert ushort to (u)long long */
{ SCONV, INBREG,
SOREG, TUSHORT,
- SBREG, TLL,
+ SBREG, TLONGLONG|TULONGLONG,
NBREG, RESC1,
- " lhu U1,AL # convert oreg (u)short to (u)longlong\n"
- " move A1,$zero\n", },
+ " lhu A1,AL # convert oreg ushort to (u)longlong\n"
+ " move U1,$zero\n", },
-/* convert (u)long to char */
{ SCONV, INAREG,
SOREG, TWORD,
SAREG, TCHAR,
@@ -149,7 +163,6 @@ struct optab table[] = {
" lb A1,AL # convert oreg word to char (endianness problem here?)\n"
" nop\n", },
-/* convert (u)long to uchar */
{ SCONV, INAREG,
SOREG, TWORD,
SAREG, TUCHAR,
@@ -157,7 +170,6 @@ struct optab table[] = {
" lbu A1,AL # convert oreg word to uchar (endianness problem here?)\n"
" nop\n", },
-/* convert (u)long to short */
{ SCONV, INAREG,
SOREG, TWORD,
SAREG, TSHORT,
@@ -173,100 +185,265 @@ struct optab table[] = {
" lhu A1,AL # convert oreg word to ushort (endianness problem here?)\n"
" nop\n", },
-/* convert long to (u)long long */
{ SCONV, INBREG,
SOREG, TSWORD,
- SBREG, TLL,
+ SBREG, TLONGLONG|TULONGLONG,
NBREG, RESC1,
" lw A1,AL # convert oreg int/long to (u)llong (endianness problem here?)\n"
" nop\n"
- " sra U1,A1,31\n"
- " sub U1,$zero,U1\n", },
+ " sra U1,A1,31\n" },
-/* convert ulong to (u)long long */
{ SCONV, INBREG,
SOREG, TUWORD,
- SBREG, TLL,
+ SBREG, TLONGLONG|TULONGLONG,
NBREG, RESC1,
" lw A1,AL # convert oreg (u)int to (u)llong (endianness problem here?)\n"
" move U1,$zero\n", },
-/* convert (u)long long to char */
{ SCONV, INAREG,
- SOREG, TLL,
+ SOREG, TLONGLONG|TULONGLONG,
SAREG, TCHAR,
NAREG, RESC1,
" lb A1,AL # convert oreg (u)llong to char (endianness problem here?)\n"
" nop\n", },
-/* convert (u)long long to uchar */
{ SCONV, INAREG,
- SOREG, TLL,
+ SOREG, TLONGLONG|TULONGLONG,
SAREG, TUCHAR,
NAREG, RESC1,
" lbu A1,AL # convert oreg (u)llong to uchar (endianness problem?)\n"
" nop\n", },
-/* convert (u)long long to short */
{ SCONV, INAREG,
- SOREG, TLL,
+ SOREG, TLONGLONG|TULONGLONG,
SAREG, TSHORT,
NAREG, RESC1,
" lh A1,AL # convert oreg (u)llong to short (endianness problem?)\n"
" nop\n", },
-/* convert (u)long long to ushort */
{ SCONV, INAREG,
- SOREG, TLL,
+ SOREG, TLONGLONG|TULONGLONG,
SAREG, TUSHORT,
NAREG, RESC1,
" lhu A1,AL # convert oreg (u)llong to ushort (endianness problem here?)\n"
" nop\n", },
-/* convert (u)long long to long */
{ SCONV, INAREG,
- SOREG, TLL,
- SAREG, TSWORD,
+ SOREG, TLONGLONG|TULONGLONG,
+ SAREG, TWORD,
NAREG, RESC1,
- " lw U1,AL # convert oreg (u)llong to short (endianness problem here?)\n"
+ " lw A1,AL # convert oreg (u)llong to (u)int (endianness problem here?)\n"
" nop\n", },
-/* convert (u)long long to ulong */
-{ SCONV, INAREG,
- SOREG, TLL,
- SAREG, TUWORD,
- NAREG, RESC1,
- " lw U1,AL # convert oreg (u)longlong to uint (endianness problem here?)\n"
- " nop\n", },
+/*
+ * Conversions of integral types (register-register)
+ *
+ * For each deunsigned type, they look something like this:
+ *
+ * signed -> bigger signed - nothing to do
+ * signed -> bigger unsigned - clear the top bits (of source type)
+ *
+ * signed -> smaller signed - sign-extend the bits (to dest type)
+ * signed -> smaller unsigned - clear the top bits (of dest type)
+ * unsigned -> smaller signed - sign-extend top bits (to dest type)
+ * unsigned -> smaller unsigned - clear the top bits (of dest type)
+ *
+ * unsigned -> bigger - nothing to do
+ */
-/* Register to register conversion with long long */
+{ SCONV, INAREG,
+ SAREG, TPOINT|TWORD,
+ SAREG, TPOINT|TWORD,
+ 0, RLEFT,
+ " # convert int to int\n", },
{ SCONV, INBREG,
- SBREG, TLL,
- SBREG, TLL,
+ SBREG, TLONGLONG|TULONGLONG,
+ SBREG, TLONGLONG|TULONGLONG,
0, RLEFT,
" # convert (u)longlong to (u)longlong", },
+{ SCONV, INAREG,
+ SAREG, TCHAR,
+ SAREG, TSWORD|TSHORT,
+ 0, RLEFT,
+ " # convert char to short/int\n", },
+
+{ SCONV, INAREG,
+ SAREG, TCHAR,
+ SAREG, TUWORD|TUSHORT|TUCHAR,
+ NAREG|NASL, RESC1,
+ " andi A1,AL,255 # convert char to uchar/ushort/uint\n", },
+
+{ SCONV, INAREG,
+ SAREG, TUCHAR,
+ SAREG, TCHAR,
+ NAREG|NASL, RESC1,
+ " sll A1,AL,24 # convert uchar to char\n"
+ " sra A1,A1,24\n", },
+
+{ SCONV, INAREG,
+ SAREG, TUCHAR,
+ SAREG, TWORD|TSHORT|TUSHORT,
+ 0, RLEFT,
+ " # convert uchar to (u)short/(u)int\n", },
+
+{ SCONV, INAREG,
+ SAREG, TSHORT,
+ SAREG, TCHAR,
+ NAREG|NASL, RESC1,
+ " sll A1,AL,24 # convert short to char\n"
+ " sra A1,A1,24\n", },
+
+{ SCONV, INAREG,
+ SAREG, TSHORT,
+ SAREG, TUCHAR,
+ NAREG|NASL, RESC1,
+ " andi A1,AL,255 # convert short to uchar\n", },
+
+{ SCONV, INAREG,
+ SAREG, TSHORT,
+ SAREG, TUWORD|TUSHORT,
+ NAREG|NASL, RESC1,
+ " andi A1,AL,65535 # convert short to ushort\n", },
+
+{ SCONV, INAREG,
+ SAREG, TSHORT,
+ SAREG, TSWORD,
+ NAREG|NASL, RESC1,
+ " sll A1,AL,16 # convert short to ushort\n"
+ " sra A1,A1,16\n", },
+
+{ SCONV, INAREG,
+ SAREG, TUSHORT,
+ SAREG, TCHAR,
+ NAREG|NASL, RESC1,
+ " sll A1,AL,24 # convert short to char\n"
+ " sra A1,A1,24\n", },
+
+{ SCONV, INAREG,
+ SAREG, TUSHORT,
+ SAREG, TUCHAR,
+ NAREG|NASL, RESC1,
+ " andi A1,AL,255 # convert ushort to char\n", },
+
+{ SCONV, INAREG,
+ SAREG, TUSHORT,
+ SAREG, TSHORT,
+ NAREG|NASL, RESC1,
+ " sll A1,AL,16 # convert short to ushort\n"
+ " sra A1,A1,16\n", },
+
+{ SCONV, INAREG,
+ SAREG, TUSHORT,
+ SAREG, TWORD,
+ 0, RDEST,
+ " # convert ushort to (u)int\n", },
+
+{ SCONV, INAREG,
+ SAREG, TSWORD,
+ SAREG, TCHAR,
+ NAREG|NASL, RESC1,
+ " sll A1,AL,8 # convert int to char\n"
+ " sra A1,A1,8\n", },
+
+{ SCONV, INAREG,
+ SAREG, TSWORD,
+ SAREG, TUCHAR,
+ NAREG|NASL, RESC1,
+ " andi A1,AL,255 # convert int to uchar\n", },
+
+{ SCONV, INAREG,
+ SAREG, TSWORD,
+ SAREG, TSHORT,
+ NAREG|NASL, RESC1,
+ " sll A1,AL,16 # convert int to short\n"
+ " sra A1,A1,16\n", },
+
+{ SCONV, INAREG,
+ SAREG, TSWORD,
+ SAREG, TUSHORT,
+ NAREG|NASL, RESC1,
+ " andi A1,AL,65535 # convert int to ushort\n", },
+
+{ SCONV, INAREG,
+ SAREG, TUWORD,
+ SAREG, TCHAR,
+ NAREG|NASL, RESC1,
+ " sll A1,AL,24 # convert int to char\n"
+ " sra A1,A1,24\n", },
+
+{ SCONV, INAREG,
+ SAREG, TUWORD,
+ SAREG, TUCHAR,
+ NAREG|NASL, RESC1,
+ " andi A1,AL,255 # convert int to uchar\n", },
+
+{ SCONV, INAREG,
+ SAREG, TUWORD,
+ SAREG, TSHORT,
+ NAREG|NASL, RESC1,
+ " sll A1,AL,16 # convert int to short\n"
+ " sra A1,A1,16\n", },
+
+{ SCONV, INAREG,
+ SAREG, TUWORD,
+ SAREG, TUSHORT,
+ NAREG|NASL, RESC1,
+ " andi A1,AL,65535 # convert int to ushort\n", },
+
{ SCONV, INBREG,
- SAREG, TPOINT|TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
- SBREG, TLL,
+ SAREG, TSWORD|TSHORT|TCHAR,
+ SBREG, TLONGLONG,
NBREG, RESC1,
- " move A1,AL # convert (u)int/(u)short/(u)char to (u)longlong\n"
- " sra A1,AL,31\n", },
+ " move A1,AL # convert int/short/char to longlong\n"
+ " sra U1,AL,31\n", },
+
+{ SCONV, INBREG,
+ SAREG, TSWORD|TSHORT|TCHAR,
+ SBREG, TULONGLONG,
+ NBREG, RESC1,
+ " move A1,AL # convert int/short/char to ulonglong\n"
+ " move U1,$zero\n", },
+
+{ SCONV, INBREG,
+ SAREG, TWORD|TUSHORT|TSHORT|TUCHAR|TCHAR,
+ SBREG, TLONGLONG|TULONGLONG,
+ NBREG, RESC1,
+ " move A1,AL # convert (u)int/(u)short/(u)char to ulonglong\n"
+ " move U1,$zero\n", },
{ SCONV, INAREG,
- SBREG, TLL,
- SAREG, TPOINT|TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
+ SBREG, TLONGLONG|TULONGLONG,
+ SAREG, TWORD,
NAREG, RESC1,
- " move A1,AL\n", },
+ " move A1,AL # convert (u)longlong to int\n", },
-/* For register to register conversion with bit length <= 32, do nothing */
-/* XXX This doesn't seem correct. USHORT->TCHAR must be sign extended */
{ SCONV, INAREG,
- SAREG, TPOINT|TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
- SAREG, TPOINT|TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
- 0, RLEFT,
- " # convert reg to reg\n", },
+ SBREG, TLONGLONG|TULONGLONG,
+ SAREG, TSHORT,
+ NAREG, RESC1,
+ " sll A1,AL,16 # convert (u)longlong to short\n"
+ " sra A1,AL,16\n", },
+
+{ SCONV, INAREG,
+ SBREG, TLONGLONG|TULONGLONG,
+ SAREG, TCHAR,
+ NAREG, RESC1,
+ " sll A1,AL,24 # convert (u)longlong to char\n"
+ " sra A1,AL,24\n", },
+
+{ SCONV, INAREG,
+ SBREG, TLONGLONG|TULONGLONG,
+ SAREG, TUSHORT,
+ NAREG, RESC1,
+ " andi A1,AL,65535 # convert (u)longlong to ushort\n", },
+
+{ SCONV, INAREG,
+ SBREG, TLONGLONG|TULONGLONG,
+ SAREG, TUCHAR,
+ NAREG, RESC1,
+ " andi A1,AL,255 # convert (u)longlong to uchar\n", },
{ SCONV, INCREG,
SCREG, TFLOAT,
@@ -343,26 +520,26 @@ struct optab table[] = {
" # convert between double and ldouble\n", },
{ SCONV, INCREG,
- SBREG, TLL,
+ SBREG, TLONGLONG|TULONGLONG,
SCREG, TFLOAT,
NSPECIAL|NCREG, RESC1,
"ZF", },
{ SCONV, INCREG,
- SBREG, TLL,
+ SBREG, TLONGLONG|TULONGLONG,
SCREG, TDOUBLE|TLDOUBLE,
NSPECIAL|NCREG, RESC1,
"ZF", },
{ SCONV, INBREG,
SCREG, TDOUBLE|TLDOUBLE,
- SBREG, TLL,
+ SBREG, TLONGLONG|TULONGLONG,
NSPECIAL|NBREG, RESC1,
"ZF", },
{ SCONV, INBREG,
SCREG, TFLOAT,
- SBREG, TLL,
+ SBREG, TLONGLONG|TULONGLONG,
NSPECIAL|NBREG, RESC1,
"ZF", },
@@ -389,10 +566,9 @@ struct optab table[] = {
" nop\n"
" nop\n", },
-
{ MUL, INBREG,
- SBREG, TLL,
- SBREG, TLL,
+ SBREG, TLONGLONG|TULONGLONG,
+ SBREG, TLONGLONG|TULONGLONG,
2*NBREG, RESC1,
" multu AL,AR\n"
" mfhi U1\n"
@@ -420,7 +596,6 @@ struct optab table[] = {
NCREG, RESC1,
" mul.d A1,AL,AR # double-floating-point multiply\n", },
-
{ DIV, INAREG,
SAREG, TUWORD|TUSHORT|TUCHAR,
SAREG, TUWORD|TUSHORT|TUCHAR,
@@ -441,8 +616,8 @@ struct optab table[] = {
" nop\n", },
{ DIV, INBREG,
- SBREG, TLL,
- SBREG, TLL,
+ SBREG, TLONGLONG|TULONGLONG,
+ SBREG, TLONGLONG|TULONGLONG,
NSPECIAL|NBREG, RESC1,
"ZE", },
@@ -478,8 +653,8 @@ struct optab table[] = {
" nop\n", },
{ MOD, INBREG,
- SBREG, TLL,
- SBREG, TLL,
+ SBREG, TLONGLONG|TULONGLONG,
+ SBREG, TLONGLONG|TULONGLONG,
NSPECIAL|NBREG, RESC1,
"ZE", },
@@ -499,27 +674,27 @@ struct optab table[] = {
{ PLUS, INAREG,
SAREG, TSWORD|TSHORT|TCHAR,
SAREG, TSWORD|TSHORT|TCHAR,
- NBREG|NAREG, RESC1,
+ NAREG|NASL, RESC1,
" add A1,AL,AR\n", },
{ PLUS, INAREG,
- SAREG, TUWORD|TUSHORT|TUCHAR,
- SAREG, TUWORD|TUSHORT|TUCHAR,
- NBREG|NAREG, RESC1,
- " addu A1,AL,AR\n", },
-
-{ PLUS, INAREG,
SAREG, TSWORD|TSHORT|TCHAR,
- SSCON, TANY,
+ SSCON, TWORD,
NAREG|NASL, RESC1,
" addi A1,AL,AR\n", },
{ PLUS, INAREG,
SAREG, TUWORD|TUSHORT|TUCHAR,
- SSCON, TANY,
+ SSCON, TWORD,
NAREG|NASL, RESC1,
" addiu A1,AL,AR\n", },
+{ PLUS, INAREG,
+ SAREG, TUWORD|TUSHORT|TUCHAR,
+ SAREG, TUWORD|TUSHORT|TUCHAR,
+ NAREG|NASL, RESC1,
+ " addu A1,AL,AR\n", },
+
{ PLUS, INCREG,
SCREG, TFLOAT,
SCREG, TFLOAT,
@@ -544,13 +719,13 @@ struct optab table[] = {
{ MINUS, INAREG,
SAREG, TSWORD|TSHORT|TCHAR,
SAREG, TSWORD|TSHORT|TCHAR,
- NBREG|NAREG, RESC1,
+ NAREG|NASL, RESC1,
" sub A1,AL,AR\n", },
{ MINUS, INAREG,
SAREG, TUWORD|TUSHORT|TUCHAR,
SAREG, TUWORD|TUSHORT|TUCHAR,
- NBREG|NAREG, RESC1,
+ NAREG|NASL, RESC1,
" subu A1,AL,AR\n", },
{ MINUS, INAREG,
@@ -578,7 +753,7 @@ struct optab table[] = {
" neg A1,AL\n", },
{ UMINUS, INBREG,
- SBREG, TLL,
+ SBREG, TLONGLONG|TULONGLONG,
SANY, TANY,
NBREG|NAREG|NBSL, RESC1,
" subu A1,$zero,AL\n"
@@ -601,8 +776,8 @@ struct optab table[] = {
/* Simple 'op rd, rs, rt' or 'op rt, rs, imm' operations */
{ OPSIMP, INBREG,
- SBREG, TLL,
- SBREG, TLL,
+ SBREG, TLONGLONG|TULONGLONG,
+ SBREG, TLONGLONG|TULONGLONG,
NBREG|NBSR|NBSL, RESC1,
" O A1,AL,AR\n"
" O U1,UL,UR\n", },
@@ -636,13 +811,19 @@ struct optab table[] = {
" srl A1,AL,AR # shift right by constant\n", },
{ LS, INAREG,
- SAREG, TWORD|TUSHORT|TSHORT|TCHAR|TUCHAR,
+ SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
SCON, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
NAREG|NASL, RESC1,
" sll A1,AL,AR # shift left by constant\n", },
{ RS, INAREG,
+ SAREG, TSWORD|TSHORT|TCHAR,
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
+ NAREG|NASL, RESC1,
+ " srav A1,AL,AR # shift right by register\n", },
+
+{ RS, INAREG,
+ SAREG, TUWORD|TUSHORT|TUCHAR,
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
NAREG|NASL, RESC1,
" srlv A1,AL,AR # shift right by register\n", },
@@ -654,25 +835,25 @@ struct optab table[] = {
" sllv A1,AL,AR # shift left by register\n", },
{ RS, INBREG,
- SBREG, TLL,
+ SBREG, TLONGLONG|TULONGLONG,
SCON, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
NBREG, RESC1,
"ZO", },
{ LS, INBREG,
- SBREG, TLL,
+ SBREG, TLONGLONG|TULONGLONG,
SCON, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
NBREG, RESC1,
"ZO", },
{ RS, INBREG,
- SBREG, TLL,
+ SBREG, TLONGLONG|TULONGLONG,
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
NSPECIAL|NBREG, RESC1,
"ZE", },
{ LS, INBREG,
- SBREG, TLL,
+ SBREG, TLONGLONG|TULONGLONG,
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
NSPECIAL|NBREG, RESC1,
"ZE", },
@@ -685,14 +866,14 @@ struct optab table[] = {
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
SANY, TANY,
NAREG|NASL, RESC1,
- " nor A1,AL # complement\n", },
+ " nor A1,$zero,AL # complement\n", },
{ COMPL, INBREG,
- SBREG, TLL,
+ SBREG, TLONGLONG|TULONGLONG,
SANY, TANY,
NBREG|NBSL, RESC1,
- " nor A1,AL # complement\n"
- " nor U1,UL\n", },
+ " nor A1,$zero,AL # complement\n"
+ " nor U1,$zero,UL\n", },
/*
* The next rules takes care of assignments. "=".
@@ -720,8 +901,8 @@ struct optab table[] = {
" nop\n", },
{ ASSIGN, FOREFF|INBREG,
- SOREG|SNAME, TLL,
- SBREG, TLL,
+ SOREG|SNAME, TLONGLONG|TULONGLONG,
+ SBREG, TLONGLONG|TULONGLONG,
0, RDEST,
" sw UR,UL # store (u)longlong\n"
" nop\n"
@@ -729,8 +910,8 @@ struct optab table[] = {
" nop\n", },
{ ASSIGN, FOREFF|INBREG,
- SBREG, TLL,
- SBREG, TLL,
+ SBREG, TLONGLONG|TULONGLONG,
+ SBREG, TLONGLONG|TULONGLONG,
0, RDEST,
" move UL,UR # register move\n"
" move AL,AR\n", },
@@ -757,14 +938,14 @@ struct optab table[] = {
SNAME|SOREG, TFLOAT,
SCREG, TFLOAT,
0, RDEST,
- " s.s AR,AL # store floating-point reg to sname\n"
+ " s.s AR,AL # store floating-point reg to oreg/sname\n"
" nop\n", },
{ ASSIGN, FOREFF|INCREG,
SNAME|SOREG, TDOUBLE|TLDOUBLE,
SCREG, TDOUBLE|TLDOUBLE,
0, RDEST,
- " s.d AR,AL # store double floating-point reg to sname\n"
+ " s.d AR,AL # store double floating-point reg to oreg/sname\n"
" nop\n", },
{ ASSIGN, FOREFF|INAREG,
@@ -772,15 +953,18 @@ struct optab table[] = {
SOREG|SNAME, TANY,
3*NAREG, RDEST,
" lw A1,AR # bit-field assignment\n"
- " li A3,ML\n"
+ " li A3,M\n"
" lw A2,AL\n"
- " sll A1,A1,HL\n"
+ " sll A1,A1,H\n"
" and A1,A1,A3\n"
- " nor A3,A3\n"
+ " nor A3,$zero,A3\n"
" and A2,A2,A3\n"
" or A2,A2,A1\n"
" sw A2,AL\n"
- " nop\n", },
+ "F lw AD,AR\n"
+ "F nop\n"
+ "F sll AD,AD,32-S\n"
+ "F sra AD,AD,32-S\n", },
/* XXX we can optimise this away */
{ ASSIGN, FOREFF|INAREG,
@@ -789,14 +973,16 @@ struct optab table[] = {
3*NAREG, RDEST,
" li A1,AR # bit-field assignment\n"
" lw A2,AL\n"
- " li A3,ML\n"
- " sll A1,A1,HL\n"
+ " li A3,M\n"
+ " sll A1,A1,H\n"
" and A1,A1,A3\n"
- " nor A3,A3\n"
+ " nor A3,$zero,A3\n"
" and A2,A2,A3\n"
" or A2,A2,A1\n"
" sw A2,AL\n"
- " nop\n", },
+ "F li AD,AR\n"
+ "F sll AD,AD,32-S\n"
+ "F sra AD,AD,32-S\n", },
{ ASSIGN, FOREFF|INAREG,
SFLD, TANY,
@@ -804,33 +990,16 @@ struct optab table[] = {
3*NAREG, RDEST,
" move A1,AR # bit-field assignment\n"
" lw A2,AL\n"
- " li A3,ML\n"
- " sll A1,A1,HL\n"
+ " li A3,M\n"
+ " sll A1,A1,H\n"
" and A1,A1,A3\n"
- " nor A3,A3\n"
+ " nor A3,$zero,A3\n"
" and A2,A2,A3\n"
" or A2,A2,A1\n"
" sw A2,AL\n"
- " nop\n", },
-
-{ ASSIGN, FOREFF|INAREG,
- SFLD, TANY,
- SFLD, TANY,
- 2*NAREG, RDEST,
- " lw A1,AR # bit-field copy\n"
- " li A3,MR\n"
- " and A1,A1,A3\n"
- " sll A1,A1,32-SR-HR\n"
- " sra A1,A1,32-SR\n"
- " lw A2,AL\n"
- " li A3,ML\n"
- " sll A1,A1,HL\n"
- " and A1,A1,A3\n"
- " nor A3,A3\n"
- " and A2,A2,A3\n"
- " or A2,A2,A1\n"
- " sw A2,AL\n"
- " nop\n", } ,
+ "F move AR,AD\n"
+ "F sll AD,AD,32-S\n"
+ "F sra AD,AD,32-S\n", },
{ STASG, INAREG|FOREFF,
SOREG|SNAME, TANY,
@@ -873,15 +1042,15 @@ struct optab table[] = {
{ OPLOG, FORCC,
SAREG, TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR,
- SCON, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
+ SSCON, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
NAREG|NASL, RESCC,
" sub A1,AL,AR\n"
" O A1,LC\n"
" nop\n", },
{ OPLOG, FORCC,
- SBREG, TLL,
- SBREG, TLL,
+ SBREG, TLONGLONG|TULONGLONG,
+ SBREG, TLONGLONG|TULONGLONG,
NAREG, RESCC,
"ZD", },
@@ -932,7 +1101,7 @@ struct optab table[] = {
{ OPLTYPE, INBREG,
SANY, TANY,
- SOREG|SNAME, TLL,
+ SOREG|SNAME, TLONGLONG|TULONGLONG,
NBREG, RESC1,
" lw U1,UL # load (u)longlong to reg\n"
" nop\n"
@@ -947,22 +1116,15 @@ struct optab table[] = {
{ OPLTYPE, INAREG,
SANY, TANY,
- SCON, TANY,
- NAREG, RESC1,
- " li A1,AL # load constant to reg\n", },
-
-{ OPLTYPE, INAREG,
- SANY, TANY,
SZERO, TANY,
NAREG, RESC1,
" move A1,$zero # load 0 to reg\n", },
-{ OPLTYPE, INBREG,
+{ OPLTYPE, INAREG,
SANY, TANY,
SCON, TANY,
- NBREG, RESC1,
- " li A1,AL # load constant to reg\n"
- " li U1,UL\n", },
+ NAREG, RESC1,
+ " li A1,AL # load constant to reg\n", },
{ OPLTYPE, INBREG,
SANY, TANY,
@@ -971,6 +1133,13 @@ struct optab table[] = {
" move A1,$zero # load 0 to reg\n"
" move U1,$zero\n", },
+{ OPLTYPE, INBREG,
+ SANY, TANY,
+ SCON, TANY,
+ NBREG, RESC1,
+ " li A1,AL # load constant to reg\n"
+ " li U1,UL\n", },
+
{ OPLTYPE, INAREG,
SANY, TANY,
SANY, TANY,
@@ -1241,8 +1410,8 @@ struct optab table[] = {
" #nop\n", },
{ FUNARG, FOREFF,
- SBREG, TLL,
- SANY, TLL,
+ SBREG, TLONGLONG|TULONGLONG,
+ SANY, TLONGLONG|TULONGLONG,
0, 0,
" addi $sp,$sp,-8 # save function arg to stack (endian problem here?\n"
" sw UL,4($sp)\n"
@@ -1296,12 +1465,12 @@ struct optab table[] = {
" nop\n", },
{ UMUL, INBREG,
- SANY, TLL,
- SOREG, TLL,
+ SANY, TLONGLONG|TULONGLONG,
+ SOREG, TLONGLONG|TULONGLONG,
NBREG, RESC1,
" lw A1,AL # (u)longlong load - endian problem here?\n"
" nop\n"
- " lw U1,AL\n"
+ " lw U1,UL\n"
" nop\n", },
{ UMUL, INCREG,
@@ -1318,6 +1487,7 @@ struct optab table[] = {
" l.d A1,AL # float load\n"
" nop\n", },
+#if 0
{ UMUL, INCREG,
SANY, TDOUBLE|TLDOUBLE,
SAREG, TPOINT,
@@ -1350,15 +1520,15 @@ struct optab table[] = {
" nop\n", },
{ UMUL, INBREG,
- SANY, TLL,
- SNAME, TLL,
+ SANY, TLONGLONG|TULONGLONG,
+ SNAME, TLONGLONG|TULONGLONG,
NBREG|NAREG, RESC1,
" la A2,AL # sname (u)long long load - endian problems here?\n"
" lw A1,(A1)\n"
" nop\n"
" lw U1,4(A1)\n"
" nop\n", },
-
+#endif
{ UMUL, INAREG,
SANY, TPOINT|TWORD,
@@ -1367,28 +1537,30 @@ struct optab table[] = {
" lw A1,(AL) # word load\n"
" nop\n", },
+#if 0
{ UMUL, INAREG,
SANY, TSHORT|TUSHORT,
- SAREG, TSHORT|TUSHORT,
+ SAREG, TPTRTO|TSHORT|TUSHORT,
NAREG, RESC1,
" lh A1,(AL) # (u)short load\n"
" nop\n", },
{ UMUL, INAREG,
SANY, TCHAR|TUCHAR,
- SAREG, TCHAR|TUCHAR,
+ SAREG, TPTRTO|TCHAR|TUCHAR,
NAREG|NASL, RESC1,
" lb A1,(AL) # (u)char load\n"
" nop\n", },
{ UMUL, INBREG,
- SANY, TLL,
- SCREG, TLL,
+ SANY, TLONGLONG|TULONGLONG,
+ SAREG, TPTRTO|TLONGLONG|TULONGLONG,
NBREG, RESC1,
" lw A1,(AL) # (u)long long load - endianness problems?\n"
" nop\n"
" lw U1,4(AL)"
" nop\n", },
+#endif
#define DF(x) FORREW,SANY,TANY,SANY,TANY,REWRITE,x,""
diff --git a/usr.bin/pcc/nova/local2.c b/usr.bin/pcc/nova/local2.c
index 8ac79c09c29..8dbca6d8fa0 100644
--- a/usr.bin/pcc/nova/local2.c
+++ b/usr.bin/pcc/nova/local2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: local2.c,v 1.2 2007/12/22 13:13:27 stefan Exp $ */
+/* $OpenBSD: local2.c,v 1.3 2007/12/22 22:56:31 stefan Exp $ */
/*
* Copyright (c) 2006 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
@@ -163,6 +163,12 @@ tlen(p) NODE *p;
}
#endif
+int
+fldexpand(NODE *p, int cookie, char **cp)
+{
+ return 0;
+}
+
#if 0
/*
* Assign to a bitfield.
diff --git a/usr.bin/pcc/pdp10/local2.c b/usr.bin/pcc/pdp10/local2.c
index b10ccc08ce4..e5a925ed9ff 100644
--- a/usr.bin/pcc/pdp10/local2.c
+++ b/usr.bin/pcc/pdp10/local2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: local2.c,v 1.3 2007/12/22 13:13:06 stefan Exp $ */
+/* $OpenBSD: local2.c,v 1.4 2007/12/22 22:56:31 stefan Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
@@ -836,6 +836,12 @@ rewfld(NODE *p)
}
int
+fldexpand(NODE *p, int cookie, char **cp)
+{
+ return 0;
+}
+
+int
flshape(NODE *p)
{
register int o = p->n_op;
diff --git a/usr.bin/pcc/powerpc/local2.c b/usr.bin/pcc/powerpc/local2.c
index b7347243dc6..982db78eaf6 100644
--- a/usr.bin/pcc/powerpc/local2.c
+++ b/usr.bin/pcc/powerpc/local2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: local2.c,v 1.5 2007/12/22 14:05:04 stefan Exp $ */
+/* $OpenBSD: local2.c,v 1.6 2007/12/22 22:56:31 stefan Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
@@ -649,6 +649,12 @@ canaddr(NODE *p)
return(0);
}
+int
+fldexpand(NODE *p, int cookie, char **cp)
+{
+ return 0;
+}
+
/*
* Does the bitfield shape match?
*/
diff --git a/usr.bin/pcc/vax/local2.c b/usr.bin/pcc/vax/local2.c
index 4a2ba225325..18cc926a886 100644
--- a/usr.bin/pcc/vax/local2.c
+++ b/usr.bin/pcc/vax/local2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: local2.c,v 1.5 2007/12/09 18:56:17 ragge Exp $ */
+/* $OpenBSD: local2.c,v 1.6 2007/12/22 22:56:31 stefan Exp $ */
/*
* Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
*
@@ -541,6 +541,12 @@ shltype( o, p ) register NODE *p; {
#endif
int
+fldexpand(NODE *p, int cookie, char **cp)
+{
+ return 0;
+}
+
+int
flshape( p ) register NODE *p; {
return( p->n_op == REG || p->n_op == NAME || p->n_op == ICON ||
(p->n_op == OREG && (!R2TEST(p->n_rval) || tlen(p) == 1)) );