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;
288 assert(a >= sizeof(Heap));
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'){
618 /* set index field */
619 rwfield(f->index, mki(off), 1);
621 /* set or get data field */
623 void *b = mk('b', len);
625 rwfield(f->reg, b, 1);
627 v = ival(rwfield(f->reg, nil, 0));
633 rwfield(f->index, f->bank, 1);
635 return rwreg(f->reg, off, len, v, write);
639 rwfield(Field *f, void *v, int write)
641 int boff, blen, wo, ws, wl, wa, wd, i;
649 if(v && TAG(v) == 'b'){
655 b = mk('b', (blen+7)/8);
656 putle(b, SIZE(b), w);
659 b = mk('b', (blen+7)/8);
661 * don't free b while in rwfieldunit()/rwreg(),
662 * gc can't find this temporary object referenced.
665 wa = fieldalign(f->flags);
668 while((wl = (blen-boff)) > 0){
669 wo = (f->bitoff+boff) / wd;
670 ws = (f->bitoff+boff) % wd;
675 for(i = 0; i < wl; i++, boff++)
676 if(b[boff/8] & (1<<(boff%8)))
680 m = ((1ULL<<wl)-1) << ws;
681 w |= rwfieldunit(f, wo*wa, wa, 0, 0) & ~m;
683 rwfieldunit(f, wo*wa, wa, w, 1);
685 w = rwfieldunit(f, wo*wa, wa, 0, 0) >> ws;
686 for(i = 0; i < wl; i++, boff++){
687 b[boff/8] |= (w&1)<<(boff%8);
697 w = getle(b, SIZE(b));
704 if(p) switch(TAG(p)){
706 return ((Name*)p)->v;
707 case 'R': case 'A': case 'L':
708 return *((Ref*)p)->ptr;
710 return rwfield(p, nil, 0);
716 todecstr(uchar *buf, int len, int sep)
721 r = d = mk('s', len*4 + 1);
728 for(i=0; i<len; i++){
730 if((*d = '0' + ((v/100) % 10)) != '0')
732 if((*d = '0' + ((v/10) % 10)) != '0')
734 *d++ = '0' + (v % 10);
741 static char hex[] = "0123456789ABCDEF";
744 tohexstr(uchar *buf, int len, int sep)
749 r = d = mk('s', len*3 + 1);
756 for(i=0; i<len; i++){
757 *d++ = hex[buf[i] >> 4];
758 *d++ = hex[buf[i] & 0xF];
766 copy(int tag, void *s)
777 if(s == nil || TAG(s) == 'i'){
780 if(v > 0xFFFFFFFFULL)
785 rwreg(d, 0, n, v, 1);
792 ((char*)d)[--n] = hex[v & 0xF];
806 return tohexstr(s, n, ' ');
811 /* zero length string is converted to zero length buffer */
823 store(void *s, void *d)
837 while((p = *pp) != nil){
839 case 'R': case 'A': case 'L':
855 if(p != nil && TAG(p) != 'N'){
862 if(TAG(d) != 'A' && TAG(d) != 'L'){
863 *pp = copy(TAG(p), s);
878 n = va_arg(f->args, Name*);
880 return fmtprint(f, "?NIL");
882 return fmtprint(f, "\\");
883 strncpy(buf, n->seg, 4);
890 if(n->up == n->up->up)
891 return fmtprint(f, "\\%s", buf);
892 return fmtprint(f, "%N.%s", n->up, buf);
907 p = va_arg(f->args, void*);
909 return fmtprint(f, "nil");
915 return fmtprint(f, "%N=%V", nm, nm->v);
916 return fmtprint(f, "%N=*", nm);
922 return fmtprint(f, "Arg%zd=%V", r->ptr - e->arg, *r->ptr);
924 return fmtprint(f, "Local%zd=%V", r->ptr - e->loc, *r->ptr);
926 return fmtprint(f, "%s", (char*)p);
928 return fmtprint(f, "\"%s\"", (char*)p);
930 return fmtprint(f, "%#llux", *((uvlong*)p));
932 n = SIZE(p)/sizeof(void*);
933 fmtprint(f, "Package(%d){", n);
937 fmtprint(f, "%V", ((void**)p)[i]);
943 fmtprint(f, "Buffer(%d){", n);
947 fmtprint(f, "%.2uX", ((uchar*)p)[i]);
953 return fmtprint(f, "Region(%s, %#llux, %#llux)",
954 spacename[g->space & 7], g->off, g->len);
957 fmtprint(f, "%N(", m->name);
958 for(i=0; i < m->narg; i++){
961 fmtprint(f, "Arg%d", i);
966 fmtprint(f, "Buffer");
971 if(TAG(l->reg) == 'f')
972 return fmtprint(f, "IndexField(%x, %x, %x) @ %V[%V]",
973 l->flags, l->bitoff, l->bitlen, l->reg, l->index);
975 return fmtprint(f, "BankField(%x, %x, %x, %V=%V) @ %V",
976 l->flags, l->bitoff, l->bitlen, l->index, l->bank, l->reg);
978 return fmtprint(f, "Field(%x, %x, %x) @ %V",
979 l->flags, l->bitoff, l->bitlen, l->reg);
981 return fmtprint(f, "%c:%p", c, p);
992 print("\n*** dumpregs: PC=%p FP=%p\n", PC, FP);
994 for(f = FP; f >= FB; f--){
995 print("%.8p.%.2zx: %-8s %N\t", f->start, f-FB, f->phase, f->dot);
997 print("%s", f->op->name);
999 for(i=0; i<f->narg; i++){
1002 print("%V", f->arg[i]);
1008 for(i=0; i<nelem(e->arg); i++)
1009 print("Arg%d=%V ", i, e->arg[i]);
1011 for(i=0; i<nelem(e->loc); i++)
1012 print("Local%d=%V ", i, e->loc[i]);
1019 xec(uchar *pc, uchar *end, Name *dot, Env *env, void **pret)
1026 if(FB < F0 || FB >= FT)
1043 if((++loop & 127) == 0)
1046 print("\n%.8p.%.2zx %-8s\t%N\t", PC, FP - FB, FP->phase, FP->dot);
1053 print("aml: PC overrun frame end");
1058 print("aml: frame stack overflow");
1067 if(amldebug) print("%.2X", c);
1072 if(amldebug) print("%.2X", c);
1078 FP->phase = FP->op->sequence;
1079 if(amldebug) print("\t%s %s", FP->op->name, FP->phase);
1083 c = pkglen(PC, FP->end, &PC);
1085 if(c < 0 || end > FP->end)
1093 if(end = memchr(PC, 0, FP->end - PC))
1112 for(i = 8; PC < end; i += 8)
1113 *((uvlong*)r) |= ((uvlong)*PC++) << i;
1120 print("*%p,%V\t%s(", FP->aux, FP->ref, FP->op->name);
1121 for(i = 0; i < FP->narg; i++){
1124 print("%V", FP->arg[i]);
1128 for(i = FP->narg; i < nelem(FP->arg); i++)
1136 if(c == '}' && PC < FP->end){
1142 if(r) switch(FP->tag){
1151 if((r = deref(r)) == nil)
1155 r = rwfield(r, nil, 0);
1161 FP->phase = "********}" + (8 - m->narg);
1162 FP->op = &optab[Ocall];
1172 if(amldebug) print(" -> %V\n", r);
1177 FP->arg[FP->narg++] = r;
1188 static char name[1024];
1199 if(d >= &name[sizeof(name)-1]){
1202 print("aml: name too long: %s\n", name);
1211 } else if(*PC == '/'){
1214 } else if(*PC == 0){
1219 if(d >= &name[sizeof(name)-5])
1225 while((d > &name[0]) && (d[-1] == '_' || d[-1] == 0))
1231 if((r = getname(FP->dot, name, FP->tag == 'N')) == nil){
1233 D2H(r)->tag = 'n'; /* unresolved name */
1247 switch(FP->start[0]){
1262 n = ival(FP->arg[0]);
1278 if((p = FP->ref) != nil){
1280 if(x >= p && x < (p+(SIZE(p)/sizeof(void*)))){
1285 n = ival(FP->arg[0]);
1287 p = mk('p', n*sizeof(void*));
1325 n->v = deref(FP->arg[0]);
1335 if((n = FP->arg[0]) != nil){
1336 m = mk('m', sizeof(Method));
1337 m->narg = ival(FP->arg[1]) & 7;
1353 if((n = FP->arg[0]) != nil){
1354 r = mk('r', sizeof(Region));
1355 r->space = ival(FP->arg[1]);
1356 r->off = ival(FP->arg[2]);
1357 r->len = ival(FP->arg[3]);
1374 if(r == nil || (TAG(r) != 'b' && TAG(r) != 'r'))
1381 if(n == nil || TAG(n) != 'N')
1384 f = mk('u', sizeof(Field));
1386 f = mk('f', sizeof(Field));
1389 f->bitoff = ival(FP->arg[1]);
1390 f->bitlen = ival(FP->arg[2]);
1393 f->bitoff = ival(FP->arg[1]);
1400 f->bitoff = 8*ival(FP->arg[1]);
1401 f->bitlen = 8*(c - Ocfld0);
1412 int flags, bitoff, n;
1421 switch(FP->op - optab){
1425 if((reg = deref(FP->arg[0])) == nil || TAG(reg) != 'r')
1427 flags = ival(FP->arg[1]);
1430 if((index = deref(FP->arg[0])) == nil || TAG(index) != 'f')
1432 if((reg = deref(FP->arg[1])) == nil || TAG(reg) != 'f') /* data field */
1434 flags = ival(FP->arg[2]);
1437 if((reg = deref(FP->arg[0])) == nil || TAG(reg) != 'r')
1439 if((index = deref(FP->arg[1])) == nil || TAG(index) != 'f')
1442 flags = ival(FP->arg[3]);
1451 if((n = pkglen(p, FP->end, &p)) < 0)
1464 if((d = getseg(FP->dot, p, 1)) == nil)
1466 if((n = pkglen(p+4, FP->end, &p)) < 0)
1468 f = mk('f', sizeof(Field));
1494 print("aml: bad opcode %p: ", PC);
1495 for(i=0; i < 8 && (FP->start+i) < FP->end; i++){
1498 print("%.2X", FP->start[i]);
1500 if((FP->start+i) < FP->end)
1510 switch(FP->op - optab){
1514 FP[-1].cond = ival(FP->arg[0]) != 0;
1533 if(ival(FP->arg[0]) == 0){
1544 cmp1(void *a, void *b)
1549 if(a == nil || TAG(a) == 'i'){
1550 c = ival(a) - ival(b);
1553 if(b == nil || TAG(b) != tag)
1555 if(b == nil || TAG(b) != tag)
1556 return -1; /* botch */
1559 return -1; /* botch */
1561 c = strcmp((char*)a, (char*)b);
1564 c = SIZE(a) - SIZE(b);
1566 c = memcmp(a, b, SIZE(a));
1576 vlong c = cmp1(FP->arg[0], FP->arg[1]);
1577 switch(FP->op - optab){
1579 if(c == 0) return mki(1);
1582 if(c > 0) return mki(1);
1585 if(c < 0) return mki(1);
1606 e = mk('E', sizeof(Env));
1607 for(i=0; i<FP->narg; i++)
1608 e->arg[i] = deref(FP->arg[i]);
1615 return (*m->eval)();
1617 FP->dot = forkname(FP->dot);
1619 FP->start = m->start;
1628 void *r = FP->arg[0];
1629 int brk = (FP->op - optab) != Oret;
1631 switch(FP->op - optab){
1654 if((e = FP->env) == nil)
1657 if(c >= 0x60 && c <= 0x67){
1658 r = mk('L', sizeof(Ref));
1659 r->ptr = &e->loc[c - 0x60];
1660 } else if(c >= 0x68 && c <= 0x6E){
1661 r = mk('A', sizeof(Ref));
1662 r->ptr = &e->arg[c - 0x68];
1672 return store(FP->arg[0], FP->arg[1]);
1683 if(a == nil || TAG(a) == 'i')
1684 a = copy('b', a); /* Concat(Int, ???) -> Buf */
1686 if(b == nil || TAG(b) != tag)
1689 return nil; /* botch */
1692 return nil; /* botch */
1698 memmove((uchar*)r + n, b, m);
1701 n = strlen((char*)a);
1702 m = strlen((char*)b);
1703 r = mk('s', n + m + 1);
1705 memmove((char*)r + n, b, m);
1706 ((char*)r)[n+m] = 0;
1709 store(r, FP->arg[2]);
1721 x = ival(FP->arg[1]);
1722 if(p = deref(FP->arg[0])) switch(TAG(p)){
1724 if(x >= strlen((char*)p))
1730 f = mk('u', sizeof(Field));
1734 store(f, FP->arg[2]);
1737 if(x >= (SIZE(p)/sizeof(void*)))
1739 if(TAG(FP->arg[0]) == 'A' || TAG(FP->arg[0]) == 'L')
1740 r = mk(TAG(FP->arg[0]), sizeof(Ref));
1742 r = mk('R', sizeof(Ref));
1744 r->ptr = ((void**)p) + x;
1745 store(r, FP->arg[2]);
1752 match1(int op, void *a, void *b)
1754 vlong c = cmp1(a, b);
1757 case 1: return c == 0;
1758 case 2: return c <= 0;
1759 case 3: return c < 0;
1760 case 4: return c >= 0;
1761 case 5: return c > 0;
1769 void **p = FP->arg[0];
1770 if(p != nil && TAG(p) == 'p'){
1771 uvlong i, n = SIZE(p)/sizeof(void*);
1772 int o1 = ival(FP->arg[1]), o2 = ival(FP->arg[3]);
1773 for(i=ival(FP->arg[5]); i<n; i++){
1774 void *a = deref(p[i]);
1775 if(match1(o1, a, FP->arg[2]) && match1(o2, a, FP->arg[4]))
1786 if((s = FP->arg[0]) == nil)
1788 store(s, FP->arg[1]);
1795 return mki(amllen(FP->arg[0]));
1804 if(TAG(p) == 's' || TAG(p) == 'n')
1805 p = getname(FP->dot, (char*)p, 0);
1819 switch(FP->op - optab){
1821 r = mki(ival(FP->arg[0]) + ival(FP->arg[1]));
1824 r = mki(ival(FP->arg[0]) - ival(FP->arg[1]));
1827 r = mki(ival(FP->arg[0]) * ival(FP->arg[1]));
1831 v = ival(FP->arg[0]);
1832 d = ival(FP->arg[1]);
1834 print("aml: division by zero: PC=%#p\n", PC);
1838 store(r, FP->arg[2]);
1839 if((FP->op - optab) != Odiv)
1842 store(r, FP->arg[3]);
1845 r = mki(ival(FP->arg[0]) << ival(FP->arg[1]));
1848 r = mki(ival(FP->arg[0]) >> ival(FP->arg[1]));
1851 r = mki(ival(FP->arg[0]) & ival(FP->arg[1]));
1854 r = mki(~(ival(FP->arg[0]) & ival(FP->arg[1])));
1857 r = mki(ival(FP->arg[0]) | ival(FP->arg[1]));
1860 r = mki(~(ival(FP->arg[0]) | ival(FP->arg[1])));
1863 r = mki(ival(FP->arg[0]) ^ ival(FP->arg[1]));
1866 r = mki(~ival(FP->arg[0]));
1867 store(r, FP->arg[1]);
1870 v = ival(FP->arg[0]);
1873 for(i=0; (v & 1) == 0; i++)
1878 v = ival(FP->arg[0]);
1881 for(i=0; v != 0; i++)
1886 return mki(ival(FP->arg[0]) && ival(FP->arg[1]));
1888 return mki(ival(FP->arg[0]) || ival(FP->arg[1]));
1890 return mki(ival(FP->arg[0]) == 0);
1893 r = mki(ival(deref(FP->arg[0]))+1);
1894 store(r, FP->arg[0]);
1897 r = mki(ival(deref(FP->arg[0]))-1);
1898 store(r, FP->arg[0]);
1902 store(r, FP->arg[2]);
1909 enum { LenOffset = 4, HdrLen = 36 };
1917 amlenum(amlroot, nil, fixnames, nil);
1920 tid = mki(1); /* fake */
1923 store(nil, FP->arg[1]);
1924 if(FP->arg[0] == nil)
1927 l = rwreg(FP->arg[0], LenOffset, 4, 0, 0);
1931 FP->aux = PC; /* save */
1932 FP->ref = FP->arg[0];
1933 switch(TAG(FP->ref)){
1935 if(SIZE(FP->ref) < l)
1937 PC = (uchar*)FP->ref + HdrLen;
1941 if(r->len < l || r->va == nil || r->mapped <= 0)
1943 PC = (uchar*)r->va + HdrLen;
1948 FP->end = PC + (l - HdrLen);
1952 tid = mki(1); /* fake */
1953 store(tid, FP->arg[1]);
1961 amldelay(ival(FP->arg[0]));
1968 amldelay(ival(FP->arg[0])*1000);
1979 switch(FP->op - optab){
1988 r = todecstr(a, SIZE(a), ',');
2000 r = tohexstr(a, SIZE(a), ',');
2005 if(a != nil && TAG(a) == 's')
2006 r = mki(strtoull((char*)a, 0, 0));
2011 store(r, FP->arg[1]);
2015 static Op optab[] = {
2016 [Obad] "", "", evalbad,
2017 [Onop] "Noop", "", evalnop,
2018 [Odebug] "Debug", "", evalnop,
2020 [Ostr] ".str", "s", evaliarg0,
2021 [Obyte] ".byte", "1", evaliarg0,
2022 [Oword] ".word", "2", evaliarg0,
2023 [Odword] ".dword", "4", evaliarg0,
2024 [Oqword] ".qword", "8", evaliarg0,
2025 [Oconst] ".const", "", evalconst,
2026 [Onamec] ".name", "", evalnamec,
2027 [Oenv] ".env", "", evalenv,
2029 [Oname] "Name", "N*", evalname,
2030 [Oscope] "Scope", "{n}", evalscope,
2031 [Oalias] "Alias", "nN", evalalias,
2033 [Odev] "Device", "{N}", evalscope,
2034 [Ocpu] "Processor", "{N141}", evalscope,
2035 [Othz] "ThermalZone", "{N}", evalscope,
2036 [Oprc] "PowerResource", "{N12}", evalscope,
2038 [Oreg] "OperationRegion", "N1ii", evalreg,
2039 [Ofld] "Field", "{n1", evalfield,
2040 [Oxfld] "IndexField", "{nn1", evalfield,
2041 [Obfld] "BankField", "{nni1", evalfield,
2043 [Ocfld] "CreateField", "*iiN", evalcfield,
2044 [Ocfld0] "CreateBitField", "*iN", evalcfield,
2045 [Ocfld1] "CreateByteField", "*iN", evalcfield,
2046 [Ocfld2] "CreateWordField", "*iN", evalcfield,
2047 [Ocfld4] "CreateDWordField", "*iN", evalcfield,
2048 [Ocfld8] "CreateQWordField", "*iN", evalcfield,
2050 [Opkg] "Package", "{1}", evalpkg,
2051 [Ovpkg] "VarPackage", "{i}", evalpkg,
2052 [Obuf] "Buffer", "{i", evalbuf,
2053 [Omet] "Method", "{N1", evalmet,
2055 [Oadd] "Add", "ii@", evalarith,
2056 [Osub] "Subtract", "ii@", evalarith,
2057 [Omod] "Mod", "ii@", evalarith,
2058 [Omul] "Multiply", "ii@", evalarith,
2059 [Odiv] "Divide", "ii@@", evalarith,
2060 [Oshl] "ShiftLef", "ii@", evalarith,
2061 [Oshr] "ShiftRight", "ii@", evalarith,
2062 [Oand] "And", "ii@", evalarith,
2063 [Onand] "Nand", "ii@", evalarith,
2064 [Oor] "Or", "ii@", evalarith,
2065 [Onor] "Nor", "ii@", evalarith,
2066 [Oxor] "Xor", "ii@", evalarith,
2067 [Onot] "Not", "i@", evalarith,
2069 [Olbit] "FindSetLeftBit", "i@", evalarith,
2070 [Orbit] "FindSetRightBit", "i@", evalarith,
2072 [Oinc] "Increment", "@", evalarith,
2073 [Odec] "Decrement", "@", evalarith,
2075 [Oland] "LAnd", "ii", evalarith,
2076 [Olor] "LOr", "ii", evalarith,
2077 [Olnot] "LNot", "i", evalarith,
2079 [Oleq] "LEqual", "**", evalcmp,
2080 [Olgt] "LGreater", "**", evalcmp,
2081 [Ollt] "LLess", "**", evalcmp,
2083 [Omutex] "Mutex", "N1", evalnop,
2084 [Oevent] "Event", "N", evalnop,
2086 [Oif] "If", "{i}", evalcond,
2087 [Oelse] "Else", "{}", evalcond,
2088 [Owhile] "While", "{,i}", evalcond,
2089 [Obreak] "Break", "", evalret,
2090 [Oret] "Return", "*", evalret,
2091 [Ocall] "Call", "", evalcall,
2093 [Ostore] "Store", "*@", evalstore,
2094 [Oindex] "Index", "@i@", evalindex,
2095 [Omatch] "Match", "*1*1*i", evalmatch,
2096 [Osize] "SizeOf", "*", evalsize,
2097 [Oref] "RefOf", "@", evaliarg0,
2098 [Ocref] "CondRefOf", "@@", evalcondref,
2099 [Oderef] "DerefOf", "@", evalderef,
2100 [Ocat] "Concatenate", "**@", evalcat,
2102 [Oacq] "Acquire", "@2", evalnop,
2103 [Osignal] "Signal", "@", evalnop,
2104 [Orel] "Release", "@", evalnop,
2105 [Ostall] "Stall", "i", evalstall,
2106 [Osleep] "Sleep", "i", evalsleep,
2107 [Oload] "Load", "*@}", evalload,
2108 [Ounload] "Unload", "@", evalnop,
2110 [Otodec] "ToDecimalString", "*@", evalconv,
2111 [Otohex] "ToHexString", "*@", evalconv,
2112 [Otoint] "ToInteger", "*@", evalconv,
2115 static uchar octab1[] = {
2116 /* 00 */ Oconst, Oconst, Obad, Obad, Obad, Obad, Oalias, Obad,
2117 /* 08 */ Oname, Obad, Obyte, Oword, Odword, Ostr, Oqword, Obad,
2118 /* 10 */ Oscope, Obuf, Opkg, Ovpkg, Omet, Obad, Obad, Obad,
2119 /* 18 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2120 /* 20 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2121 /* 28 */ Obad, Obad, Obad, Obad, Obad, Obad, Onamec, Onamec,
2122 /* 30 */ Onamec, Onamec, Onamec, Onamec, Onamec, Onamec, Onamec, Onamec,
2123 /* 38 */ Onamec, Onamec, Obad, Obad, Obad, Obad, Obad, Obad,
2124 /* 40 */ Obad, Onamec, Onamec, Onamec, Onamec, Onamec, Onamec, Onamec,
2125 /* 48 */ Onamec, Onamec, Onamec, Onamec, Onamec, Onamec, Onamec, Onamec,
2126 /* 50 */ Onamec, Onamec, Onamec, Onamec, Onamec, Onamec, Onamec, Onamec,
2127 /* 58 */ Onamec, Onamec, Onamec, Obad, Onamec, Obad, Onamec, Onamec,
2128 /* 60 */ Oenv, Oenv, Oenv, Oenv, Oenv, Oenv, Oenv, Oenv,
2129 /* 68 */ Oenv, Oenv, Oenv, Oenv, Oenv, Oenv, Oenv, Obad,
2130 /* 70 */ Ostore, Oref, Oadd, Ocat, Osub, Oinc, Odec, Omul,
2131 /* 78 */ Odiv, Oshl, Oshr, Oand, Onand, Oor, Onor, Oxor,
2132 /* 80 */ Onot, Olbit, Orbit, Oderef, Obad, Omod, Obad, Osize,
2133 /* 88 */ Oindex, Omatch, Ocfld4, Ocfld2, Ocfld1, Ocfld0, Obad, Ocfld8,
2134 /* 90 */ Oland, Olor, Olnot, Oleq, Olgt, Ollt, Obad, Otodec,
2135 /* 98 */ Otohex, Otoint, Obad, Obad, Obad, Obad, Obad, Obad,
2136 /* A0 */ Oif, Oelse, Owhile, Onop, Oret, Obreak, Obad, Obad,
2137 /* A8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2138 /* B0 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2139 /* B8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2140 /* C0 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2141 /* C8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2142 /* D0 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2143 /* D8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2144 /* E0 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2145 /* E8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2146 /* F0 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2147 /* F8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Oconst,
2150 static uchar octab2[] = {
2151 /* 00 */ Obad, Omutex, Oevent, Obad, Obad, Obad, Obad, Obad,
2152 /* 08 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2153 /* 10 */ Obad, Obad, Ocref, Ocfld, Obad, Obad, Obad, Obad,
2154 /* 18 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2155 /* 20 */ Oload, Ostall, Osleep, Oacq, Osignal,Obad, Obad, Orel,
2156 /* 28 */ Obad, Obad, Ounload,Obad, Obad, Obad, Obad, Obad,
2157 /* 30 */ Obad, Odebug, Obad, Obad, Obad, Obad, Obad, Obad,
2158 /* 38 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2159 /* 40 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2160 /* 48 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2161 /* 50 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2162 /* 58 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2163 /* 60 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2164 /* 68 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2165 /* 70 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2166 /* 78 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2167 /* 80 */ Oreg, Ofld, Odev, Ocpu, Oprc, Othz, Oxfld, Obfld,
2168 /* 88 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2169 /* 90 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2170 /* 98 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2171 /* A0 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2172 /* A8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2173 /* B0 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2174 /* B8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2175 /* C0 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2176 /* C8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2177 /* D0 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2178 /* D8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2179 /* E0 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2180 /* E8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2181 /* F0 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2182 /* F8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
2188 return p ? TAG(p) : 0;
2209 p = *((Ref*)p)->ptr;
2213 return strlen((char*)p);
2215 return SIZE(p)/sizeof(void*);
2224 amlnew(char tag, int len)
2231 return mk(tag, len + 1);
2233 return mk(tag, len * sizeof(void*));
2235 return mk(tag, len);
2242 static char *w[] = {
2251 s = FP->env->arg[0];
2252 if(s == nil || TAG(s) != 's')
2254 for(i = 0; i < nelem(w); i++)
2255 if(strcmp(s, w[i]) == 0)
2256 return mki(0xFFFFFFFF);
2268 fmtinstall('V', Vfmt);
2269 fmtinstall('N', Nfmt);
2274 n = mk('N', sizeof(Name));
2279 getname(amlroot, "_GPE", 1);
2280 getname(amlroot, "_PR", 1);
2281 getname(amlroot, "_SB", 1);
2282 getname(amlroot, "_TZ", 1);
2283 getname(amlroot, "_SI", 1);
2284 getname(amlroot, "_GL", 1);
2286 if(n = getname(amlroot, "_REV", 1))
2288 if(n = getname(amlroot, "_OS", 1))
2289 n->v = mks("Microsoft Windows");
2290 if(n = getname(amlroot, "_OSI", 1)){
2293 m = mk('m', sizeof(Method));
2311 amlload(uchar *data, int len)
2315 ret = xec(data, data+len, amlroot, nil, nil);
2316 amlenum(amlroot, nil, fixnames, nil);
2321 amlwalk(void *dot, char *name)
2323 return getname(dot, name, 0);
2327 amlenum(void *dot, char *seg, int (*proc)(void *, void *), void *arg)
2333 if(d == nil || TAG(d) != 'N')
2337 if(seg == nil || memcmp(seg, d->seg, sizeof(d->seg)) == 0)
2338 rec = (*proc)(d, arg) == 0;
2339 for(n = d->down; n && rec; n = n->next)
2340 amlenum(n, seg, proc, arg);
2346 amleval(void *dot, char *fmt, ...)
2355 e = mk('E', sizeof(Env));
2356 for(i=0;*fmt;fmt++){
2361 e->arg[i++] = mks(va_arg(a, char*));
2364 e->arg[i++] = mki(va_arg(a, int));
2367 e->arg[i++] = mki(va_arg(a, uvlong));
2372 e->arg[i++] = va_arg(a, void*);
2376 r = va_arg(a, void**);
2378 if(dot = deref(dot))
2379 if(TAG(dot) == 'm'){
2384 return xec(m->start, m->end, forkname(m->name), e, r);
2385 if(FB < F0 || FB >= FT)
2392 FP->ref = FP->aux = nil;