commit 96836855a55cd28f1449b4a58d1e5301669350c0
parent 49a4593c335126ba279f47328824abfef379725e
Author: Quentin Carbonneaux <quentin@c9x.me>
Date: Sat, 8 Apr 2017 21:09:59 -0400
rework storage of types
The arm64 ABI needs to know precisely what
floating point types are being used, so we
need to store that information.
I also made typ[] a dynamic array.
Diffstat:
M | all.h | | | 31 | +++++++++++++++++-------------- |
M | amd64/sysv.c | | | 27 | ++++++++++++++++----------- |
M | parse.c | | | 62 | ++++++++++++++++++++++++++++++++++---------------------------- |
M | util.c | | | 2 | +- |
4 files changed, 68 insertions(+), 54 deletions(-)
diff --git 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
@@ -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
@@ -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
@@ -22,7 +22,7 @@ enum {
NPtr = 256,
};
-Typ typ[NTyp];
+Typ *typ;
Ins insb[NIns], *curi;
static void *ptr[NPtr];