1*37da2899SCharles.Forsyth #include "lib9.h"
2*37da2899SCharles.Forsyth #include "isa.h"
3*37da2899SCharles.Forsyth #include "interp.h"
4*37da2899SCharles.Forsyth #include "raise.h"
5*37da2899SCharles.Forsyth
6*37da2899SCharles.Forsyth enum
7*37da2899SCharles.Forsyth {
8*37da2899SCharles.Forsyth R8 = 8, /* SUN calls these %o0 - %o7 */
9*37da2899SCharles.Forsyth R9 = 9,
10*37da2899SCharles.Forsyth R10 = 10,
11*37da2899SCharles.Forsyth R11 = 11,
12*37da2899SCharles.Forsyth R12 = 12,
13*37da2899SCharles.Forsyth R13 = 13,
14*37da2899SCharles.Forsyth R14 = 14, /* SUN %sp */
15*37da2899SCharles.Forsyth R15 = 15, /* R15/%o7 is the default link register */
16*37da2899SCharles.Forsyth
17*37da2899SCharles.Forsyth R16 = 16, /* SUN calls these %l0 - %l7 */
18*37da2899SCharles.Forsyth R17 = 17,
19*37da2899SCharles.Forsyth R18 = 18,
20*37da2899SCharles.Forsyth R19 = 19,
21*37da2899SCharles.Forsyth R20 = 20,
22*37da2899SCharles.Forsyth R21 = 21,
23*37da2899SCharles.Forsyth R22 = 22,
24*37da2899SCharles.Forsyth R23 = 23,
25*37da2899SCharles.Forsyth RLINK = 15,
26*37da2899SCharles.Forsyth
27*37da2899SCharles.Forsyth RZ = 0, /* Always 0 */
28*37da2899SCharles.Forsyth RFP = R23, /* Frame Pointer */
29*37da2899SCharles.Forsyth RMP = R22, /* Module Pointer */
30*37da2899SCharles.Forsyth RTA = R21, /* Intermediate address for double indirect */
31*37da2899SCharles.Forsyth RREG = R20, /* Pointer to REG */
32*37da2899SCharles.Forsyth RA3 = R19, /* gpr 3 */
33*37da2899SCharles.Forsyth RA2 = R18, /* gpr 2 2+3 = L */
34*37da2899SCharles.Forsyth RA1 = R17, /* gpr 1 */
35*37da2899SCharles.Forsyth RA0 = R16, /* gpr 0 0+1 = L */
36*37da2899SCharles.Forsyth
37*37da2899SCharles.Forsyth RCON = R8, /* Constant builder */
38*37da2899SCharles.Forsyth
39*37da2899SCharles.Forsyth FA2 = 2, /* Floating */
40*37da2899SCharles.Forsyth FA3 = 3,
41*37da2899SCharles.Forsyth FA4 = 4,
42*37da2899SCharles.Forsyth FA5 = 5,
43*37da2899SCharles.Forsyth
44*37da2899SCharles.Forsyth Olea = (1<<20), /* Pseudo op */
45*37da2899SCharles.Forsyth Owry = 48,
46*37da2899SCharles.Forsyth Omul = 11,
47*37da2899SCharles.Forsyth Oumul = 10,
48*37da2899SCharles.Forsyth Osdiv = 15,
49*37da2899SCharles.Forsyth Osll = 37,
50*37da2899SCharles.Forsyth Osra = 39,
51*37da2899SCharles.Forsyth Osrl = 38,
52*37da2899SCharles.Forsyth Osethi = 4,
53*37da2899SCharles.Forsyth Oadd = 0,
54*37da2899SCharles.Forsyth Oaddcc = 16,
55*37da2899SCharles.Forsyth Oaddx = 8,
56*37da2899SCharles.Forsyth Osub = 4,
57*37da2899SCharles.Forsyth Osubcc = 20,
58*37da2899SCharles.Forsyth Osubx = 12,
59*37da2899SCharles.Forsyth Oor = 2,
60*37da2899SCharles.Forsyth Oand = 1,
61*37da2899SCharles.Forsyth Oxor = 3,
62*37da2899SCharles.Forsyth Oldw = 0,
63*37da2899SCharles.Forsyth Oldsh = 10,
64*37da2899SCharles.Forsyth Ostw = 4,
65*37da2899SCharles.Forsyth Osth = 6,
66*37da2899SCharles.Forsyth Ojmpl = 56,
67*37da2899SCharles.Forsyth Ocall = 1,
68*37da2899SCharles.Forsyth Ocmp = 20, /* subcc */
69*37da2899SCharles.Forsyth Oldbu = 1,
70*37da2899SCharles.Forsyth Ostb = 5,
71*37da2899SCharles.Forsyth Oba = 8,
72*37da2899SCharles.Forsyth Obn = 0,
73*37da2899SCharles.Forsyth Obne = 9,
74*37da2899SCharles.Forsyth Obe = 1,
75*37da2899SCharles.Forsyth Obg = 10,
76*37da2899SCharles.Forsyth Oble = 2,
77*37da2899SCharles.Forsyth Obge = 11,
78*37da2899SCharles.Forsyth Obl = 3,
79*37da2899SCharles.Forsyth Obgu = 12,
80*37da2899SCharles.Forsyth Obleu = 4,
81*37da2899SCharles.Forsyth Obcc = 13,
82*37da2899SCharles.Forsyth Obcs = 5,
83*37da2899SCharles.Forsyth Obpos = 14,
84*37da2899SCharles.Forsyth Obneg = 6,
85*37da2899SCharles.Forsyth Obvc = 15,
86*37da2899SCharles.Forsyth Obvs = 7,
87*37da2899SCharles.Forsyth OfaddD = 66,
88*37da2899SCharles.Forsyth OfsubD = 70,
89*37da2899SCharles.Forsyth OfdivD = 78,
90*37da2899SCharles.Forsyth OfmulD = 74,
91*37da2899SCharles.Forsyth Oldf = 32,
92*37da2899SCharles.Forsyth Ostf = 36,
93*37da2899SCharles.Forsyth OfDtoQ = 206,
94*37da2899SCharles.Forsyth OfnegS = 5,
95*37da2899SCharles.Forsyth OfcmpD = 82,
96*37da2899SCharles.Forsyth Ofba = 8,
97*37da2899SCharles.Forsyth Ofbe = 9,
98*37da2899SCharles.Forsyth Ofbg = 6,
99*37da2899SCharles.Forsyth Ofbge = 11,
100*37da2899SCharles.Forsyth Ofbl = 4,
101*37da2899SCharles.Forsyth Ofble = 13,
102*37da2899SCharles.Forsyth Ofbne = 1,
103*37da2899SCharles.Forsyth OfWtoD = 200,
104*37da2899SCharles.Forsyth OfDtoW = 210,
105*37da2899SCharles.Forsyth Osave = 60,
106*37da2899SCharles.Forsyth Orestore= 61,
107*37da2899SCharles.Forsyth
108*37da2899SCharles.Forsyth SRCOP = (1<<0),
109*37da2899SCharles.Forsyth DSTOP = (1<<1),
110*37da2899SCharles.Forsyth WRTPC = (1<<2),
111*37da2899SCharles.Forsyth TCHECK = (1<<3),
112*37da2899SCharles.Forsyth NEWPC = (1<<4),
113*37da2899SCharles.Forsyth DBRAN = (1<<5),
114*37da2899SCharles.Forsyth THREOP = (1<<6),
115*37da2899SCharles.Forsyth
116*37da2899SCharles.Forsyth ANDAND = 1,
117*37da2899SCharles.Forsyth OROR = 2,
118*37da2899SCharles.Forsyth EQAND = 3,
119*37da2899SCharles.Forsyth
120*37da2899SCharles.Forsyth MacFRP = 0,
121*37da2899SCharles.Forsyth MacRET = 1,
122*37da2899SCharles.Forsyth MacCASE = 2,
123*37da2899SCharles.Forsyth MacCOLR = 3,
124*37da2899SCharles.Forsyth MacMCAL = 4,
125*37da2899SCharles.Forsyth MacFRAM = 5,
126*37da2899SCharles.Forsyth MacMFRA = 6,
127*37da2899SCharles.Forsyth NMACRO
128*37da2899SCharles.Forsyth };
129*37da2899SCharles.Forsyth
130*37da2899SCharles.Forsyth #define OP(n) (n<<30)
131*37da2899SCharles.Forsyth #define I13(i) ((i)&0x1fff)
132*37da2899SCharles.Forsyth #define D22(i) ((i)&0x3fffff)
133*37da2899SCharles.Forsyth #define PC30(pc) (((ulong)(pc) - (ulong)code)>>2)
134*37da2899SCharles.Forsyth
135*37da2899SCharles.Forsyth #define CALL(addr) *code=OP(1)|PC30(addr); code++
136*37da2899SCharles.Forsyth #define FM2I(op2, i, rd) *code=OP(0)|(rd<<25)|(op2<<22)|D22(i); code++
137*37da2899SCharles.Forsyth #define BRA(cond, disp) *code=OP(0)|(cond<<25)|(2<<22)|D22((disp)); code++
138*37da2899SCharles.Forsyth #define BRAF(cond, disp) *code=OP(0)|(cond<<25)|(6<<22)|D22((disp)); code++
139*37da2899SCharles.Forsyth #define BRADIS(r, o) BRA(r, ((ulong)(base+patch[o])-(ulong)code)>>2)
140*37da2899SCharles.Forsyth #define BRAFDIS(r, o) BRAF(r, ((ulong)(base+patch[o])-(ulong)code)>>2)
141*37da2899SCharles.Forsyth #define BRAMAC(r, o) BRA(r, ((ulong)(base+macro[o])-(ulong)code)>>2);
142*37da2899SCharles.Forsyth #define FM3I(op, op3, i, rs1, rd) *code++=OP(op)|(rd<<25)|(op3<<19)|(rs1<<14)|\
143*37da2899SCharles.Forsyth (1<<13)|I13(i)
144*37da2899SCharles.Forsyth #define FM3(op, op3, rs2, rs1, rd) *code++=OP(op)|(rd<<25)|(op3<<19)|(rs1<<14)|rs2
145*37da2899SCharles.Forsyth #define FMF1(opf, rs2, rs1, rd) *code++=OP(2)|(rd<<25)|(52<<19)|(rs1<<14)|(opf<<5)|rs2
146*37da2899SCharles.Forsyth #define FMF2(opf, rs2, rs1, rd) *code++=OP(2)|(rd<<25)|(53<<19)|(rs1<<14)|(opf<<5)|rs2
147*37da2899SCharles.Forsyth #define NOOP *code++=(4<<22)
148*37da2899SCharles.Forsyth #define RETURN FM3I(2, Ojmpl, 8, RLINK, RZ);
149*37da2899SCharles.Forsyth #define MOV(s, d) FM3(2, Oor, s, RZ, d)
150*37da2899SCharles.Forsyth
151*37da2899SCharles.Forsyth #define RELPC(pc) (ulong)(base+pc)
152*37da2899SCharles.Forsyth #define PATCH(ptr) *ptr |= (code-ptr) & 0x3fffff
153*37da2899SCharles.Forsyth
154*37da2899SCharles.Forsyth static ulong* code;
155*37da2899SCharles.Forsyth static ulong* base;
156*37da2899SCharles.Forsyth static ulong* patch;
157*37da2899SCharles.Forsyth static int pass;
158*37da2899SCharles.Forsyth static int puntpc = 1;
159*37da2899SCharles.Forsyth static Module* mod;
160*37da2899SCharles.Forsyth static uchar* tinit;
161*37da2899SCharles.Forsyth static ulong* litpool;
162*37da2899SCharles.Forsyth static int nlit;
163*37da2899SCharles.Forsyth static void macfrp(void);
164*37da2899SCharles.Forsyth static void macret(void);
165*37da2899SCharles.Forsyth static void maccase(void);
166*37da2899SCharles.Forsyth static void maccolr(void);
167*37da2899SCharles.Forsyth static void macmcal(void);
168*37da2899SCharles.Forsyth static void macfram(void);
169*37da2899SCharles.Forsyth static void macmfra(void);
170*37da2899SCharles.Forsyth static ulong macro[NMACRO];
171*37da2899SCharles.Forsyth void (*comvec)(void);
172*37da2899SCharles.Forsyth extern void das(ulong*, int);
173*37da2899SCharles.Forsyth
174*37da2899SCharles.Forsyth #define T(r) *((void**)(R.r))
175*37da2899SCharles.Forsyth
176*37da2899SCharles.Forsyth struct
177*37da2899SCharles.Forsyth {
178*37da2899SCharles.Forsyth int idx;
179*37da2899SCharles.Forsyth void (*gen)(void);
180*37da2899SCharles.Forsyth char* name;
181*37da2899SCharles.Forsyth } mactab[] =
182*37da2899SCharles.Forsyth {
183*37da2899SCharles.Forsyth MacFRP, macfrp, "FRP", /* decrement and free pointer */
184*37da2899SCharles.Forsyth MacRET, macret, "RET", /* return instruction */
185*37da2899SCharles.Forsyth MacCASE, maccase, "CASE", /* case instruction */
186*37da2899SCharles.Forsyth MacCOLR, maccolr, "COLR", /* increment and color pointer */
187*37da2899SCharles.Forsyth MacMCAL, macmcal, "MCAL", /* mcall bottom half */
188*37da2899SCharles.Forsyth MacFRAM, macfram, "FRAM", /* frame instruction */
189*37da2899SCharles.Forsyth MacMFRA, macmfra, "MFRA", /* punt mframe because t->initialize==0 */
190*37da2899SCharles.Forsyth };
191*37da2899SCharles.Forsyth
192*37da2899SCharles.Forsyth static void
rdestroy(void)193*37da2899SCharles.Forsyth rdestroy(void)
194*37da2899SCharles.Forsyth {
195*37da2899SCharles.Forsyth destroy(R.s);
196*37da2899SCharles.Forsyth }
197*37da2899SCharles.Forsyth
198*37da2899SCharles.Forsyth static void
rmcall(void)199*37da2899SCharles.Forsyth rmcall(void)
200*37da2899SCharles.Forsyth {
201*37da2899SCharles.Forsyth Prog *p;
202*37da2899SCharles.Forsyth Frame *f;
203*37da2899SCharles.Forsyth
204*37da2899SCharles.Forsyth f = (Frame*)R.FP;
205*37da2899SCharles.Forsyth if(f == H)
206*37da2899SCharles.Forsyth error(exModule);
207*37da2899SCharles.Forsyth
208*37da2899SCharles.Forsyth f->mr = nil;
209*37da2899SCharles.Forsyth ((void(*)(Frame*))R.dt)(f);
210*37da2899SCharles.Forsyth R.SP = (uchar*)f;
211*37da2899SCharles.Forsyth R.FP = f->fp;
212*37da2899SCharles.Forsyth if(f->t == nil)
213*37da2899SCharles.Forsyth unextend(f);
214*37da2899SCharles.Forsyth else
215*37da2899SCharles.Forsyth freeptrs(f, f->t);
216*37da2899SCharles.Forsyth p = currun();
217*37da2899SCharles.Forsyth if(p->kill != nil)
218*37da2899SCharles.Forsyth error(p->kill);
219*37da2899SCharles.Forsyth }
220*37da2899SCharles.Forsyth
221*37da2899SCharles.Forsyth static void
rmfram(void)222*37da2899SCharles.Forsyth rmfram(void)
223*37da2899SCharles.Forsyth {
224*37da2899SCharles.Forsyth Type *t;
225*37da2899SCharles.Forsyth Frame *f;
226*37da2899SCharles.Forsyth uchar *nsp;
227*37da2899SCharles.Forsyth
228*37da2899SCharles.Forsyth if(R.d == H)
229*37da2899SCharles.Forsyth error(exModule);
230*37da2899SCharles.Forsyth t = (Type*)R.s;
231*37da2899SCharles.Forsyth if(t == H)
232*37da2899SCharles.Forsyth error(exModule);
233*37da2899SCharles.Forsyth
234*37da2899SCharles.Forsyth nsp = R.SP + t->size;
235*37da2899SCharles.Forsyth if(nsp >= R.TS) {
236*37da2899SCharles.Forsyth R.s = t;
237*37da2899SCharles.Forsyth extend();
238*37da2899SCharles.Forsyth T(d) = R.s;
239*37da2899SCharles.Forsyth return;
240*37da2899SCharles.Forsyth }
241*37da2899SCharles.Forsyth f = (Frame*)R.SP;
242*37da2899SCharles.Forsyth R.SP = nsp;
243*37da2899SCharles.Forsyth f->t = t;
244*37da2899SCharles.Forsyth f->mr = nil;
245*37da2899SCharles.Forsyth initmem(t, f);
246*37da2899SCharles.Forsyth T(d) = f;
247*37da2899SCharles.Forsyth }
248*37da2899SCharles.Forsyth
249*37da2899SCharles.Forsyth static void
urk(void)250*37da2899SCharles.Forsyth urk(void)
251*37da2899SCharles.Forsyth {
252*37da2899SCharles.Forsyth error(exCompile);
253*37da2899SCharles.Forsyth }
254*37da2899SCharles.Forsyth
255*37da2899SCharles.Forsyth static int
bc(long c)256*37da2899SCharles.Forsyth bc(long c)
257*37da2899SCharles.Forsyth {
258*37da2899SCharles.Forsyth c &= ~0xfffL;
259*37da2899SCharles.Forsyth if (c == 0 || c == ~0xfffL)
260*37da2899SCharles.Forsyth return 1;
261*37da2899SCharles.Forsyth
262*37da2899SCharles.Forsyth return 0;
263*37da2899SCharles.Forsyth }
264*37da2899SCharles.Forsyth
265*37da2899SCharles.Forsyth static void
con(ulong o,int r,int opt)266*37da2899SCharles.Forsyth con(ulong o, int r, int opt)
267*37da2899SCharles.Forsyth {
268*37da2899SCharles.Forsyth if(opt != 0) {
269*37da2899SCharles.Forsyth if(bc(o)) {
270*37da2899SCharles.Forsyth FM3I(2, Oadd, o & 0x1fff, RZ, r);
271*37da2899SCharles.Forsyth return;
272*37da2899SCharles.Forsyth }
273*37da2899SCharles.Forsyth if((o & 0x3ff) == 0) {
274*37da2899SCharles.Forsyth FM2I(Osethi, o>>10, r);
275*37da2899SCharles.Forsyth return;
276*37da2899SCharles.Forsyth }
277*37da2899SCharles.Forsyth }
278*37da2899SCharles.Forsyth FM2I(Osethi, o>>10, r);
279*37da2899SCharles.Forsyth FM3I(2, Oadd, o & 0x3ff, r, r);
280*37da2899SCharles.Forsyth }
281*37da2899SCharles.Forsyth
282*37da2899SCharles.Forsyth static void
mem(int inst,ulong disp,int rm,int r)283*37da2899SCharles.Forsyth mem(int inst, ulong disp, int rm, int r)
284*37da2899SCharles.Forsyth {
285*37da2899SCharles.Forsyth int op;
286*37da2899SCharles.Forsyth
287*37da2899SCharles.Forsyth op = 3;
288*37da2899SCharles.Forsyth if(inst == Olea) {
289*37da2899SCharles.Forsyth op = 2;
290*37da2899SCharles.Forsyth inst = Oadd;
291*37da2899SCharles.Forsyth }
292*37da2899SCharles.Forsyth if(bc(disp)) {
293*37da2899SCharles.Forsyth FM3I(op, inst, disp, rm, r);
294*37da2899SCharles.Forsyth return;
295*37da2899SCharles.Forsyth }
296*37da2899SCharles.Forsyth con(disp, RCON, 1);
297*37da2899SCharles.Forsyth FM3(op, inst, RCON, rm, r);
298*37da2899SCharles.Forsyth }
299*37da2899SCharles.Forsyth
300*37da2899SCharles.Forsyth static void
opwld(Inst * i,int mi,int r)301*37da2899SCharles.Forsyth opwld(Inst *i, int mi, int r)
302*37da2899SCharles.Forsyth {
303*37da2899SCharles.Forsyth int ir, rta;
304*37da2899SCharles.Forsyth
305*37da2899SCharles.Forsyth switch(UXSRC(i->add)) {
306*37da2899SCharles.Forsyth default:
307*37da2899SCharles.Forsyth print("%D\n", i);
308*37da2899SCharles.Forsyth urk();
309*37da2899SCharles.Forsyth case SRC(AFP):
310*37da2899SCharles.Forsyth mem(mi, i->s.ind, RFP, r);
311*37da2899SCharles.Forsyth return;
312*37da2899SCharles.Forsyth case SRC(AMP):
313*37da2899SCharles.Forsyth mem(mi, i->s.ind, RMP, r);
314*37da2899SCharles.Forsyth return;
315*37da2899SCharles.Forsyth case SRC(AIMM):
316*37da2899SCharles.Forsyth con(i->s.imm, r, 1);
317*37da2899SCharles.Forsyth if(mi == Olea) {
318*37da2899SCharles.Forsyth mem(Ostw, O(REG, st), RREG, r);
319*37da2899SCharles.Forsyth con((ulong)&R.st, r, 1);
320*37da2899SCharles.Forsyth }
321*37da2899SCharles.Forsyth return;
322*37da2899SCharles.Forsyth case SRC(AIND|AFP):
323*37da2899SCharles.Forsyth ir = RFP;
324*37da2899SCharles.Forsyth break;
325*37da2899SCharles.Forsyth case SRC(AIND|AMP):
326*37da2899SCharles.Forsyth ir = RMP;
327*37da2899SCharles.Forsyth break;
328*37da2899SCharles.Forsyth }
329*37da2899SCharles.Forsyth rta = RTA;
330*37da2899SCharles.Forsyth if(mi == Olea)
331*37da2899SCharles.Forsyth rta = r;
332*37da2899SCharles.Forsyth mem(Oldw, i->s.i.f, ir, rta);
333*37da2899SCharles.Forsyth mem(mi, i->s.i.s, rta, r);
334*37da2899SCharles.Forsyth }
335*37da2899SCharles.Forsyth
336*37da2899SCharles.Forsyth static void
opwst(Inst * i,int mi,int r)337*37da2899SCharles.Forsyth opwst(Inst *i, int mi, int r)
338*37da2899SCharles.Forsyth {
339*37da2899SCharles.Forsyth int ir, rta;
340*37da2899SCharles.Forsyth
341*37da2899SCharles.Forsyth switch(UXDST(i->add)) {
342*37da2899SCharles.Forsyth default:
343*37da2899SCharles.Forsyth print("%D\n", i);
344*37da2899SCharles.Forsyth urk();
345*37da2899SCharles.Forsyth case DST(AIMM):
346*37da2899SCharles.Forsyth con(i->d.imm, r, 1);
347*37da2899SCharles.Forsyth return;
348*37da2899SCharles.Forsyth case DST(AFP):
349*37da2899SCharles.Forsyth mem(mi, i->d.ind, RFP, r);
350*37da2899SCharles.Forsyth return;
351*37da2899SCharles.Forsyth case DST(AMP):
352*37da2899SCharles.Forsyth mem(mi, i->d.ind, RMP, r);
353*37da2899SCharles.Forsyth return;
354*37da2899SCharles.Forsyth case DST(AIND|AFP):
355*37da2899SCharles.Forsyth ir = RFP;
356*37da2899SCharles.Forsyth break;
357*37da2899SCharles.Forsyth case DST(AIND|AMP):
358*37da2899SCharles.Forsyth ir = RMP;
359*37da2899SCharles.Forsyth break;
360*37da2899SCharles.Forsyth }
361*37da2899SCharles.Forsyth rta = RTA;
362*37da2899SCharles.Forsyth if(mi == Olea)
363*37da2899SCharles.Forsyth rta = r;
364*37da2899SCharles.Forsyth mem(Oldw, i->d.i.f, ir, rta);
365*37da2899SCharles.Forsyth mem(mi, i->d.i.s, rta, r);
366*37da2899SCharles.Forsyth }
367*37da2899SCharles.Forsyth
368*37da2899SCharles.Forsyth static void
opfl(Adr * a,int am,int mi,int r)369*37da2899SCharles.Forsyth opfl(Adr *a, int am, int mi, int r)
370*37da2899SCharles.Forsyth {
371*37da2899SCharles.Forsyth int ir;
372*37da2899SCharles.Forsyth
373*37da2899SCharles.Forsyth switch(am) {
374*37da2899SCharles.Forsyth default:
375*37da2899SCharles.Forsyth urk();
376*37da2899SCharles.Forsyth case AFP:
377*37da2899SCharles.Forsyth mem(mi, a->ind, RFP, r);
378*37da2899SCharles.Forsyth mem(mi, a->ind+4, RFP, r+1);
379*37da2899SCharles.Forsyth return;
380*37da2899SCharles.Forsyth case AMP:
381*37da2899SCharles.Forsyth mem(mi, a->ind, RMP, r);
382*37da2899SCharles.Forsyth mem(mi, a->ind+4, RMP, r+1);
383*37da2899SCharles.Forsyth return;
384*37da2899SCharles.Forsyth case AIND|AFP:
385*37da2899SCharles.Forsyth ir = RFP;
386*37da2899SCharles.Forsyth break;
387*37da2899SCharles.Forsyth case AIND|AMP:
388*37da2899SCharles.Forsyth ir = RMP;
389*37da2899SCharles.Forsyth break;
390*37da2899SCharles.Forsyth }
391*37da2899SCharles.Forsyth mem(Oldw, a->i.f, ir, RTA);
392*37da2899SCharles.Forsyth mem(mi, a->i.s, RTA, r);
393*37da2899SCharles.Forsyth mem(mi, a->i.s+4, RTA, r+1);
394*37da2899SCharles.Forsyth }
395*37da2899SCharles.Forsyth
396*37da2899SCharles.Forsyth static void
opflld(Inst * i,int mi,int r)397*37da2899SCharles.Forsyth opflld(Inst *i, int mi, int r)
398*37da2899SCharles.Forsyth {
399*37da2899SCharles.Forsyth opfl(&i->s, USRC(i->add), mi, r);
400*37da2899SCharles.Forsyth }
401*37da2899SCharles.Forsyth
402*37da2899SCharles.Forsyth static void
opflst(Inst * i,int mi,int r)403*37da2899SCharles.Forsyth opflst(Inst *i, int mi, int r)
404*37da2899SCharles.Forsyth {
405*37da2899SCharles.Forsyth opfl(&i->d, UDST(i->add), mi, r);
406*37da2899SCharles.Forsyth }
407*37da2899SCharles.Forsyth
408*37da2899SCharles.Forsyth static void
literal(ulong imm,int roff)409*37da2899SCharles.Forsyth literal(ulong imm, int roff)
410*37da2899SCharles.Forsyth {
411*37da2899SCharles.Forsyth nlit++;
412*37da2899SCharles.Forsyth
413*37da2899SCharles.Forsyth con((ulong)litpool, RTA, 0);
414*37da2899SCharles.Forsyth mem(Ostw, roff, RREG, RTA);
415*37da2899SCharles.Forsyth
416*37da2899SCharles.Forsyth if(pass == 0)
417*37da2899SCharles.Forsyth return;
418*37da2899SCharles.Forsyth
419*37da2899SCharles.Forsyth *litpool = imm;
420*37da2899SCharles.Forsyth litpool++;
421*37da2899SCharles.Forsyth }
422*37da2899SCharles.Forsyth
423*37da2899SCharles.Forsyth static void
punt(Inst * i,int m,void (* fn)(void))424*37da2899SCharles.Forsyth punt(Inst *i, int m, void (*fn)(void))
425*37da2899SCharles.Forsyth {
426*37da2899SCharles.Forsyth ulong pc;
427*37da2899SCharles.Forsyth
428*37da2899SCharles.Forsyth if(m & SRCOP) {
429*37da2899SCharles.Forsyth if(UXSRC(i->add) == SRC(AIMM))
430*37da2899SCharles.Forsyth literal(i->s.imm, O(REG, s));
431*37da2899SCharles.Forsyth else {
432*37da2899SCharles.Forsyth opwld(i, Olea, RA0);
433*37da2899SCharles.Forsyth mem(Ostw, O(REG, s), RREG, RA0);
434*37da2899SCharles.Forsyth }
435*37da2899SCharles.Forsyth }
436*37da2899SCharles.Forsyth
437*37da2899SCharles.Forsyth if(m & DSTOP) {
438*37da2899SCharles.Forsyth opwst(i, Olea, RA0);
439*37da2899SCharles.Forsyth mem(Ostw, O(REG, d), RREG, RA0);
440*37da2899SCharles.Forsyth }
441*37da2899SCharles.Forsyth if(m & WRTPC) {
442*37da2899SCharles.Forsyth con(RELPC(patch[i-mod->prog+1]), RA0, 0);
443*37da2899SCharles.Forsyth mem(Ostw, O(REG, PC), RREG, RA0);
444*37da2899SCharles.Forsyth }
445*37da2899SCharles.Forsyth if(m & DBRAN) {
446*37da2899SCharles.Forsyth pc = patch[(Inst*)i->d.imm-mod->prog];
447*37da2899SCharles.Forsyth literal(RELPC(pc), O(REG, d));
448*37da2899SCharles.Forsyth }
449*37da2899SCharles.Forsyth
450*37da2899SCharles.Forsyth switch(i->add&ARM) {
451*37da2899SCharles.Forsyth case AXNON:
452*37da2899SCharles.Forsyth if(m & THREOP) {
453*37da2899SCharles.Forsyth mem(Oldw, O(REG, d), RREG, RA0);
454*37da2899SCharles.Forsyth mem(Ostw, O(REG, m), RREG, RA0);
455*37da2899SCharles.Forsyth }
456*37da2899SCharles.Forsyth break;
457*37da2899SCharles.Forsyth case AXIMM:
458*37da2899SCharles.Forsyth literal((short)i->reg, O(REG, m));
459*37da2899SCharles.Forsyth break;
460*37da2899SCharles.Forsyth case AXINF:
461*37da2899SCharles.Forsyth mem(Olea, i->reg, RFP, RA0);
462*37da2899SCharles.Forsyth mem(Ostw, O(REG, m), RREG, RA0);
463*37da2899SCharles.Forsyth break;
464*37da2899SCharles.Forsyth case AXINM:
465*37da2899SCharles.Forsyth mem(Olea, i->reg, RMP, RA0);
466*37da2899SCharles.Forsyth mem(Ostw, O(REG, m), RREG, RA0);
467*37da2899SCharles.Forsyth break;
468*37da2899SCharles.Forsyth }
469*37da2899SCharles.Forsyth
470*37da2899SCharles.Forsyth CALL(fn);
471*37da2899SCharles.Forsyth mem(Ostw, O(REG, FP), RREG, RFP);
472*37da2899SCharles.Forsyth
473*37da2899SCharles.Forsyth con((ulong)&R, RREG, 1);
474*37da2899SCharles.Forsyth if(m & TCHECK) {
475*37da2899SCharles.Forsyth mem(Oldw, O(REG, t), RREG, RA0);
476*37da2899SCharles.Forsyth FM3I(2, Ocmp, 0, RA0, RZ);
477*37da2899SCharles.Forsyth BRA(Obe, 5);
478*37da2899SCharles.Forsyth NOOP;
479*37da2899SCharles.Forsyth mem(Oldw, O(REG, xpc), RREG, RLINK);
480*37da2899SCharles.Forsyth RETURN;
481*37da2899SCharles.Forsyth NOOP;
482*37da2899SCharles.Forsyth }
483*37da2899SCharles.Forsyth
484*37da2899SCharles.Forsyth mem(Oldw, O(REG, FP), RREG, RFP);
485*37da2899SCharles.Forsyth mem(Oldw, O(REG, MP), RREG, RMP);
486*37da2899SCharles.Forsyth
487*37da2899SCharles.Forsyth if(m & NEWPC) {
488*37da2899SCharles.Forsyth mem(Oldw, O(REG, PC), RREG, RA0);
489*37da2899SCharles.Forsyth FM3I(2, Ojmpl, 0, RA0, RZ);
490*37da2899SCharles.Forsyth NOOP;
491*37da2899SCharles.Forsyth }
492*37da2899SCharles.Forsyth }
493*37da2899SCharles.Forsyth
494*37da2899SCharles.Forsyth static void
midfl(Inst * i,int mi,int r)495*37da2899SCharles.Forsyth midfl(Inst *i, int mi, int r)
496*37da2899SCharles.Forsyth {
497*37da2899SCharles.Forsyth int ir;
498*37da2899SCharles.Forsyth
499*37da2899SCharles.Forsyth switch(i->add&ARM) {
500*37da2899SCharles.Forsyth default:
501*37da2899SCharles.Forsyth opflst(i, mi, r);
502*37da2899SCharles.Forsyth return;
503*37da2899SCharles.Forsyth case AXIMM:
504*37da2899SCharles.Forsyth con((short)i->reg, r, 1);
505*37da2899SCharles.Forsyth return;
506*37da2899SCharles.Forsyth case AXINF:
507*37da2899SCharles.Forsyth ir = RFP;
508*37da2899SCharles.Forsyth break;
509*37da2899SCharles.Forsyth case AXINM:
510*37da2899SCharles.Forsyth ir = RMP;
511*37da2899SCharles.Forsyth break;
512*37da2899SCharles.Forsyth }
513*37da2899SCharles.Forsyth mem(mi, i->reg, ir, r);
514*37da2899SCharles.Forsyth mem(mi, i->reg+4, ir, r+1);
515*37da2899SCharles.Forsyth }
516*37da2899SCharles.Forsyth
517*37da2899SCharles.Forsyth static void
mid(Inst * i,int mi,int r)518*37da2899SCharles.Forsyth mid(Inst *i, int mi, int r)
519*37da2899SCharles.Forsyth {
520*37da2899SCharles.Forsyth int ir;
521*37da2899SCharles.Forsyth
522*37da2899SCharles.Forsyth switch(i->add&ARM) {
523*37da2899SCharles.Forsyth default:
524*37da2899SCharles.Forsyth opwst(i, mi, r);
525*37da2899SCharles.Forsyth return;
526*37da2899SCharles.Forsyth case AXIMM:
527*37da2899SCharles.Forsyth con((short)i->reg, r, 1);
528*37da2899SCharles.Forsyth return;
529*37da2899SCharles.Forsyth case AXINF:
530*37da2899SCharles.Forsyth ir = RFP;
531*37da2899SCharles.Forsyth break;
532*37da2899SCharles.Forsyth case AXINM:
533*37da2899SCharles.Forsyth ir = RMP;
534*37da2899SCharles.Forsyth break;
535*37da2899SCharles.Forsyth }
536*37da2899SCharles.Forsyth mem(mi, i->reg, ir, r);
537*37da2899SCharles.Forsyth }
538*37da2899SCharles.Forsyth
539*37da2899SCharles.Forsyth static void
cbral(Inst * i,int jmsw,int jlsw,int mode)540*37da2899SCharles.Forsyth cbral(Inst *i, int jmsw, int jlsw, int mode)
541*37da2899SCharles.Forsyth {
542*37da2899SCharles.Forsyth ulong dst, *label;
543*37da2899SCharles.Forsyth
544*37da2899SCharles.Forsyth opwld(i, Olea, RA1);
545*37da2899SCharles.Forsyth mid(i, Olea, RA3);
546*37da2899SCharles.Forsyth mem(Oldw, 0, RA1, RA2);
547*37da2899SCharles.Forsyth mem(Oldw, 0, RA3, RA0);
548*37da2899SCharles.Forsyth FM3(2, Ocmp, RA0, RA2, RZ);
549*37da2899SCharles.Forsyth label = nil;
550*37da2899SCharles.Forsyth dst = i->d.ins-mod->prog;
551*37da2899SCharles.Forsyth switch(mode) {
552*37da2899SCharles.Forsyth case ANDAND:
553*37da2899SCharles.Forsyth label = code;
554*37da2899SCharles.Forsyth BRA(jmsw, 0);
555*37da2899SCharles.Forsyth break;
556*37da2899SCharles.Forsyth case OROR:
557*37da2899SCharles.Forsyth BRADIS(jmsw, dst);
558*37da2899SCharles.Forsyth break;
559*37da2899SCharles.Forsyth case EQAND:
560*37da2899SCharles.Forsyth BRADIS(jmsw, dst);
561*37da2899SCharles.Forsyth NOOP;
562*37da2899SCharles.Forsyth label = code;
563*37da2899SCharles.Forsyth BRA(Obne, 0);
564*37da2899SCharles.Forsyth break;
565*37da2899SCharles.Forsyth }
566*37da2899SCharles.Forsyth NOOP;
567*37da2899SCharles.Forsyth mem(Oldw, 4, RA3, RA0);
568*37da2899SCharles.Forsyth mem(Oldw, 4, RA1, RA2);
569*37da2899SCharles.Forsyth FM3(2, Ocmp, RA0, RA2, RZ);
570*37da2899SCharles.Forsyth BRADIS(jlsw, dst);
571*37da2899SCharles.Forsyth if(label != nil)
572*37da2899SCharles.Forsyth PATCH(label);
573*37da2899SCharles.Forsyth }
574*37da2899SCharles.Forsyth
575*37da2899SCharles.Forsyth static void
comcase(Inst * i,int w)576*37da2899SCharles.Forsyth comcase(Inst *i, int w)
577*37da2899SCharles.Forsyth {
578*37da2899SCharles.Forsyth int l;
579*37da2899SCharles.Forsyth WORD *t, *e;
580*37da2899SCharles.Forsyth
581*37da2899SCharles.Forsyth if(w != 0) {
582*37da2899SCharles.Forsyth opwld(i, Oldw, RA0); // v
583*37da2899SCharles.Forsyth opwst(i, Olea, RCON); // table
584*37da2899SCharles.Forsyth BRAMAC(Oba, MacCASE);
585*37da2899SCharles.Forsyth NOOP;
586*37da2899SCharles.Forsyth }
587*37da2899SCharles.Forsyth
588*37da2899SCharles.Forsyth t = (WORD*)(mod->origmp+i->d.ind+4);
589*37da2899SCharles.Forsyth l = t[-1];
590*37da2899SCharles.Forsyth
591*37da2899SCharles.Forsyth /* have to take care not to relocate the same table twice -
592*37da2899SCharles.Forsyth * the limbo compiler can duplicate a case instruction
593*37da2899SCharles.Forsyth * during its folding phase
594*37da2899SCharles.Forsyth */
595*37da2899SCharles.Forsyth
596*37da2899SCharles.Forsyth if(pass == 0) {
597*37da2899SCharles.Forsyth if(l >= 0)
598*37da2899SCharles.Forsyth t[-1] = -l-1; /* Mark it not done */
599*37da2899SCharles.Forsyth return;
600*37da2899SCharles.Forsyth }
601*37da2899SCharles.Forsyth if(l >= 0) /* Check pass 2 done */
602*37da2899SCharles.Forsyth return;
603*37da2899SCharles.Forsyth t[-1] = -l-1; /* Set real count */
604*37da2899SCharles.Forsyth e = t + t[-1]*3;
605*37da2899SCharles.Forsyth while(t < e) {
606*37da2899SCharles.Forsyth t[2] = RELPC(patch[t[2]]);
607*37da2899SCharles.Forsyth t += 3;
608*37da2899SCharles.Forsyth }
609*37da2899SCharles.Forsyth t[0] = RELPC(patch[t[0]]);
610*37da2899SCharles.Forsyth }
611*37da2899SCharles.Forsyth
612*37da2899SCharles.Forsyth static void
comcasel(Inst * i)613*37da2899SCharles.Forsyth comcasel(Inst *i)
614*37da2899SCharles.Forsyth {
615*37da2899SCharles.Forsyth int l;
616*37da2899SCharles.Forsyth WORD *t, *e;
617*37da2899SCharles.Forsyth
618*37da2899SCharles.Forsyth t = (WORD*)(mod->origmp+i->d.ind+8);
619*37da2899SCharles.Forsyth l = t[-2];
620*37da2899SCharles.Forsyth if(pass == 0) {
621*37da2899SCharles.Forsyth if(l >= 0)
622*37da2899SCharles.Forsyth t[-2] = -l-1; /* Mark it not done */
623*37da2899SCharles.Forsyth return;
624*37da2899SCharles.Forsyth }
625*37da2899SCharles.Forsyth if(l >= 0) /* Check pass 2 done */
626*37da2899SCharles.Forsyth return;
627*37da2899SCharles.Forsyth t[-2] = -l-1; /* Set real count */
628*37da2899SCharles.Forsyth e = t + t[-2]*6;
629*37da2899SCharles.Forsyth while(t < e) {
630*37da2899SCharles.Forsyth t[4] = RELPC(patch[t[4]]);
631*37da2899SCharles.Forsyth t += 6;
632*37da2899SCharles.Forsyth }
633*37da2899SCharles.Forsyth t[0] = RELPC(patch[t[0]]);
634*37da2899SCharles.Forsyth }
635*37da2899SCharles.Forsyth
636*37da2899SCharles.Forsyth static void
commframe(Inst * i)637*37da2899SCharles.Forsyth commframe(Inst *i)
638*37da2899SCharles.Forsyth {
639*37da2899SCharles.Forsyth int o;
640*37da2899SCharles.Forsyth ulong *punt, *mlnil;
641*37da2899SCharles.Forsyth
642*37da2899SCharles.Forsyth opwld(i, Oldw, RA0);
643*37da2899SCharles.Forsyth FM3I(2, Ocmp, -1, RA0, RZ);
644*37da2899SCharles.Forsyth mlnil = code;
645*37da2899SCharles.Forsyth BRA(Obe, 0);
646*37da2899SCharles.Forsyth NOOP;
647*37da2899SCharles.Forsyth
648*37da2899SCharles.Forsyth if((i->add&ARM) == AXIMM) {
649*37da2899SCharles.Forsyth o = OA(Modlink, links)+i->reg*sizeof(Modl)+O(Modl, frame);
650*37da2899SCharles.Forsyth mem(Oldw, o, RA0, RA3);
651*37da2899SCharles.Forsyth } else {
652*37da2899SCharles.Forsyth mid(i, Oldw, RA1);
653*37da2899SCharles.Forsyth FM3I(2, Osll, 3, RA1, RA1); // assumes sizeof(Modl) == 8
654*37da2899SCharles.Forsyth FM3(2, Oadd, RA0, RA1, RA1);
655*37da2899SCharles.Forsyth o = OA(Modlink, links)+O(Modl, frame);
656*37da2899SCharles.Forsyth mem(Oldw, o, RA1, RA3);
657*37da2899SCharles.Forsyth }
658*37da2899SCharles.Forsyth mem(Oldw, O(Type, initialize), RA3, RA1);
659*37da2899SCharles.Forsyth FM3I(2, Ocmp, 0, RA1, RZ);
660*37da2899SCharles.Forsyth punt = code;
661*37da2899SCharles.Forsyth BRA(Obne, 0);
662*37da2899SCharles.Forsyth NOOP;
663*37da2899SCharles.Forsyth
664*37da2899SCharles.Forsyth opwst(i, Olea, RA0);
665*37da2899SCharles.Forsyth
666*37da2899SCharles.Forsyth /* Type in RA3, destination in RA0 */
667*37da2899SCharles.Forsyth PATCH(mlnil);
668*37da2899SCharles.Forsyth con(RELPC(patch[i-mod->prog+1])-8, RLINK, 0);
669*37da2899SCharles.Forsyth BRAMAC(Oba, MacMFRA);
670*37da2899SCharles.Forsyth NOOP;
671*37da2899SCharles.Forsyth
672*37da2899SCharles.Forsyth /* Type in RA3 */
673*37da2899SCharles.Forsyth PATCH(punt);
674*37da2899SCharles.Forsyth CALL(base+macro[MacFRAM]);
675*37da2899SCharles.Forsyth NOOP;
676*37da2899SCharles.Forsyth opwst(i, Ostw, RA2);
677*37da2899SCharles.Forsyth }
678*37da2899SCharles.Forsyth
679*37da2899SCharles.Forsyth static void
commcall(Inst * i)680*37da2899SCharles.Forsyth commcall(Inst *i)
681*37da2899SCharles.Forsyth {
682*37da2899SCharles.Forsyth opwld(i, Oldw, RA2);
683*37da2899SCharles.Forsyth con(RELPC(patch[i-mod->prog+1]), RA0, 0);
684*37da2899SCharles.Forsyth mem(Ostw, O(Frame, lr), RA2, RA0);
685*37da2899SCharles.Forsyth mem(Ostw, O(Frame, fp), RA2, RFP);
686*37da2899SCharles.Forsyth mem(Oldw, O(REG, M), RREG, RA3);
687*37da2899SCharles.Forsyth mem(Ostw, O(Frame, mr), RA2, RA3);
688*37da2899SCharles.Forsyth opwst(i, Oldw, RA3);
689*37da2899SCharles.Forsyth if((i->add&ARM) == AXIMM) {
690*37da2899SCharles.Forsyth CALL(base+macro[MacMCAL]);
691*37da2899SCharles.Forsyth mem(Oldw, OA(Modlink, links)+i->reg*sizeof(Modl)+O(Modl, u.pc), RA3, RA0);
692*37da2899SCharles.Forsyth } else {
693*37da2899SCharles.Forsyth mid(i, Oldw, RA1);
694*37da2899SCharles.Forsyth FM3I(2, Osll, 3, RA1, RA1); // assumes sizeof(Modl) == 8
695*37da2899SCharles.Forsyth FM3(2, Oadd, RA1, RA3, RA0);
696*37da2899SCharles.Forsyth CALL(base+macro[MacMCAL]);
697*37da2899SCharles.Forsyth mem(Oldw, OA(Modlink, links)+O(Modl, u.pc), RA0, RA0);
698*37da2899SCharles.Forsyth }
699*37da2899SCharles.Forsyth }
700*37da2899SCharles.Forsyth
701*37da2899SCharles.Forsyth static void
larith(Inst * i,int op,int opc)702*37da2899SCharles.Forsyth larith(Inst *i, int op, int opc)
703*37da2899SCharles.Forsyth {
704*37da2899SCharles.Forsyth opflld(i, Oldw, RA0);
705*37da2899SCharles.Forsyth midfl(i, Oldw, RA2);
706*37da2899SCharles.Forsyth FM3(2, op, RA1, RA3, RA1);
707*37da2899SCharles.Forsyth FM3(2, opc, RA0, RA2, RA0);
708*37da2899SCharles.Forsyth opflst(i, Ostw, RA0);
709*37da2899SCharles.Forsyth }
710*37da2899SCharles.Forsyth
711*37da2899SCharles.Forsyth static void
movloop(Inst * i,int ld,int st)712*37da2899SCharles.Forsyth movloop(Inst *i, int ld, int st)
713*37da2899SCharles.Forsyth {
714*37da2899SCharles.Forsyth int s;
715*37da2899SCharles.Forsyth
716*37da2899SCharles.Forsyth s = 1;
717*37da2899SCharles.Forsyth if(ld == Oldw)
718*37da2899SCharles.Forsyth s = 4;
719*37da2899SCharles.Forsyth opwld(i, Olea, RA1);
720*37da2899SCharles.Forsyth opwst(i, Olea, RA2);
721*37da2899SCharles.Forsyth mem(ld, 0, RA1, RA0);
722*37da2899SCharles.Forsyth mem(st, 0, RA2, RA0);
723*37da2899SCharles.Forsyth FM3I(2, Oadd, s, RA2, RA2);
724*37da2899SCharles.Forsyth FM3I(2, Oaddcc, -1, RA3, RA3);
725*37da2899SCharles.Forsyth BRA(Obne, -4);
726*37da2899SCharles.Forsyth FM3I(2, Oadd, s, RA1, RA1);
727*37da2899SCharles.Forsyth }
728*37da2899SCharles.Forsyth
729*37da2899SCharles.Forsyth static
730*37da2899SCharles.Forsyth void
compdbg(void)731*37da2899SCharles.Forsyth compdbg(void)
732*37da2899SCharles.Forsyth {
733*37da2899SCharles.Forsyth print("%s:%d@%.8ux\n", R.M->m->name, R.t, R.st);
734*37da2899SCharles.Forsyth }
735*37da2899SCharles.Forsyth
736*37da2899SCharles.Forsyth static void
shll(Inst * i)737*37da2899SCharles.Forsyth shll(Inst *i)
738*37da2899SCharles.Forsyth {
739*37da2899SCharles.Forsyth ulong *lab0, *lab1, *lab2;
740*37da2899SCharles.Forsyth
741*37da2899SCharles.Forsyth opwld(i, Oldw, RA2);
742*37da2899SCharles.Forsyth midfl(i, Oldw, RA0);
743*37da2899SCharles.Forsyth FM3I(2, Ocmp, RZ, RA2, RZ);
744*37da2899SCharles.Forsyth lab0 = code;
745*37da2899SCharles.Forsyth BRA(Obe, 0);
746*37da2899SCharles.Forsyth FM3I(2, Ocmp, 32, RA2, RZ);
747*37da2899SCharles.Forsyth lab1 = code;
748*37da2899SCharles.Forsyth BRA(Obl, 0);
749*37da2899SCharles.Forsyth NOOP;
750*37da2899SCharles.Forsyth FM3I(2, Osub, 32, RA2, RA2);
751*37da2899SCharles.Forsyth FM3(2, Osll, RA2, RA1, RA0);
752*37da2899SCharles.Forsyth lab2 = code;
753*37da2899SCharles.Forsyth BRA(Oba, 0);
754*37da2899SCharles.Forsyth MOV(RZ, RA1);
755*37da2899SCharles.Forsyth
756*37da2899SCharles.Forsyth PATCH(lab1);
757*37da2899SCharles.Forsyth FM3(2, Osll, RA2, RA0, RA0);
758*37da2899SCharles.Forsyth con(32, RA3, 1);
759*37da2899SCharles.Forsyth FM3(2, Osub, RA2, RA3, RA3);
760*37da2899SCharles.Forsyth FM3(2, Osrl, RA3, RA1, RA3);
761*37da2899SCharles.Forsyth FM3(2, Oor, RA0, RA3, RA0);
762*37da2899SCharles.Forsyth FM3(2, Osll, RA2, RA1, RA1);
763*37da2899SCharles.Forsyth
764*37da2899SCharles.Forsyth PATCH(lab0);
765*37da2899SCharles.Forsyth PATCH(lab2);
766*37da2899SCharles.Forsyth opflst(i, Ostw, RA0);
767*37da2899SCharles.Forsyth }
768*37da2899SCharles.Forsyth
769*37da2899SCharles.Forsyth static void
comp(Inst * i)770*37da2899SCharles.Forsyth comp(Inst *i)
771*37da2899SCharles.Forsyth {
772*37da2899SCharles.Forsyth int r;
773*37da2899SCharles.Forsyth WORD *t, *e;
774*37da2899SCharles.Forsyth char buf[64];
775*37da2899SCharles.Forsyth
776*37da2899SCharles.Forsyth if(0) {
777*37da2899SCharles.Forsyth Inst xx;
778*37da2899SCharles.Forsyth xx.add = AXIMM|SRC(AIMM);
779*37da2899SCharles.Forsyth xx.s.imm = (ulong)code;
780*37da2899SCharles.Forsyth xx.reg = i-mod->prog;
781*37da2899SCharles.Forsyth puntpc = 0;
782*37da2899SCharles.Forsyth punt(&xx, SRCOP, compdbg);
783*37da2899SCharles.Forsyth puntpc = 1;
784*37da2899SCharles.Forsyth }
785*37da2899SCharles.Forsyth
786*37da2899SCharles.Forsyth switch(i->op) {
787*37da2899SCharles.Forsyth default:
788*37da2899SCharles.Forsyth snprint(buf, sizeof buf, "%s compile, no '%D'", mod->name, i);
789*37da2899SCharles.Forsyth error(buf);
790*37da2899SCharles.Forsyth break;
791*37da2899SCharles.Forsyth case IMCALL:
792*37da2899SCharles.Forsyth if((i->add&ARM) == AXIMM)
793*37da2899SCharles.Forsyth commcall(i);
794*37da2899SCharles.Forsyth else
795*37da2899SCharles.Forsyth punt(i, SRCOP|DSTOP|THREOP|WRTPC|NEWPC, optab[i->op]);
796*37da2899SCharles.Forsyth break;
797*37da2899SCharles.Forsyth case ISEND:
798*37da2899SCharles.Forsyth case IRECV:
799*37da2899SCharles.Forsyth case IALT:
800*37da2899SCharles.Forsyth punt(i, SRCOP|DSTOP|TCHECK|WRTPC, optab[i->op]);
801*37da2899SCharles.Forsyth break;
802*37da2899SCharles.Forsyth case ISPAWN:
803*37da2899SCharles.Forsyth punt(i, SRCOP|DBRAN, optab[i->op]);
804*37da2899SCharles.Forsyth break;
805*37da2899SCharles.Forsyth case IBNEC:
806*37da2899SCharles.Forsyth case IBEQC:
807*37da2899SCharles.Forsyth case IBLTC:
808*37da2899SCharles.Forsyth case IBLEC:
809*37da2899SCharles.Forsyth case IBGTC:
810*37da2899SCharles.Forsyth case IBGEC:
811*37da2899SCharles.Forsyth punt(i, SRCOP|DBRAN|NEWPC|WRTPC, optab[i->op]);
812*37da2899SCharles.Forsyth break;
813*37da2899SCharles.Forsyth case ICASEC:
814*37da2899SCharles.Forsyth comcase(i, 0);
815*37da2899SCharles.Forsyth punt(i, SRCOP|DSTOP|NEWPC, optab[i->op]);
816*37da2899SCharles.Forsyth break;
817*37da2899SCharles.Forsyth case ICASEL:
818*37da2899SCharles.Forsyth comcasel(i);
819*37da2899SCharles.Forsyth punt(i, SRCOP|DSTOP|NEWPC, optab[i->op]);
820*37da2899SCharles.Forsyth break;
821*37da2899SCharles.Forsyth case IADDC:
822*37da2899SCharles.Forsyth case IMULL:
823*37da2899SCharles.Forsyth case IDIVL:
824*37da2899SCharles.Forsyth case IMODL:
825*37da2899SCharles.Forsyth case IMODW:
826*37da2899SCharles.Forsyth case IMODB:
827*37da2899SCharles.Forsyth case IMNEWZ:
828*37da2899SCharles.Forsyth punt(i, SRCOP|DSTOP|THREOP, optab[i->op]);
829*37da2899SCharles.Forsyth break;
830*37da2899SCharles.Forsyth case ILOAD:
831*37da2899SCharles.Forsyth case INEWA:
832*37da2899SCharles.Forsyth case INEWAZ:
833*37da2899SCharles.Forsyth case INEW:
834*37da2899SCharles.Forsyth case INEWZ:
835*37da2899SCharles.Forsyth case ISLICEA:
836*37da2899SCharles.Forsyth case ISLICELA:
837*37da2899SCharles.Forsyth case ICONSB:
838*37da2899SCharles.Forsyth case ICONSW:
839*37da2899SCharles.Forsyth case ICONSL:
840*37da2899SCharles.Forsyth case ICONSF:
841*37da2899SCharles.Forsyth case ICONSM:
842*37da2899SCharles.Forsyth case ICONSMP:
843*37da2899SCharles.Forsyth case ICONSP:
844*37da2899SCharles.Forsyth case IMOVMP:
845*37da2899SCharles.Forsyth case IHEADMP:
846*37da2899SCharles.Forsyth case IHEADM:
847*37da2899SCharles.Forsyth case IHEADB:
848*37da2899SCharles.Forsyth case IHEADW:
849*37da2899SCharles.Forsyth case IHEADL:
850*37da2899SCharles.Forsyth case IHEADF:
851*37da2899SCharles.Forsyth case IINDC:
852*37da2899SCharles.Forsyth case ILENC:
853*37da2899SCharles.Forsyth case IINSC:
854*37da2899SCharles.Forsyth case ICVTAC:
855*37da2899SCharles.Forsyth case ICVTCW:
856*37da2899SCharles.Forsyth case ICVTWC:
857*37da2899SCharles.Forsyth case ICVTLC:
858*37da2899SCharles.Forsyth case ICVTCL:
859*37da2899SCharles.Forsyth case ICVTFC:
860*37da2899SCharles.Forsyth case ICVTCF:
861*37da2899SCharles.Forsyth case ICVTRF:
862*37da2899SCharles.Forsyth case ICVTFR:
863*37da2899SCharles.Forsyth case IMSPAWN:
864*37da2899SCharles.Forsyth case ICVTCA:
865*37da2899SCharles.Forsyth case ISLICEC:
866*37da2899SCharles.Forsyth case INBALT:
867*37da2899SCharles.Forsyth punt(i, SRCOP|DSTOP, optab[i->op]);
868*37da2899SCharles.Forsyth break;
869*37da2899SCharles.Forsyth case INEWCM:
870*37da2899SCharles.Forsyth case INEWCMP:
871*37da2899SCharles.Forsyth punt(i, SRCOP|DSTOP|THREOP, optab[i->op]);
872*37da2899SCharles.Forsyth break;
873*37da2899SCharles.Forsyth case IMFRAME:
874*37da2899SCharles.Forsyth if((i->add&ARM) == AXIMM)
875*37da2899SCharles.Forsyth commframe(i);
876*37da2899SCharles.Forsyth else
877*37da2899SCharles.Forsyth punt(i, SRCOP|DSTOP|THREOP, optab[i->op]);
878*37da2899SCharles.Forsyth break;
879*37da2899SCharles.Forsyth case ICASE:
880*37da2899SCharles.Forsyth comcase(i, 1);
881*37da2899SCharles.Forsyth break;
882*37da2899SCharles.Forsyth case IGOTO:
883*37da2899SCharles.Forsyth opwld(i, Oldw, RA1);
884*37da2899SCharles.Forsyth opwst(i, Olea, RA0);
885*37da2899SCharles.Forsyth FM3I(2, Osll, 2, RA1, RA1);
886*37da2899SCharles.Forsyth FM3(3, Oldw, RA1, RA0, RA0);
887*37da2899SCharles.Forsyth FM3I(2, Ojmpl, 0, RA0, RZ);
888*37da2899SCharles.Forsyth NOOP;
889*37da2899SCharles.Forsyth
890*37da2899SCharles.Forsyth if(pass == 0)
891*37da2899SCharles.Forsyth break;
892*37da2899SCharles.Forsyth
893*37da2899SCharles.Forsyth t = (WORD*)(mod->origmp+i->d.ind);
894*37da2899SCharles.Forsyth e = t + t[-1];
895*37da2899SCharles.Forsyth t[-1] = 0;
896*37da2899SCharles.Forsyth while(t < e) {
897*37da2899SCharles.Forsyth t[0] = RELPC(patch[t[0]]);
898*37da2899SCharles.Forsyth t++;
899*37da2899SCharles.Forsyth }
900*37da2899SCharles.Forsyth break;
901*37da2899SCharles.Forsyth case IMOVL:
902*37da2899SCharles.Forsyth movl:
903*37da2899SCharles.Forsyth opflld(i, Oldw, RA0);
904*37da2899SCharles.Forsyth opflst(i, Ostw, RA0);
905*37da2899SCharles.Forsyth break;
906*37da2899SCharles.Forsyth case IMOVM:
907*37da2899SCharles.Forsyth if((i->add&ARM) == AXIMM) {
908*37da2899SCharles.Forsyth if(i->reg == 8)
909*37da2899SCharles.Forsyth goto movl;
910*37da2899SCharles.Forsyth if((i->reg&3) == 0) {
911*37da2899SCharles.Forsyth con(i->reg>>2, RA3, 1);
912*37da2899SCharles.Forsyth movloop(i, Oldw, Ostw);
913*37da2899SCharles.Forsyth break;
914*37da2899SCharles.Forsyth }
915*37da2899SCharles.Forsyth }
916*37da2899SCharles.Forsyth mid(i, Oldw, RA3);
917*37da2899SCharles.Forsyth movloop(i, Oldbu, Ostb);
918*37da2899SCharles.Forsyth break;
919*37da2899SCharles.Forsyth case IFRAME:
920*37da2899SCharles.Forsyth if(UXSRC(i->add) != SRC(AIMM)) {
921*37da2899SCharles.Forsyth punt(i, SRCOP|DSTOP, optab[i->op]);
922*37da2899SCharles.Forsyth break;
923*37da2899SCharles.Forsyth }
924*37da2899SCharles.Forsyth tinit[i->s.imm] = 1;
925*37da2899SCharles.Forsyth con((ulong)mod->type[i->s.imm], RA3, 1);
926*37da2899SCharles.Forsyth CALL(base+macro[MacFRAM]);
927*37da2899SCharles.Forsyth NOOP;
928*37da2899SCharles.Forsyth opwst(i, Ostw, RA2);
929*37da2899SCharles.Forsyth break;
930*37da2899SCharles.Forsyth case INEWCB:
931*37da2899SCharles.Forsyth case INEWCW:
932*37da2899SCharles.Forsyth case INEWCF:
933*37da2899SCharles.Forsyth case INEWCP:
934*37da2899SCharles.Forsyth case INEWCL:
935*37da2899SCharles.Forsyth punt(i, DSTOP|THREOP, optab[i->op]);
936*37da2899SCharles.Forsyth break;
937*37da2899SCharles.Forsyth case IEXIT:
938*37da2899SCharles.Forsyth punt(i, 0, optab[i->op]);
939*37da2899SCharles.Forsyth break;
940*37da2899SCharles.Forsyth case ICVTBW:
941*37da2899SCharles.Forsyth opwld(i, Oldbu, RA0);
942*37da2899SCharles.Forsyth opwst(i, Ostw, RA0);
943*37da2899SCharles.Forsyth break;
944*37da2899SCharles.Forsyth case ICVTWB:
945*37da2899SCharles.Forsyth opwld(i, Oldw, RA0);
946*37da2899SCharles.Forsyth opwst(i, Ostb, RA0);
947*37da2899SCharles.Forsyth break;
948*37da2899SCharles.Forsyth case ILEA:
949*37da2899SCharles.Forsyth opwld(i, Olea, RA0);
950*37da2899SCharles.Forsyth opwst(i, Ostw, RA0);
951*37da2899SCharles.Forsyth break;
952*37da2899SCharles.Forsyth case IMOVW:
953*37da2899SCharles.Forsyth opwld(i, Oldw, RA0);
954*37da2899SCharles.Forsyth opwst(i, Ostw, RA0);
955*37da2899SCharles.Forsyth break;
956*37da2899SCharles.Forsyth case IMOVB:
957*37da2899SCharles.Forsyth opwld(i, Oldbu, RA0);
958*37da2899SCharles.Forsyth opwst(i, Ostb, RA0);
959*37da2899SCharles.Forsyth break;
960*37da2899SCharles.Forsyth case ICVTSW:
961*37da2899SCharles.Forsyth opwld(i, Oldsh, RA0);
962*37da2899SCharles.Forsyth opwst(i, Ostw, RA0);
963*37da2899SCharles.Forsyth break;
964*37da2899SCharles.Forsyth case ICVTWS:
965*37da2899SCharles.Forsyth opwld(i, Oldw, RA0);
966*37da2899SCharles.Forsyth opwst(i, Osth, RA0);
967*37da2899SCharles.Forsyth break;
968*37da2899SCharles.Forsyth case ITAIL:
969*37da2899SCharles.Forsyth opwld(i, Oldw, RA0);
970*37da2899SCharles.Forsyth mem(Oldw, O(List, tail), RA0, RA1);
971*37da2899SCharles.Forsyth goto movp;
972*37da2899SCharles.Forsyth case IMOVP:
973*37da2899SCharles.Forsyth case IHEADP:
974*37da2899SCharles.Forsyth opwld(i, Oldw, RA1);
975*37da2899SCharles.Forsyth if(i->op == IHEADP)
976*37da2899SCharles.Forsyth mem(Oldw, OA(List, data), RA1, RA1);
977*37da2899SCharles.Forsyth movp:
978*37da2899SCharles.Forsyth FM3I(2, Ocmp, (ulong)H, RA1, RZ);
979*37da2899SCharles.Forsyth BRA(Obe, 5);
980*37da2899SCharles.Forsyth con((ulong)&mutator, RA2, 1);
981*37da2899SCharles.Forsyth CALL(base+macro[MacCOLR]);
982*37da2899SCharles.Forsyth mem(Oldw, O(Heap, ref)-sizeof(Heap), RA1, RA0);
983*37da2899SCharles.Forsyth opwst(i, Oldw, RA0);
984*37da2899SCharles.Forsyth opwst(i, Ostw, RA1);
985*37da2899SCharles.Forsyth CALL(base+macro[MacFRP]);
986*37da2899SCharles.Forsyth NOOP;
987*37da2899SCharles.Forsyth break;
988*37da2899SCharles.Forsyth case ILENA:
989*37da2899SCharles.Forsyth opwld(i, Oldw, RA1);
990*37da2899SCharles.Forsyth FM3I(2, Ocmp, (ulong)H, RA1, RZ);
991*37da2899SCharles.Forsyth BRA(Obe, 3);
992*37da2899SCharles.Forsyth con(0, RA0, 1);
993*37da2899SCharles.Forsyth mem(Oldw, O(Array, len), RA1, RA0);
994*37da2899SCharles.Forsyth opwst(i, Ostw, RA0);
995*37da2899SCharles.Forsyth break;
996*37da2899SCharles.Forsyth case ILENL:
997*37da2899SCharles.Forsyth con(0, RA0, 1);
998*37da2899SCharles.Forsyth opwld(i, Oldw, RA1);
999*37da2899SCharles.Forsyth FM3I(2, Ocmp, (ulong)H, RA1, RZ);
1000*37da2899SCharles.Forsyth BRA(Obe, 5);
1001*37da2899SCharles.Forsyth NOOP;
1002*37da2899SCharles.Forsyth mem(Oldw, O(List, tail), RA1, RA1);
1003*37da2899SCharles.Forsyth BRA(Oba, -4);
1004*37da2899SCharles.Forsyth FM3I(2, Oadd, 1, RA0, RA0);
1005*37da2899SCharles.Forsyth opwst(i, Ostw, RA0);
1006*37da2899SCharles.Forsyth break;
1007*37da2899SCharles.Forsyth case ICALL:
1008*37da2899SCharles.Forsyth opwld(i, Oldw, RA0);
1009*37da2899SCharles.Forsyth con(RELPC(patch[i-mod->prog+1]), RA1, 0);
1010*37da2899SCharles.Forsyth mem(Ostw, O(Frame, lr), RA0, RA1);
1011*37da2899SCharles.Forsyth mem(Ostw, O(Frame, fp), RA0, RFP);
1012*37da2899SCharles.Forsyth BRADIS(Oba, i->d.ins-mod->prog);
1013*37da2899SCharles.Forsyth MOV(RA0, RFP);
1014*37da2899SCharles.Forsyth break;
1015*37da2899SCharles.Forsyth case IJMP:
1016*37da2899SCharles.Forsyth BRADIS(Oba, i->d.ins-mod->prog);
1017*37da2899SCharles.Forsyth NOOP;
1018*37da2899SCharles.Forsyth break;
1019*37da2899SCharles.Forsyth case IBEQW:
1020*37da2899SCharles.Forsyth r = Obe;
1021*37da2899SCharles.Forsyth braw:
1022*37da2899SCharles.Forsyth opwld(i, Oldw, RA1);
1023*37da2899SCharles.Forsyth mid(i, Oldw, RA0);
1024*37da2899SCharles.Forsyth FM3(2, Ocmp, RA0, RA1, RZ);
1025*37da2899SCharles.Forsyth BRADIS(r, i->d.ins-mod->prog);
1026*37da2899SCharles.Forsyth NOOP;
1027*37da2899SCharles.Forsyth break;
1028*37da2899SCharles.Forsyth case IBNEW:
1029*37da2899SCharles.Forsyth r = Obne;
1030*37da2899SCharles.Forsyth goto braw;
1031*37da2899SCharles.Forsyth case IBLTW:
1032*37da2899SCharles.Forsyth r = Obl;
1033*37da2899SCharles.Forsyth goto braw;
1034*37da2899SCharles.Forsyth case IBLEW:
1035*37da2899SCharles.Forsyth r = Oble;
1036*37da2899SCharles.Forsyth goto braw;
1037*37da2899SCharles.Forsyth case IBGTW:
1038*37da2899SCharles.Forsyth r = Obg;
1039*37da2899SCharles.Forsyth goto braw;
1040*37da2899SCharles.Forsyth case IBGEW:
1041*37da2899SCharles.Forsyth r = Obge;
1042*37da2899SCharles.Forsyth goto braw;
1043*37da2899SCharles.Forsyth case IBEQB:
1044*37da2899SCharles.Forsyth r = Obe;
1045*37da2899SCharles.Forsyth brab:
1046*37da2899SCharles.Forsyth opwld(i, Oldbu, RA1);
1047*37da2899SCharles.Forsyth mid(i, Oldbu, RA0);
1048*37da2899SCharles.Forsyth FM3(2, Ocmp, RA0, RA1, RZ);
1049*37da2899SCharles.Forsyth BRADIS(r, i->d.ins-mod->prog);
1050*37da2899SCharles.Forsyth NOOP;
1051*37da2899SCharles.Forsyth break;
1052*37da2899SCharles.Forsyth case IBNEB:
1053*37da2899SCharles.Forsyth r = Obne;
1054*37da2899SCharles.Forsyth goto brab;
1055*37da2899SCharles.Forsyth case IBLTB:
1056*37da2899SCharles.Forsyth r = Obl;
1057*37da2899SCharles.Forsyth goto brab;
1058*37da2899SCharles.Forsyth case IBLEB:
1059*37da2899SCharles.Forsyth r = Oble;
1060*37da2899SCharles.Forsyth goto brab;
1061*37da2899SCharles.Forsyth case IBGTB:
1062*37da2899SCharles.Forsyth r = Obg;
1063*37da2899SCharles.Forsyth goto brab;
1064*37da2899SCharles.Forsyth case IBGEB:
1065*37da2899SCharles.Forsyth r = Obge;
1066*37da2899SCharles.Forsyth goto brab;
1067*37da2899SCharles.Forsyth case IBEQF:
1068*37da2899SCharles.Forsyth r = Ofbe;
1069*37da2899SCharles.Forsyth braf:
1070*37da2899SCharles.Forsyth opflld(i, Oldf, FA4);
1071*37da2899SCharles.Forsyth midfl(i, Oldf, FA2);
1072*37da2899SCharles.Forsyth FMF2(OfcmpD, FA2, FA4, 0);
1073*37da2899SCharles.Forsyth NOOP;
1074*37da2899SCharles.Forsyth BRAFDIS(r, i->d.ins-mod->prog);
1075*37da2899SCharles.Forsyth NOOP;
1076*37da2899SCharles.Forsyth break;
1077*37da2899SCharles.Forsyth case IBNEF:
1078*37da2899SCharles.Forsyth r = Ofbne;
1079*37da2899SCharles.Forsyth goto braf;
1080*37da2899SCharles.Forsyth case IBLTF:
1081*37da2899SCharles.Forsyth r = Ofbl;
1082*37da2899SCharles.Forsyth goto braf;
1083*37da2899SCharles.Forsyth case IBLEF:
1084*37da2899SCharles.Forsyth r = Ofble;
1085*37da2899SCharles.Forsyth goto braf;
1086*37da2899SCharles.Forsyth case IBGTF:
1087*37da2899SCharles.Forsyth r = Ofbg;
1088*37da2899SCharles.Forsyth goto braf;
1089*37da2899SCharles.Forsyth case IBGEF:
1090*37da2899SCharles.Forsyth r = Ofbge;
1091*37da2899SCharles.Forsyth goto braf;
1092*37da2899SCharles.Forsyth case IRET:
1093*37da2899SCharles.Forsyth BRAMAC(Oba, MacRET);
1094*37da2899SCharles.Forsyth mem(Oldw, O(Frame,t), RFP, RA1);
1095*37da2899SCharles.Forsyth break;
1096*37da2899SCharles.Forsyth case IORW:
1097*37da2899SCharles.Forsyth r = Oor;
1098*37da2899SCharles.Forsyth goto arithw;
1099*37da2899SCharles.Forsyth case IANDW:
1100*37da2899SCharles.Forsyth r = Oand;
1101*37da2899SCharles.Forsyth goto arithw;
1102*37da2899SCharles.Forsyth case IXORW:
1103*37da2899SCharles.Forsyth r = Oxor;
1104*37da2899SCharles.Forsyth goto arithw;
1105*37da2899SCharles.Forsyth case ISUBW:
1106*37da2899SCharles.Forsyth r = Osub;
1107*37da2899SCharles.Forsyth goto arithw;
1108*37da2899SCharles.Forsyth case ISHRW:
1109*37da2899SCharles.Forsyth r = Osra;
1110*37da2899SCharles.Forsyth goto arithw;
1111*37da2899SCharles.Forsyth case ISHLW:
1112*37da2899SCharles.Forsyth r = Osll;
1113*37da2899SCharles.Forsyth goto arithw;
1114*37da2899SCharles.Forsyth case ILSRW:
1115*37da2899SCharles.Forsyth r = Osrl;
1116*37da2899SCharles.Forsyth goto arithw;
1117*37da2899SCharles.Forsyth case IMULW:
1118*37da2899SCharles.Forsyth r = Omul;
1119*37da2899SCharles.Forsyth goto arithw;
1120*37da2899SCharles.Forsyth case IDIVW:
1121*37da2899SCharles.Forsyth r = Osdiv;
1122*37da2899SCharles.Forsyth goto arithw;
1123*37da2899SCharles.Forsyth case IADDW:
1124*37da2899SCharles.Forsyth r = Oadd;
1125*37da2899SCharles.Forsyth arithw:
1126*37da2899SCharles.Forsyth mid(i, Oldw, RA1);
1127*37da2899SCharles.Forsyth if(i->op == IDIVW) {
1128*37da2899SCharles.Forsyth FM3I(2, Osra, 31, RA1, RA0);
1129*37da2899SCharles.Forsyth FM3(2, Owry, RZ, RA0, 0);
1130*37da2899SCharles.Forsyth }
1131*37da2899SCharles.Forsyth if(UXSRC(i->add) == SRC(AIMM) && bc(i->s.imm))
1132*37da2899SCharles.Forsyth FM3I(2, r, i->s.imm, RA1, RA0);
1133*37da2899SCharles.Forsyth else {
1134*37da2899SCharles.Forsyth opwld(i, Oldw, RA0);
1135*37da2899SCharles.Forsyth FM3(2, r, RA0, RA1, RA0);
1136*37da2899SCharles.Forsyth }
1137*37da2899SCharles.Forsyth opwst(i, Ostw, RA0);
1138*37da2899SCharles.Forsyth break;
1139*37da2899SCharles.Forsyth case IORB:
1140*37da2899SCharles.Forsyth r = Oor;
1141*37da2899SCharles.Forsyth goto arithb;
1142*37da2899SCharles.Forsyth case IANDB:
1143*37da2899SCharles.Forsyth r = Oand;
1144*37da2899SCharles.Forsyth goto arithb;
1145*37da2899SCharles.Forsyth case IXORB:
1146*37da2899SCharles.Forsyth r = Oxor;
1147*37da2899SCharles.Forsyth goto arithb;
1148*37da2899SCharles.Forsyth case ISUBB:
1149*37da2899SCharles.Forsyth r = Osub;
1150*37da2899SCharles.Forsyth goto arithb;
1151*37da2899SCharles.Forsyth case IMULB:
1152*37da2899SCharles.Forsyth r = Omul;
1153*37da2899SCharles.Forsyth goto arithb;
1154*37da2899SCharles.Forsyth case IDIVB:
1155*37da2899SCharles.Forsyth FM3(2, Owry, RZ, RZ, 0);
1156*37da2899SCharles.Forsyth r = Osdiv;
1157*37da2899SCharles.Forsyth goto arithb;
1158*37da2899SCharles.Forsyth case IADDB:
1159*37da2899SCharles.Forsyth r = Oadd;
1160*37da2899SCharles.Forsyth arithb:
1161*37da2899SCharles.Forsyth mid(i, Oldbu, RA1);
1162*37da2899SCharles.Forsyth opwld(i, Oldbu, RA0);
1163*37da2899SCharles.Forsyth FM3(2, r, RA0, RA1, RA0);
1164*37da2899SCharles.Forsyth opwst(i, Ostb, RA0);
1165*37da2899SCharles.Forsyth break;
1166*37da2899SCharles.Forsyth case ISHRB:
1167*37da2899SCharles.Forsyth r = Osra;
1168*37da2899SCharles.Forsyth goto shiftb;
1169*37da2899SCharles.Forsyth case ISHLB:
1170*37da2899SCharles.Forsyth r = Osll;
1171*37da2899SCharles.Forsyth shiftb:
1172*37da2899SCharles.Forsyth mid(i, Oldbu, RA1);
1173*37da2899SCharles.Forsyth if(UXSRC(i->add) == SRC(AIMM) && bc(i->s.imm))
1174*37da2899SCharles.Forsyth FM3I(2, r, i->s.imm, RA1, RA0);
1175*37da2899SCharles.Forsyth else {
1176*37da2899SCharles.Forsyth opwld(i, Oldw, RA0);
1177*37da2899SCharles.Forsyth FM3(2, r, RA0, RA1, RA0);
1178*37da2899SCharles.Forsyth }
1179*37da2899SCharles.Forsyth opwst(i, Ostb, RA0);
1180*37da2899SCharles.Forsyth break;
1181*37da2899SCharles.Forsyth case IINDL:
1182*37da2899SCharles.Forsyth case IINDF:
1183*37da2899SCharles.Forsyth case IINDW:
1184*37da2899SCharles.Forsyth case IINDB:
1185*37da2899SCharles.Forsyth opwld(i, Oldw, RA0); /* a */
1186*37da2899SCharles.Forsyth r = 0;
1187*37da2899SCharles.Forsyth switch(i->op) {
1188*37da2899SCharles.Forsyth case IINDL:
1189*37da2899SCharles.Forsyth case IINDF:
1190*37da2899SCharles.Forsyth r = 3;
1191*37da2899SCharles.Forsyth break;
1192*37da2899SCharles.Forsyth case IINDW:
1193*37da2899SCharles.Forsyth r = 2;
1194*37da2899SCharles.Forsyth break;
1195*37da2899SCharles.Forsyth }
1196*37da2899SCharles.Forsyth if(UXDST(i->add) == DST(AIMM) && bc(i->d.imm<<r)) {
1197*37da2899SCharles.Forsyth mem(Oldw, O(Array, data), RA0, RA0);
1198*37da2899SCharles.Forsyth FM3I(2, Oadd, (i->d.imm<<r), RA0, RA0);
1199*37da2899SCharles.Forsyth }
1200*37da2899SCharles.Forsyth else {
1201*37da2899SCharles.Forsyth opwst(i, Oldw, RA1);
1202*37da2899SCharles.Forsyth mem(Oldw, O(Array, data), RA0, RA0);
1203*37da2899SCharles.Forsyth if(r != 0)
1204*37da2899SCharles.Forsyth FM3I(2, Osll, r, RA1, RA1);
1205*37da2899SCharles.Forsyth FM3(2, Oadd, RA0, RA1, RA0);
1206*37da2899SCharles.Forsyth }
1207*37da2899SCharles.Forsyth r = RMP;
1208*37da2899SCharles.Forsyth if((i->add&ARM) == AXINF)
1209*37da2899SCharles.Forsyth r = RFP;
1210*37da2899SCharles.Forsyth mem(Ostw, i->reg, r, RA0);
1211*37da2899SCharles.Forsyth break;
1212*37da2899SCharles.Forsyth case IINDX:
1213*37da2899SCharles.Forsyth opwld(i, Oldw, RA0); /* a */
1214*37da2899SCharles.Forsyth /*
1215*37da2899SCharles.Forsyth r = 0;
1216*37da2899SCharles.Forsyth if(UXDST(i->add) == DST(AIMM) && bc(i->d.imm<<r))
1217*37da2899SCharles.Forsyth r = i->d.imm<<r;
1218*37da2899SCharles.Forsyth else
1219*37da2899SCharles.Forsyth */
1220*37da2899SCharles.Forsyth opwst(i, Oldw, RA1); /* i */
1221*37da2899SCharles.Forsyth mem(Oldw, O(Array, t), RA0, RA2);
1222*37da2899SCharles.Forsyth mem(Oldw, O(Array, data), RA0, RA0);
1223*37da2899SCharles.Forsyth mem(Oldw, O(Type, size), RA2, RA2);
1224*37da2899SCharles.Forsyth /*
1225*37da2899SCharles.Forsyth if(r != 0)
1226*37da2899SCharles.Forsyth FM3I(2, Oumul, r, RA2, RA1);
1227*37da2899SCharles.Forsyth else
1228*37da2899SCharles.Forsyth */
1229*37da2899SCharles.Forsyth FM3(2, Oumul, RA1, RA2, RA1);
1230*37da2899SCharles.Forsyth FM3(2, Oadd, RA0, RA1, RA0);
1231*37da2899SCharles.Forsyth r = RMP;
1232*37da2899SCharles.Forsyth if((i->add&ARM) == AXINF)
1233*37da2899SCharles.Forsyth r = RFP;
1234*37da2899SCharles.Forsyth mem(Ostw, i->reg, r, RA0);
1235*37da2899SCharles.Forsyth break;
1236*37da2899SCharles.Forsyth case IADDL:
1237*37da2899SCharles.Forsyth larith(i, Oaddcc, Oaddx);
1238*37da2899SCharles.Forsyth break;
1239*37da2899SCharles.Forsyth case ISUBL:
1240*37da2899SCharles.Forsyth larith(i, Osubcc, Osubx);
1241*37da2899SCharles.Forsyth break;
1242*37da2899SCharles.Forsyth case IORL:
1243*37da2899SCharles.Forsyth larith(i, Oor, Oor);
1244*37da2899SCharles.Forsyth break;
1245*37da2899SCharles.Forsyth case IANDL:
1246*37da2899SCharles.Forsyth larith(i, Oand, Oand);
1247*37da2899SCharles.Forsyth break;
1248*37da2899SCharles.Forsyth case IXORL:
1249*37da2899SCharles.Forsyth larith(i, Oxor, Oxor);
1250*37da2899SCharles.Forsyth break;
1251*37da2899SCharles.Forsyth case ICVTWL:
1252*37da2899SCharles.Forsyth opwld(i, Oldw, RA1);
1253*37da2899SCharles.Forsyth FM3I(2, Osra, 31, RA1, RA0);
1254*37da2899SCharles.Forsyth opflst(i, Ostw, RA0);
1255*37da2899SCharles.Forsyth break;
1256*37da2899SCharles.Forsyth case ICVTLW:
1257*37da2899SCharles.Forsyth opwld(i, Olea, RA0);
1258*37da2899SCharles.Forsyth mem(Oldw, 4, RA0, RA0);
1259*37da2899SCharles.Forsyth opwst(i, Ostw, RA0);
1260*37da2899SCharles.Forsyth break;
1261*37da2899SCharles.Forsyth case IBEQL:
1262*37da2899SCharles.Forsyth cbral(i, Obne, Obe, ANDAND);
1263*37da2899SCharles.Forsyth break;
1264*37da2899SCharles.Forsyth case IBNEL:
1265*37da2899SCharles.Forsyth cbral(i, Obne, Obne, OROR);
1266*37da2899SCharles.Forsyth break;
1267*37da2899SCharles.Forsyth case IBLEL:
1268*37da2899SCharles.Forsyth cbral(i, Obl, Obleu, EQAND);
1269*37da2899SCharles.Forsyth break;
1270*37da2899SCharles.Forsyth case IBGTL:
1271*37da2899SCharles.Forsyth cbral(i, Obg, Obgu, EQAND);
1272*37da2899SCharles.Forsyth break;
1273*37da2899SCharles.Forsyth case IBLTL:
1274*37da2899SCharles.Forsyth cbral(i, Obl, Obcs, EQAND);
1275*37da2899SCharles.Forsyth break;
1276*37da2899SCharles.Forsyth case IBGEL:
1277*37da2899SCharles.Forsyth cbral(i, Obg, Obcc, EQAND);
1278*37da2899SCharles.Forsyth break;
1279*37da2899SCharles.Forsyth case IMOVF:
1280*37da2899SCharles.Forsyth opflld(i, Oldf, FA2);
1281*37da2899SCharles.Forsyth opflst(i, Ostf, FA2);
1282*37da2899SCharles.Forsyth break;
1283*37da2899SCharles.Forsyth case IDIVF:
1284*37da2899SCharles.Forsyth r = OfdivD;
1285*37da2899SCharles.Forsyth goto arithf;
1286*37da2899SCharles.Forsyth case IMULF:
1287*37da2899SCharles.Forsyth r = OfmulD;
1288*37da2899SCharles.Forsyth goto arithf;
1289*37da2899SCharles.Forsyth case ISUBF:
1290*37da2899SCharles.Forsyth r = OfsubD;
1291*37da2899SCharles.Forsyth goto arithf;
1292*37da2899SCharles.Forsyth case IADDF:
1293*37da2899SCharles.Forsyth r = OfaddD;
1294*37da2899SCharles.Forsyth arithf:
1295*37da2899SCharles.Forsyth opflld(i, Oldf, FA2);
1296*37da2899SCharles.Forsyth midfl(i, Oldf, FA4);
1297*37da2899SCharles.Forsyth FMF1(r, FA2, FA4, FA4);
1298*37da2899SCharles.Forsyth opflst(i, Ostf, FA4);
1299*37da2899SCharles.Forsyth break;
1300*37da2899SCharles.Forsyth case INEGF:
1301*37da2899SCharles.Forsyth opflld(i, Oldf, FA2);
1302*37da2899SCharles.Forsyth FMF1(OfnegS, FA2, 0, FA2);
1303*37da2899SCharles.Forsyth opflst(i, Ostf, FA2);
1304*37da2899SCharles.Forsyth break;
1305*37da2899SCharles.Forsyth case ICVTFL:
1306*37da2899SCharles.Forsyth // >= Sparc 8
1307*37da2899SCharles.Forsyth // opflld(i, Oldf, FA2);
1308*37da2899SCharles.Forsyth // FMF1(OfDtoQ, FA2, 0, FA2);
1309*37da2899SCharles.Forsyth // opflst(i, Ostf, FA2);
1310*37da2899SCharles.Forsyth punt(i, SRCOP|DSTOP, optab[i->op]);
1311*37da2899SCharles.Forsyth break;
1312*37da2899SCharles.Forsyth case ICVTLF:
1313*37da2899SCharles.Forsyth // >= Sparc 8
1314*37da2899SCharles.Forsyth // opflld(i, Oldf, FA2);
1315*37da2899SCharles.Forsyth // FMF1(OfQtoD, FA2, 0, FA2);
1316*37da2899SCharles.Forsyth // opflst(i, Ostf, FA2);
1317*37da2899SCharles.Forsyth punt(i, SRCOP|DSTOP, optab[i->op]);
1318*37da2899SCharles.Forsyth break;
1319*37da2899SCharles.Forsyth case ICVTWF:
1320*37da2899SCharles.Forsyth opwld(i, Oldf, FA2);
1321*37da2899SCharles.Forsyth FMF1(OfWtoD, FA2, 0, FA2);
1322*37da2899SCharles.Forsyth opflst(i, Ostf, FA2);
1323*37da2899SCharles.Forsyth break;
1324*37da2899SCharles.Forsyth case ICVTFW:
1325*37da2899SCharles.Forsyth opflld(i, Oldf, FA2);
1326*37da2899SCharles.Forsyth FMF1(OfDtoW, FA2, 0, FA2);
1327*37da2899SCharles.Forsyth opwst(i, Ostf, FA2);
1328*37da2899SCharles.Forsyth break;
1329*37da2899SCharles.Forsyth case ISHLL:
1330*37da2899SCharles.Forsyth shll(i);
1331*37da2899SCharles.Forsyth break;
1332*37da2899SCharles.Forsyth case ISHRL:
1333*37da2899SCharles.Forsyth case ILSRL:
1334*37da2899SCharles.Forsyth punt(i, SRCOP|DSTOP|THREOP, optab[i->op]);
1335*37da2899SCharles.Forsyth break;
1336*37da2899SCharles.Forsyth case IRAISE:
1337*37da2899SCharles.Forsyth punt(i, SRCOP|WRTPC|NEWPC, optab[i->op]);
1338*37da2899SCharles.Forsyth break;
1339*37da2899SCharles.Forsyth case IMULX:
1340*37da2899SCharles.Forsyth case IDIVX:
1341*37da2899SCharles.Forsyth case ICVTXX:
1342*37da2899SCharles.Forsyth case IMULX0:
1343*37da2899SCharles.Forsyth case IDIVX0:
1344*37da2899SCharles.Forsyth case ICVTXX0:
1345*37da2899SCharles.Forsyth case IMULX1:
1346*37da2899SCharles.Forsyth case IDIVX1:
1347*37da2899SCharles.Forsyth case ICVTXX1:
1348*37da2899SCharles.Forsyth case ICVTFX:
1349*37da2899SCharles.Forsyth case ICVTXF:
1350*37da2899SCharles.Forsyth case IEXPW:
1351*37da2899SCharles.Forsyth case IEXPL:
1352*37da2899SCharles.Forsyth case IEXPF:
1353*37da2899SCharles.Forsyth punt(i, SRCOP|DSTOP|THREOP, optab[i->op]);
1354*37da2899SCharles.Forsyth break;
1355*37da2899SCharles.Forsyth case ISELF:
1356*37da2899SCharles.Forsyth punt(i, DSTOP, optab[i->op]);
1357*37da2899SCharles.Forsyth break;
1358*37da2899SCharles.Forsyth }
1359*37da2899SCharles.Forsyth }
1360*37da2899SCharles.Forsyth
1361*37da2899SCharles.Forsyth static void
preamble(void)1362*37da2899SCharles.Forsyth preamble(void)
1363*37da2899SCharles.Forsyth {
1364*37da2899SCharles.Forsyth ulong *start;
1365*37da2899SCharles.Forsyth
1366*37da2899SCharles.Forsyth if(comvec)
1367*37da2899SCharles.Forsyth return;
1368*37da2899SCharles.Forsyth
1369*37da2899SCharles.Forsyth comvec = malloc(10 * sizeof(*code));
1370*37da2899SCharles.Forsyth if(comvec == nil)
1371*37da2899SCharles.Forsyth error(exNomem);
1372*37da2899SCharles.Forsyth code = (ulong*)comvec;
1373*37da2899SCharles.Forsyth start = code;
1374*37da2899SCharles.Forsyth
1375*37da2899SCharles.Forsyth con((ulong)&R, RREG, 1);
1376*37da2899SCharles.Forsyth mem(Ostw, O(REG, xpc), RREG, RLINK);
1377*37da2899SCharles.Forsyth mem(Oldw, O(REG, PC), RREG, RA0);
1378*37da2899SCharles.Forsyth mem(Oldw, O(REG, FP), RREG, RFP);
1379*37da2899SCharles.Forsyth FM3I(2, Ojmpl, 0, RA0, RZ);
1380*37da2899SCharles.Forsyth mem(Oldw, O(REG, MP), RREG, RMP);
1381*37da2899SCharles.Forsyth
1382*37da2899SCharles.Forsyth segflush(comvec, 10 * sizeof(*code));
1383*37da2899SCharles.Forsyth
1384*37da2899SCharles.Forsyth if(cflag > 4) {
1385*37da2899SCharles.Forsyth print("comvec:\n");
1386*37da2899SCharles.Forsyth das(start, code-start);
1387*37da2899SCharles.Forsyth }
1388*37da2899SCharles.Forsyth }
1389*37da2899SCharles.Forsyth
1390*37da2899SCharles.Forsyth static void
maccase(void)1391*37da2899SCharles.Forsyth maccase(void)
1392*37da2899SCharles.Forsyth {
1393*37da2899SCharles.Forsyth ulong *loop, *def, *lab1;
1394*37da2899SCharles.Forsyth
1395*37da2899SCharles.Forsyth mem(Oldw, 0, RCON, RA3); // n = t[0]
1396*37da2899SCharles.Forsyth FM3I(2, Oadd, 4, RCON, RCON);
1397*37da2899SCharles.Forsyth MOV(RA3, RA1);
1398*37da2899SCharles.Forsyth FM3I(2, Osll, 1, RA1, RA1);
1399*37da2899SCharles.Forsyth FM3(2, Oadd, RA3, RA1, RA1);
1400*37da2899SCharles.Forsyth FM3I(2, Osll, 2, RA1, RA1);
1401*37da2899SCharles.Forsyth FM3(3, Oldw, RCON, RA1, RLINK);
1402*37da2899SCharles.Forsyth
1403*37da2899SCharles.Forsyth loop = code;
1404*37da2899SCharles.Forsyth FM3(2, Ocmp, RZ, RA3, RZ);
1405*37da2899SCharles.Forsyth def = code;
1406*37da2899SCharles.Forsyth BRA(Oble, 0);
1407*37da2899SCharles.Forsyth NOOP;
1408*37da2899SCharles.Forsyth
1409*37da2899SCharles.Forsyth MOV(RA3, RA2); // MOVL DX, CX n2 = n
1410*37da2899SCharles.Forsyth FM3I(2, Osra, 1, RA2, RA2); // SHR CX,1 n2 = n2>>1
1411*37da2899SCharles.Forsyth MOV(RA2, RA1);
1412*37da2899SCharles.Forsyth FM3I(2, Osll, 1, RA1, RA1);
1413*37da2899SCharles.Forsyth FM3(2, Oadd, RA2, RA1, RA1);
1414*37da2899SCharles.Forsyth FM3I(2, Osll, 2, RA1, RA1);
1415*37da2899SCharles.Forsyth
1416*37da2899SCharles.Forsyth FM3(3, Oldw, RA1, RCON, RTA); // MOV (RA1+RCON), RTA
1417*37da2899SCharles.Forsyth FM3(2, Ocmp, RTA, RA0, RZ);
1418*37da2899SCharles.Forsyth lab1 = code;
1419*37da2899SCharles.Forsyth BRA(Obge, 0);
1420*37da2899SCharles.Forsyth NOOP;
1421*37da2899SCharles.Forsyth MOV(RA2, RA3); // n = n2
1422*37da2899SCharles.Forsyth BRA(Oba, loop-code);
1423*37da2899SCharles.Forsyth NOOP;
1424*37da2899SCharles.Forsyth
1425*37da2899SCharles.Forsyth PATCH(lab1);
1426*37da2899SCharles.Forsyth FM3I(2, Oadd, 4, RA1, RTA);
1427*37da2899SCharles.Forsyth FM3(3, Oldw, RTA, RCON, RTA); // MOV (RA1+RCON), RTA
1428*37da2899SCharles.Forsyth FM3(2, Ocmp, RTA, RA0, RZ);
1429*37da2899SCharles.Forsyth lab1 = code;
1430*37da2899SCharles.Forsyth BRA(Obl, 0);
1431*37da2899SCharles.Forsyth NOOP;
1432*37da2899SCharles.Forsyth
1433*37da2899SCharles.Forsyth FM3I(2, Oadd, 12, RA1, RTA);
1434*37da2899SCharles.Forsyth FM3(2, Oadd, RTA, RCON, RCON);
1435*37da2899SCharles.Forsyth FM3(2, Osub, RA2, RA3, RA3); // SUBL CX, DX n -= n2
1436*37da2899SCharles.Forsyth FM3I(2, Oadd, -1, RA3, RA3); // DECL DX n -= 1
1437*37da2899SCharles.Forsyth BRA(Oba, loop-code);
1438*37da2899SCharles.Forsyth NOOP;
1439*37da2899SCharles.Forsyth
1440*37da2899SCharles.Forsyth PATCH(lab1);
1441*37da2899SCharles.Forsyth FM3I(2, Oadd, 8, RA1, RTA);
1442*37da2899SCharles.Forsyth FM3(3, Oldw, RTA, RCON, RLINK);
1443*37da2899SCharles.Forsyth
1444*37da2899SCharles.Forsyth PATCH(def);
1445*37da2899SCharles.Forsyth FM3I(2, Ojmpl, 0, RLINK, RZ);
1446*37da2899SCharles.Forsyth NOOP;
1447*37da2899SCharles.Forsyth }
1448*37da2899SCharles.Forsyth
1449*37da2899SCharles.Forsyth static void
macfrp(void)1450*37da2899SCharles.Forsyth macfrp(void)
1451*37da2899SCharles.Forsyth {
1452*37da2899SCharles.Forsyth ulong *lab1, *lab2;
1453*37da2899SCharles.Forsyth
1454*37da2899SCharles.Forsyth /* destroy the pointer in RA0 */
1455*37da2899SCharles.Forsyth FM3I(2, Ocmp, -1, RA0, RZ);
1456*37da2899SCharles.Forsyth lab1 = code;
1457*37da2899SCharles.Forsyth BRA(Obe, 0);
1458*37da2899SCharles.Forsyth NOOP;
1459*37da2899SCharles.Forsyth mem(Oldw, O(Heap, ref)-sizeof(Heap), RA0, RA2);
1460*37da2899SCharles.Forsyth FM3I(2, Oadd, -1, RA2, RA2);
1461*37da2899SCharles.Forsyth FM3I(2, Ocmp, 0, RA2, RZ);
1462*37da2899SCharles.Forsyth lab2 = code;
1463*37da2899SCharles.Forsyth BRA(Obne, 0);
1464*37da2899SCharles.Forsyth NOOP;
1465*37da2899SCharles.Forsyth mem(Ostw, O(REG, FP), RREG, RFP);
1466*37da2899SCharles.Forsyth mem(Ostw, O(REG, st), RREG, RLINK);
1467*37da2899SCharles.Forsyth CALL(rdestroy);
1468*37da2899SCharles.Forsyth mem(Ostw, O(REG, s), RREG, RA0);
1469*37da2899SCharles.Forsyth con((ulong)&R, RREG, 1);
1470*37da2899SCharles.Forsyth mem(Oldw, O(REG, st), RREG, RLINK);
1471*37da2899SCharles.Forsyth mem(Oldw, O(REG, FP), RREG, RFP);
1472*37da2899SCharles.Forsyth RETURN;
1473*37da2899SCharles.Forsyth mem(Oldw, O(REG, MP), RREG, RMP);
1474*37da2899SCharles.Forsyth PATCH(lab2);
1475*37da2899SCharles.Forsyth mem(Ostw, O(Heap, ref)-sizeof(Heap), RA0, RA2);
1476*37da2899SCharles.Forsyth PATCH(lab1);
1477*37da2899SCharles.Forsyth RETURN;
1478*37da2899SCharles.Forsyth NOOP;
1479*37da2899SCharles.Forsyth }
1480*37da2899SCharles.Forsyth
1481*37da2899SCharles.Forsyth static void
macret(void)1482*37da2899SCharles.Forsyth macret(void)
1483*37da2899SCharles.Forsyth {
1484*37da2899SCharles.Forsyth Inst i;
1485*37da2899SCharles.Forsyth ulong *cp1, *cp2, *cp3, *cp4, *cp5, *cp6;
1486*37da2899SCharles.Forsyth
1487*37da2899SCharles.Forsyth FM3I(2, Ocmp, 0, RA1, RZ);
1488*37da2899SCharles.Forsyth cp1 = code;
1489*37da2899SCharles.Forsyth BRA(Obe, 0); // t(Rfp) == 0
1490*37da2899SCharles.Forsyth NOOP;
1491*37da2899SCharles.Forsyth
1492*37da2899SCharles.Forsyth mem(Oldw, O(Type,destroy),RA1, RA0);
1493*37da2899SCharles.Forsyth FM3I(2, Ocmp, 0, RA0, RZ);
1494*37da2899SCharles.Forsyth cp2 = code;
1495*37da2899SCharles.Forsyth BRA(Obe, 0); // destroy(t(fp)) == 0
1496*37da2899SCharles.Forsyth NOOP;
1497*37da2899SCharles.Forsyth
1498*37da2899SCharles.Forsyth mem(Oldw, O(Frame,fp),RFP, RA2);
1499*37da2899SCharles.Forsyth FM3I(2, Ocmp, 0, RA2, RZ);
1500*37da2899SCharles.Forsyth cp3 = code;
1501*37da2899SCharles.Forsyth BRA(Obe, 0); // fp(Rfp) == 0
1502*37da2899SCharles.Forsyth NOOP;
1503*37da2899SCharles.Forsyth
1504*37da2899SCharles.Forsyth mem(Oldw, O(Frame,mr),RFP, RA3);
1505*37da2899SCharles.Forsyth FM3I(2, Ocmp, 0, RA3, RZ);
1506*37da2899SCharles.Forsyth cp4 = code;
1507*37da2899SCharles.Forsyth BRA(Obe, 0); // mr(Rfp) == 0
1508*37da2899SCharles.Forsyth NOOP;
1509*37da2899SCharles.Forsyth
1510*37da2899SCharles.Forsyth mem(Oldw, O(REG,M),RREG, RA2);
1511*37da2899SCharles.Forsyth mem(Oldw, O(Heap,ref)-sizeof(Heap),RA2, RA3);
1512*37da2899SCharles.Forsyth FM3I(2, Oaddcc, -1, RA3, RA3);
1513*37da2899SCharles.Forsyth cp5 = code;
1514*37da2899SCharles.Forsyth BRA(Obe, 0); // --ref(arg) == 0
1515*37da2899SCharles.Forsyth NOOP;
1516*37da2899SCharles.Forsyth mem(Ostw, O(Heap,ref)-sizeof(Heap),RA2, RA3);
1517*37da2899SCharles.Forsyth
1518*37da2899SCharles.Forsyth mem(Oldw, O(Frame,mr),RFP, RA1);
1519*37da2899SCharles.Forsyth mem(Ostw, O(REG,M),RREG, RA1);
1520*37da2899SCharles.Forsyth mem(Oldw, O(Modlink,compiled),RA1, RA2); // check for uncompiled code
1521*37da2899SCharles.Forsyth mem(Oldw, O(Modlink,MP),RA1, RMP);
1522*37da2899SCharles.Forsyth FM3I(2, Ocmp, 0, RA2, RZ);
1523*37da2899SCharles.Forsyth cp6 = code;
1524*37da2899SCharles.Forsyth BRA(Obe, 0);
1525*37da2899SCharles.Forsyth NOOP;
1526*37da2899SCharles.Forsyth mem(Ostw, O(REG,MP),RREG, RMP);
1527*37da2899SCharles.Forsyth
1528*37da2899SCharles.Forsyth PATCH(cp4);
1529*37da2899SCharles.Forsyth FM3I(2, Ojmpl, 0, RA0, RLINK); // call destroy(t(fp))
1530*37da2899SCharles.Forsyth NOOP;
1531*37da2899SCharles.Forsyth mem(Ostw, O(REG,SP),RREG, RFP);
1532*37da2899SCharles.Forsyth mem(Oldw, O(Frame,lr),RFP, RA1);
1533*37da2899SCharles.Forsyth mem(Oldw, O(Frame,fp),RFP, RFP);
1534*37da2899SCharles.Forsyth mem(Ostw, O(REG,FP),RREG, RFP);
1535*37da2899SCharles.Forsyth FM3I(2, Ojmpl, 0, RA1, RZ); // goto lr(Rfp)
1536*37da2899SCharles.Forsyth NOOP;
1537*37da2899SCharles.Forsyth
1538*37da2899SCharles.Forsyth PATCH(cp6);
1539*37da2899SCharles.Forsyth FM3I(2, Ojmpl, 0, RA0, RLINK); // call destroy(t(fp))
1540*37da2899SCharles.Forsyth NOOP;
1541*37da2899SCharles.Forsyth mem(Ostw, O(REG,SP),RREG, RFP);
1542*37da2899SCharles.Forsyth mem(Oldw, O(Frame,lr),RFP, RA1);
1543*37da2899SCharles.Forsyth mem(Oldw, O(Frame,fp),RFP, RFP);
1544*37da2899SCharles.Forsyth mem(Ostw, O(REG,FP),RREG, RFP);
1545*37da2899SCharles.Forsyth mem(Oldw, O(REG,xpc),RREG, RA2);
1546*37da2899SCharles.Forsyth FM3I(2, Oadd, 0x8, RA2, RA2);
1547*37da2899SCharles.Forsyth FM3I(2, Ojmpl, 0, RA2, RZ); // return to uncompiled code
1548*37da2899SCharles.Forsyth mem(Ostw, O(REG,PC),RREG, RA1);
1549*37da2899SCharles.Forsyth
1550*37da2899SCharles.Forsyth PATCH(cp1);
1551*37da2899SCharles.Forsyth PATCH(cp2);
1552*37da2899SCharles.Forsyth PATCH(cp3);
1553*37da2899SCharles.Forsyth PATCH(cp5);
1554*37da2899SCharles.Forsyth i.add = AXNON;
1555*37da2899SCharles.Forsyth punt(&i, TCHECK|NEWPC, optab[IRET]);
1556*37da2899SCharles.Forsyth }
1557*37da2899SCharles.Forsyth
1558*37da2899SCharles.Forsyth static void
maccolr(void)1559*37da2899SCharles.Forsyth maccolr(void)
1560*37da2899SCharles.Forsyth {
1561*37da2899SCharles.Forsyth ulong *br;
1562*37da2899SCharles.Forsyth
1563*37da2899SCharles.Forsyth /* color the pointer in RA1 */
1564*37da2899SCharles.Forsyth FM3I(2, Oadd, 1, RA0, RA0);
1565*37da2899SCharles.Forsyth mem(Ostw, O(Heap, ref)-sizeof(Heap), RA1, RA0);
1566*37da2899SCharles.Forsyth mem(Oldw, O(Heap, color)-sizeof(Heap), RA1, RA0);
1567*37da2899SCharles.Forsyth mem(Oldw, 0, RA2, RA2);
1568*37da2899SCharles.Forsyth FM3(2, Ocmp, RA0, RA2, RZ);
1569*37da2899SCharles.Forsyth br = code;
1570*37da2899SCharles.Forsyth BRA(Obe, 0);
1571*37da2899SCharles.Forsyth con(propagator, RA2, 1);
1572*37da2899SCharles.Forsyth mem(Ostw, O(Heap, color)-sizeof(Heap), RA1, RA2);
1573*37da2899SCharles.Forsyth con((ulong)&nprop, RA2, 1);
1574*37da2899SCharles.Forsyth RETURN;
1575*37da2899SCharles.Forsyth mem(Ostw, 0, RA2, RA2);
1576*37da2899SCharles.Forsyth PATCH(br);
1577*37da2899SCharles.Forsyth RETURN;
1578*37da2899SCharles.Forsyth NOOP;
1579*37da2899SCharles.Forsyth }
1580*37da2899SCharles.Forsyth
1581*37da2899SCharles.Forsyth static void
macmcal(void)1582*37da2899SCharles.Forsyth macmcal(void)
1583*37da2899SCharles.Forsyth {
1584*37da2899SCharles.Forsyth ulong *lab1, *lab2;
1585*37da2899SCharles.Forsyth
1586*37da2899SCharles.Forsyth mem(Oldw, O(Modlink, prog), RA3, RA1);
1587*37da2899SCharles.Forsyth FM3I(2, Ocmp, 0, RA1, RZ);
1588*37da2899SCharles.Forsyth lab1 = code;
1589*37da2899SCharles.Forsyth BRA(Obne, 0);
1590*37da2899SCharles.Forsyth NOOP;
1591*37da2899SCharles.Forsyth
1592*37da2899SCharles.Forsyth mem(Ostw, O(REG, st), RREG, RLINK);
1593*37da2899SCharles.Forsyth mem(Ostw, O(REG, FP), RREG, RA2);
1594*37da2899SCharles.Forsyth CALL(rmcall); // CALL rmcall
1595*37da2899SCharles.Forsyth mem(Ostw, O(REG, dt), RREG, RA0);
1596*37da2899SCharles.Forsyth
1597*37da2899SCharles.Forsyth con((ulong)&R, RREG, 1); // MOVL $R, RREG
1598*37da2899SCharles.Forsyth mem(Oldw, O(REG, st), RREG, RLINK);
1599*37da2899SCharles.Forsyth mem(Oldw, O(REG, FP), RREG, RFP);
1600*37da2899SCharles.Forsyth mem(Oldw, O(REG, MP), RREG, RMP);
1601*37da2899SCharles.Forsyth RETURN;
1602*37da2899SCharles.Forsyth NOOP;
1603*37da2899SCharles.Forsyth
1604*37da2899SCharles.Forsyth PATCH(lab1); // patch:
1605*37da2899SCharles.Forsyth FM3(2, Oor, RA2, RZ, RFP);
1606*37da2899SCharles.Forsyth mem(Ostw, O(REG, M), RREG, RA3); // MOVL RA3, R.M
1607*37da2899SCharles.Forsyth mem(Oldw, O(Heap, ref)-sizeof(Heap), RA3, RA1);
1608*37da2899SCharles.Forsyth FM3I(2, Oadd, 1, RA1, RA1);
1609*37da2899SCharles.Forsyth mem(Ostw, O(Heap, ref)-sizeof(Heap), RA3, RA1);
1610*37da2899SCharles.Forsyth mem(Oldw, O(Modlink, compiled), RA3, RA1);
1611*37da2899SCharles.Forsyth mem(Oldw, O(Modlink, MP), RA3, RMP); // MOVL R.M->MP, RMP
1612*37da2899SCharles.Forsyth FM3I(2, Ocmp, 0, RA1, RZ);
1613*37da2899SCharles.Forsyth lab2 = code;
1614*37da2899SCharles.Forsyth BRA(Obe, 0);
1615*37da2899SCharles.Forsyth mem(Ostw, O(REG, MP), RREG, RMP); // MOVL RA3, R.MP R.MP = ml->MP
1616*37da2899SCharles.Forsyth
1617*37da2899SCharles.Forsyth FM3I(2, Ojmpl, 0, RA0, RZ);
1618*37da2899SCharles.Forsyth NOOP;
1619*37da2899SCharles.Forsyth
1620*37da2899SCharles.Forsyth PATCH(lab2);
1621*37da2899SCharles.Forsyth mem(Ostw, O(REG,FP),RREG, RFP);
1622*37da2899SCharles.Forsyth mem(Oldw, O(REG,xpc),RREG, RA1);
1623*37da2899SCharles.Forsyth FM3I(2, Oadd, 0x8, RA1, RA1);
1624*37da2899SCharles.Forsyth FM3I(2, Ojmpl, 0, RA1, RZ); // call to uncompiled code
1625*37da2899SCharles.Forsyth mem(Ostw, O(REG,PC),RREG, RA0);
1626*37da2899SCharles.Forsyth }
1627*37da2899SCharles.Forsyth
1628*37da2899SCharles.Forsyth static void
macfram(void)1629*37da2899SCharles.Forsyth macfram(void)
1630*37da2899SCharles.Forsyth {
1631*37da2899SCharles.Forsyth ulong *lab1;
1632*37da2899SCharles.Forsyth
1633*37da2899SCharles.Forsyth mem(Oldw, O(REG, SP), RREG, RA0); // MOVL R.SP, RA0
1634*37da2899SCharles.Forsyth mem(Oldw, O(Type, size), RA3, RA1);
1635*37da2899SCharles.Forsyth FM3(2, Oadd, RA0, RA1, RA0);
1636*37da2899SCharles.Forsyth mem(Oldw, O(REG, TS), RREG, RA1);
1637*37da2899SCharles.Forsyth FM3(2, Ocmp, RA1, RA0, RZ);
1638*37da2899SCharles.Forsyth lab1 = code;
1639*37da2899SCharles.Forsyth BRA(Obl, 0);
1640*37da2899SCharles.Forsyth NOOP;
1641*37da2899SCharles.Forsyth
1642*37da2899SCharles.Forsyth mem(Ostw, O(REG, s), RREG, RA3);
1643*37da2899SCharles.Forsyth mem(Ostw, O(REG, st), RREG, RLINK);
1644*37da2899SCharles.Forsyth CALL(extend); // CALL extend
1645*37da2899SCharles.Forsyth mem(Ostw, O(REG, FP), RREG, RFP); // MOVL RFP, R.FP
1646*37da2899SCharles.Forsyth
1647*37da2899SCharles.Forsyth con((ulong)&R, RREG, 1);
1648*37da2899SCharles.Forsyth mem(Oldw, O(REG, st), RREG, RLINK);
1649*37da2899SCharles.Forsyth mem(Oldw, O(REG, FP), RREG, RFP); // MOVL R.MP, RMP
1650*37da2899SCharles.Forsyth mem(Oldw, O(REG, s), RREG, RA2); // MOVL R.s, *R.d
1651*37da2899SCharles.Forsyth mem(Oldw, O(REG, MP), RREG, RMP); // MOVL R.MP, RMP
1652*37da2899SCharles.Forsyth RETURN; // RET
1653*37da2899SCharles.Forsyth NOOP;
1654*37da2899SCharles.Forsyth
1655*37da2899SCharles.Forsyth PATCH(lab1);
1656*37da2899SCharles.Forsyth mem(Oldw, O(REG, SP), RREG, RA2); // MOVL R.SP, RA2
1657*37da2899SCharles.Forsyth mem(Ostw, O(REG, SP), RREG, RA0); // MOVL RA0, R.SP
1658*37da2899SCharles.Forsyth
1659*37da2899SCharles.Forsyth mem(Ostw, O(Frame, t), RA2, RA3); // MOVL RA3, t(RA2) f->t = t
1660*37da2899SCharles.Forsyth mem(Oldw, O(Type, initialize), RA3, RA3);
1661*37da2899SCharles.Forsyth FM3I(2, Ojmpl, 0, RA3, RZ);
1662*37da2899SCharles.Forsyth mem(Ostw, REGMOD*4, RA2, RZ); // MOVL $0, mr(RA2) f->mr
1663*37da2899SCharles.Forsyth }
1664*37da2899SCharles.Forsyth
1665*37da2899SCharles.Forsyth static void
macmfra(void)1666*37da2899SCharles.Forsyth macmfra(void)
1667*37da2899SCharles.Forsyth {
1668*37da2899SCharles.Forsyth mem(Ostw, O(REG, st), RREG, RLINK);
1669*37da2899SCharles.Forsyth mem(Ostw, O(REG, s), RREG, RA3); // Save type
1670*37da2899SCharles.Forsyth mem(Ostw, O(REG, d), RREG, RA0); // Save destination
1671*37da2899SCharles.Forsyth CALL(rmfram); // CALL rmfram
1672*37da2899SCharles.Forsyth mem(Ostw, O(REG, FP), RREG, RFP);
1673*37da2899SCharles.Forsyth
1674*37da2899SCharles.Forsyth con((ulong)&R, RREG, 1);
1675*37da2899SCharles.Forsyth mem(Oldw, O(REG, st), RREG, RLINK);
1676*37da2899SCharles.Forsyth mem(Oldw, O(REG, FP), RREG, RFP);
1677*37da2899SCharles.Forsyth mem(Oldw, O(REG, MP), RREG, RMP);
1678*37da2899SCharles.Forsyth RETURN;
1679*37da2899SCharles.Forsyth NOOP;
1680*37da2899SCharles.Forsyth }
1681*37da2899SCharles.Forsyth
1682*37da2899SCharles.Forsyth void
comd(Type * t)1683*37da2899SCharles.Forsyth comd(Type *t)
1684*37da2899SCharles.Forsyth {
1685*37da2899SCharles.Forsyth int i, j, m, c;
1686*37da2899SCharles.Forsyth
1687*37da2899SCharles.Forsyth mem(Ostw, O(REG, dt), RREG, RLINK);
1688*37da2899SCharles.Forsyth for(i = 0; i < t->np; i++) {
1689*37da2899SCharles.Forsyth c = t->map[i];
1690*37da2899SCharles.Forsyth j = i<<5;
1691*37da2899SCharles.Forsyth for(m = 0x80; m != 0; m >>= 1) {
1692*37da2899SCharles.Forsyth if(c & m) {
1693*37da2899SCharles.Forsyth CALL(base+macro[MacFRP]);
1694*37da2899SCharles.Forsyth mem(Oldw, j, RFP, RA0);
1695*37da2899SCharles.Forsyth }
1696*37da2899SCharles.Forsyth j += sizeof(WORD*);
1697*37da2899SCharles.Forsyth }
1698*37da2899SCharles.Forsyth }
1699*37da2899SCharles.Forsyth mem(Oldw, O(REG, dt), RREG, RLINK);
1700*37da2899SCharles.Forsyth RETURN;
1701*37da2899SCharles.Forsyth NOOP;
1702*37da2899SCharles.Forsyth }
1703*37da2899SCharles.Forsyth
1704*37da2899SCharles.Forsyth void
comi(Type * t)1705*37da2899SCharles.Forsyth comi(Type *t)
1706*37da2899SCharles.Forsyth {
1707*37da2899SCharles.Forsyth int i, j, m, c;
1708*37da2899SCharles.Forsyth
1709*37da2899SCharles.Forsyth con((ulong)H, RA0, 1);
1710*37da2899SCharles.Forsyth for(i = 0; i < t->np; i++) {
1711*37da2899SCharles.Forsyth c = t->map[i];
1712*37da2899SCharles.Forsyth j = i<<5;
1713*37da2899SCharles.Forsyth for(m = 0x80; m != 0; m >>= 1) {
1714*37da2899SCharles.Forsyth if(c & m)
1715*37da2899SCharles.Forsyth mem(Ostw, j, RA2, RA0);
1716*37da2899SCharles.Forsyth j += sizeof(WORD*);
1717*37da2899SCharles.Forsyth }
1718*37da2899SCharles.Forsyth }
1719*37da2899SCharles.Forsyth RETURN;
1720*37da2899SCharles.Forsyth NOOP;
1721*37da2899SCharles.Forsyth }
1722*37da2899SCharles.Forsyth
1723*37da2899SCharles.Forsyth void
typecom(Type * t)1724*37da2899SCharles.Forsyth typecom(Type *t)
1725*37da2899SCharles.Forsyth {
1726*37da2899SCharles.Forsyth int n;
1727*37da2899SCharles.Forsyth ulong *tmp, *start;
1728*37da2899SCharles.Forsyth
1729*37da2899SCharles.Forsyth if(t == nil || t->initialize != 0)
1730*37da2899SCharles.Forsyth return;
1731*37da2899SCharles.Forsyth
1732*37da2899SCharles.Forsyth tmp = mallocz(4096*sizeof(ulong), 0);
1733*37da2899SCharles.Forsyth if(tmp == nil)
1734*37da2899SCharles.Forsyth error(exNomem);
1735*37da2899SCharles.Forsyth
1736*37da2899SCharles.Forsyth code = tmp;
1737*37da2899SCharles.Forsyth comi(t);
1738*37da2899SCharles.Forsyth n = code - tmp;
1739*37da2899SCharles.Forsyth code = tmp;
1740*37da2899SCharles.Forsyth comd(t);
1741*37da2899SCharles.Forsyth n += code - tmp;
1742*37da2899SCharles.Forsyth free(tmp);
1743*37da2899SCharles.Forsyth
1744*37da2899SCharles.Forsyth n *= sizeof(*code);
1745*37da2899SCharles.Forsyth code = mallocz(n, 0);
1746*37da2899SCharles.Forsyth if(code == nil)
1747*37da2899SCharles.Forsyth return;
1748*37da2899SCharles.Forsyth
1749*37da2899SCharles.Forsyth start = code;
1750*37da2899SCharles.Forsyth t->initialize = code;
1751*37da2899SCharles.Forsyth comi(t);
1752*37da2899SCharles.Forsyth t->destroy = code;
1753*37da2899SCharles.Forsyth comd(t);
1754*37da2899SCharles.Forsyth
1755*37da2899SCharles.Forsyth segflush(start, n);
1756*37da2899SCharles.Forsyth
1757*37da2899SCharles.Forsyth if(cflag > 1)
1758*37da2899SCharles.Forsyth print("typ= %.8p %4d i %.8p d %.8p asm=%d\n",
1759*37da2899SCharles.Forsyth t, t->size, t->initialize, t->destroy, n);
1760*37da2899SCharles.Forsyth }
1761*37da2899SCharles.Forsyth
1762*37da2899SCharles.Forsyth static void
patchex(Module * m,ulong * p)1763*37da2899SCharles.Forsyth patchex(Module *m, ulong *p)
1764*37da2899SCharles.Forsyth {
1765*37da2899SCharles.Forsyth Handler *h;
1766*37da2899SCharles.Forsyth Except *e;
1767*37da2899SCharles.Forsyth
1768*37da2899SCharles.Forsyth if((h = m->htab) == nil)
1769*37da2899SCharles.Forsyth return;
1770*37da2899SCharles.Forsyth for( ; h->etab != nil; h++){
1771*37da2899SCharles.Forsyth h->pc1 = p[h->pc1];
1772*37da2899SCharles.Forsyth h->pc2 = p[h->pc2];
1773*37da2899SCharles.Forsyth for(e = h->etab; e->s != nil; e++)
1774*37da2899SCharles.Forsyth e->pc = p[e->pc];
1775*37da2899SCharles.Forsyth if(e->pc != -1)
1776*37da2899SCharles.Forsyth e->pc = p[e->pc];
1777*37da2899SCharles.Forsyth }
1778*37da2899SCharles.Forsyth }
1779*37da2899SCharles.Forsyth
1780*37da2899SCharles.Forsyth int
compile(Module * m,int size,Modlink * ml)1781*37da2899SCharles.Forsyth compile(Module *m, int size, Modlink *ml)
1782*37da2899SCharles.Forsyth {
1783*37da2899SCharles.Forsyth Link *l;
1784*37da2899SCharles.Forsyth Modl *e;
1785*37da2899SCharles.Forsyth int i, n;
1786*37da2899SCharles.Forsyth ulong *s, *tmp;
1787*37da2899SCharles.Forsyth
1788*37da2899SCharles.Forsyth base = nil;
1789*37da2899SCharles.Forsyth patch = mallocz(size*sizeof(*patch), 0);
1790*37da2899SCharles.Forsyth tinit = malloc(m->ntype*sizeof(*tinit));
1791*37da2899SCharles.Forsyth tmp = mallocz(1024*sizeof(ulong), 0);
1792*37da2899SCharles.Forsyth if(tinit == nil || patch == nil || tmp == nil)
1793*37da2899SCharles.Forsyth goto bad;
1794*37da2899SCharles.Forsyth
1795*37da2899SCharles.Forsyth preamble();
1796*37da2899SCharles.Forsyth
1797*37da2899SCharles.Forsyth mod = m;
1798*37da2899SCharles.Forsyth n = 0;
1799*37da2899SCharles.Forsyth pass = 0;
1800*37da2899SCharles.Forsyth nlit = 0;
1801*37da2899SCharles.Forsyth
1802*37da2899SCharles.Forsyth for(i = 0; i < size; i++) {
1803*37da2899SCharles.Forsyth code = tmp;
1804*37da2899SCharles.Forsyth comp(&m->prog[i]);
1805*37da2899SCharles.Forsyth patch[i] = n;
1806*37da2899SCharles.Forsyth n += code - tmp;
1807*37da2899SCharles.Forsyth }
1808*37da2899SCharles.Forsyth
1809*37da2899SCharles.Forsyth for(i = 0; i < nelem(mactab); i++) {
1810*37da2899SCharles.Forsyth code = tmp;
1811*37da2899SCharles.Forsyth mactab[i].gen();
1812*37da2899SCharles.Forsyth macro[mactab[i].idx] = n;
1813*37da2899SCharles.Forsyth n += code - tmp;
1814*37da2899SCharles.Forsyth }
1815*37da2899SCharles.Forsyth
1816*37da2899SCharles.Forsyth base = mallocz((n+nlit)*sizeof(*code), 0);
1817*37da2899SCharles.Forsyth if(base == nil)
1818*37da2899SCharles.Forsyth goto bad;
1819*37da2899SCharles.Forsyth
1820*37da2899SCharles.Forsyth if(cflag > 1)
1821*37da2899SCharles.Forsyth print("dis=%5d %5d sparc=%5d asm=%.8p lit=%d: %s\n",
1822*37da2899SCharles.Forsyth size, size*sizeof(Inst), n, base, nlit, m->name);
1823*37da2899SCharles.Forsyth
1824*37da2899SCharles.Forsyth pass++;
1825*37da2899SCharles.Forsyth nlit = 0;
1826*37da2899SCharles.Forsyth litpool = base+n;
1827*37da2899SCharles.Forsyth code = base;
1828*37da2899SCharles.Forsyth
1829*37da2899SCharles.Forsyth for(i = 0; i < size; i++) {
1830*37da2899SCharles.Forsyth s = code;
1831*37da2899SCharles.Forsyth comp(&m->prog[i]);
1832*37da2899SCharles.Forsyth if(cflag > 2) {
1833*37da2899SCharles.Forsyth print("%d %D\n", i, &m->prog[i]);
1834*37da2899SCharles.Forsyth das(s, code-s);
1835*37da2899SCharles.Forsyth }
1836*37da2899SCharles.Forsyth }
1837*37da2899SCharles.Forsyth
1838*37da2899SCharles.Forsyth for(i = 0; i < nelem(mactab); i++) {
1839*37da2899SCharles.Forsyth s = code;
1840*37da2899SCharles.Forsyth mactab[i].gen();
1841*37da2899SCharles.Forsyth if(cflag > 2) {
1842*37da2899SCharles.Forsyth print("%s:\n", mactab[i].name);
1843*37da2899SCharles.Forsyth das(s, code-s);
1844*37da2899SCharles.Forsyth }
1845*37da2899SCharles.Forsyth }
1846*37da2899SCharles.Forsyth
1847*37da2899SCharles.Forsyth if(n != (code - base))
1848*37da2899SCharles.Forsyth error(exCphase);
1849*37da2899SCharles.Forsyth
1850*37da2899SCharles.Forsyth for(l = m->ext; l->name; l++) {
1851*37da2899SCharles.Forsyth l->u.pc = (Inst*)RELPC(patch[l->u.pc-m->prog]);
1852*37da2899SCharles.Forsyth typecom(l->frame);
1853*37da2899SCharles.Forsyth }
1854*37da2899SCharles.Forsyth if(ml != nil) {
1855*37da2899SCharles.Forsyth e = &ml->links[0];
1856*37da2899SCharles.Forsyth for(i = 0; i < ml->nlinks; i++) {
1857*37da2899SCharles.Forsyth e->u.pc = (Inst*)RELPC(patch[e->u.pc-m->prog]);
1858*37da2899SCharles.Forsyth typecom(e->frame);
1859*37da2899SCharles.Forsyth e++;
1860*37da2899SCharles.Forsyth }
1861*37da2899SCharles.Forsyth }
1862*37da2899SCharles.Forsyth for(i = 0; i < m->ntype; i++) {
1863*37da2899SCharles.Forsyth if(tinit[i] != 0)
1864*37da2899SCharles.Forsyth typecom(m->type[i]);
1865*37da2899SCharles.Forsyth }
1866*37da2899SCharles.Forsyth patchex(m, patch);
1867*37da2899SCharles.Forsyth m->entry = (Inst*)RELPC(patch[mod->entry-mod->prog]);
1868*37da2899SCharles.Forsyth free(patch);
1869*37da2899SCharles.Forsyth free(tinit);
1870*37da2899SCharles.Forsyth free(tmp);
1871*37da2899SCharles.Forsyth free(m->prog);
1872*37da2899SCharles.Forsyth m->prog = (Inst*)base;
1873*37da2899SCharles.Forsyth m->compiled = 1;
1874*37da2899SCharles.Forsyth segflush(base, n*sizeof(*base));
1875*37da2899SCharles.Forsyth return 1;
1876*37da2899SCharles.Forsyth bad:
1877*37da2899SCharles.Forsyth free(patch);
1878*37da2899SCharles.Forsyth free(tinit);
1879*37da2899SCharles.Forsyth free(tmp);
1880*37da2899SCharles.Forsyth free(base);
1881*37da2899SCharles.Forsyth return 0;
1882*37da2899SCharles.Forsyth }
1883