5 typedef struct Interp Interp;
6 typedef struct Frame Frame;
7 typedef struct Heap Heap;
9 typedef struct Method Method;
10 typedef struct Region Region;
11 typedef struct Field Field;
13 typedef struct Name Name;
14 typedef struct Ref Ref;
15 typedef struct Env Env;
25 #define H2D(h) (((Heap*)(h))+1)
26 #define D2H(d) (((Heap*)(d))-1)
27 #define TAG(d) D2H(d)->tag
28 #define SIZE(d) D2H(d)->size
30 static char *spacename[] = {
73 void *reg; /* Buffer or Region or data Field */
74 void *bank; /* bank value */
75 Field *index; /* bank or index Field */
129 static Interp interp;
130 static Frame stack[32];
137 #define FT &stack[nelem(stack)]
143 Ostr, Obyte, Oword, Odword, Oqword, Oconst,
144 Onamec, Oname, Oscope, Oalias,
145 Oreg, Ofld, Oxfld, Obfld, Opkg, Ovpkg, Oenv, Obuf, Omet,
146 Odev, Ocpu, Othz, Oprc,
147 Oadd, Osub, Omod, Omul, Odiv, Oshl, Oshr, Oand, Onand, Oor,
148 Onor, Oxor, Onot, Olbit, Orbit, Oinc, Odec,
149 Oland, Olor, Olnot, Oleq, Olgt, Ollt,
150 Oindex, Omatch, Omutex, Oevent,
151 Ocfld, Ocfld0, Ocfld1, Ocfld2, Ocfld4, Ocfld8,
152 Oif, Oelse, Owhile, Obreak, Oret, Ocall,
153 Ostore, Oderef, Osize, Oref, Ocref, Ocat,
154 Oacq, Osignal, Orel, Ostall, Osleep, Oload, Ounload,
155 Otodec, Otohex, Otoint,
159 static uchar octab1[];
160 static uchar octab2[];
165 while(dot != dot->up)
188 for(i=0; i<nelem(e->loc); i++)
190 for(i=0; i<nelem(e->arg); i++)
196 gcmark(((Ref*)p)->ref);
201 for(d = n->down; d; d = d->next)
207 for(i=0; i<(SIZE(p)/sizeof(void*)); i++)
208 gcmark(((void**)p)[i]);
211 gcmark(((Region*)p)->name);
214 gcmark(((Method*)p)->name);
233 for(h = hp; h; h = h->link)
236 for(h = hp; h; h = h->link)
240 for(f = FP; f >= F0; f--){
241 for(i=0; i<f->narg; i++)
259 Region *r = (void*)H2D(h);
262 print("\namlunmapio(%N): %-8s %llux - %llux\n",
263 (Name*)r->name, spacename[r->space],
264 r->off, r->off + r->len);
273 memset(h, ~0, sizeof(Heap)+h->size);
282 mk(int tag, int size)
287 a = sizeof(Heap) + size;
302 v = mk('i', sizeof(uvlong));
310 char *r = mk('s', strlen(s)+1);
316 pkglen(uchar *p, uchar *e, uchar **np)
352 n = mk('N', sizeof(Name));
355 n->next = n->down = nil;
361 if(n->up = forkname(dot->up))
368 getseg(Name *dot, void *seg, int new)
372 for(n = l = nil; dot; dot = dot->fork){
373 for(n = dot->down; n; n = n->next){
374 if(memcmp(seg, n->seg, 4) == 0)
379 n = mk('N', sizeof(Name));
380 memmove(n->seg, seg, sizeof(n->seg));
394 getname(Name *dot, char *path, int new)
416 if(*path == 0 || *path == '.')
426 if(x = getseg(dot, seg, 0))
435 dot = getseg(dot, seg, new);
436 } while(*path++ == '.');
442 fixnames(void *dot, void *arg)
448 r = &((Name*)dot)->v;
452 if(v == nil || v == dot)
456 for(i=0; i<(SIZE(r)/sizeof(void*)); i++)
460 if(TAG(v) == 'n' && (v = getname(dot, v, 0)) != nil)
466 getle(uchar *p, int len)
473 v |= ((uvlong)p[i]) << i*8;
478 putle(uchar *p, int len, uvlong v)
482 for(i=0; i<len; i++){
489 rwreg(void *reg, int off, int len, uvlong v, int write)
495 save = interp; /* save, in case we reenter the interpreter */
496 FB = FP+1; /* allocate new base */
501 if((off+len) > SIZE(p))
512 if((off+len) > r->len)
516 print("\namlmapio(%N): %-8s %llux - %llux\n",
517 (Name*)r->name, spacename[r->space],
518 r->off, r->off + r->len);
529 if(len > sizeof(buf))
536 print("\nrwreg(%N): %-8s [%llux+%x]/%d <- %llux\n",
537 (Name*)r->name, spacename[r->space],
538 r->off, off, len, v);
541 if((*r->write)(r, p, len, off) != len)
547 if((*r->read)(r, p, len, off) != len)
553 print("\nrwreg(%N): %-8s [%llux+%x]/%d -> %llux\n",
554 (Name*)r->name, spacename[r->space],
555 r->off, off, len, v);
562 interp = save; /* restore */
574 return *((uvlong*)p);
578 return strtoull((char*)p, 0, 16);
583 return rwreg(p, 0, n, 0, 0);
590 static void *deref(void *p);
591 static void *store(void *s, void *d);
594 fieldalign(int flags)
596 switch(flags & AccMask){
611 static void *rwfield(Field *f, void *v, int write);
614 rwfieldunit(Field *f, int off, int len, uvlong v, int write)
617 if(TAG(f->reg) == 'f'){
620 /* set index field */
621 rwfield(f->index, mki(off), 1);
630 b = rwfield(f, nil, 0);
637 rwfield(f->index, f->bank, 1);
639 return rwreg(f->reg, off, len, v, write);
643 rwfield(Field *f, void *v, int write)
645 int boff, blen, wo, ws, wl, wa, wd, i;
653 if(v && TAG(v) == 'b'){
659 b = mk('b', (blen+7)/8);
660 putle(b, SIZE(b), w);
663 b = mk('b', (blen+7)/8);
664 wa = fieldalign(f->flags);
667 while((wl = (blen-boff)) > 0){
668 wo = (f->bitoff+boff) / wd;
669 ws = (f->bitoff+boff) % wd;
674 for(i = 0; i < wl; i++, boff++)
675 if(b[boff/8] & (1<<(boff%8)))
679 m = ((1ULL<<wl)-1) << ws;
680 w |= rwfieldunit(f, wo*wa, wa, 0, 0) & ~m;
682 rwfieldunit(f, wo*wa, wa, w, 1);
684 w = rwfieldunit(f, wo*wa, wa, 0, 0) >> ws;
685 for(i = 0; i < wl; i++, boff++){
686 b[boff/8] |= (w&1)<<(boff%8);
695 w = getle(b, SIZE(b));
702 if(p) switch(TAG(p)){
704 return ((Name*)p)->v;
705 case 'R': case 'A': case 'L':
706 return *((Ref*)p)->ptr;
708 return rwfield(p, nil, 0);
714 todecstr(uchar *buf, int len, int sep)
719 r = d = mk('s', len*4 + 1);
726 for(i=0; i<len; i++){
728 if((*d = '0' + ((v/100) % 10)) != '0')
730 if((*d = '0' + ((v/10) % 10)) != '0')
732 *d++ = '0' + (v % 10);
739 static char hex[] = "0123456789ABCDEF";
742 tohexstr(uchar *buf, int len, int sep)
747 r = d = mk('s', len*3 + 1);
754 for(i=0; i<len; i++){
755 *d++ = hex[buf[i] >> 4];
756 *d++ = hex[buf[i] & 0xF];
764 copy(int tag, void *s)
775 if(s == nil || TAG(s) == 'i'){
778 if(v > 0xFFFFFFFFULL)
783 rwreg(d, 0, n, v, 1);
790 ((char*)d)[--n] = hex[v & 0xF];
804 return tohexstr(s, n, ' ');
809 /* zero length string is converted to zero length buffer */
821 store(void *s, void *d)
835 while((p = *pp) != nil){
837 case 'R': case 'A': case 'L':
853 if(p != nil && TAG(p) != 'N'){
860 if(TAG(d) != 'A' && TAG(d) != 'L'){
861 *pp = copy(TAG(p), s);
876 n = va_arg(f->args, Name*);
878 return fmtprint(f, "?NIL");
880 return fmtprint(f, "\\");
881 strncpy(buf, n->seg, 4);
888 if(n->up == n->up->up)
889 return fmtprint(f, "\\%s", buf);
890 return fmtprint(f, "%N.%s", n->up, buf);
905 p = va_arg(f->args, void*);
907 return fmtprint(f, "nil");
913 return fmtprint(f, "%N=%V", nm, nm->v);
914 return fmtprint(f, "%N=*", nm);
920 return fmtprint(f, "Arg%zd=%V", r->ptr - e->arg, *r->ptr);
922 return fmtprint(f, "Local%zd=%V", r->ptr - e->loc, *r->ptr);
924 return fmtprint(f, "%s", (char*)p);
926 return fmtprint(f, "\"%s\"", (char*)p);
928 return fmtprint(f, "%#llux", *((uvlong*)p));
930 n = SIZE(p)/sizeof(void*);
931 fmtprint(f, "Package(%d){", n);
935 fmtprint(f, "%V", ((void**)p)[i]);
941 fmtprint(f, "Buffer(%d){", n);
945 fmtprint(f, "%.2uX", ((uchar*)p)[i]);
951 return fmtprint(f, "Region(%s, %#llux, %#llux)",
952 spacename[g->space & 7], g->off, g->len);
955 fmtprint(f, "%N(", m->name);
956 for(i=0; i < m->narg; i++){
959 fmtprint(f, "Arg%d", i);
964 fmtprint(f, "Buffer");
969 if(TAG(l->reg) == 'f')
970 return fmtprint(f, "IndexField(%x, %x, %x) @ %V[%V]",
971 l->flags, l->bitoff, l->bitlen, l->reg, l->index);
973 return fmtprint(f, "BankField(%x, %x, %x, %V=%V) @ %V",
974 l->flags, l->bitoff, l->bitlen, l->index, l->bank, l->reg);
976 return fmtprint(f, "Field(%x, %x, %x) @ %V",
977 l->flags, l->bitoff, l->bitlen, l->reg);
979 return fmtprint(f, "%c:%p", c, p);
990 print("\n*** dumpregs: PC=%p FP=%p\n", PC, FP);
992 for(f = FP; f >= FB; f--){
993 print("%.8p.%.2zx: %-8s %N\t", f->start, f-FB, f->phase, f->dot);
995 print("%s", f->op->name);
997 for(i=0; i<f->narg; i++){
1000 print("%V", f->arg[i]);
1006 for(i=0; i<nelem(e->arg); i++)
1007 print("Arg%d=%V ", i, e->arg[i]);
1009 for(i=0; i<nelem(e->loc); i++)
1010 print("Local%d=%V ", i, e->loc[i]);
1017 xec(uchar *pc, uchar *end, Name *dot, Env *env, void **pret)
1024 if(FB < F0 || FB >= FT)
1041 if((++loop & 127) == 0)
1044 print("\n%.8p.%.2zx %-8s\t%N\t", PC, FP - FB, FP->phase, FP->dot);
1051 print("aml: PC overrun frame end");
1056 print("aml: frame stack overflow");
1065 if(amldebug) print("%.2X", c);
1070 if(amldebug) print("%.2X", c);
1076 FP->phase = FP->op->sequence;
1077 if(amldebug) print("\t%s %s", FP->op->name, FP->phase);
1081 c = pkglen(PC, FP->end, &PC);
1083 if(c < 0 || end > FP->end)
1091 if(end = memchr(PC, 0, FP->end - PC))
1110 for(i = 8; PC < end; i += 8)
1111 *((uvlong*)r) |= ((uvlong)*PC++) << i;
1118 print("*%p,%V\t%s(", FP->aux, FP->ref, FP->op->name);
1119 for(i = 0; i < FP->narg; i++){
1122 print("%V", FP->arg[i]);
1126 for(i = FP->narg; i < nelem(FP->arg); i++)
1134 if(c == '}' && PC < FP->end){
1140 if(r) switch(FP->tag){
1149 if((r = deref(r)) == nil)
1153 r = rwfield(r, nil, 0);
1159 FP->phase = "********}" + (8 - m->narg);
1160 FP->op = &optab[Ocall];
1170 if(amldebug) print(" -> %V\n", r);
1175 FP->arg[FP->narg++] = r;
1186 static char name[1024];
1197 if(d >= &name[sizeof(name)-1]){
1200 print("aml: name too long: %s\n", name);
1209 } else if(*PC == '/'){
1212 } else if(*PC == 0){
1217 if(d >= &name[sizeof(name)-5])
1223 while((d > &name[0]) && (d[-1] == '_' || d[-1] == 0))
1229 if((r = getname(FP->dot, name, FP->tag == 'N')) == nil){
1231 D2H(r)->tag = 'n'; /* unresolved name */
1245 switch(FP->start[0]){
1260 n = ival(FP->arg[0]);
1276 if((p = FP->ref) != nil){
1278 if(x >= p && x < (p+(SIZE(p)/sizeof(void*)))){
1283 n = ival(FP->arg[0]);
1285 p = mk('p', n*sizeof(void*));
1323 n->v = deref(FP->arg[0]);
1333 if((n = FP->arg[0]) != nil){
1334 m = mk('m', sizeof(Method));
1335 m->narg = ival(FP->arg[1]) & 7;
1351 if((n = FP->arg[0]) != nil){
1352 r = mk('r', sizeof(Region));
1353 r->space = ival(FP->arg[1]);
1354 r->off = ival(FP->arg[2]);
1355 r->len = ival(FP->arg[3]);
1372 if(r == nil || (TAG(r) != 'b' && TAG(r) != 'r'))
1379 if(n == nil || TAG(n) != 'N')
1382 f = mk('u', sizeof(Field));
1384 f = mk('f', sizeof(Field));
1387 f->bitoff = ival(FP->arg[1]);
1388 f->bitlen = ival(FP->arg[2]);
1391 f->bitoff = ival(FP->arg[1]);
1398 f->bitoff = 8*ival(FP->arg[1]);
1399 f->bitlen = 8*(c - Ocfld0);
1410 int flags, bitoff, n;
1419 switch(FP->op - optab){
1423 if((reg = deref(FP->arg[0])) == nil || TAG(reg) != 'r')
1425 flags = ival(FP->arg[1]);
1428 if((index = deref(FP->arg[0])) == nil || TAG(index) != 'f')
1430 if((reg = deref(FP->arg[1])) == nil || TAG(reg) != 'f') /* data field */
1432 flags = ival(FP->arg[2]);
1435 if((reg = deref(FP->arg[0])) == nil || TAG(reg) != 'r')
1437 if((index = deref(FP->arg[1])) == nil || TAG(index) != 'f')
1440 flags = ival(FP->arg[3]);
1449 if((n = pkglen(p, FP->end, &p)) < 0)
1462 if((d = getseg(FP->dot, p, 1)) == nil)
1464 if((n = pkglen(p+4, FP->end, &p)) < 0)
1466 f = mk('f', sizeof(Field));
1492 print("aml: bad opcode %p: ", PC);
1493 for(i=0; i < 8 && (FP->start+i) < FP->end; i++){
1496 print("%.2X", FP->start[i]);
1498 if((FP->start+i) < FP->end)
1508 switch(FP->op - optab){
1512 FP[-1].cond = ival(FP->arg[0]) != 0;
1531 if(ival(FP->arg[0]) == 0){
1542 cmp1(void *a, void *b)
1547 if(a == nil || TAG(a) == 'i'){
1548 c = ival(a) - ival(b);
1551 if(b == nil || TAG(b) != tag)
1553 if(b == nil || TAG(b) != tag)
1554 return -1; /* botch */
1557 return -1; /* botch */
1559 c = strcmp((char*)a, (char*)b);
1562 c = SIZE(a) - SIZE(b);
1564 c = memcmp(a, b, SIZE(a));
1574 vlong c = cmp1(FP->arg[0], FP->arg[1]);
1575 switch(FP->op - optab){
1577 if(c == 0) return mki(1);
1580 if(c > 0) return mki(1);
1583 if(c < 0) return mki(1);
1604 e = mk('E', sizeof(Env));
1605 for(i=0; i<FP->narg; i++)
1606 e->arg[i] = deref(FP->arg[i]);
1613 return (*m->eval)();
1615 FP->dot = forkname(FP->dot);
1617 FP->start = m->start;
1626 void *r = FP->arg[0];
1627 int brk = (FP->op - optab) != Oret;
1629 switch(FP->op - optab){
1652 if((e = FP->env) == nil)
1655 if(c >= 0x60 && c <= 0x67){
1656 r = mk('L', sizeof(Ref));
1657 r->ptr = &e->loc[c - 0x60];
1658 } else if(c >= 0x68 && c <= 0x6E){
1659 r = mk('A', sizeof(Ref));
1660 r->ptr = &e->arg[c - 0x68];
1670 return store(FP->arg[0], FP->arg[1]);
1681 if(a == nil || TAG(a) == 'i')
1682 a = copy('b', a); /* Concat(Int, ???) -> Buf */
1684 if(b == nil || TAG(b) != tag)
1687 return nil; /* botch */
1690 return nil; /* botch */
1696 memmove((uchar*)r + n, b, m);
1699 n = strlen((char*)a);
1700 m = strlen((char*)b);
1701 r = mk('s', n + m + 1);
1703 memmove((char*)r + n, b, m);
1704 ((char*)r)[n+m] = 0;
1707 store(r, FP->arg[2]);
1719 x = ival(FP->arg[1]);
1720 if(p = deref(FP->arg[0])) switch(TAG(p)){
1722 if(x >= strlen((char*)p))
1728 f = mk('u', sizeof(Field));
1732 store(f, FP->arg[2]);
1735 if(x >= (SIZE(p)/sizeof(void*)))
1737 if(TAG(FP->arg[0]) == 'A' || TAG(FP->arg[0]) == 'L')
1738 r = mk(TAG(FP->arg[0]), sizeof(Ref));
1740 r = mk('R', sizeof(Ref));
1742 r->ptr = ((void**)p) + x;
1743 store(r, FP->arg[2]);
1750 match1(int op, void *a, void *b)
1752 vlong c = cmp1(a, b);
1755 case 1: return c == 0;
1756 case 2: return c <= 0;
1757 case 3: return c < 0;
1758 case 4: return c >= 0;
1759 case 5: return c > 0;
1767 void **p = FP->arg[0];
1768 if(p != nil && TAG(p) == 'p'){
1769 uvlong i, n = SIZE(p)/sizeof(void*);
1770 int o1 = ival(FP->arg[1]), o2 = ival(FP->arg[3]);
1771 for(i=ival(FP->arg[5]); i<n; i++){
1772 void *a = deref(p[i]);
1773 if(match1(o1, a, FP->arg[2]) && match1(o2, a, FP->arg[4]))
1784 if((s = FP->arg[0]) == nil)
1786 store(s, FP->arg[1]);
1793 return mki(amllen(FP->arg[0]));
1802 if(TAG(p) == 's' || TAG(p) == 'n')
1803 p = getname(FP->dot, (char*)p, 0);
1817 switch(FP->op - optab){
1819 r = mki(ival(FP->arg[0]) + ival(FP->arg[1]));
1822 r = mki(ival(FP->arg[0]) - ival(FP->arg[1]));
1825 r = mki(ival(FP->arg[0]) * ival(FP->arg[1]));
1829 v = ival(FP->arg[0]);
1830 d = ival(FP->arg[1]);
1832 print("aml: division by zero: PC=%#p\n", PC);
1836 store(r, FP->arg[2]);
1837 if((FP->op - optab) != Odiv)
1840 store(r, FP->arg[3]);
1843 r = mki(ival(FP->arg[0]) << ival(FP->arg[1]));
1846 r = mki(ival(FP->arg[0]) >> ival(FP->arg[1]));
1849 r = mki(ival(FP->arg[0]) & ival(FP->arg[1]));
1852 r = mki(~(ival(FP->arg[0]) & ival(FP->arg[1])));
1855 r = mki(ival(FP->arg[0]) | ival(FP->arg[1]));
1858 r = mki(~(ival(FP->arg[0]) | ival(FP->arg[1])));
1861 r = mki(ival(FP->arg[0]) ^ ival(FP->arg[1]));
1864 r = mki(~ival(FP->arg[0]));
1865 store(r, FP->arg[1]);
1868 v = ival(FP->arg[0]);
1871 for(i=0; (v & 1) == 0; i++)
1876 v = ival(FP->arg[0]);
1879 for(i=0; v != 0; i++)
1884 return mki(ival(FP->arg[0]) && ival(FP->arg[1]));
1886 return mki(ival(FP->arg[0]) || ival(FP->arg[1]));
1888 return mki(ival(FP->arg[0]) == 0);
1891 r = mki(ival(deref(FP->arg[0]))+1);
1892 store(r, FP->arg[0]);
1895 r = mki(ival(deref(FP->arg[0]))-1);
1896 store(r, FP->arg[0]);
1900 store(r, FP->arg[2]);
1907 enum { LenOffset = 4, HdrLen = 36 };
1915 amlenum(amlroot, nil, fixnames, nil);
1918 tid = mki(1); /* fake */
1921 store(nil, FP->arg[1]);
1922 if(FP->arg[0] == nil)
1925 l = rwreg(FP->arg[0], LenOffset, 4, 0, 0);
1929 FP->aux = PC; /* save */
1930 FP->ref = FP->arg[0];
1931 switch(TAG(FP->ref)){
1933 if(SIZE(FP->ref) < l)
1935 PC = (uchar*)FP->ref + HdrLen;
1939 if(r->len < l || r->va == nil || r->mapped <= 0)
1941 PC = (uchar*)r->va + HdrLen;
1946 FP->end = PC + (l - HdrLen);
1950 tid = mki(1); /* fake */
1951 store(tid, FP->arg[1]);
1959 amldelay(ival(FP->arg[0]));
1966 amldelay(ival(FP->arg[0])*1000);
1977 switch(FP->op - optab){
1986 r = todecstr(a, SIZE(a), ',');
1998 r = tohexstr(a, SIZE(a), ',');
2003 if(a != nil && TAG(a) == 's')
2004 r = mki(strtoull((char*)a, 0, 0));
2009 store(r, FP->arg[1]);
2013 static Op optab[] = {
2014 [Obad] "", "", evalbad,
2015 [Onop] "Noop", "", evalnop,
2016 [Odebug] "Debug", "", evalnop,
2018 [Ostr] ".str", "s", evaliarg0,
2019 [Obyte] ".byte", "1", evaliarg0,
2020 [Oword] ".word", "2", evaliarg0,
2021 [Odword] ".dword", "4", evaliarg0,
2022 [Oqword] ".qword", "8", evaliarg0,
2023 [Oconst] ".const", "", evalconst,
2024 [Onamec] ".name", "", evalnamec,
2025 [Oenv] ".env", "", evalenv,
2027 [Oname] "Name", "N*", evalname,
2028 [Oscope] "Scope", "{n}", evalscope,
2029 [Oalias] "Alias", "nN", evalalias,
2031 [Odev] "Device", "{N}", evalscope,
2032 [Ocpu] "Processor", "{N141}", evalscope,
2033 [Othz] "ThermalZone", "{N}", evalscope,
2034 [Oprc] "PowerResource", "{N12}", evalscope,
2036 [Oreg] "OperationRegion", "N1ii", evalreg,
2037 [Ofld] "Field", "{n1", evalfield,
2038 [Oxfld] "IndexField", "{nn1", evalfield,
2039 [Obfld] "BankField", "{nni1", evalfield,
2041 [Ocfld] "CreateField", "*iiN", evalcfield,
2042 [Ocfld0] "CreateBitField", "*iN", evalcfield,
2043 [Ocfld1] "CreateByteField", "*iN", evalcfield,
2044 [Ocfld2] "CreateWordField", "*iN", evalcfield,
2045 [Ocfld4] "CreateDWordField", "*iN", evalcfield,
2046 [Ocfld8] "CreateQWordField", "*iN", evalcfield,
2048 [Opkg] "Package", "{1}", evalpkg,
2049 [Ovpkg] "VarPackage", "{i}", evalpkg,
2050 [Obuf] "Buffer", "{i", evalbuf,
2051 [Omet] "Method", "{N1", evalmet,
2053 [Oadd] "Add", "ii@", evalarith,
2054 [Osub] "Subtract", "ii@", evalarith,
2055 [Omod] "Mod", "ii@", evalarith,
2056 [Omul] "Multiply", "ii@", evalarith,
2057 [Odiv] "Divide", "ii@@", evalarith,
2058 [Oshl] "ShiftLef", "ii@", evalarith,
2059 [Oshr] "ShiftRight", "ii@", evalarith,
2060 [Oand] "And", "ii@", evalarith,
2061 [Onand] "Nand", "ii@", evalarith,
2062 [Oor] "Or", "ii@", evalarith,
2063 [Onor] "Nor", "ii@", evalarith,
2064 [Oxor] "Xor", "ii@", evalarith,
2065 [Onot] "Not", "i@", evalarith,
2067 [Olbit] "FindSetLeftBit", "i@", evalarith,
2068 [Orbit] "FindSetRightBit", "i@", evalarith,
2070 [Oinc] "Increment", "@", evalarith,
2071 [Odec] "Decrement", "@", evalarith,
2073 [Oland] "LAnd", "ii", evalarith,
2074 [Olor] "LOr", "ii", evalarith,
2075 [Olnot] "LNot", "i", evalarith,
2077 [Oleq] "LEqual", "**", evalcmp,
2078 [Olgt] "LGreater", "**", evalcmp,
2079 [Ollt] "LLess", "**", evalcmp,
2081 [Omutex] "Mutex", "N1", evalnop,
2082 [Oevent] "Event", "N", evalnop,
2084 [Oif] "If", "{i}", evalcond,
2085 [Oelse] "Else", "{}", evalcond,
2086 [Owhile] "While", "{,i}", evalcond,
2087 [Obreak] "Break", "", evalret,
2088 [Oret] "Return", "*", evalret,
2089 [Ocall] "Call", "", evalcall,
2091 [Ostore] "Store", "*@", evalstore,
2092 [Oindex] "Index", "@i@", evalindex,
2093 [Omatch] "Match", "*1*1*i", evalmatch,
2094 [Osize] "SizeOf", "*", evalsize,
2095 [Oref] "RefOf", "@", evaliarg0,
2096 [Ocref] "CondRefOf", "@@", evalcondref,
2097 [Oderef] "DerefOf", "@", evalderef,
2098 [Ocat] "Concatenate", "**@", evalcat,
2100 [Oacq] "Acquire", "@2", evalnop,
2101 [Osignal] "Signal", "@", evalnop,
2102 [Orel] "Release", "@", evalnop,
2103 [Ostall] "Stall", "i", evalstall,
2104 [Osleep] "Sleep", "i", evalsleep,
2105 [Oload] "Load", "*@}", evalload,
2106 [Ounload] "Unload", "@", evalnop,
2108 [Otodec] "ToDecimalString", "*@", evalconv,
2109 [Otohex] "ToHexString", "*@", evalconv,
2110 [Otoint] "ToInteger", "*@", evalconv,
2113 static uchar octab1[] = {
2114 /* 00 */ Oconst, Oconst, Obad, Obad, Obad, Obad, Oalias, Obad,
2115 /* 08 */ Oname, Obad, Obyte, Oword, Odword, Ostr, Oqword, Obad,
2116 /* 10 */ Oscope, Obuf, Opkg, Ovpkg, Omet, Obad, Obad, Obad,
2117 /* 18 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2118 /* 20 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2119 /* 28 */ Obad, Obad, Obad, Obad, Obad, Obad, Onamec, Onamec,
2120 /* 30 */ Onamec, Onamec, Onamec, Onamec, Onamec, Onamec, Onamec, Onamec,
2121 /* 38 */ Onamec, Onamec, Obad, Obad, Obad, Obad, Obad, Obad,
2122 /* 40 */ Obad, Onamec, Onamec, Onamec, Onamec, Onamec, Onamec, Onamec,
2123 /* 48 */ Onamec, Onamec, Onamec, Onamec, Onamec, Onamec, Onamec, Onamec,
2124 /* 50 */ Onamec, Onamec, Onamec, Onamec, Onamec, Onamec, Onamec, Onamec,
2125 /* 58 */ Onamec, Onamec, Onamec, Obad, Onamec, Obad, Onamec, Onamec,
2126 /* 60 */ Oenv, Oenv, Oenv, Oenv, Oenv, Oenv, Oenv, Oenv,
2127 /* 68 */ Oenv, Oenv, Oenv, Oenv, Oenv, Oenv, Oenv, Obad,
2128 /* 70 */ Ostore, Oref, Oadd, Ocat, Osub, Oinc, Odec, Omul,
2129 /* 78 */ Odiv, Oshl, Oshr, Oand, Onand, Oor, Onor, Oxor,
2130 /* 80 */ Onot, Olbit, Orbit, Oderef, Obad, Omod, Obad, Osize,
2131 /* 88 */ Oindex, Omatch, Ocfld4, Ocfld2, Ocfld1, Ocfld0, Obad, Ocfld8,
2132 /* 90 */ Oland, Olor, Olnot, Oleq, Olgt, Ollt, Obad, Otodec,
2133 /* 98 */ Otohex, Otoint, Obad, Obad, Obad, Obad, Obad, Obad,
2134 /* A0 */ Oif, Oelse, Owhile, Onop, Oret, Obreak, Obad, Obad,
2135 /* A8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2136 /* B0 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2137 /* B8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2138 /* C0 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2139 /* C8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2140 /* D0 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2141 /* D8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2142 /* E0 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2143 /* E8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2144 /* F0 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2145 /* F8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Oconst,
2148 static uchar octab2[] = {
2149 /* 00 */ Obad, Omutex, Oevent, Obad, Obad, Obad, Obad, Obad,
2150 /* 08 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2151 /* 10 */ Obad, Obad, Ocref, Ocfld, Obad, Obad, Obad, Obad,
2152 /* 18 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2153 /* 20 */ Oload, Ostall, Osleep, Oacq, Osignal,Obad, Obad, Orel,
2154 /* 28 */ Obad, Obad, Ounload,Obad, Obad, Obad, Obad, Obad,
2155 /* 30 */ Obad, Odebug, Obad, Obad, Obad, Obad, Obad, Obad,
2156 /* 38 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2157 /* 40 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2158 /* 48 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2159 /* 50 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2160 /* 58 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2161 /* 60 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2162 /* 68 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2163 /* 70 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2164 /* 78 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2165 /* 80 */ Oreg, Ofld, Odev, Ocpu, Oprc, Othz, Oxfld, Obfld,
2166 /* 88 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2167 /* 90 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2168 /* 98 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2169 /* A0 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2170 /* A8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2171 /* B0 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2172 /* B8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2173 /* C0 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2174 /* C8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2175 /* D0 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2176 /* D8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2177 /* E0 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2178 /* E8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2179 /* F0 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2180 /* F8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2186 return p ? TAG(p) : 0;
2207 p = *((Ref*)p)->ptr;
2211 return strlen((char*)p);
2213 return SIZE(p)/sizeof(void*);
2222 amlnew(char tag, int len)
2229 return mk(tag, len + 1);
2231 return mk(tag, len * sizeof(void*));
2233 return mk(tag, len);
2240 static char *w[] = {
2249 s = FP->env->arg[0];
2250 if(s == nil || TAG(s) != 's')
2252 for(i = 0; i < nelem(w); i++)
2253 if(strcmp(s, w[i]) == 0)
2254 return mki(0xFFFFFFFF);
2266 fmtinstall('V', Vfmt);
2267 fmtinstall('N', Nfmt);
2272 n = mk('N', sizeof(Name));
2277 getname(amlroot, "_GPE", 1);
2278 getname(amlroot, "_PR", 1);
2279 getname(amlroot, "_SB", 1);
2280 getname(amlroot, "_TZ", 1);
2281 getname(amlroot, "_SI", 1);
2282 getname(amlroot, "_GL", 1);
2284 if(n = getname(amlroot, "_REV", 1))
2286 if(n = getname(amlroot, "_OS", 1))
2287 n->v = mks("Microsoft Windows");
2288 if(n = getname(amlroot, "_OSI", 1)){
2291 m = mk('m', sizeof(Method));
2309 amlload(uchar *data, int len)
2313 ret = xec(data, data+len, amlroot, nil, nil);
2314 amlenum(amlroot, nil, fixnames, nil);
2319 amlwalk(void *dot, char *name)
2321 return getname(dot, name, 0);
2325 amlenum(void *dot, char *seg, int (*proc)(void *, void *), void *arg)
2331 if(d == nil || TAG(d) != 'N')
2335 if(seg == nil || memcmp(seg, d->seg, sizeof(d->seg)) == 0)
2336 rec = (*proc)(d, arg) == 0;
2337 for(n = d->down; n && rec; n = n->next)
2338 amlenum(n, seg, proc, arg);
2344 amleval(void *dot, char *fmt, ...)
2353 e = mk('E', sizeof(Env));
2354 for(i=0;*fmt;fmt++){
2359 e->arg[i++] = mks(va_arg(a, char*));
2362 e->arg[i++] = mki(va_arg(a, int));
2365 e->arg[i++] = mki(va_arg(a, uvlong));
2370 e->arg[i++] = va_arg(a, void*);
2374 r = va_arg(a, void**);
2376 if(dot = deref(dot))
2377 if(TAG(dot) == 'm'){
2382 return xec(m->start, m->end, forkname(m->name), e, r);
2383 if(FB < F0 || FB >= FT)
2390 FP->ref = FP->aux = nil;