137da2899SCharles.Forsyth #include <lib9.h>
237da2899SCharles.Forsyth #include "isa.h"
337da2899SCharles.Forsyth #include "interp.h"
437da2899SCharles.Forsyth #include "raise.h"
537da2899SCharles.Forsyth #include "pool.h"
637da2899SCharles.Forsyth
737da2899SCharles.Forsyth REG R; /* Virtual Machine registers */
837da2899SCharles.Forsyth String snil; /* String known to be zero length */
937da2899SCharles.Forsyth
1037da2899SCharles.Forsyth #define Stmp *((WORD*)(R.FP+NREG*IBY2WD))
1137da2899SCharles.Forsyth #define Dtmp *((WORD*)(R.FP+(NREG+2)*IBY2WD))
1237da2899SCharles.Forsyth
1337da2899SCharles.Forsyth #define OP(fn) void fn(void)
1437da2899SCharles.Forsyth #define B(r) *((BYTE*)(R.r))
1537da2899SCharles.Forsyth #define W(r) *((WORD*)(R.r))
1637da2899SCharles.Forsyth #define UW(r) *((UWORD*)(R.r))
1737da2899SCharles.Forsyth #define F(r) *((REAL*)(R.r))
1837da2899SCharles.Forsyth #define V(r) *((LONG*)(R.r))
1937da2899SCharles.Forsyth #define UV(r) *((ULONG*)(R.r))
2037da2899SCharles.Forsyth #define S(r) *((String**)(R.r))
2137da2899SCharles.Forsyth #define A(r) *((Array**)(R.r))
2237da2899SCharles.Forsyth #define L(r) *((List**)(R.r))
2337da2899SCharles.Forsyth #define P(r) *((WORD**)(R.r))
2437da2899SCharles.Forsyth #define C(r) *((Channel**)(R.r))
2537da2899SCharles.Forsyth #define T(r) *((void**)(R.r))
2637da2899SCharles.Forsyth #define JMP(r) R.PC = *(Inst**)(R.r)
2737da2899SCharles.Forsyth #define SH(r) *((SHORT*)(R.r))
2837da2899SCharles.Forsyth #define SR(r) *((SREAL*)(R.r))
2937da2899SCharles.Forsyth
OP(runt)3037da2899SCharles.Forsyth OP(runt) {}
OP(negf)3137da2899SCharles.Forsyth OP(negf) { F(d) = -F(s); }
OP(jmp)3237da2899SCharles.Forsyth OP(jmp) { JMP(d); }
OP(movpc)3337da2899SCharles.Forsyth OP(movpc){ T(d) = &R.M->prog[W(s)]; }
OP(movm)3437da2899SCharles.Forsyth OP(movm) { memmove(R.d, R.s, W(m)); }
OP(lea)3537da2899SCharles.Forsyth OP(lea) { W(d) = (WORD)R.s; }
OP(movb)3637da2899SCharles.Forsyth OP(movb) { B(d) = B(s); }
OP(movw)3737da2899SCharles.Forsyth OP(movw) { W(d) = W(s); }
OP(movf)3837da2899SCharles.Forsyth OP(movf) { F(d) = F(s); }
OP(movl)3937da2899SCharles.Forsyth OP(movl) { V(d) = V(s); }
OP(cvtbw)4037da2899SCharles.Forsyth OP(cvtbw){ W(d) = B(s); }
OP(cvtwb)4137da2899SCharles.Forsyth OP(cvtwb){ B(d) = W(s); }
OP(cvtrf)4237da2899SCharles.Forsyth OP(cvtrf){ F(d) = SR(s); }
OP(cvtfr)4337da2899SCharles.Forsyth OP(cvtfr){ SR(d) = F(s); }
OP(cvtws)4437da2899SCharles.Forsyth OP(cvtws){ SH(d) = W(s); }
OP(cvtsw)4537da2899SCharles.Forsyth OP(cvtsw){ W(d) = SH(s); }
OP(cvtwf)4637da2899SCharles.Forsyth OP(cvtwf){ F(d) = W(s); }
OP(addb)4737da2899SCharles.Forsyth OP(addb) { B(d) = B(m) + B(s); }
OP(addw)4837da2899SCharles.Forsyth OP(addw) { W(d) = W(m) + W(s); }
OP(addl)4937da2899SCharles.Forsyth OP(addl) { V(d) = V(m) + V(s); }
OP(addf)5037da2899SCharles.Forsyth OP(addf) { F(d) = F(m) + F(s); }
OP(subb)5137da2899SCharles.Forsyth OP(subb) { B(d) = B(m) - B(s); }
OP(subw)5237da2899SCharles.Forsyth OP(subw) { W(d) = W(m) - W(s); }
OP(subl)5337da2899SCharles.Forsyth OP(subl) { V(d) = V(m) - V(s); }
OP(subf)5437da2899SCharles.Forsyth OP(subf) { F(d) = F(m) - F(s); }
OP(divb)5537da2899SCharles.Forsyth OP(divb) { B(d) = B(m) / B(s); }
OP(divw)5637da2899SCharles.Forsyth OP(divw) { W(d) = W(m) / W(s); }
OP(divl)5737da2899SCharles.Forsyth OP(divl) { V(d) = V(m) / V(s); }
OP(divf)5837da2899SCharles.Forsyth OP(divf) { F(d) = F(m) / F(s); }
OP(modb)5937da2899SCharles.Forsyth OP(modb) { B(d) = B(m) % B(s); }
OP(modw)6037da2899SCharles.Forsyth OP(modw) { W(d) = W(m) % W(s); }
OP(modl)6137da2899SCharles.Forsyth OP(modl) { V(d) = V(m) % V(s); }
OP(mulb)6237da2899SCharles.Forsyth OP(mulb) { B(d) = B(m) * B(s); }
OP(mulw)6337da2899SCharles.Forsyth OP(mulw) { W(d) = W(m) * W(s); }
OP(mull)6437da2899SCharles.Forsyth OP(mull) { V(d) = V(m) * V(s); }
OP(mulf)6537da2899SCharles.Forsyth OP(mulf) { F(d) = F(m) * F(s); }
OP(andb)6637da2899SCharles.Forsyth OP(andb) { B(d) = B(m) & B(s); }
OP(andw)6737da2899SCharles.Forsyth OP(andw) { W(d) = W(m) & W(s); }
OP(andl)6837da2899SCharles.Forsyth OP(andl) { V(d) = V(m) & V(s); }
OP(xorb)6937da2899SCharles.Forsyth OP(xorb) { B(d) = B(m) ^ B(s); }
OP(xorw)7037da2899SCharles.Forsyth OP(xorw) { W(d) = W(m) ^ W(s); }
OP(xorl)7137da2899SCharles.Forsyth OP(xorl) { V(d) = V(m) ^ V(s); }
OP(orb)7237da2899SCharles.Forsyth OP(orb) { B(d) = B(m) | B(s); }
OP(orw)7337da2899SCharles.Forsyth OP(orw) { W(d) = W(m) | W(s); }
OP(orl)7437da2899SCharles.Forsyth OP(orl) { V(d) = V(m) | V(s); }
OP(shlb)7537da2899SCharles.Forsyth OP(shlb) { B(d) = B(m) << W(s); }
OP(shlw)7637da2899SCharles.Forsyth OP(shlw) { W(d) = W(m) << W(s); }
OP(shll)7737da2899SCharles.Forsyth OP(shll) { V(d) = V(m) << W(s); }
OP(shrb)7837da2899SCharles.Forsyth OP(shrb) { B(d) = B(m) >> W(s); }
OP(shrw)7937da2899SCharles.Forsyth OP(shrw) { W(d) = W(m) >> W(s); }
OP(shrl)8037da2899SCharles.Forsyth OP(shrl) { V(d) = V(m) >> W(s); }
OP(lsrw)8137da2899SCharles.Forsyth OP(lsrw) { W(d) = UW(m) >> W(s); }
OP(lsrl)8237da2899SCharles.Forsyth OP(lsrl) { V(d) = UV(m) >> W(s); }
OP(beqb)8337da2899SCharles.Forsyth OP(beqb) { if(B(s) == B(m)) JMP(d); }
OP(bneb)8437da2899SCharles.Forsyth OP(bneb) { if(B(s) != B(m)) JMP(d); }
OP(bltb)8537da2899SCharles.Forsyth OP(bltb) { if(B(s) < B(m)) JMP(d); }
OP(bleb)8637da2899SCharles.Forsyth OP(bleb) { if(B(s) <= B(m)) JMP(d); }
OP(bgtb)8737da2899SCharles.Forsyth OP(bgtb) { if(B(s) > B(m)) JMP(d); }
OP(bgeb)8837da2899SCharles.Forsyth OP(bgeb) { if(B(s) >= B(m)) JMP(d); }
OP(beqw)8937da2899SCharles.Forsyth OP(beqw) { if(W(s) == W(m)) JMP(d); }
OP(bnew)9037da2899SCharles.Forsyth OP(bnew) { if(W(s) != W(m)) JMP(d); }
OP(bltw)9137da2899SCharles.Forsyth OP(bltw) { if(W(s) < W(m)) JMP(d); }
OP(blew)9237da2899SCharles.Forsyth OP(blew) { if(W(s) <= W(m)) JMP(d); }
OP(bgtw)9337da2899SCharles.Forsyth OP(bgtw) { if(W(s) > W(m)) JMP(d); }
OP(bgew)9437da2899SCharles.Forsyth OP(bgew) { if(W(s) >= W(m)) JMP(d); }
OP(beql)9537da2899SCharles.Forsyth OP(beql) { if(V(s) == V(m)) JMP(d); }
OP(bnel)9637da2899SCharles.Forsyth OP(bnel) { if(V(s) != V(m)) JMP(d); }
OP(bltl)9737da2899SCharles.Forsyth OP(bltl) { if(V(s) < V(m)) JMP(d); }
OP(blel)9837da2899SCharles.Forsyth OP(blel) { if(V(s) <= V(m)) JMP(d); }
OP(bgtl)9937da2899SCharles.Forsyth OP(bgtl) { if(V(s) > V(m)) JMP(d); }
OP(bgel)10037da2899SCharles.Forsyth OP(bgel) { if(V(s) >= V(m)) JMP(d); }
OP(beqf)10137da2899SCharles.Forsyth OP(beqf) { if(F(s) == F(m)) JMP(d); }
OP(bnef)10237da2899SCharles.Forsyth OP(bnef) { if(F(s) != F(m)) JMP(d); }
OP(bltf)10337da2899SCharles.Forsyth OP(bltf) { if(F(s) < F(m)) JMP(d); }
OP(blef)10437da2899SCharles.Forsyth OP(blef) { if(F(s) <= F(m)) JMP(d); }
OP(bgtf)10537da2899SCharles.Forsyth OP(bgtf) { if(F(s) > F(m)) JMP(d); }
OP(bgef)10637da2899SCharles.Forsyth OP(bgef) { if(F(s) >= F(m)) JMP(d); }
OP(beqc)10737da2899SCharles.Forsyth OP(beqc) { if(stringcmp(S(s), S(m)) == 0) JMP(d); }
OP(bnec)10837da2899SCharles.Forsyth OP(bnec) { if(stringcmp(S(s), S(m)) != 0) JMP(d); }
OP(bltc)10937da2899SCharles.Forsyth OP(bltc) { if(stringcmp(S(s), S(m)) < 0) JMP(d); }
OP(blec)11037da2899SCharles.Forsyth OP(blec) { if(stringcmp(S(s), S(m)) <= 0) JMP(d); }
OP(bgtc)11137da2899SCharles.Forsyth OP(bgtc) { if(stringcmp(S(s), S(m)) > 0) JMP(d); }
OP(bgec)11237da2899SCharles.Forsyth OP(bgec) { if(stringcmp(S(s), S(m)) >= 0) JMP(d); }
OP(iexit)11337da2899SCharles.Forsyth OP(iexit){ error(""); }
OP(cvtwl)11437da2899SCharles.Forsyth OP(cvtwl){ V(d) = W(s); }
OP(cvtlw)11537da2899SCharles.Forsyth OP(cvtlw){ W(d) = V(s); }
OP(cvtlf)11637da2899SCharles.Forsyth OP(cvtlf){ F(d) = V(s); }
OP(cvtfl)11737da2899SCharles.Forsyth OP(cvtfl)
11837da2899SCharles.Forsyth {
11937da2899SCharles.Forsyth REAL f;
12037da2899SCharles.Forsyth
12137da2899SCharles.Forsyth f = F(s);
12237da2899SCharles.Forsyth V(d) = f < 0 ? f - .5 : f + .5;
12337da2899SCharles.Forsyth }
OP(cvtfw)12437da2899SCharles.Forsyth OP(cvtfw)
12537da2899SCharles.Forsyth {
12637da2899SCharles.Forsyth REAL f;
12737da2899SCharles.Forsyth
12837da2899SCharles.Forsyth f = F(s);
12937da2899SCharles.Forsyth W(d) = f < 0 ? f - .5 : f + .5;
13037da2899SCharles.Forsyth }
OP(cvtcl)13137da2899SCharles.Forsyth OP(cvtcl)
13237da2899SCharles.Forsyth {
13337da2899SCharles.Forsyth String *s;
13437da2899SCharles.Forsyth
13537da2899SCharles.Forsyth s = S(s);
13637da2899SCharles.Forsyth if(s == H)
13737da2899SCharles.Forsyth V(d) = 0;
13837da2899SCharles.Forsyth else
13937da2899SCharles.Forsyth V(d) = strtoll(string2c(s), nil, 10);
14037da2899SCharles.Forsyth }
OP(iexpw)14137da2899SCharles.Forsyth OP(iexpw)
14237da2899SCharles.Forsyth {
14337da2899SCharles.Forsyth int inv;
14437da2899SCharles.Forsyth WORD x, n, r;
14537da2899SCharles.Forsyth
14637da2899SCharles.Forsyth x = W(m);
14737da2899SCharles.Forsyth n = W(s);
14837da2899SCharles.Forsyth inv = 0;
14937da2899SCharles.Forsyth if(n < 0){
15037da2899SCharles.Forsyth n = -n;
15137da2899SCharles.Forsyth inv = 1;
15237da2899SCharles.Forsyth }
15337da2899SCharles.Forsyth r = 1;
15437da2899SCharles.Forsyth for(;;){
15537da2899SCharles.Forsyth if(n&1)
15637da2899SCharles.Forsyth r *= x;
15737da2899SCharles.Forsyth if((n >>= 1) == 0)
15837da2899SCharles.Forsyth break;
15937da2899SCharles.Forsyth x *= x;
16037da2899SCharles.Forsyth }
16137da2899SCharles.Forsyth if(inv)
16237da2899SCharles.Forsyth r = 1/r;
16337da2899SCharles.Forsyth W(d) = r;
16437da2899SCharles.Forsyth }
OP(iexpl)16537da2899SCharles.Forsyth OP(iexpl)
16637da2899SCharles.Forsyth {
16737da2899SCharles.Forsyth int inv;
16837da2899SCharles.Forsyth WORD n;
16937da2899SCharles.Forsyth LONG x, r;
17037da2899SCharles.Forsyth
17137da2899SCharles.Forsyth x = V(m);
17237da2899SCharles.Forsyth n = W(s);
17337da2899SCharles.Forsyth inv = 0;
17437da2899SCharles.Forsyth if(n < 0){
17537da2899SCharles.Forsyth n = -n;
17637da2899SCharles.Forsyth inv = 1;
17737da2899SCharles.Forsyth }
17837da2899SCharles.Forsyth r = 1;
17937da2899SCharles.Forsyth for(;;){
18037da2899SCharles.Forsyth if(n&1)
18137da2899SCharles.Forsyth r *= x;
18237da2899SCharles.Forsyth if((n >>= 1) == 0)
18337da2899SCharles.Forsyth break;
18437da2899SCharles.Forsyth x *= x;
18537da2899SCharles.Forsyth }
18637da2899SCharles.Forsyth if(inv)
18737da2899SCharles.Forsyth r = 1/r;
18837da2899SCharles.Forsyth V(d) = r;
18937da2899SCharles.Forsyth }
OP(iexpf)19037da2899SCharles.Forsyth OP(iexpf)
19137da2899SCharles.Forsyth {
19237da2899SCharles.Forsyth int inv;
19337da2899SCharles.Forsyth WORD n;
19437da2899SCharles.Forsyth REAL x, r;
19537da2899SCharles.Forsyth
19637da2899SCharles.Forsyth x = F(m);
19737da2899SCharles.Forsyth n = W(s);
19837da2899SCharles.Forsyth inv = 0;
19937da2899SCharles.Forsyth if(n < 0){
20037da2899SCharles.Forsyth n = -n;
20137da2899SCharles.Forsyth inv = 1;
20237da2899SCharles.Forsyth }
20337da2899SCharles.Forsyth r = 1;
20437da2899SCharles.Forsyth for(;;){
20537da2899SCharles.Forsyth if(n&1)
20637da2899SCharles.Forsyth r *= x;
20737da2899SCharles.Forsyth if((n >>= 1) == 0)
20837da2899SCharles.Forsyth break;
20937da2899SCharles.Forsyth x *= x;
21037da2899SCharles.Forsyth }
21137da2899SCharles.Forsyth if(inv)
21237da2899SCharles.Forsyth r = 1/r;
21337da2899SCharles.Forsyth F(d) = r;
21437da2899SCharles.Forsyth }
OP(indx)21537da2899SCharles.Forsyth OP(indx)
21637da2899SCharles.Forsyth {
21737da2899SCharles.Forsyth ulong i;
21837da2899SCharles.Forsyth Array *a;
21937da2899SCharles.Forsyth
22037da2899SCharles.Forsyth a = A(s);
22137da2899SCharles.Forsyth i = W(d);
22237da2899SCharles.Forsyth if(a == H || i >= a->len)
22337da2899SCharles.Forsyth error(exBounds);
22437da2899SCharles.Forsyth W(m) = (WORD)(a->data+i*a->t->size);
22537da2899SCharles.Forsyth }
OP(indw)22637da2899SCharles.Forsyth OP(indw)
22737da2899SCharles.Forsyth {
22837da2899SCharles.Forsyth ulong i;
22937da2899SCharles.Forsyth Array *a;
23037da2899SCharles.Forsyth
23137da2899SCharles.Forsyth a = A(s);
23237da2899SCharles.Forsyth i = W(d);
23337da2899SCharles.Forsyth if(a == H || i >= a->len)
23437da2899SCharles.Forsyth error(exBounds);
23537da2899SCharles.Forsyth W(m) = (WORD)(a->data+i*sizeof(WORD));
23637da2899SCharles.Forsyth }
OP(indf)23737da2899SCharles.Forsyth OP(indf)
23837da2899SCharles.Forsyth {
23937da2899SCharles.Forsyth ulong i;
24037da2899SCharles.Forsyth Array *a;
24137da2899SCharles.Forsyth
24237da2899SCharles.Forsyth a = A(s);
24337da2899SCharles.Forsyth i = W(d);
24437da2899SCharles.Forsyth if(a == H || i >= a->len)
24537da2899SCharles.Forsyth error(exBounds);
24637da2899SCharles.Forsyth W(m) = (WORD)(a->data+i*sizeof(REAL));
24737da2899SCharles.Forsyth }
OP(indl)24837da2899SCharles.Forsyth OP(indl)
24937da2899SCharles.Forsyth {
25037da2899SCharles.Forsyth ulong i;
25137da2899SCharles.Forsyth Array *a;
25237da2899SCharles.Forsyth
25337da2899SCharles.Forsyth a = A(s);
25437da2899SCharles.Forsyth i = W(d);
25537da2899SCharles.Forsyth if(a == H || i >= a->len)
25637da2899SCharles.Forsyth error(exBounds);
25737da2899SCharles.Forsyth W(m) = (WORD)(a->data+i*sizeof(LONG));
25837da2899SCharles.Forsyth }
OP(indb)25937da2899SCharles.Forsyth OP(indb)
26037da2899SCharles.Forsyth {
26137da2899SCharles.Forsyth ulong i;
26237da2899SCharles.Forsyth Array *a;
26337da2899SCharles.Forsyth
26437da2899SCharles.Forsyth a = A(s);
26537da2899SCharles.Forsyth i = W(d);
26637da2899SCharles.Forsyth if(a == H || i >= a->len)
26737da2899SCharles.Forsyth error(exBounds);
26837da2899SCharles.Forsyth W(m) = (WORD)(a->data+i*sizeof(BYTE));
26937da2899SCharles.Forsyth }
OP(movp)27037da2899SCharles.Forsyth OP(movp)
27137da2899SCharles.Forsyth {
27237da2899SCharles.Forsyth Heap *h;
27337da2899SCharles.Forsyth WORD *dv, *sv;
27437da2899SCharles.Forsyth
27537da2899SCharles.Forsyth sv = P(s);
27637da2899SCharles.Forsyth if(sv != H) {
27737da2899SCharles.Forsyth h = D2H(sv);
27837da2899SCharles.Forsyth h->ref++;
27937da2899SCharles.Forsyth Setmark(h);
28037da2899SCharles.Forsyth }
28137da2899SCharles.Forsyth dv = P(d);
28237da2899SCharles.Forsyth P(d) = sv;
28337da2899SCharles.Forsyth destroy(dv);
28437da2899SCharles.Forsyth }
OP(movmp)28537da2899SCharles.Forsyth OP(movmp)
28637da2899SCharles.Forsyth {
28737da2899SCharles.Forsyth Type *t;
28837da2899SCharles.Forsyth
28937da2899SCharles.Forsyth t = R.M->type[W(m)];
29037da2899SCharles.Forsyth
29137da2899SCharles.Forsyth incmem(R.s, t);
29237da2899SCharles.Forsyth if (t->np)
29337da2899SCharles.Forsyth freeptrs(R.d, t);
29437da2899SCharles.Forsyth memmove(R.d, R.s, t->size);
29537da2899SCharles.Forsyth }
OP(new)29637da2899SCharles.Forsyth OP(new)
29737da2899SCharles.Forsyth {
29837da2899SCharles.Forsyth Heap *h;
29937da2899SCharles.Forsyth WORD **wp, *t;
30037da2899SCharles.Forsyth
30137da2899SCharles.Forsyth h = heap(R.M->type[W(s)]);
30237da2899SCharles.Forsyth wp = R.d;
30337da2899SCharles.Forsyth t = *wp;
30437da2899SCharles.Forsyth *wp = H2D(WORD*, h);
30537da2899SCharles.Forsyth destroy(t);
30637da2899SCharles.Forsyth }
OP(newz)30737da2899SCharles.Forsyth OP(newz)
30837da2899SCharles.Forsyth {
30937da2899SCharles.Forsyth Heap *h;
31037da2899SCharles.Forsyth WORD **wp, *t;
31137da2899SCharles.Forsyth
31237da2899SCharles.Forsyth h = heapz(R.M->type[W(s)]);
31337da2899SCharles.Forsyth wp = R.d;
31437da2899SCharles.Forsyth t = *wp;
31537da2899SCharles.Forsyth *wp = H2D(WORD*, h);
31637da2899SCharles.Forsyth destroy(t);
31737da2899SCharles.Forsyth }
OP(mnewz)31837da2899SCharles.Forsyth OP(mnewz)
31937da2899SCharles.Forsyth {
32037da2899SCharles.Forsyth Heap *h;
32137da2899SCharles.Forsyth WORD **wp, *t;
32237da2899SCharles.Forsyth Modlink *ml;
32337da2899SCharles.Forsyth
32437da2899SCharles.Forsyth ml = *(Modlink**)R.s;
32537da2899SCharles.Forsyth if(ml == H)
32637da2899SCharles.Forsyth error(exModule);
32737da2899SCharles.Forsyth h = heapz(ml->type[W(m)]);
32837da2899SCharles.Forsyth wp = R.d;
32937da2899SCharles.Forsyth t = *wp;
33037da2899SCharles.Forsyth *wp = H2D(WORD*, h);
33137da2899SCharles.Forsyth destroy(t);
33237da2899SCharles.Forsyth }
OP(frame)33337da2899SCharles.Forsyth OP(frame)
33437da2899SCharles.Forsyth {
33537da2899SCharles.Forsyth Type *t;
33637da2899SCharles.Forsyth Frame *f;
33737da2899SCharles.Forsyth uchar *nsp;
33837da2899SCharles.Forsyth
33937da2899SCharles.Forsyth t = R.M->type[W(s)];
34037da2899SCharles.Forsyth nsp = R.SP + t->size;
34137da2899SCharles.Forsyth if(nsp >= R.TS) {
34237da2899SCharles.Forsyth R.s = t;
34337da2899SCharles.Forsyth extend();
34437da2899SCharles.Forsyth T(d) = R.s;
34537da2899SCharles.Forsyth return;
34637da2899SCharles.Forsyth }
34737da2899SCharles.Forsyth f = (Frame*)R.SP;
34837da2899SCharles.Forsyth R.SP = nsp;
34937da2899SCharles.Forsyth f->t = t;
35037da2899SCharles.Forsyth f->mr = nil;
35137da2899SCharles.Forsyth if (t->np)
35237da2899SCharles.Forsyth initmem(t, f);
35337da2899SCharles.Forsyth T(d) = f;
35437da2899SCharles.Forsyth }
OP(mframe)35537da2899SCharles.Forsyth OP(mframe)
35637da2899SCharles.Forsyth {
35737da2899SCharles.Forsyth Type *t;
35837da2899SCharles.Forsyth Frame *f;
35937da2899SCharles.Forsyth uchar *nsp;
36037da2899SCharles.Forsyth Modlink *ml;
36137da2899SCharles.Forsyth int o;
36237da2899SCharles.Forsyth
36337da2899SCharles.Forsyth ml = *(Modlink**)R.s;
36437da2899SCharles.Forsyth if(ml == H)
36537da2899SCharles.Forsyth error(exModule);
36637da2899SCharles.Forsyth
36737da2899SCharles.Forsyth o = W(m);
36837da2899SCharles.Forsyth if(o >= 0){
36937da2899SCharles.Forsyth if(o >= ml->nlinks)
37037da2899SCharles.Forsyth error("invalid mframe");
37137da2899SCharles.Forsyth t = ml->links[o].frame;
37237da2899SCharles.Forsyth }
37337da2899SCharles.Forsyth else
37437da2899SCharles.Forsyth t = ml->m->ext[-o-1].frame;
37537da2899SCharles.Forsyth nsp = R.SP + t->size;
37637da2899SCharles.Forsyth if(nsp >= R.TS) {
37737da2899SCharles.Forsyth R.s = t;
37837da2899SCharles.Forsyth extend();
37937da2899SCharles.Forsyth T(d) = R.s;
38037da2899SCharles.Forsyth return;
38137da2899SCharles.Forsyth }
38237da2899SCharles.Forsyth f = (Frame*)R.SP;
38337da2899SCharles.Forsyth R.SP = nsp;
38437da2899SCharles.Forsyth f->t = t;
38537da2899SCharles.Forsyth f->mr = nil;
38637da2899SCharles.Forsyth if (t->np)
38737da2899SCharles.Forsyth initmem(t, f);
38837da2899SCharles.Forsyth T(d) = f;
38937da2899SCharles.Forsyth }
39037da2899SCharles.Forsyth void
acheck(int tsz,int sz)39137da2899SCharles.Forsyth acheck(int tsz, int sz)
39237da2899SCharles.Forsyth {
39337da2899SCharles.Forsyth if(sz < 0)
39437da2899SCharles.Forsyth error(exNegsize);
39537da2899SCharles.Forsyth /* test for overflow; assumes sz >>> tsz */
39637da2899SCharles.Forsyth if((int)(sizeof(Array) + sizeof(Heap) + tsz*sz) < sz && tsz != 0)
39737da2899SCharles.Forsyth error(exHeap);
39837da2899SCharles.Forsyth }
OP(newa)39937da2899SCharles.Forsyth OP(newa)
40037da2899SCharles.Forsyth {
40137da2899SCharles.Forsyth int sz;
40237da2899SCharles.Forsyth Type *t;
40337da2899SCharles.Forsyth Heap *h;
40437da2899SCharles.Forsyth Array *a, *at, **ap;
40537da2899SCharles.Forsyth
40637da2899SCharles.Forsyth t = R.M->type[W(m)];
40737da2899SCharles.Forsyth sz = W(s);
40837da2899SCharles.Forsyth acheck(t->size, sz);
40937da2899SCharles.Forsyth h = nheap(sizeof(Array) + (t->size*sz));
41037da2899SCharles.Forsyth h->t = &Tarray;
41137da2899SCharles.Forsyth Tarray.ref++;
41237da2899SCharles.Forsyth a = H2D(Array*, h);
41337da2899SCharles.Forsyth a->t = t;
41437da2899SCharles.Forsyth a->len = sz;
41537da2899SCharles.Forsyth a->root = H;
41637da2899SCharles.Forsyth a->data = (uchar*)a + sizeof(Array);
41737da2899SCharles.Forsyth initarray(t, a);
41837da2899SCharles.Forsyth
41937da2899SCharles.Forsyth ap = R.d;
42037da2899SCharles.Forsyth at = *ap;
42137da2899SCharles.Forsyth *ap = a;
42237da2899SCharles.Forsyth destroy(at);
42337da2899SCharles.Forsyth }
OP(newaz)42437da2899SCharles.Forsyth OP(newaz)
42537da2899SCharles.Forsyth {
42637da2899SCharles.Forsyth int sz;
42737da2899SCharles.Forsyth Type *t;
42837da2899SCharles.Forsyth Heap *h;
42937da2899SCharles.Forsyth Array *a, *at, **ap;
43037da2899SCharles.Forsyth
43137da2899SCharles.Forsyth t = R.M->type[W(m)];
43237da2899SCharles.Forsyth sz = W(s);
43337da2899SCharles.Forsyth acheck(t->size, sz);
43437da2899SCharles.Forsyth h = nheap(sizeof(Array) + (t->size*sz));
43537da2899SCharles.Forsyth h->t = &Tarray;
43637da2899SCharles.Forsyth Tarray.ref++;
43737da2899SCharles.Forsyth a = H2D(Array*, h);
43837da2899SCharles.Forsyth a->t = t;
43937da2899SCharles.Forsyth a->len = sz;
44037da2899SCharles.Forsyth a->root = H;
44137da2899SCharles.Forsyth a->data = (uchar*)a + sizeof(Array);
44237da2899SCharles.Forsyth memset(a->data, 0, t->size*sz);
44337da2899SCharles.Forsyth initarray(t, a);
44437da2899SCharles.Forsyth
44537da2899SCharles.Forsyth ap = R.d;
44637da2899SCharles.Forsyth at = *ap;
44737da2899SCharles.Forsyth *ap = a;
44837da2899SCharles.Forsyth destroy(at);
44937da2899SCharles.Forsyth }
45037da2899SCharles.Forsyth Channel*
cnewc(Type * t,void (* mover)(void),int len)45137da2899SCharles.Forsyth cnewc(Type *t, void (*mover)(void), int len)
45237da2899SCharles.Forsyth {
45337da2899SCharles.Forsyth Heap *h;
45437da2899SCharles.Forsyth Channel *c;
45537da2899SCharles.Forsyth
45637da2899SCharles.Forsyth h = heap(&Tchannel);
45737da2899SCharles.Forsyth c = H2D(Channel*, h);
458*a6e29a60SCharles.Forsyth c->send = malloc(sizeof(Progq));
459*a6e29a60SCharles.Forsyth c->recv = malloc(sizeof(Progq));
46037da2899SCharles.Forsyth if(c->send == nil || c->recv == nil){
46137da2899SCharles.Forsyth free(c->send);
46237da2899SCharles.Forsyth free(c->recv);
46337da2899SCharles.Forsyth error(exNomem);
46437da2899SCharles.Forsyth }
46537da2899SCharles.Forsyth c->send->prog = c->recv->prog = nil;
46637da2899SCharles.Forsyth c->send->next = c->recv->next = nil;
46737da2899SCharles.Forsyth c->mover = mover;
46837da2899SCharles.Forsyth c->buf = H;
46937da2899SCharles.Forsyth if(len > 0)
47037da2899SCharles.Forsyth c->buf = H2D(Array*, heaparray(t, len));
47137da2899SCharles.Forsyth c->front = 0;
47237da2899SCharles.Forsyth c->size = 0;
47337da2899SCharles.Forsyth if(mover == movtmp){
47437da2899SCharles.Forsyth c->mid.t = t;
47537da2899SCharles.Forsyth t->ref++;
47637da2899SCharles.Forsyth }
47737da2899SCharles.Forsyth return c;
47837da2899SCharles.Forsyth }
47937da2899SCharles.Forsyth Channel*
newc(Type * t,void (* mover)(void))48037da2899SCharles.Forsyth newc(Type *t, void (*mover)(void))
48137da2899SCharles.Forsyth {
48237da2899SCharles.Forsyth Channel **cp, *oldc;
48337da2899SCharles.Forsyth WORD len;
48437da2899SCharles.Forsyth
48537da2899SCharles.Forsyth len = 0;
48637da2899SCharles.Forsyth if(R.m != R.d){
48737da2899SCharles.Forsyth len = W(m);
48837da2899SCharles.Forsyth if(len < 0)
48937da2899SCharles.Forsyth error(exNegsize);
49037da2899SCharles.Forsyth }
49137da2899SCharles.Forsyth cp = R.d;
49237da2899SCharles.Forsyth oldc = *cp;
49337da2899SCharles.Forsyth *cp = cnewc(t, mover, len);
49437da2899SCharles.Forsyth destroy(oldc);
49537da2899SCharles.Forsyth return *cp;
49637da2899SCharles.Forsyth }
OP(newcl)49737da2899SCharles.Forsyth OP(newcl) { newc(&Tlong, movl); }
OP(newcb)49837da2899SCharles.Forsyth OP(newcb) { newc(&Tbyte, movb); }
OP(newcw)49937da2899SCharles.Forsyth OP(newcw) { newc(&Tword, movw); }
OP(newcf)50037da2899SCharles.Forsyth OP(newcf) { newc(&Treal, movf); }
OP(newcp)50137da2899SCharles.Forsyth OP(newcp) { newc(&Tptr, movp); }
OP(newcm)50237da2899SCharles.Forsyth OP(newcm)
50337da2899SCharles.Forsyth {
50437da2899SCharles.Forsyth Channel *c;
50537da2899SCharles.Forsyth Type *t;
50637da2899SCharles.Forsyth
50737da2899SCharles.Forsyth t = nil;
50837da2899SCharles.Forsyth if(R.m != R.d && W(m) > 0)
50937da2899SCharles.Forsyth t = dtype(nil, W(s), nil, 0);
51037da2899SCharles.Forsyth c = newc(t, movm);
51137da2899SCharles.Forsyth c->mid.w = W(s);
51237da2899SCharles.Forsyth if(t != nil)
51337da2899SCharles.Forsyth freetype(t);
51437da2899SCharles.Forsyth }
OP(newcmp)51537da2899SCharles.Forsyth OP(newcmp)
51637da2899SCharles.Forsyth {
51737da2899SCharles.Forsyth newc(R.M->type[W(s)], movtmp);
51837da2899SCharles.Forsyth }
OP(icase)51937da2899SCharles.Forsyth OP(icase)
52037da2899SCharles.Forsyth {
52137da2899SCharles.Forsyth WORD v, *t, *l, d, n, n2;
52237da2899SCharles.Forsyth
52337da2899SCharles.Forsyth v = W(s);
52437da2899SCharles.Forsyth t = (WORD*)((WORD)R.d + IBY2WD);
52537da2899SCharles.Forsyth n = t[-1];
52637da2899SCharles.Forsyth d = t[n*3];
52737da2899SCharles.Forsyth
52837da2899SCharles.Forsyth while(n > 0) {
52937da2899SCharles.Forsyth n2 = n >> 1;
53037da2899SCharles.Forsyth l = t + n2*3;
53137da2899SCharles.Forsyth if(v < l[0]) {
53237da2899SCharles.Forsyth n = n2;
53337da2899SCharles.Forsyth continue;
53437da2899SCharles.Forsyth }
53537da2899SCharles.Forsyth if(v >= l[1]) {
53637da2899SCharles.Forsyth t = l+3;
53737da2899SCharles.Forsyth n -= n2 + 1;
53837da2899SCharles.Forsyth continue;
53937da2899SCharles.Forsyth }
54037da2899SCharles.Forsyth d = l[2];
54137da2899SCharles.Forsyth break;
54237da2899SCharles.Forsyth }
54337da2899SCharles.Forsyth if(R.M->compiled) {
54437da2899SCharles.Forsyth R.PC = (Inst*)d;
54537da2899SCharles.Forsyth return;
54637da2899SCharles.Forsyth }
54737da2899SCharles.Forsyth R.PC = R.M->prog + d;
54837da2899SCharles.Forsyth }
OP(casel)54937da2899SCharles.Forsyth OP(casel)
55037da2899SCharles.Forsyth {
55137da2899SCharles.Forsyth WORD *t, *l, d, n, n2;
55237da2899SCharles.Forsyth LONG v;
55337da2899SCharles.Forsyth
55437da2899SCharles.Forsyth v = V(s);
55537da2899SCharles.Forsyth t = (WORD*)((WORD)R.d + 2*IBY2WD);
55637da2899SCharles.Forsyth n = t[-2];
55737da2899SCharles.Forsyth d = t[n*6];
55837da2899SCharles.Forsyth
55937da2899SCharles.Forsyth while(n > 0) {
56037da2899SCharles.Forsyth n2 = n >> 1;
56137da2899SCharles.Forsyth l = t + n2*6;
56237da2899SCharles.Forsyth if(v < ((LONG*)l)[0]) {
56337da2899SCharles.Forsyth n = n2;
56437da2899SCharles.Forsyth continue;
56537da2899SCharles.Forsyth }
56637da2899SCharles.Forsyth if(v >= ((LONG*)l)[1]) {
56737da2899SCharles.Forsyth t = l+6;
56837da2899SCharles.Forsyth n -= n2 + 1;
56937da2899SCharles.Forsyth continue;
57037da2899SCharles.Forsyth }
57137da2899SCharles.Forsyth d = l[4];
57237da2899SCharles.Forsyth break;
57337da2899SCharles.Forsyth }
57437da2899SCharles.Forsyth if(R.M->compiled) {
57537da2899SCharles.Forsyth R.PC = (Inst*)d;
57637da2899SCharles.Forsyth return;
57737da2899SCharles.Forsyth }
57837da2899SCharles.Forsyth R.PC = R.M->prog + d;
57937da2899SCharles.Forsyth }
OP(casec)58037da2899SCharles.Forsyth OP(casec)
58137da2899SCharles.Forsyth {
58237da2899SCharles.Forsyth WORD *l, *t, *e, n, n2, r;
58337da2899SCharles.Forsyth String *sl, *sh, *sv;
58437da2899SCharles.Forsyth
58537da2899SCharles.Forsyth sv = S(s);
58637da2899SCharles.Forsyth t = (WORD*)((WORD)R.d + IBY2WD);
58737da2899SCharles.Forsyth n = t[-1];
58837da2899SCharles.Forsyth e = t + n*3;
58937da2899SCharles.Forsyth if(n > 2){
59037da2899SCharles.Forsyth while(n > 0){
59137da2899SCharles.Forsyth n2 = n>>1;
59237da2899SCharles.Forsyth l = t + n2*3;
59337da2899SCharles.Forsyth sl = (String*)l[0];
59437da2899SCharles.Forsyth r = stringcmp(sv, sl);
59537da2899SCharles.Forsyth if(r == 0){
59637da2899SCharles.Forsyth e = &l[2];
59737da2899SCharles.Forsyth break;
59837da2899SCharles.Forsyth }
59937da2899SCharles.Forsyth if(r < 0){
60037da2899SCharles.Forsyth n = n2;
60137da2899SCharles.Forsyth continue;
60237da2899SCharles.Forsyth }
60337da2899SCharles.Forsyth sh = (String*)l[1];
60437da2899SCharles.Forsyth if(sh == H || stringcmp(sv, sh) > 0){
60537da2899SCharles.Forsyth t = l+3;
60637da2899SCharles.Forsyth n -= n2+1;
60737da2899SCharles.Forsyth continue;
60837da2899SCharles.Forsyth }
60937da2899SCharles.Forsyth e = &l[2];
61037da2899SCharles.Forsyth break;
61137da2899SCharles.Forsyth }
61237da2899SCharles.Forsyth t = e;
61337da2899SCharles.Forsyth }
61437da2899SCharles.Forsyth else{
61537da2899SCharles.Forsyth while(t < e) {
61637da2899SCharles.Forsyth sl = (String*)t[0];
61737da2899SCharles.Forsyth sh = (String*)t[1];
61837da2899SCharles.Forsyth if(sh == H) {
61937da2899SCharles.Forsyth if(stringcmp(sl, sv) == 0) {
62037da2899SCharles.Forsyth t = &t[2];
62137da2899SCharles.Forsyth goto found;
62237da2899SCharles.Forsyth }
62337da2899SCharles.Forsyth }
62437da2899SCharles.Forsyth else
62537da2899SCharles.Forsyth if(stringcmp(sl, sv) <= 0 && stringcmp(sh, sv) >= 0) {
62637da2899SCharles.Forsyth t = &t[2];
62737da2899SCharles.Forsyth goto found;
62837da2899SCharles.Forsyth }
62937da2899SCharles.Forsyth t += 3;
63037da2899SCharles.Forsyth }
63137da2899SCharles.Forsyth }
63237da2899SCharles.Forsyth found:
63337da2899SCharles.Forsyth if(R.M->compiled) {
63437da2899SCharles.Forsyth R.PC = (Inst*)*t;
63537da2899SCharles.Forsyth return;
63637da2899SCharles.Forsyth }
63737da2899SCharles.Forsyth R.PC = R.M->prog + t[0];
63837da2899SCharles.Forsyth }
OP(igoto)63937da2899SCharles.Forsyth OP(igoto)
64037da2899SCharles.Forsyth {
64137da2899SCharles.Forsyth WORD *t;
64237da2899SCharles.Forsyth
64337da2899SCharles.Forsyth t = (WORD*)((WORD)R.d + (W(s) * IBY2WD));
64437da2899SCharles.Forsyth if(R.M->compiled) {
64537da2899SCharles.Forsyth R.PC = (Inst*)t[0];
64637da2899SCharles.Forsyth return;
64737da2899SCharles.Forsyth }
64837da2899SCharles.Forsyth R.PC = R.M->prog + t[0];
64937da2899SCharles.Forsyth }
OP(call)65037da2899SCharles.Forsyth OP(call)
65137da2899SCharles.Forsyth {
65237da2899SCharles.Forsyth Frame *f;
65337da2899SCharles.Forsyth
65437da2899SCharles.Forsyth f = T(s);
65537da2899SCharles.Forsyth f->lr = R.PC;
65637da2899SCharles.Forsyth f->fp = R.FP;
65737da2899SCharles.Forsyth R.FP = (uchar*)f;
65837da2899SCharles.Forsyth JMP(d);
65937da2899SCharles.Forsyth }
OP(spawn)66037da2899SCharles.Forsyth OP(spawn)
66137da2899SCharles.Forsyth {
66237da2899SCharles.Forsyth Prog *p;
66337da2899SCharles.Forsyth
66437da2899SCharles.Forsyth p = newprog(currun(), R.M);
66537da2899SCharles.Forsyth p->R.PC = *(Inst**)R.d;
66637da2899SCharles.Forsyth newstack(p);
66737da2899SCharles.Forsyth unframe();
66837da2899SCharles.Forsyth }
OP(mspawn)66937da2899SCharles.Forsyth OP(mspawn)
67037da2899SCharles.Forsyth {
67137da2899SCharles.Forsyth Prog *p;
67237da2899SCharles.Forsyth Modlink *ml;
67337da2899SCharles.Forsyth int o;
67437da2899SCharles.Forsyth
67537da2899SCharles.Forsyth ml = *(Modlink**)R.d;
67637da2899SCharles.Forsyth if(ml == H)
67737da2899SCharles.Forsyth error(exModule);
67837da2899SCharles.Forsyth if(ml->prog == nil)
67937da2899SCharles.Forsyth error(exSpawn);
68037da2899SCharles.Forsyth p = newprog(currun(), ml);
68137da2899SCharles.Forsyth o = W(m);
68237da2899SCharles.Forsyth if(o >= 0)
68337da2899SCharles.Forsyth p->R.PC = ml->links[o].u.pc;
68437da2899SCharles.Forsyth else
68537da2899SCharles.Forsyth p->R.PC = ml->m->ext[-o-1].u.pc;
68637da2899SCharles.Forsyth newstack(p);
68737da2899SCharles.Forsyth unframe();
68837da2899SCharles.Forsyth }
OP(ret)68937da2899SCharles.Forsyth OP(ret)
69037da2899SCharles.Forsyth {
69137da2899SCharles.Forsyth Frame *f;
69237da2899SCharles.Forsyth Modlink *m;
69337da2899SCharles.Forsyth
69437da2899SCharles.Forsyth f = (Frame*)R.FP;
69537da2899SCharles.Forsyth R.FP = f->fp;
69637da2899SCharles.Forsyth if(R.FP == nil) {
69737da2899SCharles.Forsyth R.FP = (uchar*)f;
69837da2899SCharles.Forsyth error("");
69937da2899SCharles.Forsyth }
70037da2899SCharles.Forsyth R.SP = (uchar*)f;
70137da2899SCharles.Forsyth R.PC = f->lr;
70237da2899SCharles.Forsyth m = f->mr;
70337da2899SCharles.Forsyth
70437da2899SCharles.Forsyth if(f->t == nil)
70537da2899SCharles.Forsyth unextend(f);
70637da2899SCharles.Forsyth else if (f->t->np)
70737da2899SCharles.Forsyth freeptrs(f, f->t);
70837da2899SCharles.Forsyth
70937da2899SCharles.Forsyth if(m != nil) {
71037da2899SCharles.Forsyth if(R.M->compiled != m->compiled) {
71137da2899SCharles.Forsyth R.IC = 1;
71237da2899SCharles.Forsyth R.t = 1;
71337da2899SCharles.Forsyth }
71437da2899SCharles.Forsyth destroy(R.M);
71537da2899SCharles.Forsyth R.M = m;
71637da2899SCharles.Forsyth R.MP = m->MP;
71737da2899SCharles.Forsyth }
71837da2899SCharles.Forsyth }
OP(iload)71937da2899SCharles.Forsyth OP(iload)
72037da2899SCharles.Forsyth {
72137da2899SCharles.Forsyth char *n;
72237da2899SCharles.Forsyth Import *ldt;
72337da2899SCharles.Forsyth Module *m;
72437da2899SCharles.Forsyth Modlink *ml, **mp, *t;
725*a6e29a60SCharles.Forsyth Heap *h;
72637da2899SCharles.Forsyth
72737da2899SCharles.Forsyth n = string2c(S(s));
72837da2899SCharles.Forsyth m = R.M->m;
72937da2899SCharles.Forsyth if(m->rt & HASLDT)
73037da2899SCharles.Forsyth ldt = m->ldt[W(m)];
73137da2899SCharles.Forsyth else{
73237da2899SCharles.Forsyth ldt = nil;
73337da2899SCharles.Forsyth error("obsolete dis");
73437da2899SCharles.Forsyth }
73537da2899SCharles.Forsyth
73637da2899SCharles.Forsyth if(strcmp(n, "$self") == 0) {
73737da2899SCharles.Forsyth m->ref++;
73837da2899SCharles.Forsyth ml = linkmod(m, ldt, 0);
73937da2899SCharles.Forsyth if(ml != H) {
74037da2899SCharles.Forsyth ml->MP = R.M->MP;
741*a6e29a60SCharles.Forsyth h = D2H(ml->MP);
742*a6e29a60SCharles.Forsyth h->ref++;
743*a6e29a60SCharles.Forsyth Setmark(h);
74437da2899SCharles.Forsyth }
74537da2899SCharles.Forsyth }
74637da2899SCharles.Forsyth else {
74737da2899SCharles.Forsyth m = readmod(n, lookmod(n), 1);
74837da2899SCharles.Forsyth ml = linkmod(m, ldt, 1);
74937da2899SCharles.Forsyth }
75037da2899SCharles.Forsyth
75137da2899SCharles.Forsyth mp = R.d;
75237da2899SCharles.Forsyth t = *mp;
75337da2899SCharles.Forsyth *mp = ml;
75437da2899SCharles.Forsyth destroy(t);
75537da2899SCharles.Forsyth }
OP(mcall)75637da2899SCharles.Forsyth OP(mcall)
75737da2899SCharles.Forsyth {
75837da2899SCharles.Forsyth Heap *h;
75937da2899SCharles.Forsyth Prog *p;
76037da2899SCharles.Forsyth Frame *f;
76137da2899SCharles.Forsyth Linkpc *l;
76237da2899SCharles.Forsyth Modlink *ml;
76337da2899SCharles.Forsyth int o;
76437da2899SCharles.Forsyth
76537da2899SCharles.Forsyth ml = *(Modlink**)R.d;
76637da2899SCharles.Forsyth if(ml == H)
76737da2899SCharles.Forsyth error(exModule);
76837da2899SCharles.Forsyth f = T(s);
76937da2899SCharles.Forsyth f->lr = R.PC;
77037da2899SCharles.Forsyth f->fp = R.FP;
77137da2899SCharles.Forsyth f->mr = R.M;
77237da2899SCharles.Forsyth
77337da2899SCharles.Forsyth R.FP = (uchar*)f;
77437da2899SCharles.Forsyth R.M = ml;
77537da2899SCharles.Forsyth h = D2H(ml);
77637da2899SCharles.Forsyth h->ref++;
77737da2899SCharles.Forsyth
77837da2899SCharles.Forsyth o = W(m);
77937da2899SCharles.Forsyth if(o >= 0)
78037da2899SCharles.Forsyth l = &ml->links[o].u;
78137da2899SCharles.Forsyth else
78237da2899SCharles.Forsyth l = &ml->m->ext[-o-1].u;
78337da2899SCharles.Forsyth if(ml->prog == nil) {
78437da2899SCharles.Forsyth l->runt(f);
78537da2899SCharles.Forsyth h->ref--;
78637da2899SCharles.Forsyth R.M = f->mr;
78737da2899SCharles.Forsyth R.SP = R.FP;
78837da2899SCharles.Forsyth R.FP = f->fp;
78937da2899SCharles.Forsyth if(f->t == nil)
79037da2899SCharles.Forsyth unextend(f);
79137da2899SCharles.Forsyth else if (f->t->np)
79237da2899SCharles.Forsyth freeptrs(f, f->t);
79337da2899SCharles.Forsyth p = currun();
79437da2899SCharles.Forsyth if(p->kill != nil)
79537da2899SCharles.Forsyth error(p->kill);
79637da2899SCharles.Forsyth R.t = 0;
79737da2899SCharles.Forsyth return;
79837da2899SCharles.Forsyth }
79937da2899SCharles.Forsyth R.MP = R.M->MP;
80037da2899SCharles.Forsyth R.PC = l->pc;
80137da2899SCharles.Forsyth R.t = 1;
80237da2899SCharles.Forsyth
80337da2899SCharles.Forsyth if(f->mr->compiled != R.M->compiled)
80437da2899SCharles.Forsyth R.IC = 1;
80537da2899SCharles.Forsyth }
OP(lena)80637da2899SCharles.Forsyth OP(lena)
80737da2899SCharles.Forsyth {
80837da2899SCharles.Forsyth WORD l;
80937da2899SCharles.Forsyth Array *a;
81037da2899SCharles.Forsyth
81137da2899SCharles.Forsyth a = A(s);
81237da2899SCharles.Forsyth l = 0;
81337da2899SCharles.Forsyth if(a != H)
81437da2899SCharles.Forsyth l = a->len;
81537da2899SCharles.Forsyth W(d) = l;
81637da2899SCharles.Forsyth }
OP(lenl)81737da2899SCharles.Forsyth OP(lenl)
81837da2899SCharles.Forsyth {
81937da2899SCharles.Forsyth WORD l;
82037da2899SCharles.Forsyth List *a;
82137da2899SCharles.Forsyth
82237da2899SCharles.Forsyth a = L(s);
82337da2899SCharles.Forsyth l = 0;
82437da2899SCharles.Forsyth while(a != H) {
82537da2899SCharles.Forsyth l++;
82637da2899SCharles.Forsyth a = a->tail;
82737da2899SCharles.Forsyth }
82837da2899SCharles.Forsyth W(d) = l;
82937da2899SCharles.Forsyth }
83037da2899SCharles.Forsyth static int
cgetb(Channel * c,void * v)83137da2899SCharles.Forsyth cgetb(Channel *c, void *v)
83237da2899SCharles.Forsyth {
83337da2899SCharles.Forsyth Array *a;
83437da2899SCharles.Forsyth void *w;
83537da2899SCharles.Forsyth
83637da2899SCharles.Forsyth if((a = c->buf) == H)
83737da2899SCharles.Forsyth return 0;
83837da2899SCharles.Forsyth if(c->size > 0){
83937da2899SCharles.Forsyth w = a->data+c->front*a->t->size;
84037da2899SCharles.Forsyth c->front++;
84137da2899SCharles.Forsyth if(c->front == c->buf->len)
84237da2899SCharles.Forsyth c->front = 0;
84337da2899SCharles.Forsyth c->size--;
84437da2899SCharles.Forsyth R.s = w;
84537da2899SCharles.Forsyth R.m = &c->mid;
84637da2899SCharles.Forsyth R.d = v;
84737da2899SCharles.Forsyth c->mover();
84837da2899SCharles.Forsyth if(a->t->np){
84937da2899SCharles.Forsyth freeptrs(w, a->t);
85037da2899SCharles.Forsyth initmem(a->t, w);
85137da2899SCharles.Forsyth }
85237da2899SCharles.Forsyth return 1;
85337da2899SCharles.Forsyth }
85437da2899SCharles.Forsyth return 0;
85537da2899SCharles.Forsyth }
85637da2899SCharles.Forsyth static int
cputb(Channel * c,void * v)85737da2899SCharles.Forsyth cputb(Channel *c, void *v)
85837da2899SCharles.Forsyth {
85937da2899SCharles.Forsyth Array *a;
86037da2899SCharles.Forsyth WORD len, r;
86137da2899SCharles.Forsyth
86237da2899SCharles.Forsyth if((a = c->buf) == H)
86337da2899SCharles.Forsyth return 0;
86437da2899SCharles.Forsyth len = c->buf->len;
86537da2899SCharles.Forsyth if(c->size < len){
86637da2899SCharles.Forsyth r = c->front+c->size;
86737da2899SCharles.Forsyth if(r >= len)
86837da2899SCharles.Forsyth r -= len;
86937da2899SCharles.Forsyth c->size++;
87037da2899SCharles.Forsyth R.s = v;
87137da2899SCharles.Forsyth R.m = &c->mid;
87237da2899SCharles.Forsyth R.d = a->data+r*a->t->size;
87337da2899SCharles.Forsyth c->mover();
87437da2899SCharles.Forsyth return 1;
87537da2899SCharles.Forsyth }
87637da2899SCharles.Forsyth return 0;
87737da2899SCharles.Forsyth }
87837da2899SCharles.Forsyth /*
87937da2899SCharles.Forsyth int
88037da2899SCharles.Forsyth cqsize(Progq *q)
88137da2899SCharles.Forsyth {
88237da2899SCharles.Forsyth int n;
88337da2899SCharles.Forsyth
88437da2899SCharles.Forsyth n = 0;
88537da2899SCharles.Forsyth for( ; q != nil; q = q->next)
88637da2899SCharles.Forsyth if(q->prog != nil)
88737da2899SCharles.Forsyth n++;
88837da2899SCharles.Forsyth return n;
88937da2899SCharles.Forsyth }
89037da2899SCharles.Forsyth */
89137da2899SCharles.Forsyth void
cqadd(Progq ** q,Prog * p)89237da2899SCharles.Forsyth cqadd(Progq **q, Prog *p)
89337da2899SCharles.Forsyth {
89437da2899SCharles.Forsyth Progq *n;
89537da2899SCharles.Forsyth
89637da2899SCharles.Forsyth if((*q)->prog == nil){
89737da2899SCharles.Forsyth (*q)->prog = p;
89837da2899SCharles.Forsyth return;
89937da2899SCharles.Forsyth }
90037da2899SCharles.Forsyth n = (Progq*)malloc(sizeof(Progq));
90137da2899SCharles.Forsyth if(n == nil)
90237da2899SCharles.Forsyth error(exNomem);
90337da2899SCharles.Forsyth n->prog = p;
90437da2899SCharles.Forsyth n->next = nil;
90537da2899SCharles.Forsyth for( ; *q != nil; q = &(*q)->next)
90637da2899SCharles.Forsyth ;
90737da2899SCharles.Forsyth *q = n;
90837da2899SCharles.Forsyth }
90937da2899SCharles.Forsyth void
cqdel(Progq ** q)91037da2899SCharles.Forsyth cqdel(Progq **q)
91137da2899SCharles.Forsyth {
91237da2899SCharles.Forsyth Progq *f;
91337da2899SCharles.Forsyth
91437da2899SCharles.Forsyth if((*q)->next == nil){
91537da2899SCharles.Forsyth (*q)->prog = nil;
91637da2899SCharles.Forsyth return;
91737da2899SCharles.Forsyth }
91837da2899SCharles.Forsyth f = *q;
91937da2899SCharles.Forsyth *q = f->next;
92037da2899SCharles.Forsyth free(f);
92137da2899SCharles.Forsyth }
92237da2899SCharles.Forsyth void
cqdelp(Progq ** q,Prog * p)92337da2899SCharles.Forsyth cqdelp(Progq **q, Prog *p)
92437da2899SCharles.Forsyth {
92537da2899SCharles.Forsyth Progq *f;
92637da2899SCharles.Forsyth
92737da2899SCharles.Forsyth if((*q)->next == nil){
92837da2899SCharles.Forsyth if((*q)->prog == p)
92937da2899SCharles.Forsyth (*q)->prog = nil;
93037da2899SCharles.Forsyth return;
93137da2899SCharles.Forsyth }
93237da2899SCharles.Forsyth for( ; *q != nil; ){
93337da2899SCharles.Forsyth if((*q)->prog == p){
93437da2899SCharles.Forsyth f = *q;
93537da2899SCharles.Forsyth *q = (*q)->next;
93637da2899SCharles.Forsyth free(f);
93737da2899SCharles.Forsyth }
93837da2899SCharles.Forsyth else
93937da2899SCharles.Forsyth q = &(*q)->next;
94037da2899SCharles.Forsyth }
94137da2899SCharles.Forsyth }
OP(isend)94237da2899SCharles.Forsyth OP(isend)
94337da2899SCharles.Forsyth {
94437da2899SCharles.Forsyth Channel *c;
94537da2899SCharles.Forsyth Prog *p;
94637da2899SCharles.Forsyth
94737da2899SCharles.Forsyth c = C(d);
94837da2899SCharles.Forsyth if(c == H)
94937da2899SCharles.Forsyth error(exNilref);
95037da2899SCharles.Forsyth
95137da2899SCharles.Forsyth if((p = c->recv->prog) == nil) {
95237da2899SCharles.Forsyth if(c->buf != H && cputb(c, R.s))
95337da2899SCharles.Forsyth return;
95437da2899SCharles.Forsyth p = delrun(Psend);
95537da2899SCharles.Forsyth p->ptr = R.s;
95637da2899SCharles.Forsyth p->chan = c; /* for killprog */
95737da2899SCharles.Forsyth R.IC = 1;
95837da2899SCharles.Forsyth R.t = 1;
95937da2899SCharles.Forsyth cqadd(&c->send, p);
96037da2899SCharles.Forsyth return;
96137da2899SCharles.Forsyth }
96237da2899SCharles.Forsyth
96337da2899SCharles.Forsyth if(c->buf != H && c->size > 0)
96437da2899SCharles.Forsyth print("non-empty buffer in isend\n");
96537da2899SCharles.Forsyth
96637da2899SCharles.Forsyth cqdel(&c->recv);
96737da2899SCharles.Forsyth if(p->state == Palt)
96837da2899SCharles.Forsyth altdone(p->R.s, p, c, 1);
96937da2899SCharles.Forsyth
97037da2899SCharles.Forsyth R.m = &c->mid;
97137da2899SCharles.Forsyth R.d = p->ptr;
97237da2899SCharles.Forsyth p->ptr = nil;
97337da2899SCharles.Forsyth c->mover();
97437da2899SCharles.Forsyth addrun(p);
97537da2899SCharles.Forsyth R.t = 0;
97637da2899SCharles.Forsyth }
OP(irecv)97737da2899SCharles.Forsyth OP(irecv)
97837da2899SCharles.Forsyth {
97937da2899SCharles.Forsyth Channel *c;
98037da2899SCharles.Forsyth Prog *p;
98137da2899SCharles.Forsyth
98237da2899SCharles.Forsyth c = C(s);
98337da2899SCharles.Forsyth if(c == H)
98437da2899SCharles.Forsyth error(exNilref);
98537da2899SCharles.Forsyth
98637da2899SCharles.Forsyth if((p = c->send->prog) == nil) {
98737da2899SCharles.Forsyth if(c->buf != H && cgetb(c, R.d))
98837da2899SCharles.Forsyth return;
98937da2899SCharles.Forsyth p = delrun(Precv);
99037da2899SCharles.Forsyth p->ptr = R.d;
99137da2899SCharles.Forsyth p->chan = c; /* for killprog */
99237da2899SCharles.Forsyth R.IC = 1;
99337da2899SCharles.Forsyth R.t = 1;
99437da2899SCharles.Forsyth cqadd(&c->recv, p);
99537da2899SCharles.Forsyth return;
99637da2899SCharles.Forsyth }
99737da2899SCharles.Forsyth
99837da2899SCharles.Forsyth if(c->buf != H && c->size != c->buf->len)
99937da2899SCharles.Forsyth print("non-full buffer in irecv\n");
100037da2899SCharles.Forsyth
100137da2899SCharles.Forsyth cqdel(&c->send);
100237da2899SCharles.Forsyth if(p->state == Palt)
100337da2899SCharles.Forsyth altdone(p->R.s, p, c, 0);
100437da2899SCharles.Forsyth
100537da2899SCharles.Forsyth if(c->buf != H){
100637da2899SCharles.Forsyth cgetb(c, R.d);
100737da2899SCharles.Forsyth cputb(c, p->ptr);
100837da2899SCharles.Forsyth p->ptr = nil;
100937da2899SCharles.Forsyth }
101037da2899SCharles.Forsyth else{
101137da2899SCharles.Forsyth R.m = &c->mid;
101237da2899SCharles.Forsyth R.s = p->ptr;
101337da2899SCharles.Forsyth p->ptr = nil;
101437da2899SCharles.Forsyth c->mover();
101537da2899SCharles.Forsyth }
101637da2899SCharles.Forsyth addrun(p);
101737da2899SCharles.Forsyth R.t = 0;
101837da2899SCharles.Forsyth }
101937da2899SCharles.Forsyth int
csendalt(Channel * c,void * ip,Type * t,int len)102037da2899SCharles.Forsyth csendalt(Channel *c, void *ip, Type *t, int len)
102137da2899SCharles.Forsyth {
102237da2899SCharles.Forsyth REG rsav;
102337da2899SCharles.Forsyth
102437da2899SCharles.Forsyth if(c == H)
102537da2899SCharles.Forsyth error(exNilref);
102637da2899SCharles.Forsyth
102737da2899SCharles.Forsyth if(c->recv->prog == nil && (c->buf == H || c->size == c->buf->len)){
102837da2899SCharles.Forsyth if(c->buf != H){
102937da2899SCharles.Forsyth print("csendalt failed\n");
103037da2899SCharles.Forsyth freeptrs(ip, t);
103137da2899SCharles.Forsyth return 0;
103237da2899SCharles.Forsyth }
103337da2899SCharles.Forsyth c->buf = H2D(Array*, heaparray(t, len));
103437da2899SCharles.Forsyth }
103537da2899SCharles.Forsyth
103637da2899SCharles.Forsyth rsav = R;
103737da2899SCharles.Forsyth R.s = ip;
103837da2899SCharles.Forsyth R.d = &c;
103937da2899SCharles.Forsyth isend();
104037da2899SCharles.Forsyth R = rsav;
104137da2899SCharles.Forsyth freeptrs(ip, t);
104237da2899SCharles.Forsyth return 1;
104337da2899SCharles.Forsyth }
104437da2899SCharles.Forsyth
104537da2899SCharles.Forsyth List*
cons(ulong size,List ** lp)104637da2899SCharles.Forsyth cons(ulong size, List **lp)
104737da2899SCharles.Forsyth {
104837da2899SCharles.Forsyth Heap *h;
104937da2899SCharles.Forsyth List *lv, *l;
105037da2899SCharles.Forsyth
105137da2899SCharles.Forsyth h = nheap(sizeof(List) + size - sizeof(((List*)0)->data));
105237da2899SCharles.Forsyth h->t = &Tlist;
105337da2899SCharles.Forsyth Tlist.ref++;
105437da2899SCharles.Forsyth l = H2D(List*, h);
105537da2899SCharles.Forsyth l->t = nil;
105637da2899SCharles.Forsyth
105737da2899SCharles.Forsyth lv = *lp;
105837da2899SCharles.Forsyth if(lv != H) {
105937da2899SCharles.Forsyth h = D2H(lv);
106037da2899SCharles.Forsyth Setmark(h);
106137da2899SCharles.Forsyth }
106237da2899SCharles.Forsyth l->tail = lv;
106337da2899SCharles.Forsyth *lp = l;
106437da2899SCharles.Forsyth return l;
106537da2899SCharles.Forsyth }
OP(consb)106637da2899SCharles.Forsyth OP(consb)
106737da2899SCharles.Forsyth {
106837da2899SCharles.Forsyth List *l;
106937da2899SCharles.Forsyth
107037da2899SCharles.Forsyth l = cons(IBY2WD, R.d);
107137da2899SCharles.Forsyth *(BYTE*)l->data = B(s);
107237da2899SCharles.Forsyth }
OP(consw)107337da2899SCharles.Forsyth OP(consw)
107437da2899SCharles.Forsyth {
107537da2899SCharles.Forsyth List *l;
107637da2899SCharles.Forsyth
107737da2899SCharles.Forsyth l = cons(IBY2WD, R.d);
107837da2899SCharles.Forsyth *(WORD*)l->data = W(s);
107937da2899SCharles.Forsyth }
OP(consl)108037da2899SCharles.Forsyth OP(consl)
108137da2899SCharles.Forsyth {
108237da2899SCharles.Forsyth List *l;
108337da2899SCharles.Forsyth
108437da2899SCharles.Forsyth l = cons(IBY2LG, R.d);
108537da2899SCharles.Forsyth *(LONG*)l->data = V(s);
108637da2899SCharles.Forsyth }
OP(consp)108737da2899SCharles.Forsyth OP(consp)
108837da2899SCharles.Forsyth {
108937da2899SCharles.Forsyth List *l;
109037da2899SCharles.Forsyth Heap *h;
109137da2899SCharles.Forsyth WORD *sv;
109237da2899SCharles.Forsyth
109337da2899SCharles.Forsyth l = cons(IBY2WD, R.d);
109437da2899SCharles.Forsyth sv = P(s);
109537da2899SCharles.Forsyth if(sv != H) {
109637da2899SCharles.Forsyth h = D2H(sv);
109737da2899SCharles.Forsyth h->ref++;
109837da2899SCharles.Forsyth Setmark(h);
109937da2899SCharles.Forsyth }
110037da2899SCharles.Forsyth l->t = &Tptr;
110137da2899SCharles.Forsyth Tptr.ref++;
110237da2899SCharles.Forsyth *(WORD**)l->data = sv;
110337da2899SCharles.Forsyth }
OP(consf)110437da2899SCharles.Forsyth OP(consf)
110537da2899SCharles.Forsyth {
110637da2899SCharles.Forsyth List *l;
110737da2899SCharles.Forsyth
110837da2899SCharles.Forsyth l = cons(sizeof(REAL), R.d);
110937da2899SCharles.Forsyth *(REAL*)l->data = F(s);
111037da2899SCharles.Forsyth }
OP(consm)111137da2899SCharles.Forsyth OP(consm)
111237da2899SCharles.Forsyth {
111337da2899SCharles.Forsyth int v;
111437da2899SCharles.Forsyth List *l;
111537da2899SCharles.Forsyth
111637da2899SCharles.Forsyth v = W(m);
111737da2899SCharles.Forsyth l = cons(v, R.d);
111837da2899SCharles.Forsyth memmove(l->data, R.s, v);
111937da2899SCharles.Forsyth }
OP(consmp)112037da2899SCharles.Forsyth OP(consmp)
112137da2899SCharles.Forsyth {
112237da2899SCharles.Forsyth List *l;
112337da2899SCharles.Forsyth Type *t;
112437da2899SCharles.Forsyth
112537da2899SCharles.Forsyth t = R.M->type[W(m)];
112637da2899SCharles.Forsyth l = cons(t->size, R.d);
112737da2899SCharles.Forsyth incmem(R.s, t);
112837da2899SCharles.Forsyth memmove(l->data, R.s, t->size);
112937da2899SCharles.Forsyth l->t = t;
113037da2899SCharles.Forsyth t->ref++;
113137da2899SCharles.Forsyth }
OP(headb)113237da2899SCharles.Forsyth OP(headb)
113337da2899SCharles.Forsyth {
113437da2899SCharles.Forsyth List *l;
113537da2899SCharles.Forsyth
113637da2899SCharles.Forsyth l = L(s);
113737da2899SCharles.Forsyth B(d) = *(BYTE*)l->data;
113837da2899SCharles.Forsyth }
OP(headw)113937da2899SCharles.Forsyth OP(headw)
114037da2899SCharles.Forsyth {
114137da2899SCharles.Forsyth List *l;
114237da2899SCharles.Forsyth
114337da2899SCharles.Forsyth l = L(s);
114437da2899SCharles.Forsyth W(d) = *(WORD*)l->data;
114537da2899SCharles.Forsyth }
OP(headl)114637da2899SCharles.Forsyth OP(headl)
114737da2899SCharles.Forsyth {
114837da2899SCharles.Forsyth List *l;
114937da2899SCharles.Forsyth
115037da2899SCharles.Forsyth l = L(s);
115137da2899SCharles.Forsyth V(d) = *(LONG*)l->data;
115237da2899SCharles.Forsyth }
OP(headp)115337da2899SCharles.Forsyth OP(headp)
115437da2899SCharles.Forsyth {
115537da2899SCharles.Forsyth List *l;
115637da2899SCharles.Forsyth
115737da2899SCharles.Forsyth l = L(s);
115837da2899SCharles.Forsyth R.s = l->data;
115937da2899SCharles.Forsyth movp();
116037da2899SCharles.Forsyth }
OP(headf)116137da2899SCharles.Forsyth OP(headf)
116237da2899SCharles.Forsyth {
116337da2899SCharles.Forsyth List *l;
116437da2899SCharles.Forsyth
116537da2899SCharles.Forsyth l = L(s);
116637da2899SCharles.Forsyth F(d) = *(REAL*)l->data;
116737da2899SCharles.Forsyth }
OP(headm)116837da2899SCharles.Forsyth OP(headm)
116937da2899SCharles.Forsyth {
117037da2899SCharles.Forsyth List *l;
117137da2899SCharles.Forsyth
117237da2899SCharles.Forsyth l = L(s);
117337da2899SCharles.Forsyth memmove(R.d, l->data, W(m));
117437da2899SCharles.Forsyth }
OP(headmp)117537da2899SCharles.Forsyth OP(headmp)
117637da2899SCharles.Forsyth {
117737da2899SCharles.Forsyth List *l;
117837da2899SCharles.Forsyth
117937da2899SCharles.Forsyth l = L(s);
118037da2899SCharles.Forsyth R.s = l->data;
118137da2899SCharles.Forsyth movmp();
118237da2899SCharles.Forsyth }
OP(tail)118337da2899SCharles.Forsyth OP(tail)
118437da2899SCharles.Forsyth {
118537da2899SCharles.Forsyth List *l;
118637da2899SCharles.Forsyth
118737da2899SCharles.Forsyth l = L(s);
118837da2899SCharles.Forsyth R.s = &l->tail;
118937da2899SCharles.Forsyth movp();
119037da2899SCharles.Forsyth }
OP(slicea)119137da2899SCharles.Forsyth OP(slicea)
119237da2899SCharles.Forsyth {
119337da2899SCharles.Forsyth Type *t;
119437da2899SCharles.Forsyth Heap *h;
119537da2899SCharles.Forsyth Array *at, *ss, *ds;
119637da2899SCharles.Forsyth int v, n, start;
119737da2899SCharles.Forsyth
119837da2899SCharles.Forsyth v = W(m);
119937da2899SCharles.Forsyth start = W(s);
120037da2899SCharles.Forsyth n = v - start;
120137da2899SCharles.Forsyth ds = A(d);
120237da2899SCharles.Forsyth
120337da2899SCharles.Forsyth if(ds == H) {
120437da2899SCharles.Forsyth if(n == 0)
120537da2899SCharles.Forsyth return;
120637da2899SCharles.Forsyth error(exNilref);
120737da2899SCharles.Forsyth }
120837da2899SCharles.Forsyth if(n < 0 || (ulong)start > ds->len || (ulong)v > ds->len)
120937da2899SCharles.Forsyth error(exBounds);
121037da2899SCharles.Forsyth
121137da2899SCharles.Forsyth t = ds->t;
121237da2899SCharles.Forsyth h = heap(&Tarray);
121337da2899SCharles.Forsyth ss = H2D(Array*, h);
121437da2899SCharles.Forsyth ss->len = n;
121537da2899SCharles.Forsyth ss->data = ds->data + start*t->size;
121637da2899SCharles.Forsyth ss->t = t;
121737da2899SCharles.Forsyth t->ref++;
121837da2899SCharles.Forsyth
121937da2899SCharles.Forsyth if(ds->root != H) { /* slicing a slice */
122037da2899SCharles.Forsyth ds = ds->root;
122137da2899SCharles.Forsyth h = D2H(ds);
122237da2899SCharles.Forsyth h->ref++;
122337da2899SCharles.Forsyth at = A(d);
122437da2899SCharles.Forsyth A(d) = ss;
122537da2899SCharles.Forsyth ss->root = ds;
122637da2899SCharles.Forsyth destroy(at);
122737da2899SCharles.Forsyth }
122837da2899SCharles.Forsyth else {
122937da2899SCharles.Forsyth h = D2H(ds);
123037da2899SCharles.Forsyth ss->root = ds;
123137da2899SCharles.Forsyth A(d) = ss;
123237da2899SCharles.Forsyth }
123337da2899SCharles.Forsyth Setmark(h);
123437da2899SCharles.Forsyth }
OP(slicela)123537da2899SCharles.Forsyth OP(slicela)
123637da2899SCharles.Forsyth {
123737da2899SCharles.Forsyth Type *t;
123837da2899SCharles.Forsyth int l, dl;
123937da2899SCharles.Forsyth Array *ss, *ds;
124037da2899SCharles.Forsyth uchar *sp, *dp, *ep;
124137da2899SCharles.Forsyth
124237da2899SCharles.Forsyth ss = A(s);
124337da2899SCharles.Forsyth dl = W(m);
124437da2899SCharles.Forsyth ds = A(d);
124537da2899SCharles.Forsyth if(ss == H)
124637da2899SCharles.Forsyth return;
124737da2899SCharles.Forsyth if(ds == H)
124837da2899SCharles.Forsyth error(exNilref);
124937da2899SCharles.Forsyth if(dl < 0 || dl+ss->len > ds->len)
125037da2899SCharles.Forsyth error(exBounds);
125137da2899SCharles.Forsyth
125237da2899SCharles.Forsyth t = ds->t;
125337da2899SCharles.Forsyth if(t->np == 0) {
125437da2899SCharles.Forsyth memmove(ds->data+dl*t->size, ss->data, ss->len*t->size);
125537da2899SCharles.Forsyth return;
125637da2899SCharles.Forsyth }
125737da2899SCharles.Forsyth sp = ss->data;
125837da2899SCharles.Forsyth dp = ds->data+dl*t->size;
125937da2899SCharles.Forsyth
126037da2899SCharles.Forsyth if(dp > sp) {
126137da2899SCharles.Forsyth l = ss->len * t->size;
126237da2899SCharles.Forsyth sp = ss->data + l;
126337da2899SCharles.Forsyth ep = dp + l;
126437da2899SCharles.Forsyth while(ep > dp) {
126537da2899SCharles.Forsyth ep -= t->size;
126637da2899SCharles.Forsyth sp -= t->size;
126737da2899SCharles.Forsyth incmem(sp, t);
126837da2899SCharles.Forsyth if (t->np)
126937da2899SCharles.Forsyth freeptrs(ep, t);
127037da2899SCharles.Forsyth }
127137da2899SCharles.Forsyth }
127237da2899SCharles.Forsyth else {
127337da2899SCharles.Forsyth ep = dp + ss->len*t->size;
127437da2899SCharles.Forsyth while(dp < ep) {
127537da2899SCharles.Forsyth incmem(sp, t);
127637da2899SCharles.Forsyth if (t->np)
127737da2899SCharles.Forsyth freeptrs(dp, t);
127837da2899SCharles.Forsyth dp += t->size;
127937da2899SCharles.Forsyth sp += t->size;
128037da2899SCharles.Forsyth }
128137da2899SCharles.Forsyth }
128237da2899SCharles.Forsyth memmove(ds->data+dl*t->size, ss->data, ss->len*t->size);
128337da2899SCharles.Forsyth }
OP(alt)128437da2899SCharles.Forsyth OP(alt)
128537da2899SCharles.Forsyth {
128637da2899SCharles.Forsyth R.t = 0;
128737da2899SCharles.Forsyth xecalt(1);
128837da2899SCharles.Forsyth }
OP(nbalt)128937da2899SCharles.Forsyth OP(nbalt)
129037da2899SCharles.Forsyth {
129137da2899SCharles.Forsyth xecalt(0);
129237da2899SCharles.Forsyth }
OP(tcmp)129337da2899SCharles.Forsyth OP(tcmp)
129437da2899SCharles.Forsyth {
129537da2899SCharles.Forsyth void *s, *d;
129637da2899SCharles.Forsyth
129737da2899SCharles.Forsyth s = T(s);
129837da2899SCharles.Forsyth d = T(d);
129937da2899SCharles.Forsyth if(s != H && (d == H || D2H(s)->t != D2H(d)->t))
130037da2899SCharles.Forsyth error(exTcheck);
130137da2899SCharles.Forsyth }
OP(eclr)130237da2899SCharles.Forsyth OP(eclr)
130337da2899SCharles.Forsyth {
130437da2899SCharles.Forsyth /* spare slot */
130537da2899SCharles.Forsyth }
OP(badop)130637da2899SCharles.Forsyth OP(badop)
130737da2899SCharles.Forsyth {
130837da2899SCharles.Forsyth error(exOp);
130937da2899SCharles.Forsyth }
OP(iraise)131037da2899SCharles.Forsyth OP(iraise)
131137da2899SCharles.Forsyth {
131237da2899SCharles.Forsyth void *v;
131337da2899SCharles.Forsyth Heap *h;
131437da2899SCharles.Forsyth Prog *p;
131537da2899SCharles.Forsyth
131637da2899SCharles.Forsyth p = currun();
131737da2899SCharles.Forsyth v = T(s);
131837da2899SCharles.Forsyth if(v == H)
131937da2899SCharles.Forsyth error(exNilref);
132037da2899SCharles.Forsyth p->exval = v;
132137da2899SCharles.Forsyth h = D2H(v);
132237da2899SCharles.Forsyth h->ref++;
132337da2899SCharles.Forsyth if(h->t == &Tstring)
132437da2899SCharles.Forsyth error(string2c((String*)v));
132537da2899SCharles.Forsyth else
132637da2899SCharles.Forsyth error(string2c(*(String**)v));
132737da2899SCharles.Forsyth }
OP(mulx)132837da2899SCharles.Forsyth OP(mulx)
132937da2899SCharles.Forsyth {
133037da2899SCharles.Forsyth WORD p;
133137da2899SCharles.Forsyth LONG r;
133237da2899SCharles.Forsyth
133337da2899SCharles.Forsyth p = Dtmp;
133437da2899SCharles.Forsyth r = (LONG)W(m)*(LONG)W(s);
133537da2899SCharles.Forsyth if(p >= 0)
133637da2899SCharles.Forsyth r <<= p;
133737da2899SCharles.Forsyth else
133837da2899SCharles.Forsyth r >>= (-p);
133937da2899SCharles.Forsyth W(d) = (WORD)r;
134037da2899SCharles.Forsyth }
OP(divx)134137da2899SCharles.Forsyth OP(divx)
134237da2899SCharles.Forsyth {
134337da2899SCharles.Forsyth WORD p;
134437da2899SCharles.Forsyth LONG s;
134537da2899SCharles.Forsyth
134637da2899SCharles.Forsyth p = Dtmp;
134737da2899SCharles.Forsyth s = (LONG)W(m);
134837da2899SCharles.Forsyth if(p >= 0)
134937da2899SCharles.Forsyth s <<= p;
135037da2899SCharles.Forsyth else
135137da2899SCharles.Forsyth s >>= (-p);
135237da2899SCharles.Forsyth s /= (LONG)W(s);
135337da2899SCharles.Forsyth W(d) = (WORD)s;
135437da2899SCharles.Forsyth }
OP(cvtxx)135537da2899SCharles.Forsyth OP(cvtxx)
135637da2899SCharles.Forsyth {
135737da2899SCharles.Forsyth WORD p;
135837da2899SCharles.Forsyth LONG r;
135937da2899SCharles.Forsyth
136037da2899SCharles.Forsyth p = W(m);
136137da2899SCharles.Forsyth r = (LONG)W(s);
136237da2899SCharles.Forsyth if(p >= 0)
136337da2899SCharles.Forsyth r <<= p;
136437da2899SCharles.Forsyth else
136537da2899SCharles.Forsyth r >>= (-p);
136637da2899SCharles.Forsyth W(d) = (WORD)r;
136737da2899SCharles.Forsyth }
OP(mulx0)136837da2899SCharles.Forsyth OP(mulx0)
136937da2899SCharles.Forsyth {
137037da2899SCharles.Forsyth WORD x, y, p, a;
137137da2899SCharles.Forsyth LONG r;
137237da2899SCharles.Forsyth
137337da2899SCharles.Forsyth x = W(m);
137437da2899SCharles.Forsyth y = W(s);
137537da2899SCharles.Forsyth p = Dtmp;
137637da2899SCharles.Forsyth a = Stmp;
137737da2899SCharles.Forsyth if(x == 0 || y == 0){
137837da2899SCharles.Forsyth W(d) = 0;
137937da2899SCharles.Forsyth return;
138037da2899SCharles.Forsyth }
138137da2899SCharles.Forsyth r = (LONG)x*(LONG)y;
138237da2899SCharles.Forsyth if(p >= 0)
138337da2899SCharles.Forsyth r <<= p;
138437da2899SCharles.Forsyth else
138537da2899SCharles.Forsyth r >>= (-p);
138637da2899SCharles.Forsyth r /= (LONG)a;
138737da2899SCharles.Forsyth W(d) = (WORD)r;
138837da2899SCharles.Forsyth }
OP(divx0)138937da2899SCharles.Forsyth OP(divx0)
139037da2899SCharles.Forsyth {
139137da2899SCharles.Forsyth WORD x, y, p, b;
139237da2899SCharles.Forsyth LONG s;
139337da2899SCharles.Forsyth
139437da2899SCharles.Forsyth x = W(m);
139537da2899SCharles.Forsyth y = W(s);
139637da2899SCharles.Forsyth p = Dtmp;
139737da2899SCharles.Forsyth b = Stmp;
139837da2899SCharles.Forsyth if(x == 0){
139937da2899SCharles.Forsyth W(d) = 0;
140037da2899SCharles.Forsyth return;
140137da2899SCharles.Forsyth }
140237da2899SCharles.Forsyth s = (LONG)b*(LONG)x;
140337da2899SCharles.Forsyth if(p >= 0)
140437da2899SCharles.Forsyth s <<= p;
140537da2899SCharles.Forsyth else
140637da2899SCharles.Forsyth s >>= (-p);
140737da2899SCharles.Forsyth s /= (LONG)y;
140837da2899SCharles.Forsyth W(d) = (WORD)s;
140937da2899SCharles.Forsyth }
OP(cvtxx0)141037da2899SCharles.Forsyth OP(cvtxx0)
141137da2899SCharles.Forsyth {
141237da2899SCharles.Forsyth WORD x, p, a;
141337da2899SCharles.Forsyth LONG r;
141437da2899SCharles.Forsyth
141537da2899SCharles.Forsyth x = W(s);
141637da2899SCharles.Forsyth p = W(m);
141737da2899SCharles.Forsyth a = Stmp;
141837da2899SCharles.Forsyth if(x == 0){
141937da2899SCharles.Forsyth W(d) = 0;
142037da2899SCharles.Forsyth return;
142137da2899SCharles.Forsyth }
142237da2899SCharles.Forsyth r = (LONG)x;
142337da2899SCharles.Forsyth if(p >= 0)
142437da2899SCharles.Forsyth r <<= p;
142537da2899SCharles.Forsyth else
142637da2899SCharles.Forsyth r >>= (-p);
142737da2899SCharles.Forsyth r /= (LONG)a;
142837da2899SCharles.Forsyth W(d) = (WORD)r;
142937da2899SCharles.Forsyth }
OP(mulx1)143037da2899SCharles.Forsyth OP(mulx1)
143137da2899SCharles.Forsyth {
143237da2899SCharles.Forsyth WORD x, y, p, a, v;
143337da2899SCharles.Forsyth int vnz, wnz;
143437da2899SCharles.Forsyth LONG w, r;
143537da2899SCharles.Forsyth
143637da2899SCharles.Forsyth x = W(m);
143737da2899SCharles.Forsyth y = W(s);
143837da2899SCharles.Forsyth p = Dtmp;
143937da2899SCharles.Forsyth a = Stmp;
144037da2899SCharles.Forsyth if(x == 0 || y == 0){
144137da2899SCharles.Forsyth W(d) = 0;
144237da2899SCharles.Forsyth return;
144337da2899SCharles.Forsyth }
144437da2899SCharles.Forsyth vnz = p&2;
144537da2899SCharles.Forsyth wnz = p&1;
144637da2899SCharles.Forsyth p >>= 2;
144737da2899SCharles.Forsyth v = 0;
144837da2899SCharles.Forsyth w = 0;
144937da2899SCharles.Forsyth if(vnz){
145037da2899SCharles.Forsyth v = a-1;
145137da2899SCharles.Forsyth if(x >= 0 && y < 0 || x < 0 && y >= 0)
145237da2899SCharles.Forsyth v = -v;
145337da2899SCharles.Forsyth }
145437da2899SCharles.Forsyth if(wnz){
145537da2899SCharles.Forsyth if((!vnz && (x > 0 && y < 0 || x < 0 && y > 0)) ||
145637da2899SCharles.Forsyth (vnz && (x > 0 && y > 0 || x < 0 && y < 0)))
145737da2899SCharles.Forsyth w = ((LONG)1<<(-p)) - 1;
145837da2899SCharles.Forsyth }
145937da2899SCharles.Forsyth r = (LONG)x*(LONG)y + w;
146037da2899SCharles.Forsyth if(p >= 0)
146137da2899SCharles.Forsyth r <<= p;
146237da2899SCharles.Forsyth else
146337da2899SCharles.Forsyth r >>= (-p);
146437da2899SCharles.Forsyth r += (LONG)v;
146537da2899SCharles.Forsyth r /= (LONG)a;
146637da2899SCharles.Forsyth W(d) = (WORD)r;
146737da2899SCharles.Forsyth }
OP(divx1)146837da2899SCharles.Forsyth OP(divx1)
146937da2899SCharles.Forsyth {
147037da2899SCharles.Forsyth WORD x, y, p, b, v;
147137da2899SCharles.Forsyth int vnz, wnz;
147237da2899SCharles.Forsyth LONG w, s;
147337da2899SCharles.Forsyth
147437da2899SCharles.Forsyth x = W(m);
147537da2899SCharles.Forsyth y = W(s);
147637da2899SCharles.Forsyth p = Dtmp;
147737da2899SCharles.Forsyth b = Stmp;
147837da2899SCharles.Forsyth if(x == 0){
147937da2899SCharles.Forsyth W(d) = 0;
148037da2899SCharles.Forsyth return;
148137da2899SCharles.Forsyth }
148237da2899SCharles.Forsyth vnz = p&2;
148337da2899SCharles.Forsyth wnz = p&1;
148437da2899SCharles.Forsyth p >>= 2;
148537da2899SCharles.Forsyth v = 0;
148637da2899SCharles.Forsyth w = 0;
148737da2899SCharles.Forsyth if(vnz){
148837da2899SCharles.Forsyth v = 1;
148937da2899SCharles.Forsyth if(x >= 0 && y < 0 || x < 0 && y >= 0)
149037da2899SCharles.Forsyth v = -v;
149137da2899SCharles.Forsyth }
149237da2899SCharles.Forsyth if(wnz){
149337da2899SCharles.Forsyth if(x <= 0)
149437da2899SCharles.Forsyth w = ((LONG)1<<(-p)) - 1;
149537da2899SCharles.Forsyth }
149637da2899SCharles.Forsyth s = (LONG)b*(LONG)x + w;
149737da2899SCharles.Forsyth if(p >= 0)
149837da2899SCharles.Forsyth s <<= p;
149937da2899SCharles.Forsyth else
150037da2899SCharles.Forsyth s >>= (-p);
150137da2899SCharles.Forsyth s /= (LONG)y;
150237da2899SCharles.Forsyth W(d) = (WORD)s + v;
150337da2899SCharles.Forsyth }
OP(cvtxx1)150437da2899SCharles.Forsyth OP(cvtxx1)
150537da2899SCharles.Forsyth {
150637da2899SCharles.Forsyth WORD x, p, a, v;
150737da2899SCharles.Forsyth int vnz, wnz;
150837da2899SCharles.Forsyth LONG w, r;
150937da2899SCharles.Forsyth
151037da2899SCharles.Forsyth x = W(s);
151137da2899SCharles.Forsyth p = W(m);
151237da2899SCharles.Forsyth a = Stmp;
151337da2899SCharles.Forsyth if(x == 0){
151437da2899SCharles.Forsyth W(d) = 0;
151537da2899SCharles.Forsyth return;
151637da2899SCharles.Forsyth }
151737da2899SCharles.Forsyth vnz = p&2;
151837da2899SCharles.Forsyth wnz = p&1;
151937da2899SCharles.Forsyth p >>= 2;
152037da2899SCharles.Forsyth v = 0;
152137da2899SCharles.Forsyth w = 0;
152237da2899SCharles.Forsyth if(vnz){
152337da2899SCharles.Forsyth v = a-1;
152437da2899SCharles.Forsyth if(x < 0)
152537da2899SCharles.Forsyth v = -v;
152637da2899SCharles.Forsyth }
152737da2899SCharles.Forsyth if(wnz){
152837da2899SCharles.Forsyth if(!vnz && x < 0 || vnz && x > 0)
152937da2899SCharles.Forsyth w = ((LONG)1<<(-p)) - 1;
153037da2899SCharles.Forsyth }
153137da2899SCharles.Forsyth r = (LONG)x + w;
153237da2899SCharles.Forsyth if(p >= 0)
153337da2899SCharles.Forsyth r <<= p;
153437da2899SCharles.Forsyth else
153537da2899SCharles.Forsyth r >>= (-p);
153637da2899SCharles.Forsyth r += (LONG)v;
153737da2899SCharles.Forsyth r /= (LONG)a;
153837da2899SCharles.Forsyth W(d) = (WORD)r;
153937da2899SCharles.Forsyth }
154037da2899SCharles.Forsyth /*
154137da2899SCharles.Forsyth OP(cvtxx)
154237da2899SCharles.Forsyth {
154337da2899SCharles.Forsyth REAL v;
154437da2899SCharles.Forsyth
154537da2899SCharles.Forsyth v = (REAL)W(s)*F(m);
154637da2899SCharles.Forsyth v = v < 0 ? v-0.5: v+0.5;
154737da2899SCharles.Forsyth W(d) = (WORD)v;
154837da2899SCharles.Forsyth }
154937da2899SCharles.Forsyth */
OP(cvtfx)155037da2899SCharles.Forsyth OP(cvtfx)
155137da2899SCharles.Forsyth {
155237da2899SCharles.Forsyth REAL v;
155337da2899SCharles.Forsyth
155437da2899SCharles.Forsyth v = F(s)*F(m);
155537da2899SCharles.Forsyth v = v < 0 ? v-0.5: v+0.5;
155637da2899SCharles.Forsyth W(d) = (WORD)v;
155737da2899SCharles.Forsyth }
OP(cvtxf)155837da2899SCharles.Forsyth OP(cvtxf)
155937da2899SCharles.Forsyth {
156037da2899SCharles.Forsyth F(d) = (REAL)W(s)*F(m);
156137da2899SCharles.Forsyth }
156237da2899SCharles.Forsyth
OP(self)156337da2899SCharles.Forsyth OP(self)
156437da2899SCharles.Forsyth {
156537da2899SCharles.Forsyth Modlink *ml, **mp, *t;
1566*a6e29a60SCharles.Forsyth Heap *h;
156737da2899SCharles.Forsyth
156837da2899SCharles.Forsyth ml = R.M;
1569*a6e29a60SCharles.Forsyth h = D2H(ml);
1570*a6e29a60SCharles.Forsyth h->ref++;
1571*a6e29a60SCharles.Forsyth Setmark(h);
157237da2899SCharles.Forsyth mp = R.d;
157337da2899SCharles.Forsyth t = *mp;
157437da2899SCharles.Forsyth *mp = ml;
157537da2899SCharles.Forsyth destroy(t);
157637da2899SCharles.Forsyth }
157737da2899SCharles.Forsyth
157837da2899SCharles.Forsyth void
destroystack(REG * reg)157937da2899SCharles.Forsyth destroystack(REG *reg)
158037da2899SCharles.Forsyth {
158137da2899SCharles.Forsyth Type *t;
158237da2899SCharles.Forsyth Frame *f, *fp;
158337da2899SCharles.Forsyth Modlink *m;
158437da2899SCharles.Forsyth Stkext *sx;
158537da2899SCharles.Forsyth uchar *ex;
158637da2899SCharles.Forsyth
158737da2899SCharles.Forsyth ex = reg->EX;
158837da2899SCharles.Forsyth reg->EX = nil;
158937da2899SCharles.Forsyth while(ex != nil) {
159037da2899SCharles.Forsyth sx = (Stkext*)ex;
159137da2899SCharles.Forsyth fp = sx->reg.tos.fr;
159237da2899SCharles.Forsyth do {
159337da2899SCharles.Forsyth f = (Frame*)reg->FP;
159437da2899SCharles.Forsyth if(f == nil)
159537da2899SCharles.Forsyth break;
159637da2899SCharles.Forsyth reg->FP = f->fp;
159737da2899SCharles.Forsyth t = f->t;
159837da2899SCharles.Forsyth if(t == nil)
159937da2899SCharles.Forsyth t = sx->reg.TR;
160037da2899SCharles.Forsyth m = f->mr;
160137da2899SCharles.Forsyth if (t->np)
160237da2899SCharles.Forsyth freeptrs(f, t);
160337da2899SCharles.Forsyth if(m != nil) {
160437da2899SCharles.Forsyth destroy(reg->M);
160537da2899SCharles.Forsyth reg->M = m;
160637da2899SCharles.Forsyth }
160737da2899SCharles.Forsyth } while(f != fp);
160837da2899SCharles.Forsyth ex = sx->reg.EX;
160937da2899SCharles.Forsyth free(sx);
161037da2899SCharles.Forsyth }
161137da2899SCharles.Forsyth destroy(reg->M);
161237da2899SCharles.Forsyth reg->M = H; /* for devprof */
161337da2899SCharles.Forsyth }
161437da2899SCharles.Forsyth
161537da2899SCharles.Forsyth Prog*
isave(void)161637da2899SCharles.Forsyth isave(void)
161737da2899SCharles.Forsyth {
161837da2899SCharles.Forsyth Prog *p;
161937da2899SCharles.Forsyth
162037da2899SCharles.Forsyth p = delrun(Prelease);
162137da2899SCharles.Forsyth p->R = R;
162237da2899SCharles.Forsyth return p;
162337da2899SCharles.Forsyth }
162437da2899SCharles.Forsyth
162537da2899SCharles.Forsyth void
irestore(Prog * p)162637da2899SCharles.Forsyth irestore(Prog *p)
162737da2899SCharles.Forsyth {
162837da2899SCharles.Forsyth R = p->R;
162937da2899SCharles.Forsyth R.IC = 1;
163037da2899SCharles.Forsyth }
163137da2899SCharles.Forsyth
163237da2899SCharles.Forsyth void
movtmp(void)163337da2899SCharles.Forsyth movtmp(void) /* Used by send & receive */
163437da2899SCharles.Forsyth {
163537da2899SCharles.Forsyth Type *t;
163637da2899SCharles.Forsyth
163737da2899SCharles.Forsyth t = (Type*)W(m);
163837da2899SCharles.Forsyth
163937da2899SCharles.Forsyth incmem(R.s, t);
164037da2899SCharles.Forsyth if (t->np)
164137da2899SCharles.Forsyth freeptrs(R.d, t);
164237da2899SCharles.Forsyth memmove(R.d, R.s, t->size);
164337da2899SCharles.Forsyth }
164437da2899SCharles.Forsyth
164537da2899SCharles.Forsyth extern OP(cvtca);
164637da2899SCharles.Forsyth extern OP(cvtac);
164737da2899SCharles.Forsyth extern OP(cvtwc);
164837da2899SCharles.Forsyth extern OP(cvtcw);
164937da2899SCharles.Forsyth extern OP(cvtfc);
165037da2899SCharles.Forsyth extern OP(cvtcf);
165137da2899SCharles.Forsyth extern OP(insc);
165237da2899SCharles.Forsyth extern OP(indc);
165337da2899SCharles.Forsyth extern OP(addc);
165437da2899SCharles.Forsyth extern OP(lenc);
165537da2899SCharles.Forsyth extern OP(slicec);
165637da2899SCharles.Forsyth extern OP(cvtlc);
165737da2899SCharles.Forsyth
165837da2899SCharles.Forsyth #include "optab.h"
165937da2899SCharles.Forsyth
166037da2899SCharles.Forsyth void
opinit(void)166137da2899SCharles.Forsyth opinit(void)
166237da2899SCharles.Forsyth {
166337da2899SCharles.Forsyth int i;
166437da2899SCharles.Forsyth
166537da2899SCharles.Forsyth for(i = 0; i < 256; i++)
166637da2899SCharles.Forsyth if(optab[i] == nil)
166737da2899SCharles.Forsyth optab[i] = badop;
166837da2899SCharles.Forsyth }
166937da2899SCharles.Forsyth
167037da2899SCharles.Forsyth void
xec(Prog * p)167137da2899SCharles.Forsyth xec(Prog *p)
167237da2899SCharles.Forsyth {
167337da2899SCharles.Forsyth int op;
167437da2899SCharles.Forsyth
167537da2899SCharles.Forsyth R = p->R;
167637da2899SCharles.Forsyth R.MP = R.M->MP;
167737da2899SCharles.Forsyth R.IC = p->quanta;
167837da2899SCharles.Forsyth
167937da2899SCharles.Forsyth if(p->kill != nil) {
168037da2899SCharles.Forsyth char *m;
168137da2899SCharles.Forsyth m = p->kill;
168237da2899SCharles.Forsyth p->kill = nil;
168337da2899SCharles.Forsyth error(m);
168437da2899SCharles.Forsyth }
168537da2899SCharles.Forsyth
168637da2899SCharles.Forsyth // print("%lux %lux %lux %lux %lux\n", (ulong)&R, R.xpc, R.FP, R.MP, R.PC);
168737da2899SCharles.Forsyth
168837da2899SCharles.Forsyth if(R.M->compiled)
168937da2899SCharles.Forsyth comvec();
169037da2899SCharles.Forsyth else do {
169137da2899SCharles.Forsyth dec[R.PC->add]();
169237da2899SCharles.Forsyth op = R.PC->op;
169337da2899SCharles.Forsyth R.PC++;
169437da2899SCharles.Forsyth optab[op]();
169537da2899SCharles.Forsyth } while(--R.IC != 0);
169637da2899SCharles.Forsyth
169737da2899SCharles.Forsyth p->R = R;
169837da2899SCharles.Forsyth }
1699