summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--all.h31
-rw-r--r--amd64/sysv.c27
-rw-r--r--parse.c62
-rw-r--r--util.c2
4 files changed, 68 insertions, 54 deletions
diff --git a/all.h b/all.h
index c0e08fe..8cbec63 100644
--- a/all.h
+++ b/all.h
@@ -26,7 +26,7 @@ typedef struct Con Con;
 typedef struct Addr Mem;
 typedef struct Fn Fn;
 typedef struct Typ Typ;
-typedef struct Seg Seg;
+typedef struct Field Field;
 typedef struct Dat Dat;
 typedef struct Target Target;
 
@@ -35,8 +35,7 @@ enum {
 	NPred   = 63,
 	NIns    = 8192,
 	NAlign  = 3,
-	NSeg    = 32,
-	NTyp    = 128,
+	NField  = 32,
 	NBit    = CHAR_BIT * sizeof(bits),
 };
 
@@ -353,18 +352,22 @@ struct Typ {
 	char name[NString];
 	int dark;
 	int align;
-	size_t size;
-	int nunion;
-	struct Seg {
+	uint64_t size;
+	uint nunion;
+	struct Field {
 		enum {
-			SEnd,
-			SPad,
-			SInt,
-			SFlt,
-			STyp,
+			FEnd,
+			Fb,
+			Fh,
+			Fw,
+			Fl,
+			Fs,
+			Fd,
+			FPad,
+			FTyp,
 		} type;
-		uint len; /* index in typ[] for Styp */
-	} (*seg)[NSeg+1];
+		uint len; /* or index in typ[] for FTyp */
+	} (*fields)[NField+1];
 };
 
 struct Dat {
@@ -404,7 +407,7 @@ typedef enum {
 	Pfn, /* discarded after processing the function */
 } Pool;
 
-extern Typ typ[NTyp];
+extern Typ *typ;
 extern Ins insb[NIns], *curi;
 void die_(char *, char *, ...) __attribute__((noreturn));
 void *emalloc(size_t);
diff --git a/amd64/sysv.c b/amd64/sysv.c
index dcaa812..ea81eee 100644
--- a/amd64/sysv.c
+++ b/amd64/sysv.c
@@ -19,32 +19,37 @@ struct RAlloc {
 static void
 classify(AClass *a, Typ *t, int *pn, int *pe)
 {
-	Seg *seg;
-	int n, s, *cls;
+	Field *fld;
+	int s, *cls;
+	uint n;
 
 	for (n=0; n<t->nunion; n++) {
-		seg = t->seg[n];
+		fld = t->fields[n];
 		for (s=0; *pe<2; (*pe)++) {
 			cls = &a->cls[*pe];
 			for (; *pn<8; s++) {
-				switch (seg[s].type) {
-				case SEnd:
+				switch (fld[s].type) {
+				case FEnd:
 					goto Done;
-				case SPad:
+				case FPad:
 					/* don't change anything */
 					break;
-				case SFlt:
+				case Fs:
+				case Fd:
 					if (*cls == Kx)
 						*cls = Kd;
 					break;
-				case SInt:
+				case Fb:
+				case Fh:
+				case Fw:
+				case Fl:
 					*cls = Kl;
 					break;
-				case STyp:
-					classify(a, &typ[seg[s].len], pn, pe);
+				case FTyp:
+					classify(a, &typ[fld[s].len], pn, pe);
 					continue;
 				}
-				*pn += seg[s].len;
+				*pn += fld[s].len;
 			}
 		Done:
 			assert(*pn <= 8);
diff --git a/parse.c b/parse.c
index 69bd74e..81cbe9e 100644
--- a/parse.c
+++ b/parse.c
@@ -128,7 +128,7 @@ static Blk **blink;
 static Blk *blkh[BMask+1];
 static int nblk;
 static int rcls;
-static int ntyp;
+static uint ntyp;
 
 void
 err(char *s, ...)
@@ -827,27 +827,27 @@ parsefn(int export)
 }
 
 static void
-parseseg(Seg *seg, Typ *ty, int t)
+parsefields(Field *fld, Typ *ty, int t)
 {
 	Typ *ty1;
 	int n, c, a, al, type;
-	size_t sz, s;
+	uint64_t sz, s;
 
 	n = 0;
 	sz = 0;
 	al = ty->align;
 	while (t != Trbrace) {
-		type = SInt;
+		ty1 = 0;
 		switch (t) {
 		default: err("invalid type member specifier");
-		case Td: type = SFlt;
-		case Tl: s = 8; a = 3; break;
-		case Ts: type = SFlt;
-		case Tw: s = 4; a = 2; break;
-		case Th: s = 2; a = 1; break;
-		case Tb: s = 1; a = 0; break;
+		case Td: type = Fd; s = 8; a = 3; break;
+		case Tl: type = Fl; s = 8; a = 3; break;
+		case Ts: type = Fs; s = 4; a = 2; break;
+		case Tw: type = Fw; s = 4; a = 2; break;
+		case Th: type = Fh; s = 2; a = 1; break;
+		case Tb: type = Fb; s = 1; a = 0; break;
 		case Ttyp:
-			type = STyp;
+			type = FTyp;
 			ty1 = &typ[findtyp(ntyp-1)];
 			s = ty1->size;
 			a = ty1->align;
@@ -855,12 +855,13 @@ parseseg(Seg *seg, Typ *ty, int t)
 		}
 		if (a > al)
 			al = a;
-		if ((a = sz & (s-1))) {
+		a = sz & (s-1);
+		if (a) {
 			a = s - a;
-			if (n < NSeg) {
-				/* padding segment */
-				seg[n].type = SPad;
-				seg[n].len = a;
+			if (n < NField) {
+				/* padding */
+				fld[n].type = FPad;
+				fld[n].len = a;
 				n++;
 			}
 		}
@@ -871,11 +872,11 @@ parseseg(Seg *seg, Typ *ty, int t)
 		} else
 			c = 1;
 		sz += a + c*s;
-		if (type == STyp)
+		if (type == FTyp)
 			s = ty1 - typ;
-		for (; c>0 && n<NSeg; c--, n++) {
-			seg[n].type = type;
-			seg[n].len = s;
+		for (; c>0 && n<NField; c--, n++) {
+			fld[n].type = type;
+			fld[n].len = s;
 		}
 		if (t != Tcomma)
 			break;
@@ -883,7 +884,7 @@ parseseg(Seg *seg, Typ *ty, int t)
 	}
 	if (t != Trbrace)
 		err(", or } expected");
-	seg[n].type = SEnd;
+	fld[n].type = FEnd;
 	a = 1 << al;
 	if (sz < ty->size)
 		sz = ty->size;
@@ -895,10 +896,14 @@ static void
 parsetyp()
 {
 	Typ *ty;
-	int t, n, al;
+	int t, al;
+	uint n;
 
-	if (ntyp >= NTyp)
-		err("too many type definitions");
+	/* be careful if extending the syntax
+	 * to handle nested types, any pointer
+	 * held to typ[] might be invalidated!
+	 */
+	vgrow(&typ, ntyp+1);
 	ty = &typ[ntyp++];
 	ty->dark = 0;
 	ty->align = -1;
@@ -928,17 +933,17 @@ parsetyp()
 		return;
 	}
 	n = 0;
-	ty->seg = vnew(1, sizeof ty->seg[0], Pheap);
+	ty->fields = vnew(1, sizeof ty->fields[0], Pheap);
 	if (t == Tlbrace)
 		do {
 			if (t != Tlbrace)
 				err("invalid union member");
-			vgrow(&ty->seg, n+1);
-			parseseg(ty->seg[n++], ty, nextnl());
+			vgrow(&ty->fields, n+1);
+			parsefields(ty->fields[n++], ty, nextnl());
 			t = nextnl();
 		} while (t != Trbrace);
 	else
-		parseseg(ty->seg[n++], ty, t);
+		parsefields(ty->fields[n++], ty, t);
 	ty->nunion = n;
 }
 
@@ -1049,6 +1054,7 @@ parse(FILE *f, char *path, void data(Dat *), void func(Fn *))
 	lnum = 1;
 	thead = Txxx;
 	ntyp = 0;
+	typ = vnew(0, sizeof typ[0], Pheap);
 	for (;;) {
 		export = 0;
 		switch (nextnl()) {
diff --git a/util.c b/util.c
index aae1481..4144f87 100644
--- a/util.c
+++ b/util.c
@@ -22,7 +22,7 @@ enum {
 	NPtr = 256,
 };
 
-Typ typ[NTyp];
+Typ *typ;
 Ins insb[NIns], *curi;
 
 static void *ptr[NPtr];