xref: /plan9-contrib/sys/src/libaml/aml.c (revision ebd848c130c5a90707793ad058d6d29ac82262e7)
1*ebd848c1SDavid du Colombier #include <u.h>
2*ebd848c1SDavid du Colombier #include <libc.h>
3*ebd848c1SDavid du Colombier #include <aml.h>
4*ebd848c1SDavid du Colombier 
5*ebd848c1SDavid du Colombier typedef struct Interp Interp;
6*ebd848c1SDavid du Colombier typedef struct Frame Frame;
7*ebd848c1SDavid du Colombier typedef struct Heap Heap;
8*ebd848c1SDavid du Colombier 
9*ebd848c1SDavid du Colombier typedef struct Method Method;
10*ebd848c1SDavid du Colombier typedef struct Region Region;
11*ebd848c1SDavid du Colombier typedef struct Field Field;
12*ebd848c1SDavid du Colombier 
13*ebd848c1SDavid du Colombier typedef struct Name Name;
14*ebd848c1SDavid du Colombier typedef struct Ref Ref;
15*ebd848c1SDavid du Colombier typedef struct Env Env;
16*ebd848c1SDavid du Colombier typedef struct Op Op;
17*ebd848c1SDavid du Colombier 
18*ebd848c1SDavid du Colombier struct Heap {
19*ebd848c1SDavid du Colombier 	Heap	*link;
20*ebd848c1SDavid du Colombier 	short	size;
21*ebd848c1SDavid du Colombier 	uchar	mark;
22*ebd848c1SDavid du Colombier 	char	tag;
23*ebd848c1SDavid du Colombier };
24*ebd848c1SDavid du Colombier 
25*ebd848c1SDavid du Colombier #define H2D(h)	(((Heap*)(h))+1)
26*ebd848c1SDavid du Colombier #define D2H(d)	(((Heap*)(d))-1)
27*ebd848c1SDavid du Colombier #define TAG(d)	D2H(d)->tag
28*ebd848c1SDavid du Colombier #define SIZE(d)	D2H(d)->size
29*ebd848c1SDavid du Colombier 
30*ebd848c1SDavid du Colombier static char *spacename[] = {
31*ebd848c1SDavid du Colombier 	"Mem",
32*ebd848c1SDavid du Colombier 	"Io",
33*ebd848c1SDavid du Colombier 	"Pcicfg",
34*ebd848c1SDavid du Colombier 	"Ebctl",
35*ebd848c1SDavid du Colombier 	"Smbus",
36*ebd848c1SDavid du Colombier 	"Cmos",
37*ebd848c1SDavid du Colombier 	"Pcibar",
38*ebd848c1SDavid du Colombier 	"Ipmi",
39*ebd848c1SDavid du Colombier };
40*ebd848c1SDavid du Colombier 
41*ebd848c1SDavid du Colombier /* field flags */
42*ebd848c1SDavid du Colombier enum {
43*ebd848c1SDavid du Colombier 	AnyAcc		= 0x00,
44*ebd848c1SDavid du Colombier 	ByteAcc		= 0x01,
45*ebd848c1SDavid du Colombier 	WordAcc		= 0x02,
46*ebd848c1SDavid du Colombier 	DWordAcc	= 0x03,
47*ebd848c1SDavid du Colombier 	QWordAcc	= 0x04,
48*ebd848c1SDavid du Colombier 	BufferAcc	= 0x05,
49*ebd848c1SDavid du Colombier 	AccMask		= 0x07,
50*ebd848c1SDavid du Colombier 
51*ebd848c1SDavid du Colombier 	NoLock		= 0x10,
52*ebd848c1SDavid du Colombier 
53*ebd848c1SDavid du Colombier 	Preserve	= 0x00,
54*ebd848c1SDavid du Colombier 	WriteAsOnes	= 0x20,
55*ebd848c1SDavid du Colombier 	WriteAsZeros	= 0x40,
56*ebd848c1SDavid du Colombier 	UpdateMask	= 0x60,
57*ebd848c1SDavid du Colombier };
58*ebd848c1SDavid du Colombier 
59*ebd848c1SDavid du Colombier struct Method {
60*ebd848c1SDavid du Colombier 	Name	*name;
61*ebd848c1SDavid du Colombier 	int	narg;
62*ebd848c1SDavid du Colombier 	void*	(*eval)(void);
63*ebd848c1SDavid du Colombier 	uchar	*start;
64*ebd848c1SDavid du Colombier 	uchar	*end;
65*ebd848c1SDavid du Colombier };
66*ebd848c1SDavid du Colombier 
67*ebd848c1SDavid du Colombier struct Region {
68*ebd848c1SDavid du Colombier 	Amlio;
69*ebd848c1SDavid du Colombier 	char	mapped;
70*ebd848c1SDavid du Colombier };
71*ebd848c1SDavid du Colombier 
72*ebd848c1SDavid du Colombier struct Field {
73*ebd848c1SDavid du Colombier 	void	*reg;	/* Buffer or Region */
74*ebd848c1SDavid du Colombier 	Field	*index;
75*ebd848c1SDavid du Colombier 	void	*indexv;
76*ebd848c1SDavid du Colombier 	int	flags;
77*ebd848c1SDavid du Colombier 	int	bitoff;
78*ebd848c1SDavid du Colombier 	int	bitlen;
79*ebd848c1SDavid du Colombier };
80*ebd848c1SDavid du Colombier 
81*ebd848c1SDavid du Colombier struct Name {
82*ebd848c1SDavid du Colombier 	void	*v;
83*ebd848c1SDavid du Colombier 
84*ebd848c1SDavid du Colombier 	Name	*up;
85*ebd848c1SDavid du Colombier 	Name	*next;
86*ebd848c1SDavid du Colombier 	Name	*fork;
87*ebd848c1SDavid du Colombier 	Name	*down;
88*ebd848c1SDavid du Colombier 
89*ebd848c1SDavid du Colombier 	char	seg[4];
90*ebd848c1SDavid du Colombier };
91*ebd848c1SDavid du Colombier 
92*ebd848c1SDavid du Colombier struct Ref {
93*ebd848c1SDavid du Colombier 	void	*ref;
94*ebd848c1SDavid du Colombier 	void	**ptr;
95*ebd848c1SDavid du Colombier };
96*ebd848c1SDavid du Colombier 
97*ebd848c1SDavid du Colombier struct Env {
98*ebd848c1SDavid du Colombier 	void	*loc[8];
99*ebd848c1SDavid du Colombier 	void	*arg[8];
100*ebd848c1SDavid du Colombier };
101*ebd848c1SDavid du Colombier 
102*ebd848c1SDavid du Colombier struct Op {
103*ebd848c1SDavid du Colombier 	char	*name;
104*ebd848c1SDavid du Colombier 	char	*sequence;
105*ebd848c1SDavid du Colombier 	void*	(*eval)(void);
106*ebd848c1SDavid du Colombier };
107*ebd848c1SDavid du Colombier 
108*ebd848c1SDavid du Colombier struct Frame {
109*ebd848c1SDavid du Colombier 	int	tag;
110*ebd848c1SDavid du Colombier 	int	cond;
111*ebd848c1SDavid du Colombier 	char	*phase;
112*ebd848c1SDavid du Colombier 	uchar	*start;
113*ebd848c1SDavid du Colombier 	uchar	*end;
114*ebd848c1SDavid du Colombier 	Op	*op;
115*ebd848c1SDavid du Colombier 	Env	*env;
116*ebd848c1SDavid du Colombier 	Name	*dot;
117*ebd848c1SDavid du Colombier 	void	*ref;
118*ebd848c1SDavid du Colombier 	void	*aux;
119*ebd848c1SDavid du Colombier 	int	narg;
120*ebd848c1SDavid du Colombier 	void	*arg[8];
121*ebd848c1SDavid du Colombier };
122*ebd848c1SDavid du Colombier 
123*ebd848c1SDavid du Colombier struct Interp {
124*ebd848c1SDavid du Colombier 	uchar	*pc;
125*ebd848c1SDavid du Colombier 	Frame	*fp;
126*ebd848c1SDavid du Colombier };
127*ebd848c1SDavid du Colombier 
128*ebd848c1SDavid du Colombier static Interp	interp;
129*ebd848c1SDavid du Colombier static Frame	stack[32];
130*ebd848c1SDavid du Colombier 
131*ebd848c1SDavid du Colombier #define PC	interp.pc
132*ebd848c1SDavid du Colombier #define	FP	interp.fp
133*ebd848c1SDavid du Colombier #define FB	stack
134*ebd848c1SDavid du Colombier #define FT	&stack[nelem(stack)]
135*ebd848c1SDavid du Colombier 
136*ebd848c1SDavid du Colombier static Heap *hp;
137*ebd848c1SDavid du Colombier 
138*ebd848c1SDavid du Colombier enum {
139*ebd848c1SDavid du Colombier 	Obad, Onop, Odebug,
140*ebd848c1SDavid du Colombier 	Ostr, Obyte, Oword, Odword, Oqword, Oconst,
141*ebd848c1SDavid du Colombier 	Onamec, Oname, Oscope, Oalias,
142*ebd848c1SDavid du Colombier 	Oreg, Ofld, Oxfld, Opkg, Ovpkg, Oenv, Obuf, Omet,
143*ebd848c1SDavid du Colombier 	Odev, Ocpu, Othz, Oprc,
144*ebd848c1SDavid du Colombier 	Oadd, Osub, Omod, Omul, Odiv, Oshl, Oshr, Oand, Onand, Oor,
145*ebd848c1SDavid du Colombier 	Onor, Oxor, Onot, Olbit, Orbit, Oinc, Odec,
146*ebd848c1SDavid du Colombier 	Oland, Olor, Olnot, Oleq, Olgt, Ollt,
147*ebd848c1SDavid du Colombier 	Oindex, Omutex, Oevent,
148*ebd848c1SDavid du Colombier 	Ocfld, Ocfld0, Ocfld1, Ocfld2, Ocfld4, Ocfld8,
149*ebd848c1SDavid du Colombier 	Oif, Oelse, Owhile, Obreak, Oret, Ocall,
150*ebd848c1SDavid du Colombier 	Ostore, Oderef, Osize, Oref, Ocref, Ocat,
151*ebd848c1SDavid du Colombier 	Oacq, Orel, Ostall, Osleep, Oload, Ounload,
152*ebd848c1SDavid du Colombier };
153*ebd848c1SDavid du Colombier 
154*ebd848c1SDavid du Colombier static Op optab[];
155*ebd848c1SDavid du Colombier static uchar octab1[];
156*ebd848c1SDavid du Colombier static uchar octab2[];
157*ebd848c1SDavid du Colombier 
158*ebd848c1SDavid du Colombier static Name*
rootname(Name * dot)159*ebd848c1SDavid du Colombier rootname(Name *dot)
160*ebd848c1SDavid du Colombier {
161*ebd848c1SDavid du Colombier 	while(dot != dot->up)
162*ebd848c1SDavid du Colombier 		dot = dot->up;
163*ebd848c1SDavid du Colombier 	return dot;
164*ebd848c1SDavid du Colombier }
165*ebd848c1SDavid du Colombier 
166*ebd848c1SDavid du Colombier static void
gcmark(void * p)167*ebd848c1SDavid du Colombier gcmark(void *p)
168*ebd848c1SDavid du Colombier {
169*ebd848c1SDavid du Colombier 	int i;
170*ebd848c1SDavid du Colombier 	Env *e;
171*ebd848c1SDavid du Colombier 	Field *f;
172*ebd848c1SDavid du Colombier 	Heap *h;
173*ebd848c1SDavid du Colombier 	Name *n, *d;
174*ebd848c1SDavid du Colombier 
175*ebd848c1SDavid du Colombier 	if(p == nil)
176*ebd848c1SDavid du Colombier 		return;
177*ebd848c1SDavid du Colombier 	h = D2H(p);
178*ebd848c1SDavid du Colombier 	if(h->mark & 1)
179*ebd848c1SDavid du Colombier 		return;
180*ebd848c1SDavid du Colombier 	h->mark |= 1;
181*ebd848c1SDavid du Colombier 	switch(h->tag){
182*ebd848c1SDavid du Colombier 	case 'E':
183*ebd848c1SDavid du Colombier 		e = p;
184*ebd848c1SDavid du Colombier 		for(i=0; i<nelem(e->loc); i++)
185*ebd848c1SDavid du Colombier 			gcmark(e->loc[i]);
186*ebd848c1SDavid du Colombier 		for(i=0; i<nelem(e->arg); i++)
187*ebd848c1SDavid du Colombier 			gcmark(e->arg[i]);
188*ebd848c1SDavid du Colombier 		break;
189*ebd848c1SDavid du Colombier 	case 'R':
190*ebd848c1SDavid du Colombier 	case 'A':
191*ebd848c1SDavid du Colombier 	case 'L':
192*ebd848c1SDavid du Colombier 		gcmark(((Ref*)p)->ref);
193*ebd848c1SDavid du Colombier 		break;
194*ebd848c1SDavid du Colombier 	case 'N':
195*ebd848c1SDavid du Colombier 		n = p;
196*ebd848c1SDavid du Colombier 		gcmark(n->v);
197*ebd848c1SDavid du Colombier 		for(d = n->down; d; d = d->next)
198*ebd848c1SDavid du Colombier 			gcmark(d);
199*ebd848c1SDavid du Colombier 		gcmark(n->fork);
200*ebd848c1SDavid du Colombier 		gcmark(n->up);
201*ebd848c1SDavid du Colombier 		break;
202*ebd848c1SDavid du Colombier 	case 'p':
203*ebd848c1SDavid du Colombier 		for(i=0; i<(SIZE(p)/sizeof(void*)); i++)
204*ebd848c1SDavid du Colombier 			gcmark(((void**)p)[i]);
205*ebd848c1SDavid du Colombier 		break;
206*ebd848c1SDavid du Colombier 	case 'r':
207*ebd848c1SDavid du Colombier 		gcmark(((Region*)p)->name);
208*ebd848c1SDavid du Colombier 		break;
209*ebd848c1SDavid du Colombier 	case 'm':
210*ebd848c1SDavid du Colombier 		gcmark(((Method*)p)->name);
211*ebd848c1SDavid du Colombier 		break;
212*ebd848c1SDavid du Colombier 	case 'f':
213*ebd848c1SDavid du Colombier 	case 'u':
214*ebd848c1SDavid du Colombier 		f = p;
215*ebd848c1SDavid du Colombier 		gcmark(f->reg);
216*ebd848c1SDavid du Colombier 		gcmark(f->index);
217*ebd848c1SDavid du Colombier 		gcmark(f->indexv);
218*ebd848c1SDavid du Colombier 		break;
219*ebd848c1SDavid du Colombier 	}
220*ebd848c1SDavid du Colombier }
221*ebd848c1SDavid du Colombier 
222*ebd848c1SDavid du Colombier static int
gc(void)223*ebd848c1SDavid du Colombier gc(void)
224*ebd848c1SDavid du Colombier {
225*ebd848c1SDavid du Colombier 	int i;
226*ebd848c1SDavid du Colombier 	Heap *h, **hh;
227*ebd848c1SDavid du Colombier 	Frame *f;
228*ebd848c1SDavid du Colombier 
229*ebd848c1SDavid du Colombier 	for(h = hp; h; h = h->link)
230*ebd848c1SDavid du Colombier 		h->mark &= ~1;
231*ebd848c1SDavid du Colombier 
232*ebd848c1SDavid du Colombier 	for(h = hp; h; h = h->link)
233*ebd848c1SDavid du Colombier 		if(h->mark & 2)
234*ebd848c1SDavid du Colombier 			gcmark(H2D(h));
235*ebd848c1SDavid du Colombier 
236*ebd848c1SDavid du Colombier 	for(f = FP; f >= FB; f--){
237*ebd848c1SDavid du Colombier 		for(i=0; i<f->narg; i++)
238*ebd848c1SDavid du Colombier 			gcmark(f->arg[i]);
239*ebd848c1SDavid du Colombier 		gcmark(f->env);
240*ebd848c1SDavid du Colombier 		gcmark(f->dot);
241*ebd848c1SDavid du Colombier 		gcmark(f->ref);
242*ebd848c1SDavid du Colombier 	}
243*ebd848c1SDavid du Colombier 
244*ebd848c1SDavid du Colombier 	gcmark(amlroot);
245*ebd848c1SDavid du Colombier 
246*ebd848c1SDavid du Colombier 	i = 0;
247*ebd848c1SDavid du Colombier 	hh = &hp;
248*ebd848c1SDavid du Colombier 	while(h = *hh){
249*ebd848c1SDavid du Colombier 		if(h->mark){
250*ebd848c1SDavid du Colombier 			hh = &h->link;
251*ebd848c1SDavid du Colombier 			continue;
252*ebd848c1SDavid du Colombier 		}
253*ebd848c1SDavid du Colombier 		*hh = h->link;
254*ebd848c1SDavid du Colombier 		if(h->tag == 'r'){
255*ebd848c1SDavid du Colombier 			Region *r = (void*)H2D(h);
256*ebd848c1SDavid du Colombier 			if(r->mapped > 0){
257*ebd848c1SDavid du Colombier 				if(amldebug)
258*ebd848c1SDavid du Colombier 					print("\namlunmapio(%N): %-8s %llux - %llux\n",
259*ebd848c1SDavid du Colombier 						(Name*)r->name, spacename[r->space],
260*ebd848c1SDavid du Colombier 						r->off, r->off + r->len);
261*ebd848c1SDavid du Colombier 				amlunmapio(r);
262*ebd848c1SDavid du Colombier 			}
263*ebd848c1SDavid du Colombier 			r->mapped = 0;
264*ebd848c1SDavid du Colombier 			r->write = nil;
265*ebd848c1SDavid du Colombier 			r->read = nil;
266*ebd848c1SDavid du Colombier 			r->aux = nil;
267*ebd848c1SDavid du Colombier 			r->va = nil;
268*ebd848c1SDavid du Colombier 		}
269*ebd848c1SDavid du Colombier 		memset(h, ~0, sizeof(Heap)+h->size);
270*ebd848c1SDavid du Colombier 		amlfree(h);
271*ebd848c1SDavid du Colombier 		i++;
272*ebd848c1SDavid du Colombier 	}
273*ebd848c1SDavid du Colombier 
274*ebd848c1SDavid du Colombier 	return i;
275*ebd848c1SDavid du Colombier }
276*ebd848c1SDavid du Colombier 
277*ebd848c1SDavid du Colombier static void*
mk(int tag,int size)278*ebd848c1SDavid du Colombier mk(int tag, int size)
279*ebd848c1SDavid du Colombier {
280*ebd848c1SDavid du Colombier 	Heap *h;
281*ebd848c1SDavid du Colombier 	int a;
282*ebd848c1SDavid du Colombier 
283*ebd848c1SDavid du Colombier 	a = sizeof(Heap) + size;
284*ebd848c1SDavid du Colombier 	h = amlalloc(a);
285*ebd848c1SDavid du Colombier 	h->size = size;
286*ebd848c1SDavid du Colombier 	h->tag = tag;
287*ebd848c1SDavid du Colombier 	h->link = hp;
288*ebd848c1SDavid du Colombier 	hp = h;
289*ebd848c1SDavid du Colombier 	return h+1;
290*ebd848c1SDavid du Colombier }
291*ebd848c1SDavid du Colombier 
292*ebd848c1SDavid du Colombier static uvlong*
mki(uvlong i)293*ebd848c1SDavid du Colombier mki(uvlong i)
294*ebd848c1SDavid du Colombier {
295*ebd848c1SDavid du Colombier 	uvlong *v;
296*ebd848c1SDavid du Colombier 
297*ebd848c1SDavid du Colombier 	v = mk('i', sizeof(uvlong));
298*ebd848c1SDavid du Colombier 	*v = i;
299*ebd848c1SDavid du Colombier 	return v;
300*ebd848c1SDavid du Colombier }
301*ebd848c1SDavid du Colombier 
302*ebd848c1SDavid du Colombier static char*
mks(char * s)303*ebd848c1SDavid du Colombier mks(char *s)
304*ebd848c1SDavid du Colombier {
305*ebd848c1SDavid du Colombier 	char *r = mk('s', strlen(s)+1);
306*ebd848c1SDavid du Colombier 	strcpy(r, s);
307*ebd848c1SDavid du Colombier 	return r;
308*ebd848c1SDavid du Colombier }
309*ebd848c1SDavid du Colombier 
310*ebd848c1SDavid du Colombier static int
pkglen(uchar * p,uchar * e,uchar ** np)311*ebd848c1SDavid du Colombier pkglen(uchar *p, uchar *e, uchar **np)
312*ebd848c1SDavid du Colombier {
313*ebd848c1SDavid du Colombier 	ulong n;
314*ebd848c1SDavid du Colombier 	uchar b;
315*ebd848c1SDavid du Colombier 
316*ebd848c1SDavid du Colombier 	if(p >= e)
317*ebd848c1SDavid du Colombier 		return -1;
318*ebd848c1SDavid du Colombier 	b = *p++;
319*ebd848c1SDavid du Colombier 	if(b <= 0x3F)
320*ebd848c1SDavid du Colombier 		n = b;
321*ebd848c1SDavid du Colombier 	else {
322*ebd848c1SDavid du Colombier 		n = b & 0xF;
323*ebd848c1SDavid du Colombier 		if(p >= e)
324*ebd848c1SDavid du Colombier 			return -1;
325*ebd848c1SDavid du Colombier 		n += *p++ << 4;
326*ebd848c1SDavid du Colombier 		if(b >= 0x80){
327*ebd848c1SDavid du Colombier 			if(p >= e)
328*ebd848c1SDavid du Colombier 				return -1;
329*ebd848c1SDavid du Colombier 			n += *p++ << 12;
330*ebd848c1SDavid du Colombier 		}
331*ebd848c1SDavid du Colombier 		if(b >= 0xC0){
332*ebd848c1SDavid du Colombier 			if(p >= e)
333*ebd848c1SDavid du Colombier 				return -1;
334*ebd848c1SDavid du Colombier 			n += *p++ << 20;
335*ebd848c1SDavid du Colombier 		}
336*ebd848c1SDavid du Colombier 	}
337*ebd848c1SDavid du Colombier 	if(np)
338*ebd848c1SDavid du Colombier 		*np = p;
339*ebd848c1SDavid du Colombier 	return n;
340*ebd848c1SDavid du Colombier }
341*ebd848c1SDavid du Colombier 
342*ebd848c1SDavid du Colombier static Name*
forkname(Name * dot)343*ebd848c1SDavid du Colombier forkname(Name *dot)
344*ebd848c1SDavid du Colombier {
345*ebd848c1SDavid du Colombier 	Name *n;
346*ebd848c1SDavid du Colombier 
347*ebd848c1SDavid du Colombier 	n = mk('N', sizeof(Name));
348*ebd848c1SDavid du Colombier 	*n = *dot;
349*ebd848c1SDavid du Colombier 	n->fork = dot;
350*ebd848c1SDavid du Colombier 	n->next = n->down = nil;
351*ebd848c1SDavid du Colombier 	if(dot->v == dot)
352*ebd848c1SDavid du Colombier 		n->v = n;
353*ebd848c1SDavid du Colombier 	if(dot->up == dot)
354*ebd848c1SDavid du Colombier 		n->up = n;
355*ebd848c1SDavid du Colombier 	else {
356*ebd848c1SDavid du Colombier 		if(n->up = forkname(dot->up))
357*ebd848c1SDavid du Colombier 			n->up->down = n;
358*ebd848c1SDavid du Colombier 	}
359*ebd848c1SDavid du Colombier 	return n;
360*ebd848c1SDavid du Colombier }
361*ebd848c1SDavid du Colombier 
362*ebd848c1SDavid du Colombier static Name*
getseg(Name * dot,void * seg,int new)363*ebd848c1SDavid du Colombier getseg(Name *dot, void *seg, int new)
364*ebd848c1SDavid du Colombier {
365*ebd848c1SDavid du Colombier 	Name *n, *l;
366*ebd848c1SDavid du Colombier 
367*ebd848c1SDavid du Colombier 	for(n = l = nil; dot; dot = dot->fork){
368*ebd848c1SDavid du Colombier 		for(n = dot->down; n; n = n->next){
369*ebd848c1SDavid du Colombier 			if(memcmp(seg, n->seg, 4) == 0)
370*ebd848c1SDavid du Colombier 				return n;
371*ebd848c1SDavid du Colombier 			l = n;
372*ebd848c1SDavid du Colombier 		}
373*ebd848c1SDavid du Colombier 		if(new){
374*ebd848c1SDavid du Colombier 			n = mk('N', sizeof(Name));
375*ebd848c1SDavid du Colombier 			memmove(n->seg, seg, sizeof(n->seg));
376*ebd848c1SDavid du Colombier 			n->up = dot;
377*ebd848c1SDavid du Colombier 			if(l == nil)
378*ebd848c1SDavid du Colombier 				dot->down = n;
379*ebd848c1SDavid du Colombier 			else
380*ebd848c1SDavid du Colombier 				l->next = n;
381*ebd848c1SDavid du Colombier 			n->v = n;
382*ebd848c1SDavid du Colombier 			break;
383*ebd848c1SDavid du Colombier 		}
384*ebd848c1SDavid du Colombier 	}
385*ebd848c1SDavid du Colombier 	return n;
386*ebd848c1SDavid du Colombier }
387*ebd848c1SDavid du Colombier 
388*ebd848c1SDavid du Colombier Name*
getname(Name * dot,char * path,int new)389*ebd848c1SDavid du Colombier getname(Name *dot, char *path, int new)
390*ebd848c1SDavid du Colombier {
391*ebd848c1SDavid du Colombier 	char seg[4];
392*ebd848c1SDavid du Colombier 	int i, s;
393*ebd848c1SDavid du Colombier 	Name *x;
394*ebd848c1SDavid du Colombier 
395*ebd848c1SDavid du Colombier 	s = !new;
396*ebd848c1SDavid du Colombier 	if(*path == '\\'){
397*ebd848c1SDavid du Colombier 		path++;
398*ebd848c1SDavid du Colombier 		dot = rootname(dot);
399*ebd848c1SDavid du Colombier 		s = 0;
400*ebd848c1SDavid du Colombier 	}
401*ebd848c1SDavid du Colombier 	while(*path == '^'){
402*ebd848c1SDavid du Colombier 		path++;
403*ebd848c1SDavid du Colombier 		dot = dot->up;
404*ebd848c1SDavid du Colombier 		s = 0;
405*ebd848c1SDavid du Colombier 	}
406*ebd848c1SDavid du Colombier 	do {
407*ebd848c1SDavid du Colombier 		for(i=0; i<4; i++){
408*ebd848c1SDavid du Colombier 			if(*path == 0 || *path == '.')
409*ebd848c1SDavid du Colombier 				break;
410*ebd848c1SDavid du Colombier 			seg[i] = *path++;
411*ebd848c1SDavid du Colombier 		}
412*ebd848c1SDavid du Colombier 		if(i == 0)
413*ebd848c1SDavid du Colombier 			break;
414*ebd848c1SDavid du Colombier 		while(i < 4)
415*ebd848c1SDavid du Colombier 			seg[i++] = '_';
416*ebd848c1SDavid du Colombier 		if(s && *path == 0){
417*ebd848c1SDavid du Colombier 			for(;;){
418*ebd848c1SDavid du Colombier 				if(x = getseg(dot, seg, 0))
419*ebd848c1SDavid du Colombier 					break;
420*ebd848c1SDavid du Colombier 				if(dot == dot->up)
421*ebd848c1SDavid du Colombier 					break;
422*ebd848c1SDavid du Colombier 				dot = dot->up;
423*ebd848c1SDavid du Colombier 			}
424*ebd848c1SDavid du Colombier 			return x;
425*ebd848c1SDavid du Colombier 		}
426*ebd848c1SDavid du Colombier 		s = 0;
427*ebd848c1SDavid du Colombier 		dot = getseg(dot, seg, new);
428*ebd848c1SDavid du Colombier 	} while(*path++ == '.');
429*ebd848c1SDavid du Colombier 
430*ebd848c1SDavid du Colombier 	return dot;
431*ebd848c1SDavid du Colombier }
432*ebd848c1SDavid du Colombier 
433*ebd848c1SDavid du Colombier static int
fixnames(void * dot,void * arg)434*ebd848c1SDavid du Colombier fixnames(void *dot, void *arg)
435*ebd848c1SDavid du Colombier {
436*ebd848c1SDavid du Colombier 	void **r, *v;
437*ebd848c1SDavid du Colombier 	int i;
438*ebd848c1SDavid du Colombier 
439*ebd848c1SDavid du Colombier 	if(arg == nil)
440*ebd848c1SDavid du Colombier 		r = &((Name*)dot)->v;
441*ebd848c1SDavid du Colombier 	else
442*ebd848c1SDavid du Colombier 		r = arg;
443*ebd848c1SDavid du Colombier 	v = *r;
444*ebd848c1SDavid du Colombier 	if(v == nil || v == dot)
445*ebd848c1SDavid du Colombier 		return 0;
446*ebd848c1SDavid du Colombier 	if(TAG(v) == 'p'){
447*ebd848c1SDavid du Colombier 		r = (void**)v;
448*ebd848c1SDavid du Colombier 		for(i=0; i<(SIZE(r)/sizeof(void*)); i++)
449*ebd848c1SDavid du Colombier 			fixnames(dot, r+i);
450*ebd848c1SDavid du Colombier 		return 0;
451*ebd848c1SDavid du Colombier 	}
452*ebd848c1SDavid du Colombier 	if(TAG(v) == 'n' && (v = getname(dot, v, 0)) != nil)
453*ebd848c1SDavid du Colombier 		*r = v;
454*ebd848c1SDavid du Colombier 	return 0;
455*ebd848c1SDavid du Colombier }
456*ebd848c1SDavid du Colombier 
457*ebd848c1SDavid du Colombier static uvlong
getle(uchar * p,int len)458*ebd848c1SDavid du Colombier getle(uchar *p, int len)
459*ebd848c1SDavid du Colombier {
460*ebd848c1SDavid du Colombier 	uvlong v;
461*ebd848c1SDavid du Colombier 	int i;
462*ebd848c1SDavid du Colombier 
463*ebd848c1SDavid du Colombier 	v = 0ULL;
464*ebd848c1SDavid du Colombier 	for(i=0; i<len; i++)
465*ebd848c1SDavid du Colombier 		v |= ((uvlong)p[i]) << i*8;
466*ebd848c1SDavid du Colombier 	return v;
467*ebd848c1SDavid du Colombier }
468*ebd848c1SDavid du Colombier 
469*ebd848c1SDavid du Colombier static void
putle(uchar * p,int len,uvlong v)470*ebd848c1SDavid du Colombier putle(uchar *p, int len, uvlong v)
471*ebd848c1SDavid du Colombier {
472*ebd848c1SDavid du Colombier 	int i;
473*ebd848c1SDavid du Colombier 
474*ebd848c1SDavid du Colombier 	for(i=0; i<len; i++){
475*ebd848c1SDavid du Colombier 		p[i] = v;
476*ebd848c1SDavid du Colombier 		v >>= 8;
477*ebd848c1SDavid du Colombier 	}
478*ebd848c1SDavid du Colombier }
479*ebd848c1SDavid du Colombier 
480*ebd848c1SDavid du Colombier static uvlong
rwreg(void * reg,int off,int len,uvlong v,int write)481*ebd848c1SDavid du Colombier rwreg(void *reg, int off, int len, uvlong v, int write)
482*ebd848c1SDavid du Colombier {
483*ebd848c1SDavid du Colombier 	uchar buf[8], *p;
484*ebd848c1SDavid du Colombier 	Region *r;
485*ebd848c1SDavid du Colombier 
486*ebd848c1SDavid du Colombier 	switch(TAG(reg)){
487*ebd848c1SDavid du Colombier 	case 'b':
488*ebd848c1SDavid du Colombier 		p = reg;
489*ebd848c1SDavid du Colombier 		if((off+len) > SIZE(p))
490*ebd848c1SDavid du Colombier 			break;
491*ebd848c1SDavid du Colombier 		p += off;
492*ebd848c1SDavid du Colombier 		if(write)
493*ebd848c1SDavid du Colombier 			putle(p, len, v);
494*ebd848c1SDavid du Colombier 		else
495*ebd848c1SDavid du Colombier 			v = getle(p, len);
496*ebd848c1SDavid du Colombier 		return v;
497*ebd848c1SDavid du Colombier 
498*ebd848c1SDavid du Colombier 	case 'r':
499*ebd848c1SDavid du Colombier 		r = reg;
500*ebd848c1SDavid du Colombier 		if((off+len) > r->len)
501*ebd848c1SDavid du Colombier 			break;
502*ebd848c1SDavid du Colombier 		if(r->mapped == 0){
503*ebd848c1SDavid du Colombier 			if(amldebug)
504*ebd848c1SDavid du Colombier 				print("\namlmapio(%N): %-8s %llux - %llux\n",
505*ebd848c1SDavid du Colombier 					(Name*)r->name, spacename[r->space],
506*ebd848c1SDavid du Colombier 					r->off, r->off + r->len);
507*ebd848c1SDavid du Colombier 			r->mapped = 1;
508*ebd848c1SDavid du Colombier 			if(amlmapio(r) < 0)
509*ebd848c1SDavid du Colombier 				r->mapped = -1;
510*ebd848c1SDavid du Colombier 		}
511*ebd848c1SDavid du Colombier 		if(r->mapped <= 0)
512*ebd848c1SDavid du Colombier 			break;
513*ebd848c1SDavid du Colombier 
514*ebd848c1SDavid du Colombier 		if(r->va != nil)
515*ebd848c1SDavid du Colombier 			p = r->va + off;
516*ebd848c1SDavid du Colombier 		else {
517*ebd848c1SDavid du Colombier 			if(len > sizeof(buf))
518*ebd848c1SDavid du Colombier 				break;
519*ebd848c1SDavid du Colombier 			p = buf;
520*ebd848c1SDavid du Colombier 		}
521*ebd848c1SDavid du Colombier 
522*ebd848c1SDavid du Colombier 		if(write){
523*ebd848c1SDavid du Colombier 			if(amldebug)
524*ebd848c1SDavid du Colombier 				print("\nrwreg(%N): %-8s [%llux+%x]/%d <- %llux\n",
525*ebd848c1SDavid du Colombier 					(Name*)r->name, spacename[r->space],
526*ebd848c1SDavid du Colombier 					r->off, off, len, v);
527*ebd848c1SDavid du Colombier 			putle(p, len, v);
528*ebd848c1SDavid du Colombier 			if(r->write != nil){
529*ebd848c1SDavid du Colombier 				if((*r->write)(r, p, len, off) != len)
530*ebd848c1SDavid du Colombier 					break;
531*ebd848c1SDavid du Colombier 			} else if(p == buf)
532*ebd848c1SDavid du Colombier 				break;
533*ebd848c1SDavid du Colombier 		} else {
534*ebd848c1SDavid du Colombier 			if(r->read != nil){
535*ebd848c1SDavid du Colombier 				if((*r->read)(r, p, len, off) != len)
536*ebd848c1SDavid du Colombier 					break;
537*ebd848c1SDavid du Colombier 			} else if(p == buf)
538*ebd848c1SDavid du Colombier 				break;
539*ebd848c1SDavid du Colombier 			v = getle(p, len);
540*ebd848c1SDavid du Colombier 			if(amldebug)
541*ebd848c1SDavid du Colombier 				print("\nrwreg(%N): %-8s [%llux+%x]/%d -> %llux\n",
542*ebd848c1SDavid du Colombier 					(Name*)r->name, spacename[r->space],
543*ebd848c1SDavid du Colombier 					r->off, off, len, v);
544*ebd848c1SDavid du Colombier 		}
545*ebd848c1SDavid du Colombier 		return v;
546*ebd848c1SDavid du Colombier 	}
547*ebd848c1SDavid du Colombier 
548*ebd848c1SDavid du Colombier 	return ~0;
549*ebd848c1SDavid du Colombier }
550*ebd848c1SDavid du Colombier 
551*ebd848c1SDavid du Colombier static uvlong
ival(void * p)552*ebd848c1SDavid du Colombier ival(void *p)
553*ebd848c1SDavid du Colombier {
554*ebd848c1SDavid du Colombier 	int n;
555*ebd848c1SDavid du Colombier 
556*ebd848c1SDavid du Colombier 	if(p != nil){
557*ebd848c1SDavid du Colombier 		switch(TAG(p)){
558*ebd848c1SDavid du Colombier 		case 'i':
559*ebd848c1SDavid du Colombier 			return *((uvlong*)p);
560*ebd848c1SDavid du Colombier 		case 's':
561*ebd848c1SDavid du Colombier 			if(*((char*)p) == 0)
562*ebd848c1SDavid du Colombier 				break;
563*ebd848c1SDavid du Colombier 			return strtoull((char*)p, 0, 16);
564*ebd848c1SDavid du Colombier 		case 'b':
565*ebd848c1SDavid du Colombier 			n = SIZE(p);
566*ebd848c1SDavid du Colombier 			if(n > 0){
567*ebd848c1SDavid du Colombier 				if(n > 8) n = 8;
568*ebd848c1SDavid du Colombier 				return rwreg(p, 0, n, 0, 0);
569*ebd848c1SDavid du Colombier 			}
570*ebd848c1SDavid du Colombier 		}
571*ebd848c1SDavid du Colombier 	}
572*ebd848c1SDavid du Colombier 	return 0;
573*ebd848c1SDavid du Colombier }
574*ebd848c1SDavid du Colombier 
575*ebd848c1SDavid du Colombier static void *deref(void *p);
576*ebd848c1SDavid du Colombier static void *store(void *s, void *d);
577*ebd848c1SDavid du Colombier 
578*ebd848c1SDavid du Colombier static int
fieldalign(int flags)579*ebd848c1SDavid du Colombier fieldalign(int flags)
580*ebd848c1SDavid du Colombier {
581*ebd848c1SDavid du Colombier 	switch(flags & AccMask){
582*ebd848c1SDavid du Colombier 	default:
583*ebd848c1SDavid du Colombier 	case AnyAcc:
584*ebd848c1SDavid du Colombier 	case ByteAcc:
585*ebd848c1SDavid du Colombier 	case BufferAcc:
586*ebd848c1SDavid du Colombier 		return 1;
587*ebd848c1SDavid du Colombier 	case WordAcc:
588*ebd848c1SDavid du Colombier 		return 2;
589*ebd848c1SDavid du Colombier 	case DWordAcc:
590*ebd848c1SDavid du Colombier 		return 4;
591*ebd848c1SDavid du Colombier 	case QWordAcc:
592*ebd848c1SDavid du Colombier 		return 8;
593*ebd848c1SDavid du Colombier 	}
594*ebd848c1SDavid du Colombier }
595*ebd848c1SDavid du Colombier 
596*ebd848c1SDavid du Colombier static void*
rwfield(Field * f,void * v,int write)597*ebd848c1SDavid du Colombier rwfield(Field *f, void *v, int write)
598*ebd848c1SDavid du Colombier {
599*ebd848c1SDavid du Colombier 	int boff, blen, wo, ws, wl, wa, wd, i;
600*ebd848c1SDavid du Colombier 	uvlong w, m;
601*ebd848c1SDavid du Colombier 	void *reg;
602*ebd848c1SDavid du Colombier 	uchar *b;
603*ebd848c1SDavid du Colombier 
604*ebd848c1SDavid du Colombier 	if(f == nil || (reg = deref(f->reg)) == nil)
605*ebd848c1SDavid du Colombier 		return nil;
606*ebd848c1SDavid du Colombier 	if(f->index)
607*ebd848c1SDavid du Colombier 		store(f->indexv, f->index);
608*ebd848c1SDavid du Colombier 	blen = f->bitlen;
609*ebd848c1SDavid du Colombier 	if(write){
610*ebd848c1SDavid du Colombier 		if(v && TAG(v) == 'b'){
611*ebd848c1SDavid du Colombier 			b = v;
612*ebd848c1SDavid du Colombier 			if(SIZE(b)*8 < blen)
613*ebd848c1SDavid du Colombier 				blen = SIZE(b)*8;
614*ebd848c1SDavid du Colombier 		} else {
615*ebd848c1SDavid du Colombier 			w = ival(v);
616*ebd848c1SDavid du Colombier 			b = mk('b', (blen+7)/8);
617*ebd848c1SDavid du Colombier 			putle(b, SIZE(b), w);
618*ebd848c1SDavid du Colombier 		}
619*ebd848c1SDavid du Colombier 	} else
620*ebd848c1SDavid du Colombier 		b = mk('b', (blen+7)/8);
621*ebd848c1SDavid du Colombier 	wa = fieldalign(f->flags);
622*ebd848c1SDavid du Colombier 	wd = wa*8;
623*ebd848c1SDavid du Colombier 	boff = 0;
624*ebd848c1SDavid du Colombier 	while((wl = (blen-boff)) > 0){
625*ebd848c1SDavid du Colombier 		wo = (f->bitoff+boff) / wd;
626*ebd848c1SDavid du Colombier 		ws = (f->bitoff+boff) % wd;
627*ebd848c1SDavid du Colombier 		if(wl > (wd - ws))
628*ebd848c1SDavid du Colombier 			wl = wd - ws;
629*ebd848c1SDavid du Colombier 		if(write){
630*ebd848c1SDavid du Colombier 			w = 0;
631*ebd848c1SDavid du Colombier 			for(i = 0; i < wl; i++, boff++)
632*ebd848c1SDavid du Colombier 				if(b[boff/8] & (1<<(boff%8)))
633*ebd848c1SDavid du Colombier 					w |= 1ULL<<i;
634*ebd848c1SDavid du Colombier 			w <<= ws;
635*ebd848c1SDavid du Colombier 			if(wl != wd){
636*ebd848c1SDavid du Colombier 				m = ((1ULL<<wl)-1) << ws;
637*ebd848c1SDavid du Colombier 				w |= rwreg(reg, wo*wa, wa, 0, 0) & ~m;
638*ebd848c1SDavid du Colombier 			}
639*ebd848c1SDavid du Colombier 			rwreg(reg, wo*wa, wa, w, 1);
640*ebd848c1SDavid du Colombier 		} else {
641*ebd848c1SDavid du Colombier 			w = rwreg(reg, wo*wa, wa, 0, 0) >> ws;
642*ebd848c1SDavid du Colombier 			for(i = 0; i < wl; i++, boff++){
643*ebd848c1SDavid du Colombier 				b[boff/8] |= (w&1)<<(boff%8);
644*ebd848c1SDavid du Colombier 				w >>= 1;
645*ebd848c1SDavid du Colombier 			}
646*ebd848c1SDavid du Colombier 		}
647*ebd848c1SDavid du Colombier 	}
648*ebd848c1SDavid du Colombier 	if(write)
649*ebd848c1SDavid du Colombier 		return nil;
650*ebd848c1SDavid du Colombier 	if(blen > 64)
651*ebd848c1SDavid du Colombier 		return b;
652*ebd848c1SDavid du Colombier 	w = getle(b, SIZE(b));
653*ebd848c1SDavid du Colombier 	return mki(w);
654*ebd848c1SDavid du Colombier }
655*ebd848c1SDavid du Colombier 
656*ebd848c1SDavid du Colombier static void*
deref(void * p)657*ebd848c1SDavid du Colombier deref(void *p)
658*ebd848c1SDavid du Colombier {
659*ebd848c1SDavid du Colombier 	if(p) switch(TAG(p)){
660*ebd848c1SDavid du Colombier 	case 'N':
661*ebd848c1SDavid du Colombier 		return ((Name*)p)->v;
662*ebd848c1SDavid du Colombier 	case 'R': case 'A': case 'L':
663*ebd848c1SDavid du Colombier 		return *((Ref*)p)->ptr;
664*ebd848c1SDavid du Colombier 	case 'f': case 'u':
665*ebd848c1SDavid du Colombier 		return rwfield(p, nil, 0);
666*ebd848c1SDavid du Colombier 	}
667*ebd848c1SDavid du Colombier 	return p;
668*ebd848c1SDavid du Colombier }
669*ebd848c1SDavid du Colombier 
670*ebd848c1SDavid du Colombier static void*
copy(int tag,void * s)671*ebd848c1SDavid du Colombier copy(int tag, void *s)
672*ebd848c1SDavid du Colombier {
673*ebd848c1SDavid du Colombier 	static char hex[] = "0123456789ABCDEF";
674*ebd848c1SDavid du Colombier 	uvlong v;
675*ebd848c1SDavid du Colombier 	void *d;
676*ebd848c1SDavid du Colombier 	int i, n;
677*ebd848c1SDavid du Colombier 
678*ebd848c1SDavid du Colombier 	if(tag == 0){
679*ebd848c1SDavid du Colombier 		if(s == nil)
680*ebd848c1SDavid du Colombier 			return nil;
681*ebd848c1SDavid du Colombier 		tag = TAG(s);
682*ebd848c1SDavid du Colombier 	}
683*ebd848c1SDavid du Colombier 	if(s == nil || TAG(s) == 'i'){
684*ebd848c1SDavid du Colombier 		n = 4;
685*ebd848c1SDavid du Colombier 		v = ival(s);
686*ebd848c1SDavid du Colombier 		if(v > 0xFFFFFFFFULL)
687*ebd848c1SDavid du Colombier 			n <<= 1;
688*ebd848c1SDavid du Colombier 		switch(tag){
689*ebd848c1SDavid du Colombier 		case 'b':
690*ebd848c1SDavid du Colombier 			d = mk(tag, n);
691*ebd848c1SDavid du Colombier 			rwreg(d, 0, n, v, 1);
692*ebd848c1SDavid du Colombier 			return d;
693*ebd848c1SDavid du Colombier 		case 's':
694*ebd848c1SDavid du Colombier 			n <<= 1;
695*ebd848c1SDavid du Colombier 			d = mk(tag, n+1);
696*ebd848c1SDavid du Colombier 			((char*)d)[n] = 0;
697*ebd848c1SDavid du Colombier 			while(n > 0){
698*ebd848c1SDavid du Colombier 				((char*)d)[--n] = hex[v & 0xF];
699*ebd848c1SDavid du Colombier 				v >>= 4;
700*ebd848c1SDavid du Colombier 			}
701*ebd848c1SDavid du Colombier 			return d;
702*ebd848c1SDavid du Colombier 		case 'i':
703*ebd848c1SDavid du Colombier 			if(v == 0ULL)
704*ebd848c1SDavid du Colombier 				return nil;
705*ebd848c1SDavid du Colombier 			return mki(v);
706*ebd848c1SDavid du Colombier 		}
707*ebd848c1SDavid du Colombier 	} else {
708*ebd848c1SDavid du Colombier 		n = SIZE(s);
709*ebd848c1SDavid du Colombier 		switch(tag){
710*ebd848c1SDavid du Colombier 		case 's':
711*ebd848c1SDavid du Colombier 			if(TAG(s) == 'b'){
712*ebd848c1SDavid du Colombier 				d = mk(tag, n*3 + 1);
713*ebd848c1SDavid du Colombier 				for(i=0; i<n; i++){
714*ebd848c1SDavid du Colombier 					((char*)d)[i*3 + 0] = hex[((uchar*)s)[i] >> 4];
715*ebd848c1SDavid du Colombier 					((char*)d)[i*3 + 1] = hex[((uchar*)s)[i] & 0xF];
716*ebd848c1SDavid du Colombier 					((char*)d)[i*3 + 2] = ' ';
717*ebd848c1SDavid du Colombier 				}
718*ebd848c1SDavid du Colombier 				((char*)d)[n*3] = 0;
719*ebd848c1SDavid du Colombier 				return d;
720*ebd848c1SDavid du Colombier 			}
721*ebd848c1SDavid du Colombier 			/* no break */
722*ebd848c1SDavid du Colombier 		case 'b':
723*ebd848c1SDavid du Colombier 			if(TAG(s) == 's'){
724*ebd848c1SDavid du Colombier 				n = strlen(s);
725*ebd848c1SDavid du Colombier 				/* zero length string is converted to zero length buffer */
726*ebd848c1SDavid du Colombier 				if(n > 0) n++;
727*ebd848c1SDavid du Colombier 			}
728*ebd848c1SDavid du Colombier 			d = mk(tag, n);
729*ebd848c1SDavid du Colombier 			memmove(d, s, n);
730*ebd848c1SDavid du Colombier 			return d;
731*ebd848c1SDavid du Colombier 		}
732*ebd848c1SDavid du Colombier 	}
733*ebd848c1SDavid du Colombier 	return s;
734*ebd848c1SDavid du Colombier }
735*ebd848c1SDavid du Colombier 
736*ebd848c1SDavid du Colombier static void*
store(void * s,void * d)737*ebd848c1SDavid du Colombier store(void *s, void *d)
738*ebd848c1SDavid du Colombier {
739*ebd848c1SDavid du Colombier 	void *p, **pp;
740*ebd848c1SDavid du Colombier 
741*ebd848c1SDavid du Colombier 	if(d == nil)
742*ebd848c1SDavid du Colombier 		return nil;
743*ebd848c1SDavid du Colombier 	switch(TAG(d)){
744*ebd848c1SDavid du Colombier 	default:
745*ebd848c1SDavid du Colombier 		return nil;
746*ebd848c1SDavid du Colombier 	case 'A':
747*ebd848c1SDavid du Colombier 		s = deref(s);
748*ebd848c1SDavid du Colombier 		/* no break */
749*ebd848c1SDavid du Colombier 	case 'R': case 'L':
750*ebd848c1SDavid du Colombier 		pp = ((Ref*)d)->ptr;
751*ebd848c1SDavid du Colombier 		while((p = *pp) != nil){
752*ebd848c1SDavid du Colombier 			switch(TAG(p)){
753*ebd848c1SDavid du Colombier 			case 'R': case 'A': case 'L':
754*ebd848c1SDavid du Colombier 				pp = ((Ref*)p)->ptr;
755*ebd848c1SDavid du Colombier 				break;
756*ebd848c1SDavid du Colombier 			case 'N':
757*ebd848c1SDavid du Colombier 				pp = &((Name*)p)->v;
758*ebd848c1SDavid du Colombier 				break;
759*ebd848c1SDavid du Colombier 			}
760*ebd848c1SDavid du Colombier 			if(*pp == p)
761*ebd848c1SDavid du Colombier 				break;
762*ebd848c1SDavid du Colombier 		}
763*ebd848c1SDavid du Colombier 		break;
764*ebd848c1SDavid du Colombier 	case 'N':
765*ebd848c1SDavid du Colombier 		pp = &((Name*)d)->v;
766*ebd848c1SDavid du Colombier 		break;
767*ebd848c1SDavid du Colombier 	}
768*ebd848c1SDavid du Colombier 	p = *pp;
769*ebd848c1SDavid du Colombier 	if(p != nil && TAG(p) != 'N'){
770*ebd848c1SDavid du Colombier 		switch(TAG(p)){
771*ebd848c1SDavid du Colombier 		case 'f':
772*ebd848c1SDavid du Colombier 		case 'u':
773*ebd848c1SDavid du Colombier 			rwfield(p, s, 1);
774*ebd848c1SDavid du Colombier 			return d;
775*ebd848c1SDavid du Colombier 		}
776*ebd848c1SDavid du Colombier 		if(TAG(d) != 'A' && TAG(d) != 'L'){
777*ebd848c1SDavid du Colombier 			*pp = copy(TAG(p), s);
778*ebd848c1SDavid du Colombier 			return d;
779*ebd848c1SDavid du Colombier 		}
780*ebd848c1SDavid du Colombier 	}
781*ebd848c1SDavid du Colombier 	*pp = copy(0, s);
782*ebd848c1SDavid du Colombier 	return d;
783*ebd848c1SDavid du Colombier }
784*ebd848c1SDavid du Colombier 
785*ebd848c1SDavid du Colombier static int
Nfmt(Fmt * f)786*ebd848c1SDavid du Colombier Nfmt(Fmt *f)
787*ebd848c1SDavid du Colombier {
788*ebd848c1SDavid du Colombier 	char buf[5];
789*ebd848c1SDavid du Colombier 	int i;
790*ebd848c1SDavid du Colombier 	Name *n;
791*ebd848c1SDavid du Colombier 
792*ebd848c1SDavid du Colombier 	n = va_arg(f->args, Name*);
793*ebd848c1SDavid du Colombier 	if(n == nil)
794*ebd848c1SDavid du Colombier 		return fmtprint(f, "?NIL");
795*ebd848c1SDavid du Colombier 	if(n == n->up)
796*ebd848c1SDavid du Colombier 		return fmtprint(f, "\\");
797*ebd848c1SDavid du Colombier 	strncpy(buf, n->seg, 4);
798*ebd848c1SDavid du Colombier 	buf[4] = 0;
799*ebd848c1SDavid du Colombier 	for(i=3; i>0; i--){
800*ebd848c1SDavid du Colombier 		if(buf[i] != '_')
801*ebd848c1SDavid du Colombier 			break;
802*ebd848c1SDavid du Colombier 		buf[i] = 0;
803*ebd848c1SDavid du Colombier 	}
804*ebd848c1SDavid du Colombier 	if(n->up == n->up->up)
805*ebd848c1SDavid du Colombier 		return fmtprint(f, "\\%s", buf);
806*ebd848c1SDavid du Colombier 	return fmtprint(f, "%N.%s", n->up, buf);
807*ebd848c1SDavid du Colombier }
808*ebd848c1SDavid du Colombier 
809*ebd848c1SDavid du Colombier static int
Vfmt(Fmt * f)810*ebd848c1SDavid du Colombier Vfmt(Fmt *f)
811*ebd848c1SDavid du Colombier {
812*ebd848c1SDavid du Colombier 	void *p;
813*ebd848c1SDavid du Colombier 	int i, n, c;
814*ebd848c1SDavid du Colombier 	Env *e;
815*ebd848c1SDavid du Colombier 	Field *l;
816*ebd848c1SDavid du Colombier 	Name *nm;
817*ebd848c1SDavid du Colombier 	Method *m;
818*ebd848c1SDavid du Colombier 	Region *g;
819*ebd848c1SDavid du Colombier 	Ref *r;
820*ebd848c1SDavid du Colombier 
821*ebd848c1SDavid du Colombier 	p = va_arg(f->args, void*);
822*ebd848c1SDavid du Colombier 	if(p == nil)
823*ebd848c1SDavid du Colombier 		return fmtprint(f, "nil");
824*ebd848c1SDavid du Colombier 	c = TAG(p);
825*ebd848c1SDavid du Colombier 	switch(c){
826*ebd848c1SDavid du Colombier 	case 'N':
827*ebd848c1SDavid du Colombier 		nm = p;
828*ebd848c1SDavid du Colombier 		if(nm->v != nm)
829*ebd848c1SDavid du Colombier 			return fmtprint(f, "%N=%V", nm, nm->v);
830*ebd848c1SDavid du Colombier 		return fmtprint(f, "%N=*", nm);
831*ebd848c1SDavid du Colombier 	case 'A':
832*ebd848c1SDavid du Colombier 	case 'L':
833*ebd848c1SDavid du Colombier 		r = p;
834*ebd848c1SDavid du Colombier 		e = r->ref;
835*ebd848c1SDavid du Colombier 		if(c == 'A')
836*ebd848c1SDavid du Colombier 			return fmtprint(f, "Arg%ld=%V", r->ptr - e->arg, *r->ptr);
837*ebd848c1SDavid du Colombier 		if(c == 'L')
838*ebd848c1SDavid du Colombier 			return fmtprint(f, "Local%ld=%V", r->ptr - e->loc, *r->ptr);
839*ebd848c1SDavid du Colombier 	case 'n':
840*ebd848c1SDavid du Colombier 		return fmtprint(f, "%s", (char*)p);
841*ebd848c1SDavid du Colombier 	case 's':
842*ebd848c1SDavid du Colombier 		return fmtprint(f, "\"%s\"", (char*)p);
843*ebd848c1SDavid du Colombier 	case 'i':
844*ebd848c1SDavid du Colombier 		return fmtprint(f, "%#llux", *((uvlong*)p));
845*ebd848c1SDavid du Colombier 	case 'p':
846*ebd848c1SDavid du Colombier 		n = SIZE(p)/sizeof(void*);
847*ebd848c1SDavid du Colombier 		fmtprint(f, "Package(%d){", n);
848*ebd848c1SDavid du Colombier 		for(i=0; i<n; i++){
849*ebd848c1SDavid du Colombier 			if(i > 0)
850*ebd848c1SDavid du Colombier 				fmtprint(f, ", ");
851*ebd848c1SDavid du Colombier 			fmtprint(f, "%V", ((void**)p)[i]);
852*ebd848c1SDavid du Colombier 		}
853*ebd848c1SDavid du Colombier 		fmtprint(f, "}");
854*ebd848c1SDavid du Colombier 		return 0;
855*ebd848c1SDavid du Colombier 	case 'b':
856*ebd848c1SDavid du Colombier 		n = SIZE(p);
857*ebd848c1SDavid du Colombier 		fmtprint(f, "Buffer(%d){", n);
858*ebd848c1SDavid du Colombier 		for(i=0; i<n; i++){
859*ebd848c1SDavid du Colombier 			if(i > 0)
860*ebd848c1SDavid du Colombier 				fmtprint(f, ", ");
861*ebd848c1SDavid du Colombier 			fmtprint(f, "%.2uX", ((uchar*)p)[i]);
862*ebd848c1SDavid du Colombier 		}
863*ebd848c1SDavid du Colombier 		fmtprint(f, "}");
864*ebd848c1SDavid du Colombier 		return 0;
865*ebd848c1SDavid du Colombier 	case 'r':
866*ebd848c1SDavid du Colombier 		g = p;
867*ebd848c1SDavid du Colombier 		return fmtprint(f, "Region(%s, %#llux, %#llux)",
868*ebd848c1SDavid du Colombier 			spacename[g->space & 7], g->off, g->len);
869*ebd848c1SDavid du Colombier 	case 'm':
870*ebd848c1SDavid du Colombier 		m = p;
871*ebd848c1SDavid du Colombier 		fmtprint(f, "%N(", m->name);
872*ebd848c1SDavid du Colombier 		for(i=0; i < m->narg; i++){
873*ebd848c1SDavid du Colombier 			if(i > 0)
874*ebd848c1SDavid du Colombier 				fmtprint(f, ", ");
875*ebd848c1SDavid du Colombier 			fmtprint(f, "Arg%d", i);
876*ebd848c1SDavid du Colombier 		}
877*ebd848c1SDavid du Colombier 		fmtprint(f, ")");
878*ebd848c1SDavid du Colombier 		return 0;
879*ebd848c1SDavid du Colombier 	case 'u':
880*ebd848c1SDavid du Colombier 		fmtprint(f, "Buffer");
881*ebd848c1SDavid du Colombier 		/* no break */
882*ebd848c1SDavid du Colombier 	case 'f':
883*ebd848c1SDavid du Colombier 		l = p;
884*ebd848c1SDavid du Colombier 		if(l->index)
885*ebd848c1SDavid du Colombier 			return fmtprint(f, "IndexField(%x, %x, %x) @ %V[%V]",
886*ebd848c1SDavid du Colombier 				l->flags, l->bitoff, l->bitlen, l->index, l->indexv);
887*ebd848c1SDavid du Colombier 		return fmtprint(f, "Field(%x, %x, %x) @ %V",
888*ebd848c1SDavid du Colombier 			l->flags, l->bitoff, l->bitlen, l->reg);
889*ebd848c1SDavid du Colombier 	default:
890*ebd848c1SDavid du Colombier 		return fmtprint(f, "%c:%p", c, p);
891*ebd848c1SDavid du Colombier 	}
892*ebd848c1SDavid du Colombier }
893*ebd848c1SDavid du Colombier 
894*ebd848c1SDavid du Colombier static void
dumpregs(void)895*ebd848c1SDavid du Colombier dumpregs(void)
896*ebd848c1SDavid du Colombier {
897*ebd848c1SDavid du Colombier 	Frame *f;
898*ebd848c1SDavid du Colombier 	Env *e;
899*ebd848c1SDavid du Colombier 	int i;
900*ebd848c1SDavid du Colombier 
901*ebd848c1SDavid du Colombier 	print("\n*** dumpregs: PC=%p FP=%p\n", PC, FP);
902*ebd848c1SDavid du Colombier 	e = nil;
903*ebd848c1SDavid du Colombier 	for(f = FP; f >= FB; f--){
904*ebd848c1SDavid du Colombier 		print("%.8p.%.2lx: %-8s %N\t", f->start, f-FB, f->phase, f->dot);
905*ebd848c1SDavid du Colombier 		if(f->op)
906*ebd848c1SDavid du Colombier 			print("%s", f->op->name);
907*ebd848c1SDavid du Colombier 		print("(");
908*ebd848c1SDavid du Colombier 		for(i=0; i<f->narg; i++){
909*ebd848c1SDavid du Colombier 			if(i > 0)
910*ebd848c1SDavid du Colombier 				print(", ");
911*ebd848c1SDavid du Colombier 			print("%V", f->arg[i]);
912*ebd848c1SDavid du Colombier 		}
913*ebd848c1SDavid du Colombier 		print(")\n");
914*ebd848c1SDavid du Colombier 		if(e == f->env)
915*ebd848c1SDavid du Colombier 			continue;
916*ebd848c1SDavid du Colombier 		if(e = f->env){
917*ebd848c1SDavid du Colombier 			for(i=0; i<nelem(e->arg); i++)
918*ebd848c1SDavid du Colombier 				print("Arg%d=%V ", i, e->arg[i]);
919*ebd848c1SDavid du Colombier 			print("\n");
920*ebd848c1SDavid du Colombier 			for(i=0; i<nelem(e->loc); i++)
921*ebd848c1SDavid du Colombier 				print("Local%d=%V ", i, e->loc[i]);
922*ebd848c1SDavid du Colombier 			print("\n");
923*ebd848c1SDavid du Colombier 		}
924*ebd848c1SDavid du Colombier 	}
925*ebd848c1SDavid du Colombier }
926*ebd848c1SDavid du Colombier 
927*ebd848c1SDavid du Colombier static int
xec(uchar * pc,uchar * end,Name * dot,Env * env,void ** pret)928*ebd848c1SDavid du Colombier xec(uchar *pc, uchar *end, Name *dot, Env *env, void **pret)
929*ebd848c1SDavid du Colombier {
930*ebd848c1SDavid du Colombier 	static int loop;
931*ebd848c1SDavid du Colombier 	int i, c;
932*ebd848c1SDavid du Colombier 	void *r;
933*ebd848c1SDavid du Colombier 
934*ebd848c1SDavid du Colombier 	PC = pc;
935*ebd848c1SDavid du Colombier 	FP = FB;
936*ebd848c1SDavid du Colombier 
937*ebd848c1SDavid du Colombier 	FP->tag = 0;
938*ebd848c1SDavid du Colombier 	FP->cond = 0;
939*ebd848c1SDavid du Colombier 	FP->narg = 0;
940*ebd848c1SDavid du Colombier 	FP->phase = "}";
941*ebd848c1SDavid du Colombier 	FP->start = PC;
942*ebd848c1SDavid du Colombier 	FP->end = end;
943*ebd848c1SDavid du Colombier 	FP->aux = end;
944*ebd848c1SDavid du Colombier 	FB->ref = nil;
945*ebd848c1SDavid du Colombier 	FP->dot = dot;
946*ebd848c1SDavid du Colombier 	FP->env = env;
947*ebd848c1SDavid du Colombier 	FP->op = nil;
948*ebd848c1SDavid du Colombier 
949*ebd848c1SDavid du Colombier 	for(;;){
950*ebd848c1SDavid du Colombier 		if((++loop & 127) == 0)
951*ebd848c1SDavid du Colombier 			gc();
952*ebd848c1SDavid du Colombier 		if(amldebug)
953*ebd848c1SDavid du Colombier 			print("\n%.8p.%.2lx %-8s\t%N\t", PC, FP - FB, FP->phase, FP->dot);
954*ebd848c1SDavid du Colombier 		r = nil;
955*ebd848c1SDavid du Colombier 		c = *FP->phase++;
956*ebd848c1SDavid du Colombier 		switch(c){
957*ebd848c1SDavid du Colombier 		default:
958*ebd848c1SDavid du Colombier 			if(PC >= FP->end){
959*ebd848c1SDavid du Colombier 			Overrun:
960*ebd848c1SDavid du Colombier 				print("aml: PC overrun frame end");
961*ebd848c1SDavid du Colombier 				goto Out;
962*ebd848c1SDavid du Colombier 			}
963*ebd848c1SDavid du Colombier 			FP++;
964*ebd848c1SDavid du Colombier 			if(FP >= FT){
965*ebd848c1SDavid du Colombier 				print("aml: frame stack overflow");
966*ebd848c1SDavid du Colombier 				goto Out;
967*ebd848c1SDavid du Colombier 			}
968*ebd848c1SDavid du Colombier 			*FP = FP[-1];
969*ebd848c1SDavid du Colombier 			FP->aux = nil;
970*ebd848c1SDavid du Colombier 			FP->ref = nil;
971*ebd848c1SDavid du Colombier 			FP->tag = c;
972*ebd848c1SDavid du Colombier 			FP->start = PC;
973*ebd848c1SDavid du Colombier 			c = *PC++;
974*ebd848c1SDavid du Colombier 			if(amldebug) print("%.2X", c);
975*ebd848c1SDavid du Colombier 			if(c == '['){
976*ebd848c1SDavid du Colombier 				if(PC >= FP->end)
977*ebd848c1SDavid du Colombier 					goto Overrun;
978*ebd848c1SDavid du Colombier 				c = *PC++;
979*ebd848c1SDavid du Colombier 				if(amldebug) print("%.2X", c);
980*ebd848c1SDavid du Colombier 				c = octab2[c];
981*ebd848c1SDavid du Colombier 			}else
982*ebd848c1SDavid du Colombier 				c = octab1[c];
983*ebd848c1SDavid du Colombier 			FP->op = &optab[c];
984*ebd848c1SDavid du Colombier 			FP->narg = 0;
985*ebd848c1SDavid du Colombier 			FP->phase = FP->op->sequence;
986*ebd848c1SDavid du Colombier 			if(amldebug) print("\t%s %s", FP->op->name, FP->phase);
987*ebd848c1SDavid du Colombier 			continue;
988*ebd848c1SDavid du Colombier 		case '{':
989*ebd848c1SDavid du Colombier 			end = PC;
990*ebd848c1SDavid du Colombier 			c = pkglen(PC, FP->end, &PC);
991*ebd848c1SDavid du Colombier 			end += c;
992*ebd848c1SDavid du Colombier 			if(c < 0 || end > FP->end)
993*ebd848c1SDavid du Colombier 				goto Overrun;
994*ebd848c1SDavid du Colombier 			FP->end = end;
995*ebd848c1SDavid du Colombier 			continue;
996*ebd848c1SDavid du Colombier 		case ',':
997*ebd848c1SDavid du Colombier 			FP->start = PC;
998*ebd848c1SDavid du Colombier 			continue;
999*ebd848c1SDavid du Colombier 		case 's':
1000*ebd848c1SDavid du Colombier 			if(end = memchr(PC, 0, FP->end - PC))
1001*ebd848c1SDavid du Colombier 				end++;
1002*ebd848c1SDavid du Colombier 			else
1003*ebd848c1SDavid du Colombier 				end = FP->end;
1004*ebd848c1SDavid du Colombier 			c = end - PC;
1005*ebd848c1SDavid du Colombier 			r = mk('s', c+1);
1006*ebd848c1SDavid du Colombier 			memmove(r, PC, c);
1007*ebd848c1SDavid du Colombier 			((uchar*)r)[c] = 0;
1008*ebd848c1SDavid du Colombier 			PC = end;
1009*ebd848c1SDavid du Colombier 			break;
1010*ebd848c1SDavid du Colombier 		case '1':
1011*ebd848c1SDavid du Colombier 		case '2':
1012*ebd848c1SDavid du Colombier 		case '4':
1013*ebd848c1SDavid du Colombier 		case '8':
1014*ebd848c1SDavid du Colombier 			end = PC+(c-'0');
1015*ebd848c1SDavid du Colombier 			if(end > FP->end)
1016*ebd848c1SDavid du Colombier 				goto Overrun;
1017*ebd848c1SDavid du Colombier 			else {
1018*ebd848c1SDavid du Colombier 				r = mki(*PC++);
1019*ebd848c1SDavid du Colombier 				for(i = 8; PC < end; i += 8)
1020*ebd848c1SDavid du Colombier 					*((uvlong*)r) |= ((uvlong)*PC++) << i;
1021*ebd848c1SDavid du Colombier 			}
1022*ebd848c1SDavid du Colombier 			break;
1023*ebd848c1SDavid du Colombier 		case '}':
1024*ebd848c1SDavid du Colombier 		case 0:
1025*ebd848c1SDavid du Colombier 			if(FP->op){
1026*ebd848c1SDavid du Colombier 				if(amldebug){
1027*ebd848c1SDavid du Colombier 					print("*%p,%V\t%s(", FP->aux, FP->ref, FP->op->name);
1028*ebd848c1SDavid du Colombier 					for(i = 0; i < FP->narg; i++){
1029*ebd848c1SDavid du Colombier 						if(i > 0)
1030*ebd848c1SDavid du Colombier 							print(", ");
1031*ebd848c1SDavid du Colombier 						print("%V", FP->arg[i]);
1032*ebd848c1SDavid du Colombier 					}
1033*ebd848c1SDavid du Colombier 					print(")");
1034*ebd848c1SDavid du Colombier 				}
1035*ebd848c1SDavid du Colombier 				for(i = FP->narg; i < nelem(FP->arg); i++)
1036*ebd848c1SDavid du Colombier 					FP->arg[i] = nil;
1037*ebd848c1SDavid du Colombier 				r = FP->op->eval();
1038*ebd848c1SDavid du Colombier 				if(amldebug)
1039*ebd848c1SDavid du Colombier 					print(" -> %V", r);
1040*ebd848c1SDavid du Colombier 			}
1041*ebd848c1SDavid du Colombier 
1042*ebd848c1SDavid du Colombier 			c = FP->phase[-1];
1043*ebd848c1SDavid du Colombier 			if(c == '}' && PC < FP->end){
1044*ebd848c1SDavid du Colombier 				FP->narg = 0;
1045*ebd848c1SDavid du Colombier 				FP->phase = "*}";
1046*ebd848c1SDavid du Colombier 				continue;
1047*ebd848c1SDavid du Colombier 			}
1048*ebd848c1SDavid du Colombier 
1049*ebd848c1SDavid du Colombier 			if(r) switch(FP->tag){
1050*ebd848c1SDavid du Colombier 			case '@':
1051*ebd848c1SDavid du Colombier 				break;
1052*ebd848c1SDavid du Colombier 			case 'n':
1053*ebd848c1SDavid du Colombier 			case 'N':
1054*ebd848c1SDavid du Colombier 				if(TAG(r) != 'N')
1055*ebd848c1SDavid du Colombier 					r = nil;
1056*ebd848c1SDavid du Colombier 				break;
1057*ebd848c1SDavid du Colombier 			default:
1058*ebd848c1SDavid du Colombier 				if((r = deref(r)) == nil)
1059*ebd848c1SDavid du Colombier 					break;
1060*ebd848c1SDavid du Colombier 				switch(TAG(r)){
1061*ebd848c1SDavid du Colombier 				case 'f': case 'u':
1062*ebd848c1SDavid du Colombier 					r = rwfield(r, nil, 0);
1063*ebd848c1SDavid du Colombier 					break;
1064*ebd848c1SDavid du Colombier 				case 'm': {
1065*ebd848c1SDavid du Colombier 					Method *m = r;
1066*ebd848c1SDavid du Colombier 					FP->ref = m;
1067*ebd848c1SDavid du Colombier 					FP->narg = 0;
1068*ebd848c1SDavid du Colombier 					FP->phase = "********}" + (8 - m->narg);
1069*ebd848c1SDavid du Colombier 					FP->op = &optab[Ocall];
1070*ebd848c1SDavid du Colombier 					continue;
1071*ebd848c1SDavid du Colombier 					}
1072*ebd848c1SDavid du Colombier 				}
1073*ebd848c1SDavid du Colombier 			}
1074*ebd848c1SDavid du Colombier 			FP--;
1075*ebd848c1SDavid du Colombier 			break;
1076*ebd848c1SDavid du Colombier 		}
1077*ebd848c1SDavid du Colombier 		if(FP < FB){
1078*ebd848c1SDavid du Colombier 			if(pret){
1079*ebd848c1SDavid du Colombier 				if(amldebug) print(" -> %V\n", r);
1080*ebd848c1SDavid du Colombier 				*pret = r;
1081*ebd848c1SDavid du Colombier 			}
1082*ebd848c1SDavid du Colombier 			return 0;
1083*ebd848c1SDavid du Colombier 		}
1084*ebd848c1SDavid du Colombier 		FP->arg[FP->narg++] = r;
1085*ebd848c1SDavid du Colombier 	}
1086*ebd848c1SDavid du Colombier Out:
1087*ebd848c1SDavid du Colombier 	if(amldebug)
1088*ebd848c1SDavid du Colombier 		dumpregs();
1089*ebd848c1SDavid du Colombier 	return -1;
1090*ebd848c1SDavid du Colombier }
1091*ebd848c1SDavid du Colombier 
1092*ebd848c1SDavid du Colombier static void*
evalnamec(void)1093*ebd848c1SDavid du Colombier evalnamec(void)
1094*ebd848c1SDavid du Colombier {
1095*ebd848c1SDavid du Colombier 	static char name[1024];
1096*ebd848c1SDavid du Colombier 	char *d;
1097*ebd848c1SDavid du Colombier 	void *r;
1098*ebd848c1SDavid du Colombier 	int c;
1099*ebd848c1SDavid du Colombier 
1100*ebd848c1SDavid du Colombier 	c = 1;
1101*ebd848c1SDavid du Colombier 	d = name;
1102*ebd848c1SDavid du Colombier 	PC = FP->start;
1103*ebd848c1SDavid du Colombier 	if(*PC == '\\')
1104*ebd848c1SDavid du Colombier 		*d++ = *PC++;
1105*ebd848c1SDavid du Colombier 	while(*PC == '^'){
1106*ebd848c1SDavid du Colombier 		if(d >= &name[sizeof(name)-1]){
1107*ebd848c1SDavid du Colombier 		Toolong:
1108*ebd848c1SDavid du Colombier 			*d = 0;
1109*ebd848c1SDavid du Colombier 			print("aml: name too long: %s\n", name);
1110*ebd848c1SDavid du Colombier 			PC = FP->end;
1111*ebd848c1SDavid du Colombier 			return nil;
1112*ebd848c1SDavid du Colombier 		}
1113*ebd848c1SDavid du Colombier 		*d++ = *PC++;
1114*ebd848c1SDavid du Colombier 	}
1115*ebd848c1SDavid du Colombier 	if(*PC == '.'){
1116*ebd848c1SDavid du Colombier 		PC++;
1117*ebd848c1SDavid du Colombier 		c = 2;
1118*ebd848c1SDavid du Colombier 	} else if(*PC == '/'){
1119*ebd848c1SDavid du Colombier 		PC++;
1120*ebd848c1SDavid du Colombier 		c = *PC++;
1121*ebd848c1SDavid du Colombier 	} else if(*PC == 0){
1122*ebd848c1SDavid du Colombier 		PC++;
1123*ebd848c1SDavid du Colombier 		c = 0;
1124*ebd848c1SDavid du Colombier 	}
1125*ebd848c1SDavid du Colombier 	while(c > 0){
1126*ebd848c1SDavid du Colombier 		if(d >= &name[sizeof(name)-5])
1127*ebd848c1SDavid du Colombier 			goto Toolong;
1128*ebd848c1SDavid du Colombier 		*d++ = *PC++;
1129*ebd848c1SDavid du Colombier 		*d++ = *PC++;
1130*ebd848c1SDavid du Colombier 		*d++ = *PC++;
1131*ebd848c1SDavid du Colombier 		*d++ = *PC++;
1132*ebd848c1SDavid du Colombier 		while((d > &name[0]) && (d[-1] == '_' || d[-1] == 0))
1133*ebd848c1SDavid du Colombier 			d--;
1134*ebd848c1SDavid du Colombier 		if(--c > 0)
1135*ebd848c1SDavid du Colombier 			*d++ = '.';
1136*ebd848c1SDavid du Colombier 	}
1137*ebd848c1SDavid du Colombier 	*d = 0;
1138*ebd848c1SDavid du Colombier 	if((r = getname(FP->dot, name, FP->tag == 'N')) == nil){
1139*ebd848c1SDavid du Colombier 		r = mks(name);
1140*ebd848c1SDavid du Colombier 		D2H(r)->tag = 'n';	/* unresolved name */
1141*ebd848c1SDavid du Colombier 	}
1142*ebd848c1SDavid du Colombier 	return r;
1143*ebd848c1SDavid du Colombier }
1144*ebd848c1SDavid du Colombier 
1145*ebd848c1SDavid du Colombier static void*
evaliarg0(void)1146*ebd848c1SDavid du Colombier evaliarg0(void)
1147*ebd848c1SDavid du Colombier {
1148*ebd848c1SDavid du Colombier 	return FP->arg[0];
1149*ebd848c1SDavid du Colombier }
1150*ebd848c1SDavid du Colombier 
1151*ebd848c1SDavid du Colombier static void*
evalconst(void)1152*ebd848c1SDavid du Colombier evalconst(void)
1153*ebd848c1SDavid du Colombier {
1154*ebd848c1SDavid du Colombier 	switch(FP->start[0]){
1155*ebd848c1SDavid du Colombier 	case 0x01:
1156*ebd848c1SDavid du Colombier 		return mki(1);
1157*ebd848c1SDavid du Colombier 	case 0xFF:
1158*ebd848c1SDavid du Colombier 		return mki(-1);
1159*ebd848c1SDavid du Colombier 	}
1160*ebd848c1SDavid du Colombier 	return nil;
1161*ebd848c1SDavid du Colombier }
1162*ebd848c1SDavid du Colombier 
1163*ebd848c1SDavid du Colombier static void*
evalbuf(void)1164*ebd848c1SDavid du Colombier evalbuf(void)
1165*ebd848c1SDavid du Colombier {
1166*ebd848c1SDavid du Colombier 	int n, m;
1167*ebd848c1SDavid du Colombier 	uchar *p;
1168*ebd848c1SDavid du Colombier 
1169*ebd848c1SDavid du Colombier 	n = ival(FP->arg[0]);
1170*ebd848c1SDavid du Colombier 	p = mk('b', n);
1171*ebd848c1SDavid du Colombier 	m = FP->end - PC;
1172*ebd848c1SDavid du Colombier 	if(m > n)
1173*ebd848c1SDavid du Colombier 		m = n;
1174*ebd848c1SDavid du Colombier 	memmove(p, PC, m);
1175*ebd848c1SDavid du Colombier 	PC = FP->end;
1176*ebd848c1SDavid du Colombier 	return p;
1177*ebd848c1SDavid du Colombier }
1178*ebd848c1SDavid du Colombier 
1179*ebd848c1SDavid du Colombier static void*
evalpkg(void)1180*ebd848c1SDavid du Colombier evalpkg(void)
1181*ebd848c1SDavid du Colombier {
1182*ebd848c1SDavid du Colombier 	void **p, **x;
1183*ebd848c1SDavid du Colombier 	int n;
1184*ebd848c1SDavid du Colombier 
1185*ebd848c1SDavid du Colombier 	if((p = FP->ref) != nil){
1186*ebd848c1SDavid du Colombier 		x = FP->aux;
1187*ebd848c1SDavid du Colombier 		if(x >= p && x < (p+(SIZE(p)/sizeof(void*)))){
1188*ebd848c1SDavid du Colombier 			*x++ = FP->arg[0];
1189*ebd848c1SDavid du Colombier 			FP->aux = x;
1190*ebd848c1SDavid du Colombier 		}
1191*ebd848c1SDavid du Colombier 	}else {
1192*ebd848c1SDavid du Colombier 		n = ival(FP->arg[0]);
1193*ebd848c1SDavid du Colombier 		if(n < 0) n = 0;
1194*ebd848c1SDavid du Colombier 		p = mk('p', n*sizeof(void*));
1195*ebd848c1SDavid du Colombier 		FP->aux = p;
1196*ebd848c1SDavid du Colombier 		FP->ref = p;
1197*ebd848c1SDavid du Colombier 	}
1198*ebd848c1SDavid du Colombier 	return p;
1199*ebd848c1SDavid du Colombier }
1200*ebd848c1SDavid du Colombier 
1201*ebd848c1SDavid du Colombier static void*
evalname(void)1202*ebd848c1SDavid du Colombier evalname(void)
1203*ebd848c1SDavid du Colombier {
1204*ebd848c1SDavid du Colombier 	Name *n;
1205*ebd848c1SDavid du Colombier 
1206*ebd848c1SDavid du Colombier 	if(n = FP->arg[0])
1207*ebd848c1SDavid du Colombier 		n->v = FP->arg[1];
1208*ebd848c1SDavid du Colombier 	else
1209*ebd848c1SDavid du Colombier 		PC = FP->end;
1210*ebd848c1SDavid du Colombier 	return nil;
1211*ebd848c1SDavid du Colombier }
1212*ebd848c1SDavid du Colombier 
1213*ebd848c1SDavid du Colombier static void*
evalscope(void)1214*ebd848c1SDavid du Colombier evalscope(void)
1215*ebd848c1SDavid du Colombier {
1216*ebd848c1SDavid du Colombier 	Name *n;
1217*ebd848c1SDavid du Colombier 
1218*ebd848c1SDavid du Colombier 	if(n = FP->arg[0])
1219*ebd848c1SDavid du Colombier 		FP->dot = n;
1220*ebd848c1SDavid du Colombier 	else
1221*ebd848c1SDavid du Colombier 		PC = FP->end;
1222*ebd848c1SDavid du Colombier 	FP->op = nil;
1223*ebd848c1SDavid du Colombier 	return nil;
1224*ebd848c1SDavid du Colombier }
1225*ebd848c1SDavid du Colombier 
1226*ebd848c1SDavid du Colombier static void*
evalalias(void)1227*ebd848c1SDavid du Colombier evalalias(void)
1228*ebd848c1SDavid du Colombier {
1229*ebd848c1SDavid du Colombier 	Name *n;
1230*ebd848c1SDavid du Colombier 
1231*ebd848c1SDavid du Colombier 	if(n = FP->arg[1])
1232*ebd848c1SDavid du Colombier 		n->v = deref(FP->arg[0]);
1233*ebd848c1SDavid du Colombier 	return nil;
1234*ebd848c1SDavid du Colombier }
1235*ebd848c1SDavid du Colombier 
1236*ebd848c1SDavid du Colombier static void*
evalmet(void)1237*ebd848c1SDavid du Colombier evalmet(void)
1238*ebd848c1SDavid du Colombier {
1239*ebd848c1SDavid du Colombier 	Name *n;
1240*ebd848c1SDavid du Colombier 	Method *m;
1241*ebd848c1SDavid du Colombier 
1242*ebd848c1SDavid du Colombier 	if((n = FP->arg[0]) != nil){
1243*ebd848c1SDavid du Colombier 		m = mk('m', sizeof(Method));
1244*ebd848c1SDavid du Colombier 		m->narg = ival(FP->arg[1]) & 7;
1245*ebd848c1SDavid du Colombier 		m->start = PC;
1246*ebd848c1SDavid du Colombier 		m->end = FP->end;
1247*ebd848c1SDavid du Colombier 		m->name = n;
1248*ebd848c1SDavid du Colombier 		n->v = m;
1249*ebd848c1SDavid du Colombier 	}
1250*ebd848c1SDavid du Colombier 	PC = FP->end;
1251*ebd848c1SDavid du Colombier 	return nil;
1252*ebd848c1SDavid du Colombier }
1253*ebd848c1SDavid du Colombier 
1254*ebd848c1SDavid du Colombier static void*
evalreg(void)1255*ebd848c1SDavid du Colombier evalreg(void)
1256*ebd848c1SDavid du Colombier {
1257*ebd848c1SDavid du Colombier 	Name *n;
1258*ebd848c1SDavid du Colombier 	Region *r;
1259*ebd848c1SDavid du Colombier 
1260*ebd848c1SDavid du Colombier 	if((n = FP->arg[0]) != nil){
1261*ebd848c1SDavid du Colombier 		r = mk('r', sizeof(Region));
1262*ebd848c1SDavid du Colombier 		r->space = ival(FP->arg[1]);
1263*ebd848c1SDavid du Colombier 		r->off = ival(FP->arg[2]);
1264*ebd848c1SDavid du Colombier 		r->len = ival(FP->arg[3]);
1265*ebd848c1SDavid du Colombier 		r->name = n;
1266*ebd848c1SDavid du Colombier 		r->va = nil;
1267*ebd848c1SDavid du Colombier 		n->v = r;
1268*ebd848c1SDavid du Colombier 	}
1269*ebd848c1SDavid du Colombier 	return nil;
1270*ebd848c1SDavid du Colombier }
1271*ebd848c1SDavid du Colombier 
1272*ebd848c1SDavid du Colombier static void*
evalcfield(void)1273*ebd848c1SDavid du Colombier evalcfield(void)
1274*ebd848c1SDavid du Colombier {
1275*ebd848c1SDavid du Colombier 	void *r;
1276*ebd848c1SDavid du Colombier 	Field *f;
1277*ebd848c1SDavid du Colombier 	Name *n;
1278*ebd848c1SDavid du Colombier 	int c;
1279*ebd848c1SDavid du Colombier 
1280*ebd848c1SDavid du Colombier 	r = FP->arg[0];
1281*ebd848c1SDavid du Colombier 	if(r == nil || (TAG(r) != 'b' && TAG(r) != 'r'))
1282*ebd848c1SDavid du Colombier 		return nil;
1283*ebd848c1SDavid du Colombier 	c = FP->op - optab;
1284*ebd848c1SDavid du Colombier 	if(c == Ocfld)
1285*ebd848c1SDavid du Colombier 		n = FP->arg[3];
1286*ebd848c1SDavid du Colombier 	else
1287*ebd848c1SDavid du Colombier 		n = FP->arg[2];
1288*ebd848c1SDavid du Colombier 	if(n == nil || TAG(n) != 'N')
1289*ebd848c1SDavid du Colombier 		return nil;
1290*ebd848c1SDavid du Colombier 	if(TAG(r) == 'b')
1291*ebd848c1SDavid du Colombier 		f = mk('u', sizeof(Field));
1292*ebd848c1SDavid du Colombier 	else
1293*ebd848c1SDavid du Colombier 		f = mk('f', sizeof(Field));
1294*ebd848c1SDavid du Colombier 	switch(c){
1295*ebd848c1SDavid du Colombier 	case Ocfld:
1296*ebd848c1SDavid du Colombier 		f->bitoff = ival(FP->arg[1]);
1297*ebd848c1SDavid du Colombier 		f->bitlen = ival(FP->arg[2]);
1298*ebd848c1SDavid du Colombier 		break;
1299*ebd848c1SDavid du Colombier 	case Ocfld0:
1300*ebd848c1SDavid du Colombier 		f->bitoff = ival(FP->arg[1]);
1301*ebd848c1SDavid du Colombier 		f->bitlen = 1;
1302*ebd848c1SDavid du Colombier 		break;
1303*ebd848c1SDavid du Colombier 	case Ocfld1:
1304*ebd848c1SDavid du Colombier 	case Ocfld2:
1305*ebd848c1SDavid du Colombier 	case Ocfld4:
1306*ebd848c1SDavid du Colombier 	case Ocfld8:
1307*ebd848c1SDavid du Colombier 		f->bitoff = 8*ival(FP->arg[1]);
1308*ebd848c1SDavid du Colombier 		f->bitlen = 8*(c - Ocfld0);
1309*ebd848c1SDavid du Colombier 		break;
1310*ebd848c1SDavid du Colombier 	}
1311*ebd848c1SDavid du Colombier 	f->reg = r;
1312*ebd848c1SDavid du Colombier 	n->v = f;
1313*ebd848c1SDavid du Colombier 	return nil;
1314*ebd848c1SDavid du Colombier }
1315*ebd848c1SDavid du Colombier 
1316*ebd848c1SDavid du Colombier static void*
evalfield(void)1317*ebd848c1SDavid du Colombier evalfield(void)
1318*ebd848c1SDavid du Colombier {
1319*ebd848c1SDavid du Colombier 	int flags, bitoff, wa, n;
1320*ebd848c1SDavid du Colombier 	Field *f, *df;
1321*ebd848c1SDavid du Colombier 	Name *d;
1322*ebd848c1SDavid du Colombier 	uchar *p;
1323*ebd848c1SDavid du Colombier 
1324*ebd848c1SDavid du Colombier 	df = nil;
1325*ebd848c1SDavid du Colombier 	flags = 0;
1326*ebd848c1SDavid du Colombier 	bitoff = 0;
1327*ebd848c1SDavid du Colombier 	switch(FP->op - optab){
1328*ebd848c1SDavid du Colombier 	case Ofld:
1329*ebd848c1SDavid du Colombier 		flags = ival(FP->arg[1]);
1330*ebd848c1SDavid du Colombier 		break;
1331*ebd848c1SDavid du Colombier 	case Oxfld:
1332*ebd848c1SDavid du Colombier 		df = deref(FP->arg[1]);
1333*ebd848c1SDavid du Colombier 		if(df == nil || TAG(df) != 'f')
1334*ebd848c1SDavid du Colombier 			goto Out;
1335*ebd848c1SDavid du Colombier 		flags = ival(FP->arg[2]);
1336*ebd848c1SDavid du Colombier 		break;
1337*ebd848c1SDavid du Colombier 	}
1338*ebd848c1SDavid du Colombier 	p = PC;
1339*ebd848c1SDavid du Colombier 	if(p >= FP->end)
1340*ebd848c1SDavid du Colombier 		return nil;
1341*ebd848c1SDavid du Colombier 	while(p < FP->end){
1342*ebd848c1SDavid du Colombier 		if(*p == 0x00){
1343*ebd848c1SDavid du Colombier 			p++;
1344*ebd848c1SDavid du Colombier 			if((n = pkglen(p, FP->end, &p)) < 0)
1345*ebd848c1SDavid du Colombier 				break;
1346*ebd848c1SDavid du Colombier 			bitoff += n;
1347*ebd848c1SDavid du Colombier 			continue;
1348*ebd848c1SDavid du Colombier 		}
1349*ebd848c1SDavid du Colombier 		if(*p == 0x01){
1350*ebd848c1SDavid du Colombier 			p++;
1351*ebd848c1SDavid du Colombier 			flags = *p;
1352*ebd848c1SDavid du Colombier 			p += 2;
1353*ebd848c1SDavid du Colombier 			continue;
1354*ebd848c1SDavid du Colombier 		}
1355*ebd848c1SDavid du Colombier 		if(p+4 >= FP->end)
1356*ebd848c1SDavid du Colombier 			break;
1357*ebd848c1SDavid du Colombier 		if((d = getseg(FP->dot, p, 1)) == nil)
1358*ebd848c1SDavid du Colombier 			break;
1359*ebd848c1SDavid du Colombier 		if((n = pkglen(p+4, FP->end, &p)) < 0)
1360*ebd848c1SDavid du Colombier 			break;
1361*ebd848c1SDavid du Colombier 		f = mk('f', sizeof(Field));
1362*ebd848c1SDavid du Colombier 		f->flags = flags;
1363*ebd848c1SDavid du Colombier 		f->bitlen = n;
1364*ebd848c1SDavid du Colombier 		switch(FP->op - optab){
1365*ebd848c1SDavid du Colombier 		case Ofld:
1366*ebd848c1SDavid du Colombier 			f->reg = FP->arg[0];
1367*ebd848c1SDavid du Colombier 			f->bitoff = bitoff;
1368*ebd848c1SDavid du Colombier 			break;
1369*ebd848c1SDavid du Colombier 		case Oxfld:
1370*ebd848c1SDavid du Colombier 			wa = fieldalign(df->flags);
1371*ebd848c1SDavid du Colombier 			f->reg = df->reg;
1372*ebd848c1SDavid du Colombier 			f->bitoff = df->bitoff + (bitoff % (wa*8));
1373*ebd848c1SDavid du Colombier 			f->indexv = mki((bitoff/(wa*8))*wa);
1374*ebd848c1SDavid du Colombier 			f->index = FP->arg[0];
1375*ebd848c1SDavid du Colombier 			break;
1376*ebd848c1SDavid du Colombier 		}
1377*ebd848c1SDavid du Colombier 		bitoff += n;
1378*ebd848c1SDavid du Colombier 		d->v = f;
1379*ebd848c1SDavid du Colombier 	}
1380*ebd848c1SDavid du Colombier Out:
1381*ebd848c1SDavid du Colombier 	PC = FP->end;
1382*ebd848c1SDavid du Colombier 	return nil;
1383*ebd848c1SDavid du Colombier }
1384*ebd848c1SDavid du Colombier 
1385*ebd848c1SDavid du Colombier static void*
evalnop(void)1386*ebd848c1SDavid du Colombier evalnop(void)
1387*ebd848c1SDavid du Colombier {
1388*ebd848c1SDavid du Colombier 	return nil;
1389*ebd848c1SDavid du Colombier }
1390*ebd848c1SDavid du Colombier 
1391*ebd848c1SDavid du Colombier static void*
evalbad(void)1392*ebd848c1SDavid du Colombier evalbad(void)
1393*ebd848c1SDavid du Colombier {
1394*ebd848c1SDavid du Colombier 	int i;
1395*ebd848c1SDavid du Colombier 
1396*ebd848c1SDavid du Colombier 	print("aml: bad opcode %p: ", PC);
1397*ebd848c1SDavid du Colombier 	for(i=0; i < 8 && (FP->start+i) < FP->end; i++){
1398*ebd848c1SDavid du Colombier 		if(i > 0)
1399*ebd848c1SDavid du Colombier 			print(" ");
1400*ebd848c1SDavid du Colombier 		print("%.2X", FP->start[i]);
1401*ebd848c1SDavid du Colombier 	}
1402*ebd848c1SDavid du Colombier 	if((FP->start+i) < FP->end)
1403*ebd848c1SDavid du Colombier 		print("...");
1404*ebd848c1SDavid du Colombier 	print("\n");
1405*ebd848c1SDavid du Colombier 	PC = FP->end;
1406*ebd848c1SDavid du Colombier 	return nil;
1407*ebd848c1SDavid du Colombier }
1408*ebd848c1SDavid du Colombier 
1409*ebd848c1SDavid du Colombier static void*
evalcond(void)1410*ebd848c1SDavid du Colombier evalcond(void)
1411*ebd848c1SDavid du Colombier {
1412*ebd848c1SDavid du Colombier 	switch(FP->op - optab){
1413*ebd848c1SDavid du Colombier 	case Oif:
1414*ebd848c1SDavid du Colombier 		if(FP <= FB)
1415*ebd848c1SDavid du Colombier 			break;
1416*ebd848c1SDavid du Colombier 		FP[-1].cond = ival(FP->arg[0]) != 0;
1417*ebd848c1SDavid du Colombier 		if(!FP[-1].cond)
1418*ebd848c1SDavid du Colombier 			PC = FP->end;
1419*ebd848c1SDavid du Colombier 		break;
1420*ebd848c1SDavid du Colombier 	case Oelse:
1421*ebd848c1SDavid du Colombier 		if(FP <= FB)
1422*ebd848c1SDavid du Colombier 			break;
1423*ebd848c1SDavid du Colombier 		if(FP[-1].cond)
1424*ebd848c1SDavid du Colombier 			PC = FP->end;
1425*ebd848c1SDavid du Colombier 		break;
1426*ebd848c1SDavid du Colombier 	case Owhile:
1427*ebd848c1SDavid du Colombier 		if(FP->aux){
1428*ebd848c1SDavid du Colombier 			if(PC >= FP->end){
1429*ebd848c1SDavid du Colombier 				PC = FP->start;
1430*ebd848c1SDavid du Colombier 				FP->aux = nil;
1431*ebd848c1SDavid du Colombier 			}
1432*ebd848c1SDavid du Colombier 			return nil;
1433*ebd848c1SDavid du Colombier 		}
1434*ebd848c1SDavid du Colombier 		FP->aux = FP->end;
1435*ebd848c1SDavid du Colombier 		if(ival(FP->arg[0]) == 0){
1436*ebd848c1SDavid du Colombier 			PC = FP->end;
1437*ebd848c1SDavid du Colombier 			break;
1438*ebd848c1SDavid du Colombier 		}
1439*ebd848c1SDavid du Colombier 		return nil;
1440*ebd848c1SDavid du Colombier 	}
1441*ebd848c1SDavid du Colombier 	FP->op = nil;
1442*ebd848c1SDavid du Colombier 	return nil;
1443*ebd848c1SDavid du Colombier }
1444*ebd848c1SDavid du Colombier 
1445*ebd848c1SDavid du Colombier static void*
evalcmp(void)1446*ebd848c1SDavid du Colombier evalcmp(void)
1447*ebd848c1SDavid du Colombier {
1448*ebd848c1SDavid du Colombier 	void *a, *b;
1449*ebd848c1SDavid du Colombier 	int tag, c;
1450*ebd848c1SDavid du Colombier 
1451*ebd848c1SDavid du Colombier 	a = FP->arg[0];
1452*ebd848c1SDavid du Colombier 	b = FP->arg[1];
1453*ebd848c1SDavid du Colombier 	if(a == nil || TAG(a) == 'i'){
1454*ebd848c1SDavid du Colombier 		c = ival(a) - ival(b);
1455*ebd848c1SDavid du Colombier 	} else {
1456*ebd848c1SDavid du Colombier 		tag = TAG(a);
1457*ebd848c1SDavid du Colombier 		if(b == nil || TAG(b) != tag)
1458*ebd848c1SDavid du Colombier 			b = copy(tag, b);
1459*ebd848c1SDavid du Colombier 		if(TAG(b) != tag)
1460*ebd848c1SDavid du Colombier 			return nil;	/* botch */
1461*ebd848c1SDavid du Colombier 		switch(tag){
1462*ebd848c1SDavid du Colombier 		default:
1463*ebd848c1SDavid du Colombier 			return nil;	/* botch */
1464*ebd848c1SDavid du Colombier 		case 's':
1465*ebd848c1SDavid du Colombier 			c = strcmp((char*)a, (char*)b);
1466*ebd848c1SDavid du Colombier 			break;
1467*ebd848c1SDavid du Colombier 		case 'b':
1468*ebd848c1SDavid du Colombier 			if((c = SIZE(a) - SIZE(b)) == 0)
1469*ebd848c1SDavid du Colombier 				c = memcmp(a, b, SIZE(a));
1470*ebd848c1SDavid du Colombier 			break;
1471*ebd848c1SDavid du Colombier 		}
1472*ebd848c1SDavid du Colombier 	}
1473*ebd848c1SDavid du Colombier 
1474*ebd848c1SDavid du Colombier 	switch(FP->op - optab){
1475*ebd848c1SDavid du Colombier 	case Oleq:
1476*ebd848c1SDavid du Colombier 		if(c == 0) return mki(1);
1477*ebd848c1SDavid du Colombier 		break;
1478*ebd848c1SDavid du Colombier 	case Olgt:
1479*ebd848c1SDavid du Colombier 		if(c > 0) return mki(1);
1480*ebd848c1SDavid du Colombier 		break;
1481*ebd848c1SDavid du Colombier 	case Ollt:
1482*ebd848c1SDavid du Colombier 		if(c < 0) return mki(1);
1483*ebd848c1SDavid du Colombier 		break;
1484*ebd848c1SDavid du Colombier 	}
1485*ebd848c1SDavid du Colombier 	return nil;
1486*ebd848c1SDavid du Colombier }
1487*ebd848c1SDavid du Colombier 
1488*ebd848c1SDavid du Colombier static void*
evalcall(void)1489*ebd848c1SDavid du Colombier evalcall(void)
1490*ebd848c1SDavid du Colombier {
1491*ebd848c1SDavid du Colombier 	Method *m;
1492*ebd848c1SDavid du Colombier 	Env *e;
1493*ebd848c1SDavid du Colombier 	int i;
1494*ebd848c1SDavid du Colombier 
1495*ebd848c1SDavid du Colombier 	if(FP->aux){
1496*ebd848c1SDavid du Colombier 		if(PC >= FP->end){
1497*ebd848c1SDavid du Colombier 			PC = FP->aux;
1498*ebd848c1SDavid du Colombier 			FP->end = PC;
1499*ebd848c1SDavid du Colombier 		}
1500*ebd848c1SDavid du Colombier 		return nil;
1501*ebd848c1SDavid du Colombier 	}
1502*ebd848c1SDavid du Colombier 	m = FP->ref;
1503*ebd848c1SDavid du Colombier 	e = mk('E', sizeof(Env));
1504*ebd848c1SDavid du Colombier 	for(i=0; i<FP->narg; i++)
1505*ebd848c1SDavid du Colombier 		e->arg[i] = deref(FP->arg[i]);
1506*ebd848c1SDavid du Colombier 	FP->env = e;
1507*ebd848c1SDavid du Colombier 	FP->narg = 0;
1508*ebd848c1SDavid du Colombier 	FP->dot = m->name;
1509*ebd848c1SDavid du Colombier 	if(m->eval != nil){
1510*ebd848c1SDavid du Colombier 		FP->op = nil;
1511*ebd848c1SDavid du Colombier 		FP->end = PC;
1512*ebd848c1SDavid du Colombier 		return (*m->eval)();
1513*ebd848c1SDavid du Colombier 	}
1514*ebd848c1SDavid du Colombier 	FP->dot = forkname(FP->dot);
1515*ebd848c1SDavid du Colombier 	FP->aux = PC;
1516*ebd848c1SDavid du Colombier 	FP->start = m->start;
1517*ebd848c1SDavid du Colombier 	FP->end = m->end;
1518*ebd848c1SDavid du Colombier 	PC = FP->start;
1519*ebd848c1SDavid du Colombier 	return nil;
1520*ebd848c1SDavid du Colombier }
1521*ebd848c1SDavid du Colombier 
1522*ebd848c1SDavid du Colombier static void*
evalret(void)1523*ebd848c1SDavid du Colombier evalret(void)
1524*ebd848c1SDavid du Colombier {
1525*ebd848c1SDavid du Colombier 	void *r = FP->arg[0];
1526*ebd848c1SDavid du Colombier 	int brk = (FP->op - optab) != Oret;
1527*ebd848c1SDavid du Colombier 	while(--FP >= FB){
1528*ebd848c1SDavid du Colombier 		switch(FP->op - optab){
1529*ebd848c1SDavid du Colombier 		case Owhile:
1530*ebd848c1SDavid du Colombier 			if(!brk)
1531*ebd848c1SDavid du Colombier 				continue;
1532*ebd848c1SDavid du Colombier 			PC = FP->end;
1533*ebd848c1SDavid du Colombier 			return nil;
1534*ebd848c1SDavid du Colombier 		case Ocall:
1535*ebd848c1SDavid du Colombier 			PC = FP->aux;
1536*ebd848c1SDavid du Colombier 			return r;
1537*ebd848c1SDavid du Colombier 		}
1538*ebd848c1SDavid du Colombier 	}
1539*ebd848c1SDavid du Colombier 	FP = FB;
1540*ebd848c1SDavid du Colombier 	PC = FB->end;
1541*ebd848c1SDavid du Colombier 	return r;
1542*ebd848c1SDavid du Colombier }
1543*ebd848c1SDavid du Colombier 
1544*ebd848c1SDavid du Colombier static void*
evalenv(void)1545*ebd848c1SDavid du Colombier evalenv(void)
1546*ebd848c1SDavid du Colombier {
1547*ebd848c1SDavid du Colombier 	Ref *r;
1548*ebd848c1SDavid du Colombier 	Env *e;
1549*ebd848c1SDavid du Colombier 	int c;
1550*ebd848c1SDavid du Colombier 
1551*ebd848c1SDavid du Colombier 	if((e = FP->env) == nil)
1552*ebd848c1SDavid du Colombier 		return nil;
1553*ebd848c1SDavid du Colombier 	c = FP->start[0];
1554*ebd848c1SDavid du Colombier 	if(c >= 0x60 && c <= 0x67){
1555*ebd848c1SDavid du Colombier 		r = mk('L', sizeof(Ref));
1556*ebd848c1SDavid du Colombier 		r->ptr = &e->loc[c - 0x60];
1557*ebd848c1SDavid du Colombier 	} else if(c >= 0x68 && c <= 0x6E){
1558*ebd848c1SDavid du Colombier 		r = mk('A', sizeof(Ref));
1559*ebd848c1SDavid du Colombier 		r->ptr = &e->arg[c - 0x68];
1560*ebd848c1SDavid du Colombier 	} else
1561*ebd848c1SDavid du Colombier 		return nil;
1562*ebd848c1SDavid du Colombier 	r->ref = e;
1563*ebd848c1SDavid du Colombier 	return r;
1564*ebd848c1SDavid du Colombier }
1565*ebd848c1SDavid du Colombier 
1566*ebd848c1SDavid du Colombier static void*
evalstore(void)1567*ebd848c1SDavid du Colombier evalstore(void)
1568*ebd848c1SDavid du Colombier {
1569*ebd848c1SDavid du Colombier 	return store(FP->arg[0], FP->arg[1]);
1570*ebd848c1SDavid du Colombier }
1571*ebd848c1SDavid du Colombier 
1572*ebd848c1SDavid du Colombier static void*
evalcat(void)1573*ebd848c1SDavid du Colombier evalcat(void)
1574*ebd848c1SDavid du Colombier {
1575*ebd848c1SDavid du Colombier 	void *r, *a, *b;
1576*ebd848c1SDavid du Colombier 	int tag, n, m;
1577*ebd848c1SDavid du Colombier 
1578*ebd848c1SDavid du Colombier 	a = FP->arg[0];
1579*ebd848c1SDavid du Colombier 	b = FP->arg[1];
1580*ebd848c1SDavid du Colombier 	if(a == nil || TAG(a) == 'i')
1581*ebd848c1SDavid du Colombier 		a = copy('b', a);	/* Concat(Int, ???) -> Buf */
1582*ebd848c1SDavid du Colombier 	tag = TAG(a);
1583*ebd848c1SDavid du Colombier 	if(b == nil || TAG(b) != tag)
1584*ebd848c1SDavid du Colombier 		b = copy(tag, b);
1585*ebd848c1SDavid du Colombier 	if(TAG(b) != tag)
1586*ebd848c1SDavid du Colombier 		return nil;	/* botch */
1587*ebd848c1SDavid du Colombier 	switch(tag){
1588*ebd848c1SDavid du Colombier 	default:
1589*ebd848c1SDavid du Colombier 		return nil;	/* botch */
1590*ebd848c1SDavid du Colombier 	case 'b':
1591*ebd848c1SDavid du Colombier 		n = SIZE(a);
1592*ebd848c1SDavid du Colombier 		m = SIZE(b);
1593*ebd848c1SDavid du Colombier 		r = mk('b', n + m);
1594*ebd848c1SDavid du Colombier 		memmove(r, a, n);
1595*ebd848c1SDavid du Colombier 		memmove((uchar*)r + n, b, m);
1596*ebd848c1SDavid du Colombier 		break;
1597*ebd848c1SDavid du Colombier 	case 's':
1598*ebd848c1SDavid du Colombier 		n = strlen((char*)a);
1599*ebd848c1SDavid du Colombier 		m = strlen((char*)b);
1600*ebd848c1SDavid du Colombier 		r = mk('s', n + m + 1);
1601*ebd848c1SDavid du Colombier 		memmove(r, a, n);
1602*ebd848c1SDavid du Colombier 		memmove((char*)r + n, b, m);
1603*ebd848c1SDavid du Colombier 		((char*)r)[n+m] = 0;
1604*ebd848c1SDavid du Colombier 		break;
1605*ebd848c1SDavid du Colombier 	}
1606*ebd848c1SDavid du Colombier 	store(r, FP->arg[2]);
1607*ebd848c1SDavid du Colombier 	return r;
1608*ebd848c1SDavid du Colombier }
1609*ebd848c1SDavid du Colombier 
1610*ebd848c1SDavid du Colombier static void*
evalindex(void)1611*ebd848c1SDavid du Colombier evalindex(void)
1612*ebd848c1SDavid du Colombier {
1613*ebd848c1SDavid du Colombier 	Field *f;
1614*ebd848c1SDavid du Colombier 	void *p;
1615*ebd848c1SDavid du Colombier 	Ref *r;
1616*ebd848c1SDavid du Colombier 	int x;
1617*ebd848c1SDavid du Colombier 
1618*ebd848c1SDavid du Colombier 	x = ival(FP->arg[1]);
1619*ebd848c1SDavid du Colombier 	if(p = deref(FP->arg[0])) switch(TAG(p)){
1620*ebd848c1SDavid du Colombier 	case 's':
1621*ebd848c1SDavid du Colombier 		if(x >= strlen((char*)p))
1622*ebd848c1SDavid du Colombier 			break;
1623*ebd848c1SDavid du Colombier 		/* no break */
1624*ebd848c1SDavid du Colombier 	case 'b':
1625*ebd848c1SDavid du Colombier 		if(x < 0 || x >= SIZE(p))
1626*ebd848c1SDavid du Colombier 			break;
1627*ebd848c1SDavid du Colombier 		f = mk('u', sizeof(Field));
1628*ebd848c1SDavid du Colombier 		f->reg = p;
1629*ebd848c1SDavid du Colombier 		f->bitlen = 8;
1630*ebd848c1SDavid du Colombier 		f->bitoff = 8*x;
1631*ebd848c1SDavid du Colombier 		store(f, FP->arg[2]);
1632*ebd848c1SDavid du Colombier 		return f;
1633*ebd848c1SDavid du Colombier 	case 'p':
1634*ebd848c1SDavid du Colombier 		if(x < 0 || x >= (SIZE(p)/sizeof(void*)))
1635*ebd848c1SDavid du Colombier 			break;
1636*ebd848c1SDavid du Colombier 		if(TAG(FP->arg[0]) == 'A' || TAG(FP->arg[0]) == 'L')
1637*ebd848c1SDavid du Colombier 			r = mk(TAG(FP->arg[0]), sizeof(Ref));
1638*ebd848c1SDavid du Colombier 		else
1639*ebd848c1SDavid du Colombier 			r = mk('R', sizeof(Ref));
1640*ebd848c1SDavid du Colombier 		r->ref = p;
1641*ebd848c1SDavid du Colombier 		r->ptr = ((void**)p) + x;
1642*ebd848c1SDavid du Colombier 		store(r, FP->arg[2]);
1643*ebd848c1SDavid du Colombier 		return r;
1644*ebd848c1SDavid du Colombier 	}
1645*ebd848c1SDavid du Colombier 	return nil;
1646*ebd848c1SDavid du Colombier }
1647*ebd848c1SDavid du Colombier 
1648*ebd848c1SDavid du Colombier static void*
evalcondref(void)1649*ebd848c1SDavid du Colombier evalcondref(void)
1650*ebd848c1SDavid du Colombier {
1651*ebd848c1SDavid du Colombier 	void *s;
1652*ebd848c1SDavid du Colombier 	if((s = FP->arg[0]) == nil)
1653*ebd848c1SDavid du Colombier 		return nil;
1654*ebd848c1SDavid du Colombier 	store(s, FP->arg[1]);
1655*ebd848c1SDavid du Colombier 	return mki(1);
1656*ebd848c1SDavid du Colombier }
1657*ebd848c1SDavid du Colombier 
1658*ebd848c1SDavid du Colombier static void*
evalsize(void)1659*ebd848c1SDavid du Colombier evalsize(void)
1660*ebd848c1SDavid du Colombier {
1661*ebd848c1SDavid du Colombier 	return mki(amllen(FP->arg[0]));
1662*ebd848c1SDavid du Colombier }
1663*ebd848c1SDavid du Colombier 
1664*ebd848c1SDavid du Colombier static void*
evalderef(void)1665*ebd848c1SDavid du Colombier evalderef(void)
1666*ebd848c1SDavid du Colombier {
1667*ebd848c1SDavid du Colombier 	void *p;
1668*ebd848c1SDavid du Colombier 
1669*ebd848c1SDavid du Colombier 	if(p = FP->arg[0]){
1670*ebd848c1SDavid du Colombier 		if(TAG(p) == 's' || TAG(p) == 'n')
1671*ebd848c1SDavid du Colombier 			p = getname(FP->dot, (char*)p, 0);
1672*ebd848c1SDavid du Colombier 		p = deref(p);
1673*ebd848c1SDavid du Colombier 	}
1674*ebd848c1SDavid du Colombier 	return p;
1675*ebd848c1SDavid du Colombier }
1676*ebd848c1SDavid du Colombier 
1677*ebd848c1SDavid du Colombier static void*
evalarith(void)1678*ebd848c1SDavid du Colombier evalarith(void)
1679*ebd848c1SDavid du Colombier {
1680*ebd848c1SDavid du Colombier 	uvlong v, d;
1681*ebd848c1SDavid du Colombier 	void *r;
1682*ebd848c1SDavid du Colombier 	int i;
1683*ebd848c1SDavid du Colombier 
1684*ebd848c1SDavid du Colombier 	r = nil;
1685*ebd848c1SDavid du Colombier 	switch(FP->op - optab){
1686*ebd848c1SDavid du Colombier 	case Oadd:
1687*ebd848c1SDavid du Colombier 		r = mki(ival(FP->arg[0]) + ival(FP->arg[1]));
1688*ebd848c1SDavid du Colombier 		break;
1689*ebd848c1SDavid du Colombier 	case Osub:
1690*ebd848c1SDavid du Colombier 		r = mki(ival(FP->arg[0]) - ival(FP->arg[1]));
1691*ebd848c1SDavid du Colombier 		break;
1692*ebd848c1SDavid du Colombier 	case Omul:
1693*ebd848c1SDavid du Colombier 		r = mki(ival(FP->arg[0]) * ival(FP->arg[1]));
1694*ebd848c1SDavid du Colombier 		break;
1695*ebd848c1SDavid du Colombier 	case Omod:
1696*ebd848c1SDavid du Colombier 	case Odiv:
1697*ebd848c1SDavid du Colombier 		v = ival(FP->arg[0]);
1698*ebd848c1SDavid du Colombier 		d = ival(FP->arg[1]);
1699*ebd848c1SDavid du Colombier 		if(d == 0){
1700*ebd848c1SDavid du Colombier 			print("aml: division by zero: PC=%#p\n", PC);
1701*ebd848c1SDavid du Colombier 			return nil;
1702*ebd848c1SDavid du Colombier 		}
1703*ebd848c1SDavid du Colombier 		r = mki(v % d);
1704*ebd848c1SDavid du Colombier 		store(r, FP->arg[2]);
1705*ebd848c1SDavid du Colombier 		if((FP->op - optab) != Odiv)
1706*ebd848c1SDavid du Colombier 			return r;
1707*ebd848c1SDavid du Colombier 		r = mki(v / d);
1708*ebd848c1SDavid du Colombier 		store(r, FP->arg[3]);
1709*ebd848c1SDavid du Colombier 		return r;
1710*ebd848c1SDavid du Colombier 	case Oshl:
1711*ebd848c1SDavid du Colombier 		r = mki(ival(FP->arg[0]) << ival(FP->arg[1]));
1712*ebd848c1SDavid du Colombier 		break;
1713*ebd848c1SDavid du Colombier 	case Oshr:
1714*ebd848c1SDavid du Colombier 		r = mki(ival(FP->arg[0]) >> ival(FP->arg[1]));
1715*ebd848c1SDavid du Colombier 		break;
1716*ebd848c1SDavid du Colombier 	case Oand:
1717*ebd848c1SDavid du Colombier 		r = mki(ival(FP->arg[0]) & ival(FP->arg[1]));
1718*ebd848c1SDavid du Colombier 		break;
1719*ebd848c1SDavid du Colombier 	case Onand:
1720*ebd848c1SDavid du Colombier 		r = mki(~(ival(FP->arg[0]) & ival(FP->arg[1])));
1721*ebd848c1SDavid du Colombier 		break;
1722*ebd848c1SDavid du Colombier 	case Oor:
1723*ebd848c1SDavid du Colombier 		r = mki(ival(FP->arg[0]) | ival(FP->arg[1]));
1724*ebd848c1SDavid du Colombier 		break;
1725*ebd848c1SDavid du Colombier 	case Onor:
1726*ebd848c1SDavid du Colombier 		r = mki(~(ival(FP->arg[0]) | ival(FP->arg[1])));
1727*ebd848c1SDavid du Colombier 		break;
1728*ebd848c1SDavid du Colombier 	case Oxor:
1729*ebd848c1SDavid du Colombier 		r = mki(ival(FP->arg[0]) ^ ival(FP->arg[1]));
1730*ebd848c1SDavid du Colombier 		break;
1731*ebd848c1SDavid du Colombier 	case Onot:
1732*ebd848c1SDavid du Colombier 		r = mki(~ival(FP->arg[0]));
1733*ebd848c1SDavid du Colombier 		store(r, FP->arg[1]);
1734*ebd848c1SDavid du Colombier 		return r;
1735*ebd848c1SDavid du Colombier 	case Olbit:
1736*ebd848c1SDavid du Colombier 		v = ival(FP->arg[0]);
1737*ebd848c1SDavid du Colombier 		if(v == 0)
1738*ebd848c1SDavid du Colombier 			break;
1739*ebd848c1SDavid du Colombier 		for(i=0; (v & 1) == 0; i++)
1740*ebd848c1SDavid du Colombier 			v >>= 1;
1741*ebd848c1SDavid du Colombier 		r = mki(i+1);
1742*ebd848c1SDavid du Colombier 		break;
1743*ebd848c1SDavid du Colombier 	case Orbit:
1744*ebd848c1SDavid du Colombier 		v = ival(FP->arg[0]);
1745*ebd848c1SDavid du Colombier 		if(v == 0)
1746*ebd848c1SDavid du Colombier 			break;
1747*ebd848c1SDavid du Colombier 		for(i=0; v != 0; i++)
1748*ebd848c1SDavid du Colombier 			v >>= 1;
1749*ebd848c1SDavid du Colombier 		r = mki(i);
1750*ebd848c1SDavid du Colombier 		break;
1751*ebd848c1SDavid du Colombier 	case Oland:
1752*ebd848c1SDavid du Colombier 		return mki(ival(FP->arg[0]) && ival(FP->arg[1]));
1753*ebd848c1SDavid du Colombier 	case Olor:
1754*ebd848c1SDavid du Colombier 		return mki(ival(FP->arg[0]) || ival(FP->arg[1]));
1755*ebd848c1SDavid du Colombier 	case Olnot:
1756*ebd848c1SDavid du Colombier 		return mki(ival(FP->arg[0]) == 0);
1757*ebd848c1SDavid du Colombier 
1758*ebd848c1SDavid du Colombier 	case Oinc:
1759*ebd848c1SDavid du Colombier 		r = mki(ival(deref(FP->arg[0]))+1);
1760*ebd848c1SDavid du Colombier 		store(r, FP->arg[0]);
1761*ebd848c1SDavid du Colombier 		return r;
1762*ebd848c1SDavid du Colombier 	case Odec:
1763*ebd848c1SDavid du Colombier 		r = mki(ival(deref(FP->arg[0]))-1);
1764*ebd848c1SDavid du Colombier 		store(r, FP->arg[0]);
1765*ebd848c1SDavid du Colombier 		return r;
1766*ebd848c1SDavid du Colombier 	}
1767*ebd848c1SDavid du Colombier 
1768*ebd848c1SDavid du Colombier 	store(r, FP->arg[2]);
1769*ebd848c1SDavid du Colombier 	return r;
1770*ebd848c1SDavid du Colombier }
1771*ebd848c1SDavid du Colombier 
1772*ebd848c1SDavid du Colombier static void*
evalload(void)1773*ebd848c1SDavid du Colombier evalload(void)
1774*ebd848c1SDavid du Colombier {
1775*ebd848c1SDavid du Colombier 	enum { LenOffset = 4, HdrLen = 36 };
1776*ebd848c1SDavid du Colombier 	uvlong *tid;
1777*ebd848c1SDavid du Colombier 	Region *r;
1778*ebd848c1SDavid du Colombier 	int l;
1779*ebd848c1SDavid du Colombier 
1780*ebd848c1SDavid du Colombier 	tid = nil;
1781*ebd848c1SDavid du Colombier 	if(FP->aux){
1782*ebd848c1SDavid du Colombier 		if(PC >= FP->end){
1783*ebd848c1SDavid du Colombier 			amlenum(amlroot, nil, fixnames, nil);
1784*ebd848c1SDavid du Colombier 			FP->aux = nil;
1785*ebd848c1SDavid du Colombier 			FP->end = PC;
1786*ebd848c1SDavid du Colombier 			tid = mki(1);	/* fake */
1787*ebd848c1SDavid du Colombier 		}
1788*ebd848c1SDavid du Colombier 	} else {
1789*ebd848c1SDavid du Colombier 		store(nil, FP->arg[1]);
1790*ebd848c1SDavid du Colombier 		if(FP->arg[0] == nil)
1791*ebd848c1SDavid du Colombier 			return nil;
1792*ebd848c1SDavid du Colombier 
1793*ebd848c1SDavid du Colombier 		l = rwreg(FP->arg[0], LenOffset, 4, 0, 0);
1794*ebd848c1SDavid du Colombier 		if(l <= HdrLen)
1795*ebd848c1SDavid du Colombier 			return nil;
1796*ebd848c1SDavid du Colombier 
1797*ebd848c1SDavid du Colombier 		FP->aux = PC;	/* save */
1798*ebd848c1SDavid du Colombier 		FP->ref = FP->arg[0];
1799*ebd848c1SDavid du Colombier 		switch(TAG(FP->ref)){
1800*ebd848c1SDavid du Colombier 		case 'b':
1801*ebd848c1SDavid du Colombier 			if(SIZE(FP->ref) < l)
1802*ebd848c1SDavid du Colombier 				return nil;
1803*ebd848c1SDavid du Colombier 			PC = (uchar*)FP->ref + HdrLen;
1804*ebd848c1SDavid du Colombier 			break;
1805*ebd848c1SDavid du Colombier 		case 'r':
1806*ebd848c1SDavid du Colombier 			r = FP->ref;
1807*ebd848c1SDavid du Colombier 			if(r->len < l || r->va == nil || r->mapped <= 0)
1808*ebd848c1SDavid du Colombier 				return nil;
1809*ebd848c1SDavid du Colombier 			PC = (uchar*)r->va + HdrLen;
1810*ebd848c1SDavid du Colombier 			break;
1811*ebd848c1SDavid du Colombier 		default:
1812*ebd848c1SDavid du Colombier 			return nil;
1813*ebd848c1SDavid du Colombier 		}
1814*ebd848c1SDavid du Colombier 		FP->end = PC + (l - HdrLen);
1815*ebd848c1SDavid du Colombier 		FP->dot = amlroot;
1816*ebd848c1SDavid du Colombier 		FP->env = nil;
1817*ebd848c1SDavid du Colombier 
1818*ebd848c1SDavid du Colombier 		tid = mki(1); /* fake */
1819*ebd848c1SDavid du Colombier 		store(tid, FP->arg[1]);
1820*ebd848c1SDavid du Colombier 	}
1821*ebd848c1SDavid du Colombier 	return tid;
1822*ebd848c1SDavid du Colombier }
1823*ebd848c1SDavid du Colombier 
1824*ebd848c1SDavid du Colombier static void*
evalstall(void)1825*ebd848c1SDavid du Colombier evalstall(void)
1826*ebd848c1SDavid du Colombier {
1827*ebd848c1SDavid du Colombier 	amldelay(ival(FP->arg[0]));
1828*ebd848c1SDavid du Colombier 	return nil;
1829*ebd848c1SDavid du Colombier }
1830*ebd848c1SDavid du Colombier 
1831*ebd848c1SDavid du Colombier static void*
evalsleep(void)1832*ebd848c1SDavid du Colombier evalsleep(void)
1833*ebd848c1SDavid du Colombier {
1834*ebd848c1SDavid du Colombier 	amldelay(ival(FP->arg[0])*1000);
1835*ebd848c1SDavid du Colombier 	return nil;
1836*ebd848c1SDavid du Colombier }
1837*ebd848c1SDavid du Colombier 
1838*ebd848c1SDavid du Colombier static Op optab[] = {
1839*ebd848c1SDavid du Colombier 	[Obad]		"",			"",		evalbad,
1840*ebd848c1SDavid du Colombier 	[Onop]		"Noop",			"",		evalnop,
1841*ebd848c1SDavid du Colombier 	[Odebug]	"Debug",		"",		evalnop,
1842*ebd848c1SDavid du Colombier 
1843*ebd848c1SDavid du Colombier 	[Ostr]		".str",			"s",		evaliarg0,
1844*ebd848c1SDavid du Colombier 	[Obyte]		".byte",		"1",		evaliarg0,
1845*ebd848c1SDavid du Colombier 	[Oword]		".word",		"2",		evaliarg0,
1846*ebd848c1SDavid du Colombier 	[Odword]	".dword",		"4",		evaliarg0,
1847*ebd848c1SDavid du Colombier 	[Oqword]	".qword",		"8",		evaliarg0,
1848*ebd848c1SDavid du Colombier 	[Oconst]	".const",		"",		evalconst,
1849*ebd848c1SDavid du Colombier 	[Onamec]	".name",		"",		evalnamec,
1850*ebd848c1SDavid du Colombier 	[Oenv]		".env",			"",		evalenv,
1851*ebd848c1SDavid du Colombier 
1852*ebd848c1SDavid du Colombier 	[Oname]		"Name",			"N*",		evalname,
1853*ebd848c1SDavid du Colombier 	[Oscope]	"Scope",		"{n}",		evalscope,
1854*ebd848c1SDavid du Colombier 	[Oalias]	"Alias",		"nN",		evalalias,
1855*ebd848c1SDavid du Colombier 
1856*ebd848c1SDavid du Colombier 	[Odev]		"Device",		"{N}",		evalscope,
1857*ebd848c1SDavid du Colombier 	[Ocpu]		"Processor",		"{N141}",	evalscope,
1858*ebd848c1SDavid du Colombier 	[Othz]		"ThermalZone",		"{N}",		evalscope,
1859*ebd848c1SDavid du Colombier 	[Oprc]		"PowerResource",	"{N12}",	evalscope,
1860*ebd848c1SDavid du Colombier 
1861*ebd848c1SDavid du Colombier 	[Oreg]		"OperationRegion",	"N1ii",		evalreg,
1862*ebd848c1SDavid du Colombier 	[Ofld]		"Field",		"{n1",		evalfield,
1863*ebd848c1SDavid du Colombier 	[Oxfld]		"IndexField",		"{nn1",		evalfield,
1864*ebd848c1SDavid du Colombier 
1865*ebd848c1SDavid du Colombier 	[Ocfld]		"CreateField",		"*iiN",		evalcfield,
1866*ebd848c1SDavid du Colombier 	[Ocfld0]	"CreateBitField",	"*iN",		evalcfield,
1867*ebd848c1SDavid du Colombier 	[Ocfld1]	"CreateByteField",	"*iN",		evalcfield,
1868*ebd848c1SDavid du Colombier 	[Ocfld2]	"CreateWordField",	"*iN",		evalcfield,
1869*ebd848c1SDavid du Colombier 	[Ocfld4]	"CreateDWordField",	"*iN",		evalcfield,
1870*ebd848c1SDavid du Colombier 	[Ocfld8]	"CreateQWordField",	"*iN",		evalcfield,
1871*ebd848c1SDavid du Colombier 
1872*ebd848c1SDavid du Colombier 	[Opkg]		"Package",		"{1}",		evalpkg,
1873*ebd848c1SDavid du Colombier 	[Ovpkg]		"VarPackage",		"{i}",		evalpkg,
1874*ebd848c1SDavid du Colombier 	[Obuf]		"Buffer",		"{i",		evalbuf,
1875*ebd848c1SDavid du Colombier 	[Omet]		"Method",		"{N1",		evalmet,
1876*ebd848c1SDavid du Colombier 
1877*ebd848c1SDavid du Colombier 	[Oadd]		"Add",			"ii@",		evalarith,
1878*ebd848c1SDavid du Colombier 	[Osub]		"Subtract",		"ii@",		evalarith,
1879*ebd848c1SDavid du Colombier 	[Omod]		"Mod",			"ii@",		evalarith,
1880*ebd848c1SDavid du Colombier 	[Omul]		"Multiply",		"ii@",		evalarith,
1881*ebd848c1SDavid du Colombier 	[Odiv]		"Divide",		"ii@@",		evalarith,
1882*ebd848c1SDavid du Colombier 	[Oshl]		"ShiftLef",		"ii@",		evalarith,
1883*ebd848c1SDavid du Colombier 	[Oshr]		"ShiftRight",		"ii@",		evalarith,
1884*ebd848c1SDavid du Colombier 	[Oand]		"And",			"ii@",		evalarith,
1885*ebd848c1SDavid du Colombier 	[Onand]		"Nand",			"ii@",		evalarith,
1886*ebd848c1SDavid du Colombier 	[Oor]		"Or",			"ii@",		evalarith,
1887*ebd848c1SDavid du Colombier 	[Onor]		"Nor",			"ii@",		evalarith,
1888*ebd848c1SDavid du Colombier 	[Oxor]		"Xor",			"ii@",		evalarith,
1889*ebd848c1SDavid du Colombier 	[Onot]		"Not",			"i@",		evalarith,
1890*ebd848c1SDavid du Colombier 
1891*ebd848c1SDavid du Colombier 	[Olbit]		"FindSetLeftBit",	"i@",		evalarith,
1892*ebd848c1SDavid du Colombier 	[Orbit]		"FindSetRightBit",	"i@",		evalarith,
1893*ebd848c1SDavid du Colombier 
1894*ebd848c1SDavid du Colombier 	[Oinc]		"Increment",		"@",		evalarith,
1895*ebd848c1SDavid du Colombier 	[Odec]		"Decrement",		"@",		evalarith,
1896*ebd848c1SDavid du Colombier 
1897*ebd848c1SDavid du Colombier 	[Oland]		"LAnd",			"ii",		evalarith,
1898*ebd848c1SDavid du Colombier 	[Olor]		"LOr",			"ii",		evalarith,
1899*ebd848c1SDavid du Colombier 	[Olnot]		"LNot",			"i",		evalarith,
1900*ebd848c1SDavid du Colombier 
1901*ebd848c1SDavid du Colombier 	[Oleq]		"LEqual",		"**",		evalcmp,
1902*ebd848c1SDavid du Colombier 	[Olgt]		"LGreater",		"**",		evalcmp,
1903*ebd848c1SDavid du Colombier 	[Ollt]		"LLess",		"**",		evalcmp,
1904*ebd848c1SDavid du Colombier 
1905*ebd848c1SDavid du Colombier 	[Omutex]	"Mutex",		"N1",		evalnop,
1906*ebd848c1SDavid du Colombier 	[Oevent]	"Event",		"N",		evalnop,
1907*ebd848c1SDavid du Colombier 
1908*ebd848c1SDavid du Colombier 	[Oif]		"If",			"{i}",		evalcond,
1909*ebd848c1SDavid du Colombier 	[Oelse]		"Else",			"{}",		evalcond,
1910*ebd848c1SDavid du Colombier 	[Owhile]	"While",		"{,i}",		evalcond,
1911*ebd848c1SDavid du Colombier 	[Obreak]	"Break",		"",		evalret,
1912*ebd848c1SDavid du Colombier 	[Oret]		"Return",		"*",		evalret,
1913*ebd848c1SDavid du Colombier 	[Ocall]		"Call",			"",		evalcall,
1914*ebd848c1SDavid du Colombier 
1915*ebd848c1SDavid du Colombier 	[Ostore]	"Store",		"*@",		evalstore,
1916*ebd848c1SDavid du Colombier 	[Oindex]	"Index",		"@i@",		evalindex,
1917*ebd848c1SDavid du Colombier 	[Osize]		"SizeOf",		"*",		evalsize,
1918*ebd848c1SDavid du Colombier 	[Oref]		"RefOf",		"@",		evaliarg0,
1919*ebd848c1SDavid du Colombier 	[Ocref]		"CondRefOf",		"@@",		evalcondref,
1920*ebd848c1SDavid du Colombier 	[Oderef]	"DerefOf",		"@",		evalderef,
1921*ebd848c1SDavid du Colombier 	[Ocat]		"Concatenate",		"**@",		evalcat,
1922*ebd848c1SDavid du Colombier 
1923*ebd848c1SDavid du Colombier 	[Oacq]		"Acquire",		"@2",		evalnop,
1924*ebd848c1SDavid du Colombier 	[Orel]		"Release",		"@",		evalnop,
1925*ebd848c1SDavid du Colombier 	[Ostall]	"Stall",		"i",		evalstall,
1926*ebd848c1SDavid du Colombier 	[Osleep]	"Sleep",		"i",		evalsleep,
1927*ebd848c1SDavid du Colombier 	[Oload] 	"Load", 		"*@}", 		evalload,
1928*ebd848c1SDavid du Colombier 	[Ounload]	"Unload",		"@",		evalnop,
1929*ebd848c1SDavid du Colombier };
1930*ebd848c1SDavid du Colombier 
1931*ebd848c1SDavid du Colombier static uchar octab1[] = {
1932*ebd848c1SDavid du Colombier /* 00 */	Oconst,	Oconst,	Obad,	Obad,	Obad,	Obad,	Oalias,	Obad,
1933*ebd848c1SDavid du Colombier /* 08 */	Oname,	Obad,	Obyte,	Oword,	Odword,	Ostr,	Oqword,	Obad,
1934*ebd848c1SDavid du Colombier /* 10 */	Oscope,	Obuf,	Opkg,	Ovpkg,	Omet,	Obad,	Obad,	Obad,
1935*ebd848c1SDavid du Colombier /* 18 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1936*ebd848c1SDavid du Colombier /* 20 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1937*ebd848c1SDavid du Colombier /* 28 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Onamec,	Onamec,
1938*ebd848c1SDavid du Colombier /* 30 */	Onamec,	Onamec,	Onamec,	Onamec,	Onamec,	Onamec,	Onamec,	Onamec,
1939*ebd848c1SDavid du Colombier /* 38 */	Onamec,	Onamec,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1940*ebd848c1SDavid du Colombier /* 40 */	Obad,	Onamec,	Onamec,	Onamec,	Onamec,	Onamec,	Onamec,	Onamec,
1941*ebd848c1SDavid du Colombier /* 48 */	Onamec,	Onamec,	Onamec,	Onamec,	Onamec,	Onamec,	Onamec,	Onamec,
1942*ebd848c1SDavid du Colombier /* 50 */	Onamec,	Onamec,	Onamec,	Onamec,	Onamec,	Onamec,	Onamec,	Onamec,
1943*ebd848c1SDavid du Colombier /* 58 */	Onamec,	Onamec,	Onamec,	Obad,	Onamec,	Obad,	Onamec,	Onamec,
1944*ebd848c1SDavid du Colombier /* 60 */	Oenv,	Oenv,	Oenv,	Oenv,	Oenv,	Oenv,	Oenv,	Oenv,
1945*ebd848c1SDavid du Colombier /* 68 */	Oenv,	Oenv,	Oenv,	Oenv,	Oenv,	Oenv,	Oenv,	Obad,
1946*ebd848c1SDavid du Colombier /* 70 */	Ostore,	Oref,	Oadd,	Ocat,	Osub,	Oinc,	Odec,	Omul,
1947*ebd848c1SDavid du Colombier /* 78 */	Odiv,	Oshl,	Oshr,	Oand,	Onand,	Oor,	Onor,	Oxor,
1948*ebd848c1SDavid du Colombier /* 80 */	Onot,	Olbit,	Orbit,	Oderef,	Obad,	Omod,	Obad,	Osize,
1949*ebd848c1SDavid du Colombier /* 88 */	Oindex,	Obad,	Ocfld4,	Ocfld2,	Ocfld1,	Ocfld0,	Obad,	Ocfld8,
1950*ebd848c1SDavid du Colombier /* 90 */	Oland,	Olor,	Olnot,	Oleq,	Olgt,	Ollt,	Obad,	Obad,
1951*ebd848c1SDavid du Colombier /* 98 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1952*ebd848c1SDavid du Colombier /* A0 */	Oif,	Oelse,	Owhile,	Onop,	Oret,	Obreak,	Obad,	Obad,
1953*ebd848c1SDavid du Colombier /* A8 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1954*ebd848c1SDavid du Colombier /* B0 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1955*ebd848c1SDavid du Colombier /* B8 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1956*ebd848c1SDavid du Colombier /* C0 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1957*ebd848c1SDavid du Colombier /* C8 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1958*ebd848c1SDavid du Colombier /* D0 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1959*ebd848c1SDavid du Colombier /* D8 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1960*ebd848c1SDavid du Colombier /* E0 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1961*ebd848c1SDavid du Colombier /* E8 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1962*ebd848c1SDavid du Colombier /* F0 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1963*ebd848c1SDavid du Colombier /* F8 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Oconst,
1964*ebd848c1SDavid du Colombier };
1965*ebd848c1SDavid du Colombier 
1966*ebd848c1SDavid du Colombier static uchar octab2[] = {
1967*ebd848c1SDavid du Colombier /* 00 */	Obad,	Omutex,	Oevent,	Obad,	Obad,	Obad,	Obad,	Obad,
1968*ebd848c1SDavid du Colombier /* 08 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1969*ebd848c1SDavid du Colombier /* 10 */	Obad,	Obad,	Ocref,	Ocfld,	Obad,	Obad,	Obad,	Obad,
1970*ebd848c1SDavid du Colombier /* 18 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1971*ebd848c1SDavid du Colombier /* 20 */	Oload,	Ostall,	Osleep,	Oacq,	Obad,	Obad,	Obad,	Orel,
1972*ebd848c1SDavid du Colombier /* 28 */	Obad,	Obad,	Ounload,Obad,	Obad,	Obad,	Obad,	Obad,
1973*ebd848c1SDavid du Colombier /* 30 */	Obad,	Odebug,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1974*ebd848c1SDavid du Colombier /* 38 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1975*ebd848c1SDavid du Colombier /* 40 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1976*ebd848c1SDavid du Colombier /* 48 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1977*ebd848c1SDavid du Colombier /* 50 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1978*ebd848c1SDavid du Colombier /* 58 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1979*ebd848c1SDavid du Colombier /* 60 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1980*ebd848c1SDavid du Colombier /* 68 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1981*ebd848c1SDavid du Colombier /* 70 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1982*ebd848c1SDavid du Colombier /* 78 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1983*ebd848c1SDavid du Colombier /* 80 */	Oreg,	Ofld,	Odev,	Ocpu,	Oprc,	Othz,	Oxfld,	Obad,
1984*ebd848c1SDavid du Colombier /* 88 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1985*ebd848c1SDavid du Colombier /* 90 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1986*ebd848c1SDavid du Colombier /* 98 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1987*ebd848c1SDavid du Colombier /* A0 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1988*ebd848c1SDavid du Colombier /* A8 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1989*ebd848c1SDavid du Colombier /* B0 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1990*ebd848c1SDavid du Colombier /* B8 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1991*ebd848c1SDavid du Colombier /* C0 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1992*ebd848c1SDavid du Colombier /* C8 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1993*ebd848c1SDavid du Colombier /* D0 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1994*ebd848c1SDavid du Colombier /* D8 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1995*ebd848c1SDavid du Colombier /* E0 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1996*ebd848c1SDavid du Colombier /* E8 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1997*ebd848c1SDavid du Colombier /* F0 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1998*ebd848c1SDavid du Colombier /* F8 */	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,	Obad,
1999*ebd848c1SDavid du Colombier };
2000*ebd848c1SDavid du Colombier 
2001*ebd848c1SDavid du Colombier int
amltag(void * p)2002*ebd848c1SDavid du Colombier amltag(void *p)
2003*ebd848c1SDavid du Colombier {
2004*ebd848c1SDavid du Colombier 	return p ? TAG(p) : 0;
2005*ebd848c1SDavid du Colombier }
2006*ebd848c1SDavid du Colombier 
2007*ebd848c1SDavid du Colombier void*
amlval(void * p)2008*ebd848c1SDavid du Colombier amlval(void *p)
2009*ebd848c1SDavid du Colombier {
2010*ebd848c1SDavid du Colombier 	return deref(p);
2011*ebd848c1SDavid du Colombier }
2012*ebd848c1SDavid du Colombier 
2013*ebd848c1SDavid du Colombier uvlong
amlint(void * p)2014*ebd848c1SDavid du Colombier amlint(void *p)
2015*ebd848c1SDavid du Colombier {
2016*ebd848c1SDavid du Colombier 	return ival(p);
2017*ebd848c1SDavid du Colombier }
2018*ebd848c1SDavid du Colombier 
2019*ebd848c1SDavid du Colombier int
amllen(void * p)2020*ebd848c1SDavid du Colombier amllen(void *p)
2021*ebd848c1SDavid du Colombier {
2022*ebd848c1SDavid du Colombier 	while(p){
2023*ebd848c1SDavid du Colombier 		switch(TAG(p)){
2024*ebd848c1SDavid du Colombier 		case 'R':
2025*ebd848c1SDavid du Colombier 			p = *((Ref*)p)->ptr;
2026*ebd848c1SDavid du Colombier 			continue;
2027*ebd848c1SDavid du Colombier 		case 'n':
2028*ebd848c1SDavid du Colombier 		case 's':
2029*ebd848c1SDavid du Colombier 			return strlen((char*)p);
2030*ebd848c1SDavid du Colombier 		case 'p':
2031*ebd848c1SDavid du Colombier 			return SIZE(p)/sizeof(void*);
2032*ebd848c1SDavid du Colombier 		default:
2033*ebd848c1SDavid du Colombier 			return SIZE(p);
2034*ebd848c1SDavid du Colombier 		}
2035*ebd848c1SDavid du Colombier 	}
2036*ebd848c1SDavid du Colombier 	return 0;
2037*ebd848c1SDavid du Colombier }
2038*ebd848c1SDavid du Colombier 
2039*ebd848c1SDavid du Colombier void*
amlnew(char tag,int len)2040*ebd848c1SDavid du Colombier amlnew(char tag, int len)
2041*ebd848c1SDavid du Colombier {
2042*ebd848c1SDavid du Colombier 	switch(tag){
2043*ebd848c1SDavid du Colombier 	case 'i':
2044*ebd848c1SDavid du Colombier 		return mki(0);
2045*ebd848c1SDavid du Colombier 	case 'n':
2046*ebd848c1SDavid du Colombier 	case 's':
2047*ebd848c1SDavid du Colombier 		return mk(tag, len + 1);
2048*ebd848c1SDavid du Colombier 	case 'p':
2049*ebd848c1SDavid du Colombier 		return mk(tag, len * sizeof(void*));
2050*ebd848c1SDavid du Colombier 	default:
2051*ebd848c1SDavid du Colombier 		return mk(tag, len);
2052*ebd848c1SDavid du Colombier 	}
2053*ebd848c1SDavid du Colombier }
2054*ebd848c1SDavid du Colombier 
2055*ebd848c1SDavid du Colombier static void*
evalosi(void)2056*ebd848c1SDavid du Colombier evalosi(void)
2057*ebd848c1SDavid du Colombier {
2058*ebd848c1SDavid du Colombier 	static char *w[] = {
2059*ebd848c1SDavid du Colombier 		"Windows 2001",
2060*ebd848c1SDavid du Colombier 		"Windows 2001 SP1",
2061*ebd848c1SDavid du Colombier 		"Windows 2001 SP2",
2062*ebd848c1SDavid du Colombier 		"Windows 2006",
2063*ebd848c1SDavid du Colombier 	};
2064*ebd848c1SDavid du Colombier 	char *s;
2065*ebd848c1SDavid du Colombier 	int i;
2066*ebd848c1SDavid du Colombier 
2067*ebd848c1SDavid du Colombier 	s = FP->env->arg[0];
2068*ebd848c1SDavid du Colombier 	if(s == nil || TAG(s) != 's')
2069*ebd848c1SDavid du Colombier 		return nil;
2070*ebd848c1SDavid du Colombier 	for(i = 0; i < nelem(w); i++)
2071*ebd848c1SDavid du Colombier 		if(strcmp(s, w[i]) == 0)
2072*ebd848c1SDavid du Colombier 			return mki(0xFFFFFFFF);
2073*ebd848c1SDavid du Colombier 	return nil;
2074*ebd848c1SDavid du Colombier }
2075*ebd848c1SDavid du Colombier 
2076*ebd848c1SDavid du Colombier void
amlinit(void)2077*ebd848c1SDavid du Colombier amlinit(void)
2078*ebd848c1SDavid du Colombier {
2079*ebd848c1SDavid du Colombier 	Name *n;
2080*ebd848c1SDavid du Colombier 
2081*ebd848c1SDavid du Colombier 	fmtinstall('V', Vfmt);
2082*ebd848c1SDavid du Colombier 	fmtinstall('N', Nfmt);
2083*ebd848c1SDavid du Colombier 
2084*ebd848c1SDavid du Colombier 	n = mk('N', sizeof(Name));
2085*ebd848c1SDavid du Colombier 	n->up = n;
2086*ebd848c1SDavid du Colombier 
2087*ebd848c1SDavid du Colombier 	amlroot = n;
2088*ebd848c1SDavid du Colombier 
2089*ebd848c1SDavid du Colombier 	getname(amlroot, "_GPE", 1);
2090*ebd848c1SDavid du Colombier 	getname(amlroot, "_PR", 1);
2091*ebd848c1SDavid du Colombier 	getname(amlroot, "_SB", 1);
2092*ebd848c1SDavid du Colombier 	getname(amlroot, "_TZ", 1);
2093*ebd848c1SDavid du Colombier 	getname(amlroot, "_SI", 1);
2094*ebd848c1SDavid du Colombier 	getname(amlroot, "_GL", 1);
2095*ebd848c1SDavid du Colombier 
2096*ebd848c1SDavid du Colombier 	if(n = getname(amlroot, "_REV", 1))
2097*ebd848c1SDavid du Colombier 		n->v = mki(2);
2098*ebd848c1SDavid du Colombier 	if(n = getname(amlroot, "_OS", 1))
2099*ebd848c1SDavid du Colombier 		n->v = mks("Microsoft Windows");
2100*ebd848c1SDavid du Colombier 	if(n = getname(amlroot, "_OSI", 1)){
2101*ebd848c1SDavid du Colombier 		Method *m;
2102*ebd848c1SDavid du Colombier 
2103*ebd848c1SDavid du Colombier 		m = mk('m', sizeof(Method));
2104*ebd848c1SDavid du Colombier 		m->narg = 1;
2105*ebd848c1SDavid du Colombier 		m->eval = evalosi;
2106*ebd848c1SDavid du Colombier 		m->name = n;
2107*ebd848c1SDavid du Colombier 		n->v = m;
2108*ebd848c1SDavid du Colombier 	}
2109*ebd848c1SDavid du Colombier }
2110*ebd848c1SDavid du Colombier 
2111*ebd848c1SDavid du Colombier void
amlexit(void)2112*ebd848c1SDavid du Colombier amlexit(void)
2113*ebd848c1SDavid du Colombier {
2114*ebd848c1SDavid du Colombier 	amlroot = nil;
2115*ebd848c1SDavid du Colombier 	FP = FB-1;
2116*ebd848c1SDavid du Colombier 	gc();
2117*ebd848c1SDavid du Colombier }
2118*ebd848c1SDavid du Colombier 
2119*ebd848c1SDavid du Colombier int
amlload(uchar * data,int len)2120*ebd848c1SDavid du Colombier amlload(uchar *data, int len)
2121*ebd848c1SDavid du Colombier {
2122*ebd848c1SDavid du Colombier 	int ret;
2123*ebd848c1SDavid du Colombier 
2124*ebd848c1SDavid du Colombier 	ret = xec(data, data+len, amlroot, nil, nil);
2125*ebd848c1SDavid du Colombier 	amlenum(amlroot, nil, fixnames, nil);
2126*ebd848c1SDavid du Colombier 	return ret;
2127*ebd848c1SDavid du Colombier }
2128*ebd848c1SDavid du Colombier 
2129*ebd848c1SDavid du Colombier void*
amlwalk(void * dot,char * name)2130*ebd848c1SDavid du Colombier amlwalk(void *dot, char *name)
2131*ebd848c1SDavid du Colombier {
2132*ebd848c1SDavid du Colombier 	return getname(dot, name, 0);
2133*ebd848c1SDavid du Colombier }
2134*ebd848c1SDavid du Colombier 
2135*ebd848c1SDavid du Colombier void
amlenum(void * dot,char * seg,int (* proc)(void *,void *),void * arg)2136*ebd848c1SDavid du Colombier amlenum(void *dot, char *seg, int (*proc)(void *, void *), void *arg)
2137*ebd848c1SDavid du Colombier {
2138*ebd848c1SDavid du Colombier 	Name *n, *d;
2139*ebd848c1SDavid du Colombier 	int rec;
2140*ebd848c1SDavid du Colombier 
2141*ebd848c1SDavid du Colombier 	d = dot;
2142*ebd848c1SDavid du Colombier 	if(d == nil || TAG(d) != 'N')
2143*ebd848c1SDavid du Colombier 		return;
2144*ebd848c1SDavid du Colombier 	do {
2145*ebd848c1SDavid du Colombier 		rec = 1;
2146*ebd848c1SDavid du Colombier 		if(seg == nil || memcmp(seg, d->seg, sizeof(d->seg)) == 0)
2147*ebd848c1SDavid du Colombier 			rec = (*proc)(d, arg) == 0;
2148*ebd848c1SDavid du Colombier 		for(n = d->down; n && rec; n = n->next)
2149*ebd848c1SDavid du Colombier 			amlenum(n, seg, proc, arg);
2150*ebd848c1SDavid du Colombier 		d = d->fork;
2151*ebd848c1SDavid du Colombier 	} while(d);
2152*ebd848c1SDavid du Colombier }
2153*ebd848c1SDavid du Colombier 
2154*ebd848c1SDavid du Colombier int
amleval(void * dot,char * fmt,...)2155*ebd848c1SDavid du Colombier amleval(void *dot, char *fmt, ...)
2156*ebd848c1SDavid du Colombier {
2157*ebd848c1SDavid du Colombier 	va_list a;
2158*ebd848c1SDavid du Colombier 	Method *m;
2159*ebd848c1SDavid du Colombier 	void **r;
2160*ebd848c1SDavid du Colombier 	Env *e;
2161*ebd848c1SDavid du Colombier 	int i;
2162*ebd848c1SDavid du Colombier 
2163*ebd848c1SDavid du Colombier 	va_start(a, fmt);
2164*ebd848c1SDavid du Colombier 	e = mk('E', sizeof(Env));
2165*ebd848c1SDavid du Colombier 	for(i=0;*fmt;fmt++){
2166*ebd848c1SDavid du Colombier 		switch(*fmt){
2167*ebd848c1SDavid du Colombier 		default:
2168*ebd848c1SDavid du Colombier 			return -1;
2169*ebd848c1SDavid du Colombier 		case 's':
2170*ebd848c1SDavid du Colombier 			e->arg[i++] = mks(va_arg(a, char*));
2171*ebd848c1SDavid du Colombier 			break;
2172*ebd848c1SDavid du Colombier 		case 'i':
2173*ebd848c1SDavid du Colombier 			e->arg[i++] = mki(va_arg(a, int));
2174*ebd848c1SDavid du Colombier 			break;
2175*ebd848c1SDavid du Colombier 		case 'I':
2176*ebd848c1SDavid du Colombier 			e->arg[i++] = mki(va_arg(a, uvlong));
2177*ebd848c1SDavid du Colombier 			break;
2178*ebd848c1SDavid du Colombier 		case 'b':
2179*ebd848c1SDavid du Colombier 		case 'p':
2180*ebd848c1SDavid du Colombier 		case '*':
2181*ebd848c1SDavid du Colombier 			e->arg[i++] = va_arg(a, void*);
2182*ebd848c1SDavid du Colombier 			break;
2183*ebd848c1SDavid du Colombier 		}
2184*ebd848c1SDavid du Colombier 	}
2185*ebd848c1SDavid du Colombier 	r = va_arg(a, void**);
2186*ebd848c1SDavid du Colombier 	va_end(a);
2187*ebd848c1SDavid du Colombier 	if(dot = deref(dot))
2188*ebd848c1SDavid du Colombier 	if(TAG(dot) == 'm'){
2189*ebd848c1SDavid du Colombier 		m = dot;
2190*ebd848c1SDavid du Colombier 		if(i != m->narg)
2191*ebd848c1SDavid du Colombier 			return -1;
2192*ebd848c1SDavid du Colombier 		if(m->eval == nil)
2193*ebd848c1SDavid du Colombier 			return xec(m->start, m->end, forkname(m->name), e, r);
2194*ebd848c1SDavid du Colombier 		FP = FB;
2195*ebd848c1SDavid du Colombier 		FP->op = nil;
2196*ebd848c1SDavid du Colombier 		FP->env = e;
2197*ebd848c1SDavid du Colombier 		FP->narg = 0;
2198*ebd848c1SDavid du Colombier 		FP->dot = m->name;
2199*ebd848c1SDavid du Colombier 		FP->ref = FP->aux = nil;
2200*ebd848c1SDavid du Colombier 		dot = (*m->eval)();
2201*ebd848c1SDavid du Colombier 	}
2202*ebd848c1SDavid du Colombier 	if(r != nil)
2203*ebd848c1SDavid du Colombier 		*r = dot;
2204*ebd848c1SDavid du Colombier 	return 0;
2205*ebd848c1SDavid du Colombier }
2206*ebd848c1SDavid du Colombier 
2207*ebd848c1SDavid du Colombier void
amltake(void * p)2208*ebd848c1SDavid du Colombier amltake(void *p)
2209*ebd848c1SDavid du Colombier {
2210*ebd848c1SDavid du Colombier 	if(p != nil)
2211*ebd848c1SDavid du Colombier 		D2H(p)->mark |= 2;
2212*ebd848c1SDavid du Colombier }
2213*ebd848c1SDavid du Colombier 
2214*ebd848c1SDavid du Colombier void
amldrop(void * p)2215*ebd848c1SDavid du Colombier amldrop(void *p)
2216*ebd848c1SDavid du Colombier {
2217*ebd848c1SDavid du Colombier 	if(p != nil)
2218*ebd848c1SDavid du Colombier 		D2H(p)->mark &= ~2;
2219*ebd848c1SDavid du Colombier }
2220