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