diff options
author | Quentin Carbonneaux <quentin@c9x.me> | 2017-04-08 21:09:59 -0400 |
---|---|---|
committer | Quentin Carbonneaux <quentin@c9x.me> | 2017-04-08 21:57:05 -0400 |
commit | 96836855a55cd28f1449b4a58d1e5301669350c0 (patch) | |
tree | 3b0688d1b63f528d41edba87232e5469d95d08cb | |
parent | 49a4593c335126ba279f47328824abfef379725e (diff) | |
download | roux-96836855a55cd28f1449b4a58d1e5301669350c0.tar.gz |
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.
-rw-r--r-- | all.h | 31 | ||||
-rw-r--r-- | amd64/sysv.c | 27 | ||||
-rw-r--r-- | parse.c | 62 | ||||
-rw-r--r-- | util.c | 2 |
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]; |