Browse Source

Plan 9 from Bell Labs 2011-11-01

David du Colombier 12 years ago
parent
commit
3962f42683

+ 19 - 13
sys/src/9/pc/devether.c

@@ -447,26 +447,32 @@ etherprobe(int cardno, int ctlrno)
 	sprint(buf+i, "\n");
 	print(buf);
 
+	/*
+	 * input queues are allocated by ../port/netif.c:/^openfile.
+	 * the size will be the last argument to netifinit() below.
+	 *
+	 * output queues should be small, to minimise `bufferbloat',
+	 * which confuses tcp's feedback loop.  at 1Gb/s, it only takes
+	 * ~15µs to transmit a full-sized non-jumbo packet.
+	 */
+
 	/* compute log10(ether->mbps) into lg */
 	for(lg = 0, mb = ether->mbps; mb >= 10; lg++)
 		mb /= 10;
-	if (lg > 0)
-		lg--;
-	if (lg > 14)			/* 2^(14+17) = 2⁳ⁱ */
+	if (lg > 14)			/* sanity cap; 2**(14+15) = 2²⁹ */
 		lg = 14;
-	/* allocate larger output queues for higher-speed interfaces */
-	bsz = 1UL << (lg + 17);		/* 2ⁱ⁷ = 128K, bsz = 2ⁿ × 128K */
-	while (bsz > mainmem->maxsize / 8 && bsz > 128*1024)
-		bsz /= 2;
 
+	/* allocate larger input queues for higher-speed interfaces */
+	bsz = 1UL << (lg + 15);		/* 2ⁱ⁵ = 32K, bsz = 2ⁿ × 32K */
+	while (bsz > mainmem->maxsize / 8 && bsz > 128*1024)	/* sanity */
+		bsz /= 2;
 	netifinit(ether, name, Ntypes, bsz);
-	if(ether->oq == nil) {
-		ether->oq = qopen(bsz, Qmsg, 0, 0);
-		ether->limit = bsz;
-	}
+
 	if(ether->oq == nil)
-		panic("etherreset %s: can't allocate output queue of %ld bytes",
-			name, bsz);
+		ether->oq = qopen(1 << (lg + 13), Qmsg, 0, 0);
+	if(ether->oq == nil)
+		panic("etherreset %s: can't allocate output queue", name);
+
 	ether->alen = Eaddrlen;
 	memmove(ether->addr, ether->ea, Eaddrlen);
 	memset(ether->bcast, 0xFF, Eaddrlen);

+ 1 - 1
sys/src/9/pc/ether2114x.c

@@ -630,7 +630,7 @@ ctlrinit(Ether* ether)
 	bp->wp += sizeof(bi)*16;
 
 	ctlr->setupbp = bp;
-	ether->oq = qopen(256*1024, Qmsg, 0, 0);
+	ether->oq = qopen(64*1024, Qmsg, 0, 0);
 	transmit(ether);
 }
 

+ 1 - 1
sys/src/9/pc/ether82543gc.c

@@ -339,7 +339,7 @@ enum {					/* Tdesc status */
 
 enum {
 	Nrdesc		= 256,		/* multiple of 8 */
-	Ntdesc		= 256,		/* multiple of 8 */
+	Ntdesc		= 64,		/* multiple of 8 */
 	Nblocks		= 4098,		/* total number of blocks to use */
 
 	SBLOCKSIZE	= 2048,

+ 1 - 1
sys/src/9/pc/ether82557.c

@@ -1300,7 +1300,7 @@ reset(Ether* ether)
 	 * Load the chip configuration and start it off.
 	 */
 	if(ether->oq == 0)
-		ether->oq = qopen(256*1024, Qmsg, 0, 0);
+		ether->oq = qopen(64*1024, Qmsg, 0, 0);
 	configure(ether, 0);
 	command(ctlr, CUstart, PADDR(&ctlr->cbr->status));
 

+ 2 - 2
sys/src/9/pc/ether82563.c

@@ -411,7 +411,7 @@ enum {
 
 enum {
 	Nrd		= 256,		/* power of two */
-	Ntd		= 128,		/* power of two */
+	Ntd		= 64,		/* power of two */
 	Nrb		= 1024,		/* private receive buffers per Ctlr */
 };
 
@@ -1250,13 +1250,13 @@ i82563attach(Ether* edev)
 	char name[KNAMELEN];
 
 	ctlr = edev->ctlr;
-	ctlr->edev = edev;			/* point back to Ether* */
 	qlock(&ctlr->alock);
 	if(ctlr->attached){
 		qunlock(&ctlr->alock);
 		return;
 	}
 
+	ctlr->edev = edev;			/* point back to Ether* */
 	ctlr->nrd = Nrd;
 	ctlr->ntd = Ntd;
 

+ 1 - 1
sys/src/9/pc/ether82598.c

@@ -303,7 +303,7 @@ typedef struct {
 enum {
 	Rbsz	= 12*1024,
 	Nrd	= 256,
-	Ntd	= 256,
+	Ntd	= 64,
 	Nrb	= 256,
 };
 

+ 1 - 1
sys/src/9/pc/etherdp83820.c

@@ -338,7 +338,7 @@ enum {
 	Nrd		= 256,
 	Nrb		= 4*Nrd,
 	Rbsz		= ROUNDUP(sizeof(Etherpkt)+8, 8),
-	Ntd		= 128,
+	Ntd		= 64,
 };
 
 typedef struct Ctlr Ctlr;

+ 1 - 1
sys/src/9/pc/etherigbe.c

@@ -708,7 +708,7 @@ igbectl(Ether* edev, void* buf, long n)
 		v = strtol(cb->f[1], &p, 0);
 		if(v < 0 || p == cb->f[1] || v > 0xFFFF)
 			error(Ebadarg);
-		ctlr->rdtr = v;;
+		ctlr->rdtr = v;
 		csr32w(ctlr, Rdtr, Fpd|v);
 		break;
 	}

+ 1 - 1
sys/src/9/pc/ethersmc.c

@@ -553,7 +553,7 @@ interrupt(Ureg*, void *arg)
 
 		if (status & IntAlloc) {
 			outb(port + IntrMask, mask & ~IntAlloc);
-			txstart(ether);;
+			txstart(ether);
 			mask = inb(port + IntrMask);
 		}
 

+ 1 - 1
sys/src/9/pc/ethervt6105m.c

@@ -282,7 +282,7 @@ enum {						/* Tx Ds branch */
 
 enum {
 	Nrd		= 196,
-	Ntd		= 128,
+	Ntd		= 64,
 	Crcsz		= 4,
 	Bslop		= 48,
 	Rdbsz		= ETHERMAXTU+Crcsz+Bslop,

+ 1 - 0
sys/src/cmd/8a/a.h

@@ -72,6 +72,7 @@ struct	Gen
 	double	dval;
 	char	sval[8];
 	long	offset;
+	long	offset2;
 	Sym*	sym;
 	short	type;
 	short	index;

+ 60 - 3
sys/src/cmd/8a/a.y

@@ -4,6 +4,10 @@
 %union	{
 	Sym	*sym;
 	long	lval;
+	struct {
+		long v1;
+		long v2;
+	} con2;
 	double	dval;
 	char	sval[8];
 	Gen	gen;
@@ -16,16 +20,17 @@
 %left	'+' '-'
 %left	'*' '/' '%'
 %token	<lval>	LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4
-%token	<lval>	LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPES LTYPEM LTYPEI
+%token	<lval>	LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPES LTYPEM LTYPEI LTYPEG
 %token	<lval>	LCONST LFP LPC LSB
 %token	<lval>	LBREG LLREG LSREG LFREG
 %token	<dval>	LFCONST
 %token	<sval>	LSCONST LSP
 %token	<sym>	LNAME LLAB LVAR
 %type	<lval>	con expr pointer offset
-%type	<gen>	mem imm reg nam rel rem rim rom omem nmem
+%type	<con2>	con2
+%type	<gen>	mem imm imm2 reg nam rel rem rim rom omem nmem
 %type	<gen2>	nonnon nonrel nonrem rimnon rimrem remrim
-%type	<gen2>	spec1 spec2 spec3 spec4 spec5 spec6 spec7
+%type	<gen2>	spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8
 %%
 prog:
 |	prog line
@@ -73,6 +78,7 @@ inst:
 |	LTYPES spec5	{ outcode($1, &$2); }
 |	LTYPEM spec6	{ outcode($1, &$2); }
 |	LTYPEI spec7	{ outcode($1, &$2); }
+|	LTYPEG spec8	{ outcode($1, &$2); }
 
 nonnon:
 	{
@@ -219,6 +225,19 @@ spec7:
 		$$.to = $3;
 	}
 
+spec8:	/* GLOBL */
+	mem ',' imm
+	{
+		$$.from = $1;
+		$$.to = $3;
+	}
+|	mem ',' con ',' imm
+	{
+		$$.from = $1;
+		$$.from.scale = $3;
+		$$.to = $5;
+	}
+
 rem:
 	reg
 |	mem
@@ -236,6 +255,7 @@ rom:
 	}
 |	reg
 |	omem
+|	imm
 
 rim:
 	rem
@@ -335,6 +355,37 @@ imm:
 		$$.dval = -$3;
 	}
 
+imm2:
+	'$' con2
+	{
+		$$ = nullgen;
+		$$.type = D_CONST2;
+		$$.offset = $2.v1;
+		$$.offset2 = $2.v2;
+	}
+
+con2:
+	LCONST
+	{
+		$$.v1 = $1;
+		$$.v2 = 0;
+	}
+|	'-' LCONST
+	{
+		$$.v1 = -$2;
+		$$.v2 = 0;
+	}
+|	LCONST '-' LCONST
+	{
+		$$.v1 = $1;
+		$$.v2 = $3;
+	}
+|	'-' LCONST '-' LCONST
+	{
+		$$.v1 = -$2;
+		$$.v2 = $4;
+	}
+
 mem:
 	omem
 |	nmem
@@ -386,6 +437,12 @@ omem:
 		$$ = nullgen;
 		$$.type = D_INDIR+D_SP;
 	}
+|	con '(' LSREG ')'
+	{
+		$$ = nullgen;
+		$$.type = D_INDIR+$3;
+		$$.offset = $1;
+	}
 |	'(' LLREG '*' con ')'
 	{
 		$$ = nullgen;

+ 1 - 1
sys/src/cmd/8a/l.s

@@ -221,7 +221,7 @@ TEXT	mode32bit(SB),$0
 	 *  16 meg of physical memory
 	 */
 	LEAL	tpt-KZERO(SB),AX	/* get phys addr of temporary page table */
-	ADDL	$(BY2PG-1),AX		/* must be page alligned */
+	ADDL	$(BY2PG-1),AX		/* must be page aligned */
 	ANDL	$(~(BY2PG-1)),AX	/* ... */
 	MOVL	$(4*1024),CX		/* pte's per page */
 	MOVL	$((((4*1024)-1)<<PGSHIFT)|PTEVALID|PTEKERNEL|PTEWRITE),BX

+ 62 - 4
sys/src/cmd/8a/lex.c

@@ -274,6 +274,9 @@ struct
 	"CMPSB",	LTYPE0,	ACMPSB,
 	"CMPSL",	LTYPE0,	ACMPSL,
 	"CMPSW",	LTYPE0,	ACMPSW,
+	"CMPXCHGB",	LTYPE3,	ACMPXCHGB,
+	"CMPXCHGL",	LTYPE3,	ACMPXCHGL,
+	"CMPXCHGW",	LTYPE3,	ACMPXCHGW,
 	"DAA",		LTYPE0,	ADAA,
 	"DAS",		LTYPE0,	ADAS,
 	"DATA",		LTYPED,	ADATA,
@@ -285,14 +288,14 @@ struct
 	"DIVW",		LTYPE2,	ADIVW,
 	"END",		LTYPE0,	AEND,
 	"ENTER",	LTYPE2,	AENTER,
-	"GLOBL",	LTYPET,	AGLOBL,
+	"GLOBL",	LTYPEG,	AGLOBL,
 	"HLT",		LTYPE0,	AHLT,
 	"IDIVB",	LTYPE2,	AIDIVB,
 	"IDIVL",	LTYPE2,	AIDIVL,
 	"IDIVW",	LTYPE2,	AIDIVW,
-	"IMULB",	LTYPE2,	AIMULB,
-	"IMULL",	LTYPE2,	AIMULL,
-	"IMULW",	LTYPE2,	AIMULW,
+	"IMULB",	LTYPEI,	AIMULB,
+	"IMULL",	LTYPEI,	AIMULL,
+	"IMULW",	LTYPEI,	AIMULW,
 	"INB",		LTYPE0,	AINB,
 	"INL",		LTYPE0,	AINL,
 	"INW",		LTYPE0,	AINW,
@@ -493,6 +496,39 @@ struct
 	"XORL",		LTYPE3,	AXORL,
 	"XORW",		LTYPE3,	AXORW,
 
+	"CMOVLCC",	LTYPE3,	ACMOVLCC,
+	"CMOVLCS",	LTYPE3,	ACMOVLCS,
+	"CMOVLEQ",	LTYPE3,	ACMOVLEQ,
+	"CMOVLGE",	LTYPE3,	ACMOVLGE,
+	"CMOVLGT",	LTYPE3,	ACMOVLGT,
+	"CMOVLHI",	LTYPE3,	ACMOVLHI,
+	"CMOVLLE",	LTYPE3,	ACMOVLLE,
+	"CMOVLLS",	LTYPE3,	ACMOVLLS,
+	"CMOVLLT",	LTYPE3,	ACMOVLLT,
+	"CMOVLMI",	LTYPE3,	ACMOVLMI,
+	"CMOVLNE",	LTYPE3,	ACMOVLNE,
+	"CMOVLOC",	LTYPE3,	ACMOVLOC,
+	"CMOVLOS",	LTYPE3,	ACMOVLOS,
+	"CMOVLPC",	LTYPE3,	ACMOVLPC,
+	"CMOVLPL",	LTYPE3,	ACMOVLPL,
+	"CMOVLPS",	LTYPE3,	ACMOVLPS,
+	"CMOVWCC",	LTYPE3,	ACMOVWCC,
+	"CMOVWCS",	LTYPE3,	ACMOVWCS,
+	"CMOVWEQ",	LTYPE3,	ACMOVWEQ,
+	"CMOVWGE",	LTYPE3,	ACMOVWGE,
+	"CMOVWGT",	LTYPE3,	ACMOVWGT,
+	"CMOVWHI",	LTYPE3,	ACMOVWHI,
+	"CMOVWLE",	LTYPE3,	ACMOVWLE,
+	"CMOVWLS",	LTYPE3,	ACMOVWLS,
+	"CMOVWLT",	LTYPE3,	ACMOVWLT,
+	"CMOVWMI",	LTYPE3,	ACMOVWMI,
+	"CMOVWNE",	LTYPE3,	ACMOVWNE,
+	"CMOVWOC",	LTYPE3,	ACMOVWOC,
+	"CMOVWOS",	LTYPE3,	ACMOVWOS,
+	"CMOVWPC",	LTYPE3,	ACMOVWPC,
+	"CMOVWPL",	LTYPE3,	ACMOVWPL,
+	"CMOVWPS",	LTYPE3,	ACMOVWPS,
+
 	"FMOVB",	LTYPE3, AFMOVB,
 	"FMOVBP",	LTYPE3, AFMOVBP,
 	"FMOVD",	LTYPE3, AFMOVD,
@@ -507,6 +543,14 @@ struct
 	"FMOVWP",	LTYPE3, AFMOVWP,
 	"FMOVX",	LTYPE3, AFMOVX,
 	"FMOVXP",	LTYPE3, AFMOVXP,
+	"FCMOVCC",	LTYPE3, AFCMOVCC,
+	"FCMOVCS",	LTYPE3, AFCMOVCS,
+	"FCMOVEQ",	LTYPE3, AFCMOVEQ,
+	"FCMOVHI",	LTYPE3, AFCMOVHI,
+	"FCMOVLS",	LTYPE3, AFCMOVLS,
+	"FCMOVNE",	LTYPE3, AFCMOVNE,
+	"FCMOVNU",	LTYPE3, AFCMOVNU,
+	"FCMOVUN",	LTYPE3, AFCMOVUN,
 	"FCOMB",	LTYPE3, AFCOMB,
 	"FCOMBP",	LTYPE3, AFCOMBP,
 	"FCOMD",	LTYPE3, AFCOMD,
@@ -514,11 +558,15 @@ struct
 	"FCOMDPP",	LTYPE3, AFCOMDPP,
 	"FCOMF",	LTYPE3, AFCOMF,
 	"FCOMFP",	LTYPE3, AFCOMFP,
+	"FCOMI",	LTYPE3, AFCOMI,
+	"FCOMIP",	LTYPE3, AFCOMIP,
 	"FCOML",	LTYPE3, AFCOML,
 	"FCOMLP",	LTYPE3, AFCOMLP,
 	"FCOMW",	LTYPE3, AFCOMW,
 	"FCOMWP",	LTYPE3, AFCOMWP,
 	"FUCOM",	LTYPE3, AFUCOM,
+	"FUCOMI",	LTYPE3, AFUCOMI,
+	"FUCOMIP",	LTYPE3, AFUCOMIP,
 	"FUCOMP",	LTYPE3, AFUCOMP,
 	"FUCOMPP",	LTYPE3, AFUCOMPP,
 	"FADDW",	LTYPE3, AFADDW,
@@ -704,6 +752,9 @@ zaddr(Gen *a, int s)
 	case D_FCONST:
 		t |= T_FCONST;
 		break;
+	case D_CONST2:
+		t |= T_OFFSET|T_OFFSET2;
+		break;
 	case D_SCONST:
 		t |= T_SCONST;
 		break;
@@ -723,6 +774,13 @@ zaddr(Gen *a, int s)
 		Bputc(&obuf, l>>16);
 		Bputc(&obuf, l>>24);
 	}
+	if(t & T_OFFSET2) {
+		l = a->offset2;
+		Bputc(&obuf, l);
+		Bputc(&obuf, l>>8);
+		Bputc(&obuf, l>>16);
+		Bputc(&obuf, l>>24);
+	}
 	if(t & T_SYM)		/* implies sym */
 		Bputc(&obuf, s);
 	if(t & T_FCONST) {

+ 60 - 0
sys/src/cmd/8c/8.out.h

@@ -2,6 +2,7 @@
 #define	NSNAME	8
 #define NOPROF	(1<<0)
 #define DUPOK	(1<<1)
+#define NOSPLIT	(1<<2)
 
 enum	as
 {
@@ -353,6 +354,58 @@ enum	as
 
 	ASIGNAME,
 
+	AFCOMI,
+	AFCOMIP,
+	AFUCOMI,
+	AFUCOMIP,
+	ACMPXCHGB,
+	ACMPXCHGL,
+	ACMPXCHGW,
+
+	/* conditional move */
+	ACMOVLCC,
+	ACMOVLCS,
+	ACMOVLEQ,
+	ACMOVLGE,
+	ACMOVLGT,
+	ACMOVLHI,
+	ACMOVLLE,
+	ACMOVLLS,
+	ACMOVLLT,
+	ACMOVLMI,
+	ACMOVLNE,
+	ACMOVLOC,
+	ACMOVLOS,
+	ACMOVLPC,
+	ACMOVLPL,
+	ACMOVLPS,
+	ACMOVWCC,
+	ACMOVWCS,
+	ACMOVWEQ,
+	ACMOVWGE,
+	ACMOVWGT,
+	ACMOVWHI,
+	ACMOVWLE,
+	ACMOVWLS,
+	ACMOVWLT,
+	ACMOVWMI,
+	ACMOVWNE,
+	ACMOVWOC,
+	ACMOVWOS,
+	ACMOVWPC,
+	ACMOVWPL,
+	ACMOVWPS,
+
+	AFCMOVCC,
+	AFCMOVCS,
+	AFCMOVEQ,
+	AFCMOVHI,
+	AFCMOVLS,
+	AFCMOVNE,
+	AFCMOVNU,
+	AFCMOVUN,
+
+	/* add new operations here. nowhere else. here. */
 	ALAST
 };
 
@@ -378,6 +431,7 @@ enum
 	D_DI,
 
 	D_F0		= 16,
+	D_F7		= D_F0 + 7,
 
 	D_CS		= 24,
 	D_SS,
@@ -413,12 +467,18 @@ enum
 
 	D_INDIR,	/* additive */
 
+	D_CONST2 = D_INDIR+D_INDIR,
+
+	D_SIZE,	/* 8l internal */
+
 	T_TYPE		= 1<<0,
 	T_INDEX		= 1<<1,
 	T_OFFSET	= 1<<2,
 	T_FCONST	= 1<<3,
 	T_SYM		= 1<<4,
 	T_SCONST	= 1<<5,
+	T_OFFSET2	= 1<<6,
+	T_GOTYPE	= 1<<7,
 
 	REGARG		= -1,
 	REGRET		= D_AX,

+ 0 - 1117
sys/src/cmd/8c/bound.c

@@ -1,1117 +0,0 @@
-#include "gc.h"
-#include "bound.h"
-
-static	BB*	bbfree;
-static	BBset*	bbsfree;
-static	int	bballoc;
-static	int	bbsalloc;
-static	BB	bbz;
-static	BBset	bbsz;
-static	BB*	firstbb;
-static	BB*	lastbb;
-static	BB*	wounded;
-static	BB*	bbaux;
-static	BBset*	recalc;
-static	BBset*	bbhash[BBHASH];
-static	BB**	ordered;
-static	int	bcount;
-static	BBset**	heap;
-static	int	heapn;
-static	int	bsize;
-static	char	bbbuff[BBBSIZE];
-static	int	bchange;
-
-#define	bdebug	(debug['v'])
-#define	dbg	0
-#define	bcheck	0
-
-static long
-Rn(Reg *r)
-{
-	if(r == R)
-		return -1;
-	return r->rpo;
-}
-
-static BB*
-bba(void)
-{
-	BB *b;
-
-	bballoc++;
-	b = bbfree;
-	if(b == nil) {
-		b = alloc(sizeof(*b));
-	} else
-		bbfree = b->link;
-
-	*b = bbz;
-	return b;
-}
-
-static void
-bfree(BB *b)
-{
-	bballoc--;
-	b->link = bbfree;
-	bbfree = b;
-}
-
-static BBset*
-bbsa(void)
-{
-	BBset *b;
-
-	bballoc++;
-	b = bbsfree;
-	if(b == nil) {
-		b = alloc(sizeof(*b));
-	} else
-		bbsfree = b->link;
-
-	*b = bbsz;
-	return b;
-}
-
-static void
-bsfree(BBset *b)
-{
-	bballoc--;
-	b->link = bbsfree;
-	bbsfree = b;
-}
-
-static void
-dumpheap(void)
-{
-	int i;
-
-	for(i = 1; i <= heapn; i++)
-		print(" %d", heap[i]->damage);
-}
-
-static void
-checkheap(void)
-{
-	int N, N2, n, c;
-
-	N = heapn;
-	N2 = N >> 1;
-	for(n = 1; n <= N2; n++) {
-		c = n << 1;
-		if((heap[c]->damage > heap[n]->damage)
-		|| ((c < N) && (heap[c + 1]->damage > heap[n]->damage))) {
-			print("bad heap (%d:%d) %d [", n, heap[n]->damage, heapn);
-			dumpheap();
-			print(" ]\n");
-			abort();
-		}
-	}
-}
-
-static void
-downheap(int n)
-{
-	int N, N2, d, c;
-	BBset *s, *t, *u;
-
-	s = heap[n];
-	d = s->damage;
-//print("down %d %d", n, d);
-	N = heapn;
-	N2 = N >> 1;
-	while(n <= N2) {
-		c = n << 1;
-		t = heap[c];
-		if(c < N) {
-			u = heap[c + 1];
-			if(t->damage < u->damage) {
-				t = u;
-				c++;
-			}
-		}
-//print(" [%d %d]", c, t->damage);
-		if(t->damage < d)
-			break;
-		heap[n] = t;
-		t->index = n;
-		n = c;
-	}
-	heap[n] = s;
-	s->index = n;
-//print("\n");
-//checkheap();
-}
-
-static void
-upheap(int n)
-{
-	int f, d;
-	BBset *s, *t;
-
-	s = heap[n];
-	d = s->damage;
-//print("up %d %d", n, d);
-	while(n > 1) {
-		f = n >> 1;
-		t = heap[f];
-//print(" [%d %d]", f, t->damage);
-		if(t->damage >= d)
-			break;
-		heap[n] = t;
-		t->index = n;
-		n = f;
-	}
-	heap[n] = s;
-	s->index = n;
-//print("\n");
-//checkheap();
-}
-
-static void
-heapremove(BBset *s)
-{
-	int x;
-	BBset *t;
-
-	x = s->index;
-	s->index = 0;
-	if(x == 0)
-		return;
-	if(x == heapn) {
-		heapn--;
-		return;
-	}
-	t = heap[heapn--];
-	heap[x] = t;
-	t->index = x;
-	if(s->damage < t->damage)
-		upheap(x);
-	else
-		downheap(x);
-}
-
-static void
-heapadd(BBset *s)
-{
-	int n;
-
-	n = heapn + 1;
-	heap[n] = s;
-	s->index = n;
-	heapn = n;
-	upheap(n);
-
-}
-
-static void
-bbsrecalc(BBset *s)
-{
-	if(s->recalc)
-		return;
-	s->recalc = 1;
-	s->link = recalc;
-	recalc = s;
-	heapremove(s);
-}
-
-static void
-bbadd(BB *b, Hval h)
-{
-	int k;
-	BBset *s;
-
-	k = h[0] & BBMASK;
-	for(s = bbhash[k]; s != nil; s = s->next) {
-		if(BBEQ(s->hash, h)) {
-			b->set = s;
-			b->link = s->ents;
-			s->ents = b;
-			bbsrecalc(s);
-			return;
-		}
-	}
-	s = bbsa();
-	s->next = bbhash[k];
-	bbhash[k] = s;
-	b->set = s;
-	b->link = nil;
-	s->ents = b;
-	BBCP(s->hash, h);
-	bbsrecalc(s);
-}
-
-static int
-hashbb(BB *b, Hval h)
-{
-	Reg *r;
-	Prog *p;
-	char *s;
-	int c, f, i, n;
-
-	r = b->first;
-	s = bbbuff;
-	i = 0;
-	n = BBBSIZE;
-	for(;;) {
-		p = r->prog;
-		if(p->as != ANOP) {
-			if(p->to.type == D_BRANCH)
-				p->to.offset = r->s2->rpo;
-			c = snprint(s, n, "%P", p);
-			s += c;
-			n -= c;
-			i++;
-		}
-		if(r == b->last)
-			break;
-		r = r->link;
-	}
-	if(n == 0)
-		return Bbig;
-	b->len = i;
-	BBMKHASH(bbbuff, BBBSIZE - n, h);
-	f = b->flags;
-	if(i == 1 && r->prog->as == AJMP && b->first->p1 == R)
-		f = Bjo;
-	else if(b->first->p1 != R)
-		f |= Bpre;
-	if(bdebug)
-		print("A %x %s %ux %ux\n", f, bbbuff, h[0], h[1]);
-	return f;
-}
-
-static void
-enterbb(BB *b)
-{
-	Hval h;
-
-	b->flags = hashbb(b, h);
-	if(b->flags != Bbig)
-		bbadd(b, h);
-}
-
-static void
-preproc(BB *b, int x)
-{
-	BB *n;
-	Reg *r;
-
-	ordered[x] = b;
-	if(b->last->rpo - b->first->rpo > BBBIG) {
-		b->flags = Bbig;
-		return;
-	}
-	if(b->first->p2 == nil) {
-		b->flags = Bdel;
-		return;
-	}
-	switch(b->last->prog->as) {
-	case ARET:
-	case AJMP:
-	case AIRETL:
-		break;
-
-	default:
-		b->flags = Bdel;
-		n = bba();
-		n->first = b->first;
-		for(r = b->last->link; r != R; r = r->link) {
-			switch(r->prog->as) {
-			case ARET:
-			case AJMP:
-			case AIRETL:
-				n->last = r;
-				n->flags = Bpin;
-				enterbb(n);
-				if(n->flags & Bpin) {
-					n->aux = bbaux;
-					bbaux = n;
-				}
-				else
-					bfree(n);
-				return;
-			}
-		}
-		bfree(n);
-		return;
-	}
-	enterbb(b);
-}
-
-static int
-p2len(Reg *r)
-{
-	int c;
-
-	c = 0;
-	for(r = r->p2; r != nil; r = r->p2link)
-		c++;
-	return c;
-}
-
-static void
-calcdamage(BBset *s)
-{
-	BB *f;
-	int d, t;
-
-	s->recalc = 0;
-	f = s->ents;
-	if(f == nil)
-		return;
-	if(f->flags & Bjo) {
-		if(bdebug)
-			print("add %ld jo\n", f->first->rpo);
-		s->damage = COSTJO;
-		heapadd(s);
-		return;
-	}
-	if(f->link == nil) {
-		if(bdebug)
-			print("solo %x %x\n", s->hash[0], s->hash[1]);
-		return;
-	}
-
-	d = 0;
-	t = 0;
-	while(f != nil) {
-		if((f->flags & (Bpre|Bpin)) == 0 && f->last->link != R) {
-			t = 1;
-			d += (f->last->rpo - f->first->rpo) >> 1;
-		}
-		d += p2len(f->first);
-		f = f->link;
-	}
-
-	if(t == 0) {
-		if(bdebug)
-			print("all pre %ld\n", s->ents->first->rpo);
-		return;
-	}
-
-	if(bdebug)
-		print("add %ld %d\n", s->ents->first->rpo, d);
-	if(d > COSTHI)
-		d = COSTHI;
-	s->damage = d;
-	heapadd(s);
-}
-
-static Reg*
-findjump(BB *b)
-{
-	Reg *r, *l;
-
-	r = b->first;
-	l = b->last;
-
-	for(;;) {
-		if(r->prog->as == AJMP)
-			break;
-		if(r == l) {
-			diag(Z, "findjump botch");
-			break;
-		}
-		r = r->link;
-	}
-	return r;
-}
-
-static BB*
-findset(int r)
-{
-	BB *s, **p;
-	int n, n2;
-
-	if(r < ordered[0]->first->rpo)
-		return nil;
-	n = bcount;
-	p = ordered;
-	while(n > 0) {
-		n2 = n >> 1;
-		s = p[n2];
-		if(r < s->first->rpo) {
-			n = n2;
-			continue;
-		}
-		if(r > s->last->rpo) {
-			n2++;
-			p += n2;
-			n -= n2;
-			continue;
-		}
-		return s;
-	}
-	diag(Z, "findset botch");
-	return nil;
-}
-
-static void
-wound(Reg *r)
-{
-	BB *b, *p, **n;
-	BBset *s;
-
-	b = findset(r->rpo);
-	if(b == nil)
-		return;
-	s = b->set;
-	if(s == nil)
-		return;
-	for(n = &s->ents; (p = *n) != nil; n = &(*n)->link) {
-		if(p == b) {
-			*n = b->link;
-			b->link = wounded;
-			wounded = b;
-			bbsrecalc(s);
-			return;
-		}
-	}
-}
-
-static void
-printbl(Reg *l)
-{
-	if(l == nil) {
-		print("Z");
-		return;
-	}
-
-	print("%ld", l->rpo);
-	while((l = l->p2link) != nil)
-		print(" %ld", l->rpo);
-}
-
-static void
-appset(Reg *e, Reg *s)
-{
-	for(;;) {
-		if(s->p2link == R) {
-			s->p2link = e;
-			return;
-		}
-		s = s->p2link;
-	}
-}
-
-static Reg*
-delset(Reg *e, Reg *s)
-{
-	Reg *c, *l;
-
-	c = s;
-	l = nil;
-	for(;;) {
-		if(e == c) {
-			if(l == nil)
-				return s->p2link;
-			l->p2link = c->p2link;
-			return s;
-		}
-		l = c;
-		c = c->p2link;
-		if(c == nil)
-			return s;
-	}
-}
-
-static void
-redest(Reg *s, Reg *d)
-{
-	while(s != R) {
-		s->s2 = d;
-		s = s->p2link;
-	}
-}
-
-static void
-changedest(Reg *s, Reg *d, int x)
-{
-	Reg *l;
-
-	if(bdebug) {
-		print("change %ld [", s->rpo);
-		printbl(s->p2);
-		print("] -> %ld [", d->rpo);
-		printbl(d->p2);
-		print("]\n");
-	}
-
-	if(s->p2 == nil) {
-//		print("deadjmp\n");
-		return;
-	}
-
-	l = s->p2;
-	for(;;) {
-		if(bdebug)
-			print("s2 %ld = %ld\n", l->rpo, d->rpo);
-		l->s2 = d;
-		wound(l);
-		if(l->p2link == nil)
-			break;
-		l = l->p2link;
-	}
-
-	if(x) {
-		l->p2link = delset(s, d->p2);
-		d->p2 = s->p2;
-	}
-	else {
-		l->p2link = d->p2;
-		d->p2 = s->p2;
-		s->p2 = nil;
-	}
-
-	if(bdebug) {
-		print("result [");
-		printbl(d->p2);
-		print("]\n");
-	}
-
-	bchange = 1;
-}
-
-static void
-bexcise(BB *b)
-{
-	Reg *r, *l;
-
-	l = b->last;
-	r = b->first;
-	if(bdebug)
-		print("excise %ld to %ld\n", r->rpo, l->rpo);
-	for(;;) {
-		r->prog->as = ANOP;
-		r->prog->to.type = D_NONE;
-		r->p2 = R;
-		if(r->s2 != R) {
-			r->s2->p2 = delset(r, r->s2->p2);
-			r->s2 = R;
-		}
-		if(r == l)
-			break;
-		r = r->link;
-	}
-}
-
-static int
-backtrack(Reg *s, Reg *d)
-{
-	int i;
-	char l[BINST], r[BINST];
-
-//print("backtrack %ld %ld\n", Rn(s), Rn(d));
-	i = 0;
-	while(s != nil && d != nil) {
-		if(snprint(l, BINST, "%P", s->prog) == BINST)
-			break;
-		if(snprint(r, BINST, "%P", d->prog) == BINST)
-			break;
-//print("%s\t%s\n", l, r);
-		if(strcmp(l, r) != 0)
-			break;
-		i++;
-		s = s->p2link;
-		d = d->p2link;
-	}
-	return i;
-}
-
-static void
-checktails(void)
-{
-	int c;
-	Reg *r;
-
-	c = 0;
-	for(r = firstr; r->link != R; r = r->link) {
-		if(r->prog->as == AJMP && r->s2 != nil)
-			c += backtrack(r->p1, r->s2->p1);
-	}
-
-	if(c > 0)
-		print("tails %s %d\n", firstr->prog->from.sym->name, c);
-}
-
-static void
-process(BBset *s)
-{
-	Reg *h;
-	BB *f, *o, *p, *t;
-
-	if(bdebug)
-		print("process %d %x %x\n", s->damage, s->hash[0], s->hash[1]);
-	f = s->ents;
-	if(f->flags & Bjo) {
-		s->ents = nil;
-		h = findjump(f)->s2;
-		o = nil;
-		while(f != nil) {
-			t = f->link;
-			if((f->flags & Bjo) != 0 && f->first->s2 != f->first) {
-				changedest(f->first, h, 1);
-				bexcise(f);
-			}
-			else {
-				f->link = o;
-				o = f;
-			}
-			f = t;
-		}
-		s->ents = o;
-	}
-	else {
-		o = nil;
-		p = nil;
-		while(f != nil) {
-			t = f->link;
-			if((f->flags & (Bpre|Bpin)) != 0 || (f->last->link == R)) {
-				f->link = p;
-				p = f;
-			}
-			else {
-				f->link = o;
-				o = f;
-			}
-			f = t;
-		}
-		if(o == nil) {
-			diag(Z, "all Bpre");
-			return;
-		}
-		if(p == nil) {
-			p = o;
-			o = p->link;
-			p->link = nil;
-			s->ents = p;
-		}
-		else
-			s->ents = p;
-
-		h = p->first;
-		// oblit o list repl with jmp to h
-		while(o != nil) {
-			changedest(o->first, h, 1);
-			bexcise(o);
-			o = o->link;
-		}
-
-		bbsrecalc(s);
-	}
-}
-
-static void
-iterate(void)
-{
-	BBset *s;
-	BB *b, *t;
-
-	heapn = 0;
-
-	for(;;) {
-		for(b = wounded; b != nil; b = t) {
-			t = b->link;
-			enterbb(b);
-		}
-		wounded = nil;
-
-		for(s = recalc; s != nil; s = s->link)
-			calcdamage(s);
-		recalc = nil;
-
-		if(heapn == 0)
-			return;
-
-		s = heap[1];
-		heapremove(s);
-		process(s);
-	}
-}
-
-static void
-cleanup(void)
-{
-	int i;
-	BB *l, *n;
-	BBset *b, *t;
-
-	for(i = 0; i < BBHASH; i++) {
-		b = bbhash[i];
-		bbhash[i] = nil;
-		while(b != nil) {
-			t = b->next;
-			bsfree(b);
-			b = t;
-		}
-	}
-	for(i = 0; i < bcount; i++)
-		bfree(ordered[i]);
-	for(l = bbaux; l != nil; l = n) {
-		n = l->aux;
-		bfree(l);
-	}
-	bbaux = nil;
-}
-
-static void
-prreg(Reg *r)
-{
-	Prog *p;
-
-	p = r->prog;
-	if(p->to.type == D_BRANCH)
-		p->to.offset = r->s2->rpo;
-	print("%ld:%P\tr %lX ", r->rpo, r->prog, r->regu);
-	print("p1 %ld p2 %ld p2l %ld s1 %ld s2 %ld link %ld",
-		Rn(r->p1), Rn(r->p2), Rn(r->p2link),
-		Rn(r->s1), Rn(r->s2), Rn(r->link));
-	if(!r->active)
-		print(" d");
-//	print(" %p %p\n", r->prog, r->prog->link);
-	print("\n");
-}
-
-static	void	prfunc(char*);
-
-static void
-checkr(int d)
-{
-	Prog *p;
-	Reg *r, *t;
-
-	for(r = firstr; r->link != R; r = r->link) {
-		for(p = r->prog->link; p != P && p != r->link->prog; p = p->link)
-			;
-		if(p == P) {
-			print("%ld: bad prog link\n", r->rpo);
-			if(d)
-				prfunc(nil);
-			abort();
-		}
-		if(r->s1 != R && (r->s1 != r->link || r->link->p1 != r)) {
-			print("%ld: bad s1 p1\n", r->rpo);
-			if(d)
-				prfunc(nil);
-			abort();
-		}
-		if(r->s2 != R && r->s2->p2 == nil) {
-			print("%ld: no p2 for s2\n", r->rpo);
-			if(d)
-				prfunc(nil);
-			abort();
-		}
-		if(r->p2 != R) {
-			t = r->p2->s2;
-			while(t != r) {
-				t = t->p2link;
-				if(t == R) {
-					print("%ld: bad s2 for p2\n", r->rpo);
-					if(d)
-						prfunc(nil);
-					abort();
-				}
-			}
-		}
-	}
-}
-
-static void
-prfunc(char *s)
-{
-	Reg *r;
-
-	if(s != nil)
-		print("%s structure %s\n", s, firstr->prog->from.sym->name);
-	for(r = firstr; r != R; r = r->link)
-		prreg(r);
-	if(s != nil) {
-		print("end\n");
-		checkr(0);
-	}
-}
-
-/* find p in r's list and replace with l */
-static void
-adjprog(Reg *r, Prog *p, Prog *l)
-{
-	Prog *t, **n;
-
-	for(n = &r->prog->link; (t = *n) != nil; n = &t->link) {
-		if(t == p) {
-			*n = l;
-			return;
-		}
-	}
-	print("adjprog botch\n");
-	abort();
-}
-
-static void
-jumptojump(void)
-{
-	Reg *r;
-
-	for(r = firstr; r != R; r = r->link) {
-		if(r->prog->as == AJMP && r->p2 != R && r->s2 != r) {
-			if(bdebug)
-				print("jump as dest %ld -> %ld\n", r->rpo, r->s2->rpo);
-			changedest(r, r->s2, 0);
-			bchange++;
-		}
-	}
-}
-
-/* drag a tail to replace a jump.  seems to be a bad idea. */
-static void
-rearrange(void)
-{
-	int i;
-	Reg *j, *t;
-	BB *b, *p, *s;
-
-	for(i = 0; i < bcount; i++) {
-		b = ordered[i];
-		if(b->flags & Bdel)
-			continue;
-		j = b->last;
-		if(j->prog->as == AJMP && j->s2->p1 == R) {
-			t = j->s2;
-			if(t == b->first)
-				continue;
-			s = findset(t->rpo);
-			if(s == nil) {
-				diag(Z, "no self");
-				continue;
-			}
-			if(s == ordered[0])
-				continue;
-			if(s->flags & Bdel)
-				continue;
-			if(s->last->link == R)
-				continue;
-			if(bdebug)
-				print("drag %ld to %ld\n", t->rpo, j->rpo);
-			p = findset(t->rpo - 1);
-			if(p == nil) {
-				diag(Z, "no predec");
-				continue;
-			}
-			if(p->last->link != t) {
-				diag(Z, "bad predec %ld %ld", p->last->rpo, t->rpo);
-				continue;
-			}
-
-			/* poison everything in sight */
-			b->flags |= Bdel;
-			s->flags |= Bdel;
-			findset(j->link->rpo)->flags |= Bdel;
-			findset(s->last->link->rpo)->flags |= Bdel;
-
-			/* remove */
-			adjprog(p->last, t->prog, s->last->link->prog);
-			p->last->link = s->last->link;
-
-			/* fix tail */
-			adjprog(s->last, s->last->link->prog, j->link->prog);
-			s->last->link = j->link;
-
-			/* fix head */
-			adjprog(j, j->link->prog, t->prog);
-			j->link = t;
-
-			/* nop the jump */
-			j->prog->as = ANOP;
-			j->prog->to.type = D_NONE;
-			j->s2 = nil;
-			j->link->p2 = delset(j, j->link->p2);
-			j->s1 = t;
-			t->p1 = j;
-			if(bcheck)
-				checkr(1);
-			bchange++;
-		}
-	}
-}
-
-void
-jumptodot(void)
-{
-	Reg *r;
-
-	for(r = firstr; r != R; r = r->link) {
-		if(r->prog->as == AJMP && r->s2 == r->link) {
-			if(debug['v'])
-				print("jump to next %ld\n", r->rpo);
-			r->prog->as = ANOP;
-			r->prog->to.type = D_NONE;
-			r->s2 = nil;
-			r->link->p2 = delset(r, r->link->p2);
-			findset(r->rpo)->flags |= Bdel;
-			findset(r->link->rpo)->flags |= Bdel;
-			bchange++;
-		}
-	}
-}
-
-void
-comtarg(void)
-{
-	int n;
-	BB *b, *c;
-	Reg *r, *l, *p, *t;
-
-loop:
-	bchange = 0;
-
-	/* excise NOPS because they just get in the way */
-	/* some have p2 because they are excised labelled moves */
-
-	if(debug['v']) {
-		n = 0;
-		for(r = firstr; r != R; r = r->link)
-			r->rpo = n++;
-		prfunc("prenop");
-	}
-
-	r = firstr;
-	l = r->link;
-	while(l != R) {
-		if(l->prog->as == ANOP) {
-			t = l->p1;
-			p = l->p2;
-if(dbg) print("nop %ld [", l->rpo);
-if(dbg) printbl(p);
-			for(;;) {
-				adjprog(r, l->prog, l->prog->link);
-				r->link = l->link;
-				l->link = freer;
-				freer = l;
-				l = r->link;
-				if(l->prog->as != ANOP)
-					break;
-if(dbg) print("] %ld [", l->rpo);
-if(dbg) printbl(l->p2);
-				if(p == R)
-					p = l->p2;
-				else if(l->p2 != nil)
-					appset(l->p2, p);
-			}
-if(dbg) print("] %ld [", l->rpo);
-if(dbg) printbl(l->p2);
-			if(p != R) {
-				redest(p, l);
-				if(l->p2 != R)
-					appset(p, l->p2);
-				else
-					l->p2 = p;
-			}
-if(dbg) print("] -> [");
-if(dbg) printbl(l->p2);
-if(dbg) print("]\n");
-			if(r->s1 != R)
-				r->s1 = l;
-			l->p1 = t;
-		}
-		r = l;
-		l = r->link;
-	}
-
-	n = 0;
-	for(r = firstr; r != R; r = r->link)
-		r->rpo = n++;
-
-	if(debug['v'])
-		prfunc("input");
-
-	firstbb = nil;
-	lastbb = nil;
-
-	if(debug['v'])
-		print("bbstart\n");
-
-	n = 0;
-	r = firstr;
-	do {
-		b = bba();
-		b->first = r;
-		for(;;) {
-			l = r;
-			r = r->link;
-			switch(l->prog->as) {
-			case ARET:
-			case AJMP:
-			case AIRETL:
-				goto out;
-			}
-			if(r->p2 != R)
-				break;
-		}
-	out:
-		b->last = l;
-		if(lastbb == nil)
-			firstbb = b;
-		else
-			lastbb->link = b;
-		lastbb = b;
-		if(bdebug)
-			print("BB %ld %ld\n", b->first->rpo, b->last->rpo);
-		n++;
-	} while(r != R);
-
-	if(debug['v'])
-		print("end\n");
-
-	if(n > bsize) {
-		bsize = n * 3 / 2;
-		if(bsize < BBINIT)
-			bsize = BBINIT;
-		ordered = alloc(bsize * sizeof(*ordered));
-		heap = alloc((bsize + 1) * sizeof(*ordered));
-	}
-
-	if(debug['v'])
-		print("preprocstart\n");
-
-	n = 0;
-	for(b = firstbb; b != nil; b = c) {
-		c = b->link;
-		preproc(b, n++);
-	}
-
-	if(debug['v'])
-		print("end\n");
-
-	bcount = n;
-
-	jumptojump();
-
-	if(debug['v'])
-		print("iteratestart\n");
-
-	iterate();
-//checktails();
-
-	if(debug['v'])
-		print("end\n");
-
-	if(debug['v'])
-		print("extrastart\n");
-
-	jumptodot();
-//	rearrange();
-
-	if(debug['v'])
-		print("end\n");
-
-	cleanup();
-	if(bballoc || bbsalloc)
-		diag(Z, "bballoc %d %d", bballoc, bbsalloc);
-
-	if(debug['v'])
-		prfunc("output");
-
-	if(1 && bchange)
-		goto loop;
-}

+ 0 - 56
sys/src/cmd/8c/bound.h

@@ -1,56 +0,0 @@
-/*
- *	Bounding Box stuff (brucee 04/03/30).
- */
-
-#include <mp.h>
-#include <libsec.h>
-
-typedef	struct	BB	BB;
-typedef	struct	BBset	BBset;
-typedef uchar		Hval[SHA1dlen];
-
-#define	BBEQ(a, b)		(memcmp((a), (b), SHA1dlen) == 0)
-#define	BBMKHASH(b, n, h)	sha1((uchar *)(b), (n), (h), nil)
-#define	BBCP(d, s)		memmove(d, s, SHA1dlen)
-
-enum
-{
-	Bpre	= 1 << 0,	/* has a flow in */
-	Bjo	= 1 << 1,	/* a jump only */
-	Bbig	= 1 << 2,	/* too big */
-	Bdel	= 1 << 3,	/* deleted or not of interest */
-	Bpin	= 1 << 4,	/* pinned by embedded labels */
-
-	BBHASH	= 64,		/* power of 2 <= 256 */
-	BBMASK	= BBHASH - 1,
-
-	BBINIT	= 128,
-	BBBIG	= 64,
-	BBBSIZE	= 8192,
-	BINST	= 128,
-
-	COSTHI	= 0x7F,
-	COSTJO	= 0xFF,
-};
-
-struct	BB
-{
-	Reg*	first;
-	Reg*	last;
-	BBset*	set;
-	BB*	link;
-	BB*	aux;
-	short	flags;
-	short	len;
-};
-
-struct	BBset
-{
-	Hval	hash;
-	BB*	ents;
-	BBset*	next;
-	BBset*	link;
-	short	index;
-	uchar	damage;
-	uchar	recalc;
-};

+ 0 - 2
sys/src/cmd/8c/mkfile

@@ -2,7 +2,6 @@
 
 TARG=8c
 OFILES=\
-	bound.$O\
 	cgen.$O\
 	cgen64.$O\
 	div.$O\
@@ -33,7 +32,6 @@ $LIB:
 	mk install
 	mk clean
 
-bound.$O:	bound.h
 
 %.$O: ../cc/%.c
 	$CC $CFLAGS ../cc/$stem.c

+ 0 - 2
sys/src/cmd/8c/peep.c

@@ -67,8 +67,6 @@ peep(void)
 	pc = 0;	/* speculating it won't kill */
 
 loop1:
-	if(debug['b'])
-		comtarg();
 
 	t = 0;
 	for(r=firstr; r!=R; r=r->link) {

+ 12 - 5
sys/src/cmd/8l/l.h

@@ -37,7 +37,7 @@ struct	Adr
 		Sym*	u1sym;
 	} u1;
 	short	type;
-	char	index;
+	uchar	index;
 	char	scale;
 };
 
@@ -58,11 +58,12 @@ struct	Prog
 	Prog*	pcond;	/* work on this */
 	long	pc;
 	long	line;
-	uchar	mark;	/* work on these */
-	uchar	back;
-
 	short	as;
 	char	width;		/* fake for DATA */
+	char	ft;		/* oclass cache */
+	char	tt;
+	uchar	mark;	/* work on these */
+	uchar	back;
 };
 struct	Auto
 {
@@ -203,6 +204,7 @@ EXTERN union
 #pragma	varargck	type	"D"	Adr*
 #pragma	varargck	type	"P"	Prog*
 #pragma	varargck	type	"R"	int
+#pragma	varargck	type	"R"	uint
 #pragma	varargck	type	"S"	char*
 
 #pragma	varargck	argpos	diag 1
@@ -270,7 +272,7 @@ EXTERN	int	dtype;
 EXTERN	Adr*	reloca;
 EXTERN	int	doexp, dlm;
 EXTERN	int	imports, nimports;
-EXTERN	int	exports, nexports;
+EXTERN	int	exports, nexports, allexport;
 EXTERN	char*	EXPTAB;
 EXTERN	Prog	undefp;
 
@@ -345,3 +347,8 @@ void	xdefine(char*, int, long);
 void	xfol(Prog*);
 int	zaddr(uchar*, Adr*, Sym*[]);
 void	zerosig(char*);
+
+#pragma	varargck	type	"D"	Adr*
+#pragma	varargck	type	"P"	Prog*
+#pragma	varargck	type	"R"	int
+#pragma	varargck	type	"A"	int

+ 22 - 22
sys/src/cmd/8l/list.c

@@ -24,18 +24,18 @@ Pconv(Fmt *fp)
 	switch(p->as) {
 	case ATEXT:
 		if(p->from.scale) {
-			sprint(str, "(%ld)	%A	%D,%d,%D",
+			snprint(str, sizeof(str), "(%ld)	%A	%D,%d,%D",
 				p->line, p->as, &p->from, p->from.scale, &p->to);
 			break;
 		}
 	default:
-		sprint(str, "(%ld)	%A	%D,%D",
+		snprint(str, sizeof(str), "(%ld)	%A	%D,%D",
 			p->line, p->as, &p->from, &p->to);
 		break;
 	case ADATA:
 	case AINIT:
 	case ADYNT:
-		sprint(str, "(%ld)	%A	%D/%d,%D",
+		snprint(str, sizeof(str), "(%ld)	%A	%D/%d,%D",
 			p->line, p->as, &p->from, p->from.scale, &p->to);
 		break;
 	}
@@ -55,7 +55,7 @@ Aconv(Fmt *fp)
 int
 Dconv(Fmt *fp)
 {
-	char str[40], s[20];
+	char str[STRINGSZ+40], s[20];
 	Adr *a;
 	int i;
 
@@ -63,15 +63,15 @@ Dconv(Fmt *fp)
 	i = a->type;
 	if(i >= D_INDIR) {
 		if(a->offset)
-			sprint(str, "%ld(%R)", a->offset, i-D_INDIR);
+			snprint(str, sizeof(str), "%ld(%R)", a->offset, i-D_INDIR);
 		else
-			sprint(str, "(%R)", i-D_INDIR);
+			snprint(str, sizeof(str), "(%R)", i-D_INDIR);
 		goto brk;
 	}
 	switch(i) {
 
 	default:
-		sprint(str, "%R", i);
+		snprint(str, sizeof(str), "%R", i);
 		break;
 
 	case D_NONE:
@@ -81,57 +81,57 @@ Dconv(Fmt *fp)
 	case D_BRANCH:
 		if(bigP != P && bigP->pcond != P)
 			if(a->sym != S)
-				sprint(str, "%lux+%s", bigP->pcond->pc,
+				snprint(str, sizeof(str), "%lux+%s", bigP->pcond->pc,
 					a->sym->name);
 			else
-				sprint(str, "%lux", bigP->pcond->pc);
+				snprint(str, sizeof(str), "%lux", bigP->pcond->pc);
 		else
-			sprint(str, "%ld(PC)", a->offset);
+			snprint(str, sizeof(str), "%ld(PC)", a->offset);
 		break;
 
 	case D_EXTERN:
-		sprint(str, "%s+%ld(SB)", a->sym->name, a->offset);
+		snprint(str, sizeof(str), "%s+%ld(SB)", a->sym->name, a->offset);
 		break;
 
 	case D_STATIC:
-		sprint(str, "%s<%d>+%ld(SB)", a->sym->name,
+		snprint(str, sizeof(str), "%s<%d>+%ld(SB)", a->sym->name,
 			a->sym->version, a->offset);
 		break;
 
 	case D_AUTO:
-		sprint(str, "%s+%ld(SP)", a->sym->name, a->offset);
+		snprint(str, sizeof(str), "%s+%ld(SP)", a->sym->name, a->offset);
 		break;
 
 	case D_PARAM:
 		if(a->sym)
-			sprint(str, "%s+%ld(FP)", a->sym->name, a->offset);
+			snprint(str, sizeof(str), "%s+%ld(FP)", a->sym->name, a->offset);
 		else
-			sprint(str, "%ld(FP)", a->offset);
+			snprint(str, sizeof(str), "%ld(FP)", a->offset);
 		break;
 
 	case D_CONST:
-		sprint(str, "$%ld", a->offset);
+		snprint(str, sizeof(str), "$%ld", a->offset);
 		break;
 
 	case D_FCONST:
-		sprint(str, "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l);
+		snprint(str, sizeof(str), "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l);
 		break;
 
 	case D_SCONST:
-		sprint(str, "$\"%S\"", a->scon);
+		snprint(str, sizeof(str), "$\"%S\"", a->scon);
 		break;
 
 	case D_ADDR:
 		a->type = a->index;
 		a->index = D_NONE;
-		sprint(str, "$%D", a);
+		snprint(str, sizeof(str), "$%D", a);
 		a->index = a->type;
 		a->type = D_ADDR;
 		goto conv;
 	}
 brk:
 	if(a->index != D_NONE) {
-		sprint(s, "(%R*%d)", a->index, a->scale);
+		snprint(s, sizeof(s), "(%R*%d)", a->index, a->scale);
 		strcat(str, s);
 	}
 conv:
@@ -218,9 +218,9 @@ Rconv(Fmt *fp)
 
 	r = va_arg(fp->args, int);
 	if(r >= D_AL && r <= D_NONE)
-		sprint(str, "%s", regstr[r-D_AL]);
+		snprint(str, sizeof(str), "%s", regstr[r-D_AL]);
 	else
-		sprint(str, "gok(%d)", r);
+		snprint(str, sizeof(str), "gok(%d)", r);
 
 	return fmtstrcpy(fp, str);
 }

+ 7 - 2
sys/src/cmd/8l/obj.c

@@ -95,8 +95,13 @@ main(int argc, char *argv[])
 		break;
 	case 'x':	/* produce export table */
 		doexp = 1;
-		if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1]))
-			readundefs(ARGF(), SEXPORT);
+		if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1])){
+			a = ARGF();
+			if(strcmp(a, "*") == 0)
+				allexport = 1;
+			else
+				readundefs(a, SEXPORT);
+		}
 		break;
 	case 'u':	/* produce dynamically loadable module */
 		dlm = 1;

+ 3 - 3
sys/src/cmd/8l/pass.c

@@ -311,7 +311,7 @@ patch(void)
 				switch(s->type) {
 				default:
 					/* diag prints TNAME first */
-					diag("%s is undefined", s->name);
+					diag("undefined: %s", s->name);
 					s->type = STEXT;
 					s->value = vexit;
 					break;	/* or fall through to set offset? */
@@ -678,14 +678,14 @@ export(void)
 	n = 0;
 	for(i = 0; i < NHASH; i++)
 		for(s = hash[i]; s != S; s = s->link)
-			if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT))
+			if(s->type != SXREF && s->type != SUNDEF && (nexports == 0 && s->sig != 0 || s->subtype == SEXPORT || allexport))
 				n++;
 	esyms = malloc(n*sizeof(Sym*));
 	ne = n;
 	n = 0;
 	for(i = 0; i < NHASH; i++)
 		for(s = hash[i]; s != S; s = s->link)
-			if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT))
+			if(s->type != SXREF && s->type != SUNDEF && (nexports == 0 && s->sig != 0 || s->subtype == SEXPORT || allexport))
 				esyms[n++] = s;
 	for(i = 0; i < ne-1; i++)
 		for(j = i+1; j < ne; j++)

+ 30 - 2
sys/src/cmd/8l/span.c

@@ -303,6 +303,24 @@ asmlc(void)
 	Bflush(&bso);
 }
 
+int
+prefixof(Adr *a)
+{
+	switch(a->type) {
+	case D_INDIR+D_CS:
+		return 0x2e;
+	case D_INDIR+D_DS:
+		return 0x3e;
+	case D_INDIR+D_ES:
+		return 0x26;
+	case D_INDIR+D_FS:
+		return 0x64;
+	case D_INDIR+D_GS:
+		return 0x65;
+	}
+	return 0;
+}
+
 int
 oclass(Adr *a)
 {
@@ -334,6 +352,8 @@ oclass(Adr *a)
 		return Yax;
 
 	case D_CL:
+		return Ycl;
+
 	case D_DL:
 	case D_BL:
 	case D_AH:
@@ -606,7 +626,7 @@ asmand(Adr *a, int r)
 	}
 	if(t >= D_INDIR) {
 		t -= D_INDIR;
-		if(t == D_NONE) {
+		if(t == D_NONE || D_CS <= t && t <= D_GS) {
 			*andptr++ = (0 << 6) | (5 << 0) | (r << 3);
 			put4(v);
 			return;
@@ -767,6 +787,7 @@ uchar	ymovtab[] =
 	ASHRL,	Ycol,	Yml,	6,	0xac,0xad,0,0,
 
 /* extra imul */
+	AIMULW,	Yml,	Yrl,	7,	Pq,0xaf,0,0,
 	AIMULL,	Yml,	Yrl,	7,	Pm,0xaf,0,0,
 	0
 };
@@ -821,7 +842,14 @@ doasm(Prog *p)
 	Prog *q, pp;
 	uchar *t;
 	int z, op, ft, tt;
-	long v;
+	long v, pre;
+
+	pre = prefixof(&p->from);
+	if(pre)
+		*andptr++ = pre;
+	pre = prefixof(&p->to);
+	if(pre)
+		*andptr++ = pre;
 
 	o = &optab[p->as];
 	ft = oclass(&p->from) * Ymax;