libaml: import 9front's improvements
This commit is contained in:
parent
83e3161789
commit
c13d386ab5
|
@ -36,6 +36,7 @@ void amldrop(void *);
|
|||
|
||||
void* amlroot;
|
||||
int amldebug;
|
||||
uint64_t amlintmask;
|
||||
|
||||
#pragma varargck type "V" void*
|
||||
#pragma varargck type "N" void*
|
||||
|
|
|
@ -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]); i<n; i++){
|
||||
void *a = deref(p[i]);
|
||||
if(match1(o1, a, FP->arg[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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue