shithub: riscv

Download patch

ref: e3df6c863d559cfdc50b3108de9813dd926bb109
parent: c3025ce1302e58f077d85da4662509d0d085b0fd
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Tue Sep 5 17:58:03 EDT 2023

7l: do a single pass to produce data segment instead of doing it in chunks

--- a/sys/src/cmd/7l/asm.c
+++ b/sys/src/cmd/7l/asm.c
@@ -45,9 +45,10 @@
 asmb(void)
 {
 	Prog *p;
-	long magic, t, etext;
+	long magic, etext;
 	vlong vl;
 	Optab *o;
+	uchar *sbuf, *dbuf;
 
 	if(debug['v'])
 		Bprint(&bso, "%5.2f asm\n", cputime());
@@ -59,8 +60,7 @@
 		if(p->as == ATEXT) {
 			curtext = p;
 			autosize = p->to.offset + PCSZ;
-		}
-		if(p->as == ADWORD && (pc & 7) != 0) {
+		}else if(p->as == ADWORD && (pc & 7) != 0) {
 			lputl(0);
 			pc += 4;
 		}
@@ -84,12 +84,11 @@
 
 	/* output strings in text segment */
 	etext = INITTEXT + textsize;
-	for(t = pc; t < etext; t += sizeof(buf)-100) {
-		if(etext-t > sizeof(buf)-100)
-			datblk(t, sizeof(buf)-100, 1);
-		else
-			datblk(t, etext-t, 1);
-	}
+	sbuf = calloc(1, etext-pc);
+	dbuf = calloc(1, datsize);
+	datfill(sbuf, pc, dbuf, 0);
+	write(cout, sbuf, etext-pc);
+	free(sbuf);
 
 	curtext = P;
 	switch(HEADTYPE) {
@@ -110,12 +109,8 @@
 		write(cout, buf, INITDAT-textsize);
 		textsize = INITDAT;
 	}
-	for(t = 0; t < datsize; t += sizeof(buf)-100) {
-		if(datsize-t > sizeof(buf)-100)
-			datblk(t, sizeof(buf)-100, 0);
-		else
-			datblk(t, datsize-t, 0);
-	}
+	write(cout, dbuf, datsize);
+	free(dbuf);
 
 	symsize = 0;
 	lcsize = 0;
@@ -465,75 +460,63 @@
 }
 
 void
-datblk(long s, long n, int str)
+datfill(uchar *sbuf, long soff, uchar *dbuf, long doff)
 {
 	Sym *v;
 	Prog *p;
-	char *cast;
+	uchar *cast, *b, *nuxi;
 	long a, l, fl, j;
 	vlong d;
 	int i, c;
 
-	memset(buf.dbuf, 0, n+100);
 	for(p = datap; p != P; p = p->link) {
-		if(str != (p->from.sym->type == SSTRING))
-			continue;
 		curp = p;
 		a = p->from.sym->value + p->from.offset;
-		l = a - s;
+		l = a;
+		if(p->from.sym->type == SSTRING){
+			b = sbuf;
+			l -= soff;
+		}else{
+			b = dbuf;
+			l -= doff;
+		}
+
 		c = p->reg;
 		i = 0;
-		if(l < 0) {
-			if(l+c <= 0)
-				continue;
-			while(l < 0) {
-				l++;
-				i++;
-			}
-		}
-		if(l >= n)
-			continue;
 		if(p->as != AINIT && p->as != ADYNT && !p->from.sym->dupok) {
 			for(j=l+(c-i)-1; j>=l; j--)
-				if(buf.dbuf[j]) {
+				if(b[j]) {
 					print("%P\n", p);
 					diag("multiple initialization");
 					break;
 				}
 		}
+		cast = nuxi = nil;
 		switch(p->to.type) {
 		default:
 			diag("unknown mode in initialization%P", p);
 			break;
 
+		case D_SCONST:
+			while(i < c)
+				b[l++] = p->to.sval[i++];
+			break;
+
 		case D_FCONST:
 			switch(c) {
 			default:
 			case 4:
 				fl = ieeedtof(p->to.ieee);
-				cast = (char*)&fl;
-				for(; i<c; i++) {
-					buf.dbuf[l] = cast[fnuxi4[i]];
-					l++;
-				}
+				cast = (uchar*)&fl;
+				nuxi = fnuxi4;
 				break;
 			case 8:
-				cast = (char*)p->to.ieee;
-				for(; i<c; i++) {
-					buf.dbuf[l] = cast[fnuxi8[i]];
-					l++;
-				}
+				cast = (uchar*)p->to.ieee;
+				nuxi = fnuxi8;
 				break;
 			}
 			break;
 
-		case D_SCONST:
-			for(; i<c; i++) {
-				buf.dbuf[l] = p->to.sval[i];
-				l++;
-			}
-			break;
-
 		case D_CONST:
 			d = p->to.offset;
 			v = p->to.sym;
@@ -553,40 +536,14 @@
 				if(dlm)
 					dynreloc(v, a+INITDAT, 1);
 			}
-			cast = (char*)&d;
-			switch(c) {
-			default:
-				diag("bad nuxi %d %d%P", c, i, curp);
-				break;
-			case 1:
-				for(; i<c; i++) {
-					buf.dbuf[l] = cast[inuxi1[i]];
-					l++;
-				}
-				break;
-			case 2:
-				for(; i<c; i++) {
-					buf.dbuf[l] = cast[inuxi2[i]];
-					l++;
-				}
-				break;
-			case 4:
-				for(; i<c; i++) {
-					buf.dbuf[l] = cast[inuxi4[i]];
-					l++;
-				}
-				break;
-			case 8:
-				for(; i<c; i++) {
-					buf.dbuf[l] = cast[inuxi8[i]];
-					l++;
-				}
-				break;
-			}
+			cast = (uchar*)&d;
+			nuxi = inuxi[c];
 			break;
 		}
+		if(cast)
+			while(i < c)
+				b[l++] = cast[nuxi[i++]];
 	}
-	write(cout, buf.dbuf, n);
 }
 
 int
--- a/sys/src/cmd/7l/l.h
+++ b/sys/src/cmd/7l/l.h
@@ -242,18 +242,14 @@
 	MAXHIST		= 20,	/* limit of path elements for history symbols */
 };
 
-EXTERN union
+EXTERN struct
 {
-	struct
-	{
-		uchar	obuf[MAXIO];			/* output buffer */
-		uchar	ibuf[MAXIO];			/* input buffer */
-	} u;
-	char	dbuf[1];
+	uchar	obuf[MAXIO];			/* output buffer */
+	uchar	ibuf[MAXIO];			/* input buffer */
 } buf;
 
-#define	cbuf	u.obuf
-#define	xbuf	u.ibuf
+#define	cbuf	obuf
+#define	xbuf	ibuf
 
 EXTERN	long	HEADR;			/* length of header */
 EXTERN	int	HEADTYPE;		/* type of header */
@@ -278,12 +274,9 @@
 EXTERN	Prog*	etextp;
 EXTERN	Prog*	firstp;
 
-EXTERN	char	fnuxi4[4];
-EXTERN	char	fnuxi8[8];
-EXTERN	char	inuxi1[1];
-EXTERN	char	inuxi2[2];
-EXTERN	char	inuxi4[4];
-EXTERN	uchar	inuxi8[8];
+EXTERN	uchar	fnuxi4[4];
+EXTERN	uchar	fnuxi8[8];
+EXTERN	uchar	inuxi[9][8];
 
 EXTERN	Sym*	hash[NHASH];
 EXTERN	Sym*	histfrog[MAXHIST];
@@ -363,7 +356,7 @@
 int	cmp(int, int);
 int	compound(Prog*);
 void	cput(int);
-void	datblk(long, long, int);
+void	datfill(uchar*, long, uchar*, long);
 void	diag(char*, ...);
 void	dodata(void);
 void	doprof1(void);
--- a/sys/src/cmd/7l/obj.c
+++ b/sys/src/cmd/7l/obj.c
@@ -1360,13 +1360,13 @@
 	for(i=0; i<4; i++) {
 		c = find1(0x04030201L, i+1);
 		if(i < 2)
-			inuxi2[i] = c;
+			inuxi[2][i] = c;
 		if(i < 1)
-			inuxi1[i] = c;
-		inuxi4[i] = c;
+			inuxi[1][i] = c;
+		inuxi[4][i] = c;
 		fnuxi4[i] = c;
-		inuxi8[i] = c;
-		inuxi8[i+4] = c+4;
+		inuxi[8][i] = c;
+		inuxi[8][i+4] = c+4;
 		fnuxi8[i] = c;
 		fnuxi8[i+4] = c+4;
 	}
@@ -1373,16 +1373,16 @@
 	if(debug['v']) {
 		Bprint(&bso, "inuxi = ");
 		for(i=0; i<1; i++)
-			Bprint(&bso, "%d", inuxi1[i]);
+			Bprint(&bso, "%d", inuxi[1][i]);
 		Bprint(&bso, " ");
 		for(i=0; i<2; i++)
-			Bprint(&bso, "%d", inuxi2[i]);
+			Bprint(&bso, "%d", inuxi[2][i]);
 		Bprint(&bso, " ");
 		for(i=0; i<4; i++)
-			Bprint(&bso, "%d", inuxi4[i]);
+			Bprint(&bso, "%d", inuxi[4][i]);
 		Bprint(&bso, " ");
 		for(i=0; i<8; i++)
-			Bprint(&bso, "%d", inuxi8[i]);
+			Bprint(&bso, "%d", inuxi[8][i]);
 		Bprint(&bso, "\nfnuxi = ");
 		for(i=0; i<4; i++)
 			Bprint(&bso, "%d", fnuxi4[i]);