From c13d386ab5a3801203cd6b7e8ead1c2eff49524b Mon Sep 17 00:00:00 2001 From: Giacomo Tesio Date: Tue, 20 Jun 2017 01:02:18 +0200 Subject: [PATCH] libaml: import 9front's improvements --- sys/include/aml.h | 1 + sys/src/lib/aml/aml.c | 118 +++++++++++++++++++++++++++++++++++------- 2 files changed, 99 insertions(+), 20 deletions(-) diff --git a/sys/include/aml.h b/sys/include/aml.h index ef4f6bd..46d86de 100644 --- a/sys/include/aml.h +++ b/sys/include/aml.h @@ -36,6 +36,7 @@ void amldrop(void *); void* amlroot; int amldebug; +uint64_t amlintmask; #pragma varargck type "V" void* #pragma varargck type "N" void* diff --git a/sys/src/lib/aml/aml.c b/sys/src/lib/aml/aml.c index 6eecbac..d78035d 100644 --- a/sys/src/lib/aml/aml.c +++ b/sys/src/lib/aml/aml.c @@ -17,7 +17,7 @@ typedef struct Op Op; struct Heap { Heap *link; - short size; + int size; uint8_t mark; char tag; }; @@ -139,16 +139,17 @@ enum { Obad, Onop, Odebug, Ostr, Obyte, Oword, Odword, Oqword, Oconst, Onamec, Oname, Oscope, Oalias, - Oreg, Ofld, Oxfld, Opkg, Ovpkg, Oenv, Obuf, Omet, + Oreg, Ofld, Oxfld, Obfld, Opkg, Ovpkg, Oenv, Obuf, Omet, Odev, Ocpu, Othz, Oprc, Oadd, Osub, Omod, Omul, Odiv, Oshl, Oshr, Oand, Onand, Oor, Onor, Oxor, Onot, Olbit, Orbit, Oinc, Odec, Oland, Olor, Olnot, Oleq, Olgt, Ollt, - Oindex, Omutex, Oevent, + Oindex, Omatch, Omutex, Oevent, Ocfld, Ocfld0, Ocfld1, Ocfld2, Ocfld4, Ocfld8, Oif, Oelse, Owhile, Obreak, Oret, Ocall, Ostore, Oderef, Osize, Oref, Ocref, Ocat, Oacq, Orel, Ostall, Osleep, Oload, Ounload, + Otoint, }; static Op optab[]; @@ -281,6 +282,7 @@ mk(int tag, int size) int a; a = sizeof(Heap) + size; + assert(a >= 0); h = amlalloc(a); h->size = size; h->tag = tag; @@ -295,7 +297,7 @@ mki(uint64_t i) uint64_t *v; v = mk('i', sizeof(uint64_t)); - *v = i; + *v = i & amlintmask; return v; } @@ -392,6 +394,9 @@ getname(Name *dot, char *path, int new) int i, s; Name *x; + if(dot == nil) + return nil; + s = !new; if(*path == '\\'){ path++; @@ -1155,7 +1160,7 @@ evalconst(void) case 0x01: return mki(1); case 0xFF: - return mki(-1); + return mki(~0ULL); } return nil; } @@ -1334,6 +1339,12 @@ evalfield(void) goto Out; flags = ival(FP->arg[2]); break; + case Obfld: + df = deref(FP->arg[1]); + if(df == nil || TAG(df) != 'f') + goto Out; + flags = ival(FP->arg[3]); + break; } p = PC; if(p >= FP->end) @@ -1373,6 +1384,12 @@ evalfield(void) f->indexv = mki((bitoff/(wa*8))*wa); f->index = FP->arg[0]; break; + case Obfld: + f->reg = FP->arg[0]; + f->bitoff = bitoff; + f->indexv = FP->arg[2]; + f->index = df; + break; } bitoff += n; d->v = f; @@ -1442,14 +1459,12 @@ evalcond(void) return nil; } -static void* -evalcmp(void) +static int64_t +cmp1(void *a, void *b) { - void *a, *b; - int tag, c; + int64_t c; + int tag; - a = FP->arg[0]; - b = FP->arg[1]; if(a == nil || TAG(a) == 'i'){ c = ival(a) - ival(b); } else { @@ -1457,20 +1472,27 @@ evalcmp(void) if(b == nil || TAG(b) != tag) b = copy(tag, b); if(TAG(b) != tag) - return nil; /* botch */ + return -1; /* botch */ switch(tag){ default: - return nil; /* botch */ + return -1; /* botch */ case 's': c = strcmp((char*)a, (char*)b); break; case 'b': - if((c = SIZE(a) - SIZE(b)) == 0) + c = SIZE(a) - SIZE(b); + if(c == 0) c = memcmp(a, b, SIZE(a)); break; } } + return c; +} +static void* +evalcmp(void) +{ + int64_t c = cmp1(FP->arg[0], FP->arg[1]); switch(FP->op - optab){ case Oleq: if(c == 0) return mki(1); @@ -1613,7 +1635,7 @@ evalindex(void) Field *f; void *p; Ref *r; - int x; + uint64_t x; x = ival(FP->arg[1]); if(p = deref(FP->arg[0])) switch(TAG(p)){ @@ -1622,7 +1644,7 @@ evalindex(void) break; /* no break */ case 'b': - if(x < 0 || x >= SIZE(p)) + if(x >= SIZE(p)) break; f = mk('u', sizeof(Field)); f->reg = p; @@ -1631,7 +1653,7 @@ evalindex(void) store(f, FP->arg[2]); return f; case 'p': - if(x < 0 || x >= (SIZE(p)/sizeof(void*))) + if(x >= (SIZE(p)/sizeof(void*))) break; if(TAG(FP->arg[0]) == 'A' || TAG(FP->arg[0]) == 'L') r = mk(TAG(FP->arg[0]), sizeof(Ref)); @@ -1645,6 +1667,37 @@ evalindex(void) return nil; } +static int +match1(int op, void *a, void *b) +{ + int64_t c = cmp1(a, b); + switch(op){ + case 0: return 1; + case 1: return c == 0; + case 2: return c <= 0; + case 3: return c < 0; + case 4: return c >= 0; + case 5: return c > 0; + } + return 0; +} + +static void* +evalmatch(void) +{ + void **p = FP->arg[0]; + if(p != nil && TAG(p) == 'p'){ + uint64_t i, n = SIZE(p)/sizeof(void*); + int o1 = ival(FP->arg[1]), o2 = ival(FP->arg[3]); + for(i=ival(FP->arg[5]); iarg[2]) && match1(o2, a, FP->arg[4])) + return mki(i); + } + } + return mki(~0ULL); +} + static void* evalcondref(void) { @@ -1835,6 +1888,24 @@ evalsleep(void) return nil; } +static void* +evalconv(void) +{ + void *r; + + r = nil; + switch(FP->op - optab){ + case Otoint: + if(FP->arg[0] != nil && TAG(FP->arg[0]) == 's') + r = mki(strtoull((char*)FP->arg[0], 0, 0)); + else + r = mki(ival(FP->arg[0])); + break; + } + store(r, FP->arg[1]); + return r; +} + static Op optab[] = { [Obad] "", "", evalbad, [Onop] "Noop", "", evalnop, @@ -1861,6 +1932,7 @@ static Op optab[] = { [Oreg] "OperationRegion", "N1ii", evalreg, [Ofld] "Field", "{n1", evalfield, [Oxfld] "IndexField", "{nn1", evalfield, + [Obfld] "BankField", "{nni1", evalfield, [Ocfld] "CreateField", "*iiN", evalcfield, [Ocfld0] "CreateBitField", "*iN", evalcfield, @@ -1914,6 +1986,7 @@ static Op optab[] = { [Ostore] "Store", "*@", evalstore, [Oindex] "Index", "@i@", evalindex, + [Omatch] "Match", "*1*1*i", evalmatch, [Osize] "SizeOf", "*", evalsize, [Oref] "RefOf", "@", evaliarg0, [Ocref] "CondRefOf", "@@", evalcondref, @@ -1926,6 +1999,8 @@ static Op optab[] = { [Osleep] "Sleep", "i", evalsleep, [Oload] "Load", "*@}", evalload, [Ounload] "Unload", "@", evalnop, + + [Otoint] "ToInteger", "*@", evalconv, }; static uint8_t octab1[] = { @@ -1946,9 +2021,9 @@ static uint8_t octab1[] = { /* 70 */ Ostore, Oref, Oadd, Ocat, Osub, Oinc, Odec, Omul, /* 78 */ Odiv, Oshl, Oshr, Oand, Onand, Oor, Onor, Oxor, /* 80 */ Onot, Olbit, Orbit, Oderef, Obad, Omod, Obad, Osize, -/* 88 */ Oindex, Obad, Ocfld4, Ocfld2, Ocfld1, Ocfld0, Obad, Ocfld8, +/* 88 */ Oindex, Omatch, Ocfld4, Ocfld2, Ocfld1, Ocfld0, Obad, Ocfld8, /* 90 */ Oland, Olor, Olnot, Oleq, Olgt, Ollt, Obad, Obad, -/* 98 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad, +/* 98 */ Obad, Otoint, Obad, Obad, Obad, Obad, Obad, Obad, /* A0 */ Oif, Oelse, Owhile, Onop, Oret, Obreak, Obad, Obad, /* A8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad, /* B0 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad, @@ -1980,7 +2055,7 @@ static uint8_t octab2[] = { /* 68 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad, /* 70 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad, /* 78 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad, -/* 80 */ Oreg, Ofld, Odev, Ocpu, Oprc, Othz, Oxfld, Obad, +/* 80 */ Oreg, Ofld, Odev, Ocpu, Oprc, Othz, Oxfld, Obfld, /* 88 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad, /* 90 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad, /* 98 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad, @@ -2081,6 +2156,9 @@ amlinit(void) fmtinstall('V', Vfmt); fmtinstall('N', Nfmt); + if(!amlintmask) + amlintmask = ~0ULL; + n = mk('N', sizeof(Name)); n->up = n;