xref: /inferno-os/libinterp/comp-mips.c (revision 4eb166cf184c1f102fb79e31b1465ea3e2021c39)
137da2899SCharles.Forsyth #include "lib9.h"
237da2899SCharles.Forsyth #include "isa.h"
337da2899SCharles.Forsyth #include "interp.h"
437da2899SCharles.Forsyth #include "raise.h"
537da2899SCharles.Forsyth 
637da2899SCharles.Forsyth #define T(r)	*((void**)(R.r))
737da2899SCharles.Forsyth 
837da2899SCharles.Forsyth #define	SRR(op,c,r1,r2)		gen((op)|((c)<<6)|((r1)<<16)|((r2)<<11))
937da2899SCharles.Forsyth #define	RRR(op,r1,r2,r3)	gen((op)|((r1)<<16)|((r2)<<21)|((r3)<<11))
1037da2899SCharles.Forsyth #define	FRRR(op,r1,r2,r3)	gen((op)|((r1)<<16)|((r2)<<11)|((r3)<<6))
1137da2899SCharles.Forsyth #define	FI(op,c)		gen((op)|((c)&0xffff))
1237da2899SCharles.Forsyth #define	IRR(op,c,r1,r2)		gen((op)|((c)&0xffff)|((r1)<<21)|((r2)<<16))
1337da2899SCharles.Forsyth #define	BRRI(op,r1,r2,c)	gen((op)|((r1)<<21)|((r2)<<16)|((c)&0xffff))
1437da2899SCharles.Forsyth #define	BRI(op,r,c)		gen((op)|((r)<<21)|((c)&0xffff))
1537da2899SCharles.Forsyth #define	JR(op,r)		gen((op)|((r)<<21))
1637da2899SCharles.Forsyth #define	J(op,c)			gen((op)|(((ulong)(c)>>2)&0x3FFFFFFUL))
1737da2899SCharles.Forsyth 
18*4eb166cfSCharles.Forsyth #ifndef HIOFFSET
19*4eb166cfSCharles.Forsyth #define	HIOFFSET	0	/* big endian */
20*4eb166cfSCharles.Forsyth #endif
21*4eb166cfSCharles.Forsyth 
2237da2899SCharles.Forsyth enum
2337da2899SCharles.Forsyth {
2437da2899SCharles.Forsyth 	Rzero	= 0,
2537da2899SCharles.Forsyth 
2637da2899SCharles.Forsyth 	Ro1	= 8,
2737da2899SCharles.Forsyth 	Ro2	= 9,
2837da2899SCharles.Forsyth 	Ro3	= 10,
2937da2899SCharles.Forsyth 	Ri	= 11,
3037da2899SCharles.Forsyth 	Rj	= 12,
3137da2899SCharles.Forsyth 
3237da2899SCharles.Forsyth 	Rmp	= 13,
3337da2899SCharles.Forsyth 	Rfp	= 14,
3437da2899SCharles.Forsyth 	Rreg	= 15,
3537da2899SCharles.Forsyth 
3637da2899SCharles.Forsyth 	Rpic	= 25,
3737da2899SCharles.Forsyth 	Rlink	= 31,
3837da2899SCharles.Forsyth 
3937da2899SCharles.Forsyth 	Rf1	= 4,
4037da2899SCharles.Forsyth 	Rf2	= 6,
4137da2899SCharles.Forsyth 
4237da2899SCharles.Forsyth 	Olw	= 0x23<<26,
4337da2899SCharles.Forsyth 	Olbu	= 0x24<<26,
4437da2899SCharles.Forsyth 	Olhu	= 0x25<<26,
4537da2899SCharles.Forsyth 	Osw	= 0x2b<<26,
4637da2899SCharles.Forsyth 	Osb	= 0x28<<26,
4737da2899SCharles.Forsyth 	Oaddui	= 0x09<<26,
4837da2899SCharles.Forsyth 	Olui	= 0x0f<<26,
4937da2899SCharles.Forsyth 	Oori	= 0x0d<<26,
5037da2899SCharles.Forsyth 	Odiv	= (0x00<<26) | 0x1a,
5137da2899SCharles.Forsyth 	Omul	= (0x00<<26) | 0x18,
5237da2899SCharles.Forsyth 	Omfhi	= (0x00<<26) | 0x10,
5337da2899SCharles.Forsyth 	Omflo	= (0x00<<26) | 0x12,
5437da2899SCharles.Forsyth 	Osubu	= (0x00<<26) | 0x23,
5537da2899SCharles.Forsyth 	Oaddu	= (0x00<<26) | 0x21,
5637da2899SCharles.Forsyth 	Oand	= (0x00<<26) | 0x24,
5737da2899SCharles.Forsyth 	Oor	= (0x00<<26) | 0x25,
5837da2899SCharles.Forsyth 	Oxor	= (0x00<<26) | 0x26,
5937da2899SCharles.Forsyth 	Odelay	= (0x00<<26) | 0x27,
6037da2899SCharles.Forsyth 	Osll	= (0x00<<26) | 0x00,
6137da2899SCharles.Forsyth 	Osrl	= (0x00<<26) | 0x02,
6237da2899SCharles.Forsyth 	Osra	= (0x00<<26) | 0x03,
6337da2899SCharles.Forsyth 	Osllv	= (0x00<<26) | 0x04,
6437da2899SCharles.Forsyth 	Osrlv	= (0x00<<26) | 0x06,
6537da2899SCharles.Forsyth 	Osrav	= (0x00<<26) | 0x07,
6637da2899SCharles.Forsyth 	Oslt	= (0x00<<26) | 0x2a,
6737da2899SCharles.Forsyth 	Osltu	= (0x00<<26) | 0x2b,
6837da2899SCharles.Forsyth 	Obeq	= 0x04<<26,
6937da2899SCharles.Forsyth 	Obne	= 0x05<<26,
7037da2899SCharles.Forsyth 	Obltz	= (0x01<<26) | (0x0<<16),
7137da2899SCharles.Forsyth 	Obgtz	= (0x07<<26) | (0x0<<16),
7237da2899SCharles.Forsyth 	Oblez	= (0x06<<26) | (0x0<<16),
7337da2899SCharles.Forsyth 	Obgez	= (0x01<<26) | (0x1<<16),
7437da2899SCharles.Forsyth 	Ojr	= (0x00<<26) | 0x08,
7537da2899SCharles.Forsyth 	Ojalr	= (0x00<<26) | 0x09 | (Rlink<<11),
7637da2899SCharles.Forsyth 	Oj	= (0x02<<26),
7737da2899SCharles.Forsyth 	Ojal	= (0x03<<26),
7837da2899SCharles.Forsyth 	Olea	= Oaddui,		// pseudo op
7937da2899SCharles.Forsyth 
8037da2899SCharles.Forsyth 	Olf	= 0x31<<26,
8137da2899SCharles.Forsyth 	Osf	= 0x39<<26,
8237da2899SCharles.Forsyth 	Oaddf	= (0x11<<26) | (17<<21) | 0,
8337da2899SCharles.Forsyth 	Osubf	= (0x11<<26) | (17<<21) | 1,
8437da2899SCharles.Forsyth 	Omulf	= (0x11<<26) | (17<<21) | 2,
8537da2899SCharles.Forsyth 	Odivf	= (0x11<<26) | (17<<21) | 3,
8637da2899SCharles.Forsyth 	Onegf	= (0x11<<26) | (17<<21) | 7,
8737da2899SCharles.Forsyth 
8837da2899SCharles.Forsyth 	Ocvtwf	= (0x11<<26) | (20<<21) | 33,
8937da2899SCharles.Forsyth 	Ocvtfw	= (0x11<<26) | (17<<21) | 36,
9037da2899SCharles.Forsyth 
9137da2899SCharles.Forsyth 	Ofeq	= (0x11<<26) | (17<<21) | (3<<4) | 2,
9237da2899SCharles.Forsyth 	Oflt	= (0x11<<26) | (17<<21) | (3<<4) | 12,
9337da2899SCharles.Forsyth 
9437da2899SCharles.Forsyth 	Obrf	= (0x11<<26) | (0x100<<16),
9537da2899SCharles.Forsyth 	Obrt	= (0x11<<26) | (0x101<<16),
9637da2899SCharles.Forsyth 
9737da2899SCharles.Forsyth 	SRCOP	= (1<<0),
9837da2899SCharles.Forsyth 	DSTOP	= (1<<1),
9937da2899SCharles.Forsyth 	WRTPC	= (1<<2),
10037da2899SCharles.Forsyth 	TCHECK	= (1<<3),
10137da2899SCharles.Forsyth 	NEWPC	= (1<<4),
10237da2899SCharles.Forsyth 	DBRAN	= (1<<5),
10337da2899SCharles.Forsyth 	THREOP	= (1<<6),
10437da2899SCharles.Forsyth 
10537da2899SCharles.Forsyth 	ANDAND	= 1,
10637da2899SCharles.Forsyth 	OROR,
10737da2899SCharles.Forsyth 	EQAND,
10837da2899SCharles.Forsyth 
10937da2899SCharles.Forsyth 	XOR,
11037da2899SCharles.Forsyth 	IOR,
11137da2899SCharles.Forsyth 	AND,
11237da2899SCharles.Forsyth 	ADD,
11337da2899SCharles.Forsyth 	SUB,
11437da2899SCharles.Forsyth 
11537da2899SCharles.Forsyth 	OMASK	= (1<<4) - 1,
11637da2899SCharles.Forsyth 	REV1	= 1<<4,
11737da2899SCharles.Forsyth 	REV2	= 1<<5,
11837da2899SCharles.Forsyth 
119*4eb166cfSCharles.Forsyth 	Bhi		= HIOFFSET,
120*4eb166cfSCharles.Forsyth 	Blo		= Bhi ^ 4,
121*4eb166cfSCharles.Forsyth 
12237da2899SCharles.Forsyth 	MacRET	= 0,
12337da2899SCharles.Forsyth 	MacFRP,
12437da2899SCharles.Forsyth 	MacINDX,
12537da2899SCharles.Forsyth 	MacCASE,
12637da2899SCharles.Forsyth 	MacLENA,
12737da2899SCharles.Forsyth 	MacFRAM,
12837da2899SCharles.Forsyth 	MacMOVM,
12937da2899SCharles.Forsyth 	MacCOLR,
13037da2899SCharles.Forsyth 	MacMCAL,
13137da2899SCharles.Forsyth 	MacMFRA,
13237da2899SCharles.Forsyth 	MacEND,
13337da2899SCharles.Forsyth 	NMACRO
13437da2899SCharles.Forsyth };
13537da2899SCharles.Forsyth 
13637da2899SCharles.Forsyth extern	char	Tmodule[];
13737da2899SCharles.Forsyth 	void	(*comvec)(void);
13837da2899SCharles.Forsyth extern	void	das(ulong*);
13937da2899SCharles.Forsyth static	ulong*	code;
14037da2899SCharles.Forsyth static	ulong*	base;
14137da2899SCharles.Forsyth static	ulong*	patch;
14237da2899SCharles.Forsyth static	int	pass;
14337da2899SCharles.Forsyth static	int	regdelay;
14437da2899SCharles.Forsyth static	Module*	mod;
14537da2899SCharles.Forsyth static	ulong*	tinit;
14637da2899SCharles.Forsyth static	ulong*	litpool;
14737da2899SCharles.Forsyth static	int	nlit;
14837da2899SCharles.Forsyth static	ulong	macro[NMACRO];
14937da2899SCharles.Forsyth static	void	rdestroy(void);
15037da2899SCharles.Forsyth static	void	macret(void);
15137da2899SCharles.Forsyth static	void	macfrp(void);
15237da2899SCharles.Forsyth static	void	macindx(void);
15337da2899SCharles.Forsyth static	void	maccase(void);
15437da2899SCharles.Forsyth static	void	maclena(void);
15537da2899SCharles.Forsyth static	void	macfram(void);
15637da2899SCharles.Forsyth static	void	macmovm(void);
15737da2899SCharles.Forsyth static	void	maccvtfw(void);
15837da2899SCharles.Forsyth static	void	maccolr(void);
15937da2899SCharles.Forsyth static	void	macend(void);
16037da2899SCharles.Forsyth static	void	macmcal(void);
16137da2899SCharles.Forsyth static	void	macmfra(void);
16237da2899SCharles.Forsyth 
16337da2899SCharles.Forsyth struct
16437da2899SCharles.Forsyth {
16537da2899SCharles.Forsyth 	int	o;
16637da2899SCharles.Forsyth 	void	(*f)(void);
16737da2899SCharles.Forsyth } macinit[] =
16837da2899SCharles.Forsyth {
16937da2899SCharles.Forsyth 	MacFRP,		macfrp,		/* decrement and free pointer */
17037da2899SCharles.Forsyth 	MacRET,		macret,		/* return instruction */
17137da2899SCharles.Forsyth 	MacCASE,	maccase,	/* case instruction */
17237da2899SCharles.Forsyth 	MacCOLR,	maccolr,	/* increment and color pointer */
17337da2899SCharles.Forsyth 	MacFRAM,	macfram,	/* frame instruction */
17437da2899SCharles.Forsyth 	MacMCAL,	macmcal,	/* mcall bottom half */
17537da2899SCharles.Forsyth 	MacMFRA,	macmfra,	/* punt mframe because t->initialize==0 */
17637da2899SCharles.Forsyth 	MacMOVM,	macmovm,
17737da2899SCharles.Forsyth 	MacLENA,	maclena,
17837da2899SCharles.Forsyth 	MacINDX,	macindx,
17937da2899SCharles.Forsyth 	MacEND,		macend,
18037da2899SCharles.Forsyth 	0
18137da2899SCharles.Forsyth };
18237da2899SCharles.Forsyth 
18337da2899SCharles.Forsyth static void
rdestroy(void)18437da2899SCharles.Forsyth rdestroy(void)
18537da2899SCharles.Forsyth {
18637da2899SCharles.Forsyth 	destroy(R.s);
18737da2899SCharles.Forsyth }
18837da2899SCharles.Forsyth 
18937da2899SCharles.Forsyth static void
rmcall(void)19037da2899SCharles.Forsyth rmcall(void)
19137da2899SCharles.Forsyth {
19237da2899SCharles.Forsyth 	Prog *p;
19337da2899SCharles.Forsyth 	Frame *f;
19437da2899SCharles.Forsyth 
19537da2899SCharles.Forsyth 	f = (Frame*)R.FP;
19637da2899SCharles.Forsyth 	if(f == H)
19737da2899SCharles.Forsyth 		error(exModule);
19837da2899SCharles.Forsyth 
19937da2899SCharles.Forsyth 	f->mr = nil;
20037da2899SCharles.Forsyth 	((void(*)(Frame*))R.dt)(f);
20137da2899SCharles.Forsyth 	R.SP = (uchar*)f;
20237da2899SCharles.Forsyth 	R.FP = f->fp;
20337da2899SCharles.Forsyth 	if(f->t == nil)
20437da2899SCharles.Forsyth 		unextend(f);
20537da2899SCharles.Forsyth 	else
20637da2899SCharles.Forsyth 		freeptrs(f, f->t);
20737da2899SCharles.Forsyth 	p = currun();
20837da2899SCharles.Forsyth 	if(p->kill != nil)
20937da2899SCharles.Forsyth 		error(p->kill);
21037da2899SCharles.Forsyth }
21137da2899SCharles.Forsyth 
21237da2899SCharles.Forsyth static void
rmfram(void)21337da2899SCharles.Forsyth rmfram(void)
21437da2899SCharles.Forsyth {
21537da2899SCharles.Forsyth 	Type *t;
21637da2899SCharles.Forsyth 	Frame *f;
21737da2899SCharles.Forsyth 	uchar *nsp;
21837da2899SCharles.Forsyth 
21937da2899SCharles.Forsyth 	t = (Type*)R.s;
22037da2899SCharles.Forsyth 	nsp = R.SP + t->size;
22137da2899SCharles.Forsyth 	if(nsp >= R.TS) {
22237da2899SCharles.Forsyth 		R.s = t;
22337da2899SCharles.Forsyth 		extend();
22437da2899SCharles.Forsyth 		T(d) = R.s;
22537da2899SCharles.Forsyth 		return;
22637da2899SCharles.Forsyth 	}
22737da2899SCharles.Forsyth 	f = (Frame*)R.SP;
22837da2899SCharles.Forsyth 	R.SP = nsp;
22937da2899SCharles.Forsyth 	f->t = t;
23037da2899SCharles.Forsyth 	f->mr = nil;
23137da2899SCharles.Forsyth 	initmem(t, f);
23237da2899SCharles.Forsyth 	T(d) = f;
23337da2899SCharles.Forsyth }
23437da2899SCharles.Forsyth 
23537da2899SCharles.Forsyth void
urk(char * s)23637da2899SCharles.Forsyth urk(char *s)
23737da2899SCharles.Forsyth {
23837da2899SCharles.Forsyth 	print("urk: %s\n", s);
23937da2899SCharles.Forsyth 	exits(0);
24037da2899SCharles.Forsyth }
24137da2899SCharles.Forsyth 
24237da2899SCharles.Forsyth void
gen(ulong o)24337da2899SCharles.Forsyth gen(ulong o)
24437da2899SCharles.Forsyth {
24537da2899SCharles.Forsyth 	*code++ = o;
24637da2899SCharles.Forsyth }
24737da2899SCharles.Forsyth 
24837da2899SCharles.Forsyth void
delay(void)24937da2899SCharles.Forsyth delay(void)
25037da2899SCharles.Forsyth {
25137da2899SCharles.Forsyth 	gen(Odelay);
25237da2899SCharles.Forsyth }
25337da2899SCharles.Forsyth 
25437da2899SCharles.Forsyth int
bigc(long c)25537da2899SCharles.Forsyth bigc(long c)
25637da2899SCharles.Forsyth {
25737da2899SCharles.Forsyth 	c >>= 15;
25837da2899SCharles.Forsyth 	if(c == 0 || c == -1)
25937da2899SCharles.Forsyth 		return 0;
26037da2899SCharles.Forsyth 	return 1;
26137da2899SCharles.Forsyth }
26237da2899SCharles.Forsyth 
26337da2899SCharles.Forsyth void
ldbigc(ulong c,int reg)26437da2899SCharles.Forsyth ldbigc(ulong c, int reg)
26537da2899SCharles.Forsyth {
26637da2899SCharles.Forsyth 	IRR(Olui, c>>16,Rzero,reg);
26737da2899SCharles.Forsyth 	IRR(Oori, c,reg,reg);
26837da2899SCharles.Forsyth }
26937da2899SCharles.Forsyth 
27037da2899SCharles.Forsyth void
ldc(ulong c,int reg)27137da2899SCharles.Forsyth ldc(ulong c, int reg)
27237da2899SCharles.Forsyth {
27337da2899SCharles.Forsyth 
27437da2899SCharles.Forsyth 	if(bigc(c))
27537da2899SCharles.Forsyth 		ldbigc(c, reg);
27637da2899SCharles.Forsyth 	else
27737da2899SCharles.Forsyth 		IRR(Oaddui, c,Rzero, reg);
27837da2899SCharles.Forsyth }
27937da2899SCharles.Forsyth 
28037da2899SCharles.Forsyth void
xchg(void)28137da2899SCharles.Forsyth xchg(void)
28237da2899SCharles.Forsyth {
28337da2899SCharles.Forsyth 	ulong t;
28437da2899SCharles.Forsyth 
28537da2899SCharles.Forsyth 	t = code[-1];
28637da2899SCharles.Forsyth 	code[-1] = code[-2];
28737da2899SCharles.Forsyth 	code[-2] = t;
28837da2899SCharles.Forsyth }
28937da2899SCharles.Forsyth 
29037da2899SCharles.Forsyth void
opx(int mode,Adr * a,int op,int reg,int del)29137da2899SCharles.Forsyth opx(int mode, Adr *a, int op, int reg, int del)
29237da2899SCharles.Forsyth {
29337da2899SCharles.Forsyth 	ulong c;
29437da2899SCharles.Forsyth 	int r, rx;
29537da2899SCharles.Forsyth 
29637da2899SCharles.Forsyth 	switch(mode) {
29737da2899SCharles.Forsyth 	case AFP:
29837da2899SCharles.Forsyth 		c = a->ind;
29937da2899SCharles.Forsyth 		if(bigc(c))
30037da2899SCharles.Forsyth 			urk("bigc op1b 1");
30137da2899SCharles.Forsyth 		if(regdelay == Rfp)
30237da2899SCharles.Forsyth 			delay();
30337da2899SCharles.Forsyth 		IRR(op, c,Rfp, reg);
30437da2899SCharles.Forsyth 		break;
30537da2899SCharles.Forsyth 	case AMP:
30637da2899SCharles.Forsyth 		c = a->ind;
30737da2899SCharles.Forsyth 		if(bigc(c))
30837da2899SCharles.Forsyth 			urk("bigc op1b 2");
30937da2899SCharles.Forsyth 		if(regdelay == Rmp)
31037da2899SCharles.Forsyth 			delay();
31137da2899SCharles.Forsyth 		IRR(op, c,Rmp, reg);
31237da2899SCharles.Forsyth 		break;
31337da2899SCharles.Forsyth 	case AIMM:
31437da2899SCharles.Forsyth 		if(op == Olea) {
31537da2899SCharles.Forsyth 			if(a->imm != 0) {
31637da2899SCharles.Forsyth 				ldc(a->imm, reg);
31737da2899SCharles.Forsyth 				IRR(Osw, O(REG,st),Rreg, reg);
31837da2899SCharles.Forsyth 			} else
31937da2899SCharles.Forsyth 				IRR(Osw, O(REG,st),Rreg, Rzero);
32037da2899SCharles.Forsyth 			IRR(Oaddui, O(REG,st),Rreg, reg);
32137da2899SCharles.Forsyth 		} else
32237da2899SCharles.Forsyth 			ldc(a->imm, reg);
32337da2899SCharles.Forsyth 		return;
32437da2899SCharles.Forsyth 	case AIND|AFP:
32537da2899SCharles.Forsyth 		r = Rfp;
32637da2899SCharles.Forsyth 		goto offset;
32737da2899SCharles.Forsyth 	case AIND|AMP:
32837da2899SCharles.Forsyth 		r = Rmp;
32937da2899SCharles.Forsyth 	offset:
33037da2899SCharles.Forsyth 		if(regdelay == r)
33137da2899SCharles.Forsyth 			delay();
33237da2899SCharles.Forsyth 		c = a->i.s;
33337da2899SCharles.Forsyth 		rx = Ri;
33437da2899SCharles.Forsyth 		if(op == Olea || op == Olw)
33537da2899SCharles.Forsyth 			rx = reg;
33637da2899SCharles.Forsyth 		IRR(Olw, a->i.f,r, rx);
33737da2899SCharles.Forsyth 		if(c != 0 || op != Oaddui) {
33837da2899SCharles.Forsyth 			delay();
33937da2899SCharles.Forsyth 			IRR(op, c,rx, reg);
34037da2899SCharles.Forsyth 		}
34137da2899SCharles.Forsyth 		break;
34237da2899SCharles.Forsyth 	}
34337da2899SCharles.Forsyth 	if(op != Olea && del)
34437da2899SCharles.Forsyth 		delay();
34537da2899SCharles.Forsyth 	regdelay = 0;
34637da2899SCharles.Forsyth }
34737da2899SCharles.Forsyth 
34837da2899SCharles.Forsyth void
op1(Inst * i,int op,int reg,int del)34937da2899SCharles.Forsyth op1(Inst *i, int op, int reg, int del)
35037da2899SCharles.Forsyth {
35137da2899SCharles.Forsyth 	opx(USRC(i->add), &i->s, op, reg, del);
35237da2899SCharles.Forsyth }
35337da2899SCharles.Forsyth 
35437da2899SCharles.Forsyth void
op3(Inst * i,int op,int reg,int del)35537da2899SCharles.Forsyth op3(Inst *i, int op, int reg, int del)
35637da2899SCharles.Forsyth {
35737da2899SCharles.Forsyth 	opx(UDST(i->add), &i->d, op, reg, del);
35837da2899SCharles.Forsyth }
35937da2899SCharles.Forsyth 
36037da2899SCharles.Forsyth void
op2(Inst * i,int op,int reg,int del)36137da2899SCharles.Forsyth op2(Inst *i, int op, int reg, int del)
36237da2899SCharles.Forsyth {
36337da2899SCharles.Forsyth 	switch(i->add & ARM) {
36437da2899SCharles.Forsyth 	case AXNON:
36537da2899SCharles.Forsyth 		op3(i, op, reg, del);
36637da2899SCharles.Forsyth 		return;
36737da2899SCharles.Forsyth 	case AXIMM:
36837da2899SCharles.Forsyth 		if(op == Olea) {
36937da2899SCharles.Forsyth 			if((short)i->reg != 0) {
37037da2899SCharles.Forsyth 				ldc((short)i->reg, reg);
37137da2899SCharles.Forsyth 				IRR(Osw, O(REG,t),Rreg, reg);
37237da2899SCharles.Forsyth 			} else
37337da2899SCharles.Forsyth 				IRR(Osw, O(REG,t),Rreg, Rzero);
37437da2899SCharles.Forsyth 			IRR(Oaddui, O(REG,t),Rreg, reg);
37537da2899SCharles.Forsyth 		} else
37637da2899SCharles.Forsyth 			ldc((short)i->reg, reg);
37737da2899SCharles.Forsyth 		return;
37837da2899SCharles.Forsyth 	case AXINF:
37937da2899SCharles.Forsyth 		IRR(op, i->reg,Rfp, reg);
38037da2899SCharles.Forsyth 		break;
38137da2899SCharles.Forsyth 	case AXINM:
38237da2899SCharles.Forsyth 		IRR(op, i->reg,Rmp, reg);
38337da2899SCharles.Forsyth 		break;
38437da2899SCharles.Forsyth 	}
38537da2899SCharles.Forsyth 	if(op != Olea && del)
38637da2899SCharles.Forsyth 		delay();
38737da2899SCharles.Forsyth }
38837da2899SCharles.Forsyth 
38937da2899SCharles.Forsyth ulong
branch(Inst * i)39037da2899SCharles.Forsyth branch(Inst *i)
39137da2899SCharles.Forsyth {
39237da2899SCharles.Forsyth 	ulong rel;
39337da2899SCharles.Forsyth 
39437da2899SCharles.Forsyth 	if(base == 0)
39537da2899SCharles.Forsyth 		return 0;
39637da2899SCharles.Forsyth 	rel = patch[(Inst*)i->d.imm - mod->prog];
39737da2899SCharles.Forsyth 	rel += (base - code) - 1;
39837da2899SCharles.Forsyth 	return rel & 0xffff;
39937da2899SCharles.Forsyth }
40037da2899SCharles.Forsyth 
40137da2899SCharles.Forsyth static void
literal(ulong imm,int roff)40237da2899SCharles.Forsyth literal(ulong imm, int roff)
40337da2899SCharles.Forsyth {
40437da2899SCharles.Forsyth 	nlit++;
40537da2899SCharles.Forsyth 
40637da2899SCharles.Forsyth 	ldbigc((ulong)litpool, Ro1);
40737da2899SCharles.Forsyth 	IRR(Osw, roff, Rreg, Ro1);
40837da2899SCharles.Forsyth 
40937da2899SCharles.Forsyth 	if(pass == 0)
41037da2899SCharles.Forsyth 		return;
41137da2899SCharles.Forsyth 
41237da2899SCharles.Forsyth 	*litpool = imm;
41337da2899SCharles.Forsyth 	litpool++;
41437da2899SCharles.Forsyth }
41537da2899SCharles.Forsyth 
41637da2899SCharles.Forsyth void
punt(Inst * i,int m,void (* fn)(void))41737da2899SCharles.Forsyth punt(Inst *i, int m, void (*fn)(void))
41837da2899SCharles.Forsyth {
41937da2899SCharles.Forsyth 	ulong *cp, pc;
42037da2899SCharles.Forsyth 
42137da2899SCharles.Forsyth 	if(m & SRCOP) {
42237da2899SCharles.Forsyth 		op1(i, Olea, Ro1, 1);
42337da2899SCharles.Forsyth 		IRR(Osw, O(REG,s),Rreg, Ro1);
42437da2899SCharles.Forsyth 	}
42537da2899SCharles.Forsyth 	if(m & DSTOP) {
42637da2899SCharles.Forsyth 		op3(i, Olea, Ro3, 1);
42737da2899SCharles.Forsyth 		IRR(Osw, O(REG,d),Rreg, Ro3);
42837da2899SCharles.Forsyth 	}
42937da2899SCharles.Forsyth 	if(m & WRTPC) {
43037da2899SCharles.Forsyth 		pc = patch[i-mod->prog+1];
43137da2899SCharles.Forsyth 		ldbigc((ulong)(base+pc), Ro1);
43237da2899SCharles.Forsyth 		IRR(Osw, O(REG,PC),Rreg, Ro1);
43337da2899SCharles.Forsyth 	}
43437da2899SCharles.Forsyth 	if(m & DBRAN) {
43537da2899SCharles.Forsyth 		pc = patch[(Inst*)i->d.imm-mod->prog];
43637da2899SCharles.Forsyth 		literal((ulong)(base+pc), O(REG, d));
43737da2899SCharles.Forsyth 	}
43837da2899SCharles.Forsyth 
43937da2899SCharles.Forsyth 	if((i->add&ARM) == AXNON) {
44037da2899SCharles.Forsyth 		if(m & THREOP) {
44137da2899SCharles.Forsyth 			delay();
44237da2899SCharles.Forsyth 			IRR(Olw, O(REG,d),Rreg, Ro2);
44337da2899SCharles.Forsyth 			delay();
44437da2899SCharles.Forsyth 			IRR(Osw, O(REG,m),Rreg, Ro2);
44537da2899SCharles.Forsyth 		}
44637da2899SCharles.Forsyth 	} else {
44737da2899SCharles.Forsyth 		op2(i, Olea, Ro2, 1);
44837da2899SCharles.Forsyth 		IRR(Osw, O(REG,m),Rreg, Ro2);
44937da2899SCharles.Forsyth 	}
45037da2899SCharles.Forsyth 
45137da2899SCharles.Forsyth 	ldc((ulong)fn, Rpic);
45237da2899SCharles.Forsyth 	JR(Ojalr, Rpic);
45337da2899SCharles.Forsyth 	IRR(Osw, O(REG,FP),Rreg, Rfp);
45437da2899SCharles.Forsyth 
45537da2899SCharles.Forsyth 	ldc((ulong)&R, Rreg);
45637da2899SCharles.Forsyth 	IRR(Olw, O(REG,FP),Rreg, Rfp);
45737da2899SCharles.Forsyth 	IRR(Olw, O(REG,MP),Rreg, Rmp);
45837da2899SCharles.Forsyth 	regdelay = Rmp;
45937da2899SCharles.Forsyth 
46037da2899SCharles.Forsyth 	if(m & TCHECK) {
46137da2899SCharles.Forsyth 		IRR(Olw, O(REG,t),Rreg, Ro1);
46237da2899SCharles.Forsyth 		xchg();
46337da2899SCharles.Forsyth 		cp = code;
46437da2899SCharles.Forsyth 		BRRI(Obeq,Ro1,Rzero,0);
46537da2899SCharles.Forsyth 		IRR(Olw, O(REG,xpc),Rreg, Ro2);
46637da2899SCharles.Forsyth 		delay();
46737da2899SCharles.Forsyth 		JR(Ojr, Ro2);
46837da2899SCharles.Forsyth 		delay();
46937da2899SCharles.Forsyth 		*cp |= (code - cp) - 1;
47037da2899SCharles.Forsyth 		regdelay = 0;
47137da2899SCharles.Forsyth 	}
47237da2899SCharles.Forsyth 
47337da2899SCharles.Forsyth 	if(m & NEWPC) {
47437da2899SCharles.Forsyth 		IRR(Olw, O(REG,PC),Rreg, Ro1);
47537da2899SCharles.Forsyth 		if(m & TCHECK)
47637da2899SCharles.Forsyth 			delay();
47737da2899SCharles.Forsyth 		else
47837da2899SCharles.Forsyth 			xchg();
47937da2899SCharles.Forsyth 		JR(Ojr, Ro1);
48037da2899SCharles.Forsyth 		delay();
48137da2899SCharles.Forsyth 		regdelay = 0;
48237da2899SCharles.Forsyth 	}
48337da2899SCharles.Forsyth }
48437da2899SCharles.Forsyth 
48537da2899SCharles.Forsyth static void
comgoto(Inst * i)48637da2899SCharles.Forsyth comgoto(Inst *i)
48737da2899SCharles.Forsyth {
48837da2899SCharles.Forsyth 	WORD *t, *e;
48937da2899SCharles.Forsyth 
49037da2899SCharles.Forsyth 	op1(i, Olw, Ro2, 0);
49137da2899SCharles.Forsyth 	op3(i, Olea, Ro3, 0);
49237da2899SCharles.Forsyth 	SRR(Osll, 2, Ro2, Ro2);
49337da2899SCharles.Forsyth 	RRR(Oaddu, Ro2, Ro3, Ro3);
49437da2899SCharles.Forsyth 	IRR(Olw, 0,Ro3, Ro1);
49537da2899SCharles.Forsyth 	delay();
49637da2899SCharles.Forsyth 	JR(Ojr, Ro1);
49737da2899SCharles.Forsyth 	delay();
49837da2899SCharles.Forsyth 
49937da2899SCharles.Forsyth 	if(pass == 0)
50037da2899SCharles.Forsyth 		return;
50137da2899SCharles.Forsyth 
50237da2899SCharles.Forsyth 	t = (WORD*)(mod->origmp+i->d.ind);
50337da2899SCharles.Forsyth 	e = t + t[-1];
50437da2899SCharles.Forsyth 	t[-1] = 0;
50537da2899SCharles.Forsyth 	while(t < e) {
50637da2899SCharles.Forsyth 		t[0] = (ulong)(base + patch[t[0]]);
50737da2899SCharles.Forsyth 		t++;
50837da2899SCharles.Forsyth 	}
50937da2899SCharles.Forsyth }
51037da2899SCharles.Forsyth 
51137da2899SCharles.Forsyth static void
comcase(Inst * i,int w)51237da2899SCharles.Forsyth comcase(Inst *i, int w)
51337da2899SCharles.Forsyth {
51437da2899SCharles.Forsyth 	int l;
51537da2899SCharles.Forsyth 	WORD *t, *e;
51637da2899SCharles.Forsyth 
51737da2899SCharles.Forsyth 	if(w != 0) {
51837da2899SCharles.Forsyth 		op1(i, Olw, Ro1, 0);		// v
51937da2899SCharles.Forsyth 		op3(i, Olea, Ro3, 0);		// table
52037da2899SCharles.Forsyth 		J(Oj, base+macro[MacCASE]);
52137da2899SCharles.Forsyth 		xchg();
52237da2899SCharles.Forsyth 	}
52337da2899SCharles.Forsyth 
52437da2899SCharles.Forsyth 	t = (WORD*)(mod->origmp+i->d.ind+4);
52537da2899SCharles.Forsyth 	l = t[-1];
52637da2899SCharles.Forsyth 
52737da2899SCharles.Forsyth 	/* have to take care not to relocate the same table twice -
52837da2899SCharles.Forsyth 	 * the limbo compiler can duplicate a case instruction
52937da2899SCharles.Forsyth 	 * during its folding phase
53037da2899SCharles.Forsyth 	 */
53137da2899SCharles.Forsyth 
53237da2899SCharles.Forsyth 	if(pass == 0) {
53337da2899SCharles.Forsyth 		if(l >= 0)
53437da2899SCharles.Forsyth 			t[-1] = -l-1;	/* Mark it not done */
53537da2899SCharles.Forsyth 		return;
53637da2899SCharles.Forsyth 	}
53737da2899SCharles.Forsyth 	if(l >= 0)			/* Check pass 2 done */
53837da2899SCharles.Forsyth 		return;
53937da2899SCharles.Forsyth 	t[-1] = -l-1;			/* Set real count */
54037da2899SCharles.Forsyth 	e = t + t[-1]*3;
54137da2899SCharles.Forsyth 	while(t < e) {
54237da2899SCharles.Forsyth 		t[2] = (ulong)(base + patch[t[2]]);
54337da2899SCharles.Forsyth 		t += 3;
54437da2899SCharles.Forsyth 	}
54537da2899SCharles.Forsyth 	t[0] = (ulong)(base + patch[t[0]]);
54637da2899SCharles.Forsyth }
54737da2899SCharles.Forsyth 
54837da2899SCharles.Forsyth static void
comcasel(Inst * i)54937da2899SCharles.Forsyth comcasel(Inst *i)
55037da2899SCharles.Forsyth {
55137da2899SCharles.Forsyth 	int l;
55237da2899SCharles.Forsyth 	WORD *t, *e;
55337da2899SCharles.Forsyth 
55437da2899SCharles.Forsyth 	t = (WORD*)(mod->origmp+i->d.ind+8);
55537da2899SCharles.Forsyth 	l = t[-2];
55637da2899SCharles.Forsyth 	if(pass == 0) {
55737da2899SCharles.Forsyth 		if(l >= 0)
55837da2899SCharles.Forsyth 			t[-2] = -l-1;	/* Mark it not done */
55937da2899SCharles.Forsyth 		return;
56037da2899SCharles.Forsyth 	}
56137da2899SCharles.Forsyth 	if(l >= 0)			/* Check pass 2 done */
56237da2899SCharles.Forsyth 		return;
56337da2899SCharles.Forsyth 	t[-2] = -l-1;			/* Set real count */
56437da2899SCharles.Forsyth 	e = t + t[-2]*6;
56537da2899SCharles.Forsyth 	while(t < e) {
56637da2899SCharles.Forsyth 		t[4] = (ulong)base + patch[t[4]];
56737da2899SCharles.Forsyth 		t += 6;
56837da2899SCharles.Forsyth 	}
56937da2899SCharles.Forsyth 	t[0] = (ulong)base + patch[t[0]];
57037da2899SCharles.Forsyth }
57137da2899SCharles.Forsyth 
57237da2899SCharles.Forsyth static void
commframe(Inst * i)57337da2899SCharles.Forsyth commframe(Inst *i)
57437da2899SCharles.Forsyth {
57537da2899SCharles.Forsyth 	Modlink *ml;
57637da2899SCharles.Forsyth 	ulong *cp1, *cp2;
57737da2899SCharles.Forsyth 
57837da2899SCharles.Forsyth 	op1(i, Olw, Ro1, 0);
57937da2899SCharles.Forsyth 	ldc((ulong)H, Ri);
58037da2899SCharles.Forsyth 	cp1 = code;
58137da2899SCharles.Forsyth 	BRRI(Obeq, Ro1,Ri, 0);
58237da2899SCharles.Forsyth 	delay();
58337da2899SCharles.Forsyth 
58437da2899SCharles.Forsyth 	ml = nil;
58537da2899SCharles.Forsyth 	IRR(Olw, (ulong)&ml->links[i->reg].frame,Ro1, Ri);
58637da2899SCharles.Forsyth 	delay();
58737da2899SCharles.Forsyth 	IRR(Olw, O(Type,initialize),Ri, Ro2);
58837da2899SCharles.Forsyth 	delay();
58937da2899SCharles.Forsyth 	cp2 = code;
59037da2899SCharles.Forsyth 	BRRI(Obne, Ro2,Rzero, 0);
59137da2899SCharles.Forsyth 	delay();
59237da2899SCharles.Forsyth 
59337da2899SCharles.Forsyth 	op3(i, Olea, Rj, 0);
59437da2899SCharles.Forsyth 
59537da2899SCharles.Forsyth 	*cp1 |= (code - cp1) - 1;
59637da2899SCharles.Forsyth 	ldbigc((ulong)(base+patch[i-mod->prog+1]), Rlink);
59737da2899SCharles.Forsyth 	J(Oj, base+macro[MacMFRA]);
59837da2899SCharles.Forsyth 	xchg();
59937da2899SCharles.Forsyth 
60037da2899SCharles.Forsyth 	*cp2 |= (code - cp2) - 1;
60137da2899SCharles.Forsyth 	J(Ojal, base+macro[MacFRAM]);
60237da2899SCharles.Forsyth 	delay();
60337da2899SCharles.Forsyth 	op3(i, Osw, Ro1, 0);
60437da2899SCharles.Forsyth }
60537da2899SCharles.Forsyth 
60637da2899SCharles.Forsyth static void
commcall(Inst * i)60737da2899SCharles.Forsyth commcall(Inst *i)
60837da2899SCharles.Forsyth {
60937da2899SCharles.Forsyth 	Modlink *ml;
61037da2899SCharles.Forsyth 
61137da2899SCharles.Forsyth 	op1(i, Olw, Ro1, 0);				// f in Ro1
61237da2899SCharles.Forsyth 	IRR(Olw, O(REG,M),Rreg, Ro3);
61337da2899SCharles.Forsyth 	IRR(Osw, O(Frame,fp),Ro1, Rfp);			// f->fp = R.FP
61437da2899SCharles.Forsyth 	IRR(Osw, O(Frame,mr),Ro1, Ro3);			// f->mr = R.M
61537da2899SCharles.Forsyth 	op3(i, Olw, Ri, 1);
61637da2899SCharles.Forsyth 	ml = nil;
61737da2899SCharles.Forsyth 	IRR(Olw, (ulong)&ml->links[i->reg].u.pc,Ri, Rj);// ml->entry in Rj
61837da2899SCharles.Forsyth 	J(Ojal, base+macro[MacMCAL]);
61937da2899SCharles.Forsyth 	xchg();
62037da2899SCharles.Forsyth }
62137da2899SCharles.Forsyth 
62237da2899SCharles.Forsyth static void
cbral(Inst * i,int op,int mode)62337da2899SCharles.Forsyth cbral(Inst *i, int op, int mode)
62437da2899SCharles.Forsyth {
62537da2899SCharles.Forsyth 	ulong *cp;
62637da2899SCharles.Forsyth 
62737da2899SCharles.Forsyth 	cp = 0;
62837da2899SCharles.Forsyth 	op1(i, Olea, Ri, 0);
62937da2899SCharles.Forsyth 	op2(i, Olea, Rj, 0);
630*4eb166cfSCharles.Forsyth 	IRR(Olw, Bhi,Ri, Ro1);
631*4eb166cfSCharles.Forsyth 	IRR(Olw, Bhi,Rj, Ro2);
632*4eb166cfSCharles.Forsyth 	IRR(Olw, Blo,Ri, Ri);
63337da2899SCharles.Forsyth 
63437da2899SCharles.Forsyth 	switch(mode & OMASK) {
63537da2899SCharles.Forsyth 	case ANDAND:
63637da2899SCharles.Forsyth 		cp = code;
63737da2899SCharles.Forsyth 		BRRI(Obne, Ro2,Ro1, 0);
63837da2899SCharles.Forsyth 		goto b1;
63937da2899SCharles.Forsyth 
64037da2899SCharles.Forsyth 	case OROR:
64137da2899SCharles.Forsyth 		BRRI(Obne, Ro2,Ro1, branch(i));
64237da2899SCharles.Forsyth 	b1:
643*4eb166cfSCharles.Forsyth 		IRR(Olw, Blo,Rj, Rj);
64437da2899SCharles.Forsyth 		delay();
64537da2899SCharles.Forsyth 		BRRI(op, Rj,Ri, branch(i));
64637da2899SCharles.Forsyth 		break;
64737da2899SCharles.Forsyth 
64837da2899SCharles.Forsyth 	case EQAND:
64937da2899SCharles.Forsyth 		if(mode & REV1)
65037da2899SCharles.Forsyth 			RRR(Oslt, Ro2,Ro1, Ro3);
65137da2899SCharles.Forsyth 		else
65237da2899SCharles.Forsyth 			RRR(Oslt, Ro1,Ro2, Ro3);
65337da2899SCharles.Forsyth 		BRI(Obne, Ro3, branch(i));
654*4eb166cfSCharles.Forsyth 		IRR(Olw, Blo,Rj, Rj);
65537da2899SCharles.Forsyth 		cp = code;
65637da2899SCharles.Forsyth 		BRRI(Obne, Ro2,Ro1, 0);
65737da2899SCharles.Forsyth 		if(mode & REV2)
65837da2899SCharles.Forsyth 			RRR(Osltu, Rj,Ri, Ro3);
65937da2899SCharles.Forsyth 		else
66037da2899SCharles.Forsyth 			RRR(Osltu, Ri,Rj, Ro3);
66137da2899SCharles.Forsyth 		BRI(op, Ro3, branch(i));
66237da2899SCharles.Forsyth 		break;
66337da2899SCharles.Forsyth 	}
66437da2899SCharles.Forsyth 	delay();
66537da2899SCharles.Forsyth 	if(cp)
66637da2899SCharles.Forsyth 		*cp |= (code - cp) - 1;
66737da2899SCharles.Forsyth }
66837da2899SCharles.Forsyth 
66937da2899SCharles.Forsyth static void
op12(Inst * i,int b1flag,int b2flag)67037da2899SCharles.Forsyth op12(Inst *i, int b1flag, int b2flag)
67137da2899SCharles.Forsyth {
67237da2899SCharles.Forsyth 	int o1, o2;
67337da2899SCharles.Forsyth 
67437da2899SCharles.Forsyth 	o1 = Olw;
67537da2899SCharles.Forsyth 	if(b1flag)
67637da2899SCharles.Forsyth 		o1 = Olbu;
67737da2899SCharles.Forsyth 	o2 = Olw;
67837da2899SCharles.Forsyth 	if(b2flag)
67937da2899SCharles.Forsyth 		o2 = Olbu;
68037da2899SCharles.Forsyth 	if((i->add & ARM) == AXIMM) {
68137da2899SCharles.Forsyth 		op1(i, o1, Ro1, 0);
68237da2899SCharles.Forsyth 		op2(i, o2, Ro2, 1);
68337da2899SCharles.Forsyth 	} else {
68437da2899SCharles.Forsyth 		op2(i, o2, Ro2, 0);
68537da2899SCharles.Forsyth 		op1(i, o1, Ro1, 1);
68637da2899SCharles.Forsyth 	}
68737da2899SCharles.Forsyth }
68837da2899SCharles.Forsyth 
68937da2899SCharles.Forsyth static void
op13(Inst * i,int o1,int o2)69037da2899SCharles.Forsyth op13(Inst *i, int o1, int o2)
69137da2899SCharles.Forsyth {
69237da2899SCharles.Forsyth 	op1(i, o1, Ro1, 1);
69337da2899SCharles.Forsyth 	op3(i, o2, Ro1, 0);
69437da2899SCharles.Forsyth }
69537da2899SCharles.Forsyth 
69637da2899SCharles.Forsyth static void
shrl(Inst * i)69737da2899SCharles.Forsyth shrl(Inst *i)
69837da2899SCharles.Forsyth {
69937da2899SCharles.Forsyth 	int c;
70037da2899SCharles.Forsyth 
70137da2899SCharles.Forsyth 	if(USRC(i->add) != AIMM) {
70237da2899SCharles.Forsyth 		punt(i, SRCOP|DSTOP|THREOP, optab[i->op]);
70337da2899SCharles.Forsyth 		return;
70437da2899SCharles.Forsyth 	}
70537da2899SCharles.Forsyth 	c = i->s.imm;
70637da2899SCharles.Forsyth 	op2(i, Olea, Ro3, 1);
707*4eb166cfSCharles.Forsyth 	IRR(Olw, Bhi,Ro3, Ro1);
70837da2899SCharles.Forsyth 	if(c >= 32) {
70937da2899SCharles.Forsyth 		if((i->add&ARM) != AXNON)
71037da2899SCharles.Forsyth 			op3(i, Olea, Ro3, 0);
71137da2899SCharles.Forsyth 		else
71237da2899SCharles.Forsyth 			delay();
71337da2899SCharles.Forsyth 		SRR(Osra, 31, Ro1, Ro2);
714*4eb166cfSCharles.Forsyth 		IRR(Osw, Bhi,Ro3, Ro2);
71537da2899SCharles.Forsyth 		if(c >= 64) {
716*4eb166cfSCharles.Forsyth 			IRR(Osw, Blo,Ro3, Ro2);
71737da2899SCharles.Forsyth 			return;
71837da2899SCharles.Forsyth 		}
71937da2899SCharles.Forsyth 		if(c > 32)
72037da2899SCharles.Forsyth 			SRR(Osra, c-32, Ro1, Ro1);
721*4eb166cfSCharles.Forsyth 		IRR(Osw, Blo,Ro3, Ro1);
72237da2899SCharles.Forsyth 		return;
72337da2899SCharles.Forsyth 	}
724*4eb166cfSCharles.Forsyth 	IRR(Olw, Blo,Ro3, Ro2);
72537da2899SCharles.Forsyth 	if((i->add&ARM) != AXNON)
72637da2899SCharles.Forsyth 		op3(i, Olea, Ro3, !c);
72737da2899SCharles.Forsyth 	if(c != 0) {
72837da2899SCharles.Forsyth 		SRR(Osll, 32-c, Ro1, Ri);
72937da2899SCharles.Forsyth 		SRR(Osra, c, Ro1, Ro1);
73037da2899SCharles.Forsyth 		SRR(Osrl, c, Ro2, Ro2);
73137da2899SCharles.Forsyth 		RRR(Oor, Ri, Ro2, Ro2);
73237da2899SCharles.Forsyth 	}
733*4eb166cfSCharles.Forsyth 	IRR(Osw, Blo,Ro3, Ro2);
734*4eb166cfSCharles.Forsyth 	IRR(Osw, Bhi,Ro3, Ro1);
73537da2899SCharles.Forsyth }
73637da2899SCharles.Forsyth 
73737da2899SCharles.Forsyth static void
shll(Inst * i)73837da2899SCharles.Forsyth shll(Inst *i)
73937da2899SCharles.Forsyth {
74037da2899SCharles.Forsyth 	int c;
74137da2899SCharles.Forsyth 
74237da2899SCharles.Forsyth 	if(USRC(i->add) != AIMM) {
74337da2899SCharles.Forsyth 		punt(i, SRCOP|DSTOP|THREOP, optab[i->op]);
74437da2899SCharles.Forsyth 		return;
74537da2899SCharles.Forsyth 	}
74637da2899SCharles.Forsyth 	c = i->s.imm;
74737da2899SCharles.Forsyth 	if(c >= 64) {
74837da2899SCharles.Forsyth 		op3(i, Olea, Ro3, 1);
749*4eb166cfSCharles.Forsyth 		IRR(Osw, Bhi,Ro3, Rzero);
750*4eb166cfSCharles.Forsyth 		IRR(Osw, Blo,Ro3, Rzero);
75137da2899SCharles.Forsyth 		return;
75237da2899SCharles.Forsyth 	}
75337da2899SCharles.Forsyth 	op2(i, Olea, Ro3, 1);
75437da2899SCharles.Forsyth 	if(c >= 32) {
755*4eb166cfSCharles.Forsyth 		IRR(Olw, Blo,Ro3, Ro1);
75637da2899SCharles.Forsyth 		if((i->add&ARM) != AXNON)
75737da2899SCharles.Forsyth 			op3(i, Olea, Ro3, 1);
758*4eb166cfSCharles.Forsyth 		IRR(Osw, Blo,Ro3, Rzero);
75937da2899SCharles.Forsyth 		if(c > 32)
76037da2899SCharles.Forsyth 			SRR(Osll, c-32, Ro1, Ro1);
761*4eb166cfSCharles.Forsyth 		IRR(Osw, Bhi,Ro3, Ro1);
76237da2899SCharles.Forsyth 		return;
76337da2899SCharles.Forsyth 	}
764*4eb166cfSCharles.Forsyth 	IRR(Olw, Blo,Ro3, Ro2);
765*4eb166cfSCharles.Forsyth 	IRR(Olw, Bhi,Ro3, Ro1);
76637da2899SCharles.Forsyth 	if((i->add&ARM) != AXNON)
76737da2899SCharles.Forsyth 		op3(i, Olea, Ro3, !c);
76837da2899SCharles.Forsyth 	if(c != 0) {
76937da2899SCharles.Forsyth 		SRR(Osrl, 32-c, Ro2, Ri);
77037da2899SCharles.Forsyth 		SRR(Osll, c, Ro2, Ro2);
77137da2899SCharles.Forsyth 		SRR(Osll, c, Ro1, Ro1);
77237da2899SCharles.Forsyth 		RRR(Oor, Ri, Ro1, Ro1);
77337da2899SCharles.Forsyth 	}
774*4eb166cfSCharles.Forsyth 	IRR(Osw, Blo,Ro3, Ro2);
775*4eb166cfSCharles.Forsyth 	IRR(Osw, Bhi,Ro3, Ro1);
77637da2899SCharles.Forsyth }
77737da2899SCharles.Forsyth 
77837da2899SCharles.Forsyth static void
compdbg(void)77937da2899SCharles.Forsyth compdbg(void)
78037da2899SCharles.Forsyth {
78137da2899SCharles.Forsyth 	print("%s:%d@%.8ux\n", R.M->m->name, R.t, R.st);
78237da2899SCharles.Forsyth }
78337da2899SCharles.Forsyth 
78437da2899SCharles.Forsyth static void
comp(Inst * i)78537da2899SCharles.Forsyth comp(Inst *i)
78637da2899SCharles.Forsyth {
78737da2899SCharles.Forsyth 	int o, q, b;
78837da2899SCharles.Forsyth 	ulong *cp, *cp1;
78937da2899SCharles.Forsyth 	char buf[64];
79037da2899SCharles.Forsyth 
79137da2899SCharles.Forsyth 	if(0) {
79237da2899SCharles.Forsyth 		Inst xx;
79337da2899SCharles.Forsyth 		xx.add = AXIMM|SRC(AIMM);
79437da2899SCharles.Forsyth 		xx.s.imm = (ulong)code;
79537da2899SCharles.Forsyth 		xx.reg = i-mod->prog;
79637da2899SCharles.Forsyth 		punt(&xx, SRCOP, compdbg);
79737da2899SCharles.Forsyth 	}
79837da2899SCharles.Forsyth 
79937da2899SCharles.Forsyth 	switch(i->op) {
80037da2899SCharles.Forsyth 	default:
80137da2899SCharles.Forsyth 		snprint(buf, sizeof buf, "%s compile, no '%D'", mod->name, i);
80237da2899SCharles.Forsyth 		error(buf);
80337da2899SCharles.Forsyth 		break;
80437da2899SCharles.Forsyth 	case IMCALL:
80537da2899SCharles.Forsyth 		if((i->add&ARM) == AXIMM)
80637da2899SCharles.Forsyth 			commcall(i);
80737da2899SCharles.Forsyth 		else
80837da2899SCharles.Forsyth 			punt(i, SRCOP|DSTOP|THREOP|WRTPC|NEWPC, optab[i->op]);
80937da2899SCharles.Forsyth 		break;
81037da2899SCharles.Forsyth 	case ISEND:
81137da2899SCharles.Forsyth 	case IRECV:
81237da2899SCharles.Forsyth 	case IALT:
81337da2899SCharles.Forsyth 		punt(i, SRCOP|DSTOP|TCHECK|WRTPC, optab[i->op]);
81437da2899SCharles.Forsyth 		break;
81537da2899SCharles.Forsyth 	case ISPAWN:
81637da2899SCharles.Forsyth 		punt(i, SRCOP|DBRAN, optab[i->op]);
81737da2899SCharles.Forsyth 		break;
81837da2899SCharles.Forsyth 	case IBNEC:
81937da2899SCharles.Forsyth 	case IBEQC:
82037da2899SCharles.Forsyth 	case IBLTC:
82137da2899SCharles.Forsyth 	case IBLEC:
82237da2899SCharles.Forsyth 	case IBGTC:
82337da2899SCharles.Forsyth 	case IBGEC:
82437da2899SCharles.Forsyth 		punt(i, SRCOP|DBRAN|NEWPC|WRTPC, optab[i->op]);
82537da2899SCharles.Forsyth 		break;
82637da2899SCharles.Forsyth 	case ICASEC:
82737da2899SCharles.Forsyth 		comcase(i, 0);
82837da2899SCharles.Forsyth 		punt(i, SRCOP|DSTOP|NEWPC, optab[i->op]);
82937da2899SCharles.Forsyth 		break;
83037da2899SCharles.Forsyth 	case ICASEL:
83137da2899SCharles.Forsyth 		comcasel(i);
83237da2899SCharles.Forsyth 		punt(i, SRCOP|DSTOP|NEWPC, optab[i->op]);
83337da2899SCharles.Forsyth 		break;
83437da2899SCharles.Forsyth 	case IADDC:
83537da2899SCharles.Forsyth 	case IMULL:
83637da2899SCharles.Forsyth 	case IDIVL:
83737da2899SCharles.Forsyth 	case IMODL:
83837da2899SCharles.Forsyth 	case ILSRL:
83937da2899SCharles.Forsyth 	case IMNEWZ:
84037da2899SCharles.Forsyth 		punt(i, SRCOP|DSTOP|THREOP, optab[i->op]);
84137da2899SCharles.Forsyth 		break;
84237da2899SCharles.Forsyth 	case IMFRAME:
84337da2899SCharles.Forsyth 		if((i->add&ARM) == AXIMM)
84437da2899SCharles.Forsyth 			commframe(i);
84537da2899SCharles.Forsyth 		else
84637da2899SCharles.Forsyth 			punt(i, SRCOP|DSTOP|THREOP, optab[i->op]);
84737da2899SCharles.Forsyth 		break;
84837da2899SCharles.Forsyth 	case ILOAD:
84937da2899SCharles.Forsyth 	case INEWA:
85037da2899SCharles.Forsyth 	case INEWAZ:
85137da2899SCharles.Forsyth 	case INEW:
85237da2899SCharles.Forsyth 	case INEWZ:
85337da2899SCharles.Forsyth 	case ISLICEA:
85437da2899SCharles.Forsyth 	case ISLICELA:
85537da2899SCharles.Forsyth 	case ICONSB:
85637da2899SCharles.Forsyth 	case ICONSW:
85737da2899SCharles.Forsyth 	case ICONSL:
85837da2899SCharles.Forsyth 	case ICONSF:
85937da2899SCharles.Forsyth 	case ICONSM:
86037da2899SCharles.Forsyth 	case ICONSMP:
86137da2899SCharles.Forsyth 	case ICONSP:
86237da2899SCharles.Forsyth 	case IMOVMP:
86337da2899SCharles.Forsyth 	case IHEADL:
86437da2899SCharles.Forsyth 	case IHEADMP:
86537da2899SCharles.Forsyth 	case IINDC:
86637da2899SCharles.Forsyth 	case ILENC:
86737da2899SCharles.Forsyth 	case IINSC:
86837da2899SCharles.Forsyth 	case ICVTAC:
86937da2899SCharles.Forsyth 	case ICVTCW:
87037da2899SCharles.Forsyth 	case ICVTWC:
87137da2899SCharles.Forsyth 	case ICVTCL:
87237da2899SCharles.Forsyth 	case ICVTLC:
87337da2899SCharles.Forsyth 	case ICVTFC:
87437da2899SCharles.Forsyth 	case ICVTCF:
87537da2899SCharles.Forsyth 	case ICVTFL:
87637da2899SCharles.Forsyth 	case ICVTLF:
87737da2899SCharles.Forsyth 	case ICVTFR:
87837da2899SCharles.Forsyth 	case ICVTRF:
87937da2899SCharles.Forsyth 	case IMSPAWN:
88037da2899SCharles.Forsyth 	case ICVTCA:
88137da2899SCharles.Forsyth 	case ISLICEC:
88237da2899SCharles.Forsyth 	case INBALT:
88337da2899SCharles.Forsyth 		punt(i, SRCOP|DSTOP, optab[i->op]);
88437da2899SCharles.Forsyth 		break;
88537da2899SCharles.Forsyth 	case INEWCM:
88637da2899SCharles.Forsyth 	case INEWCMP:
88737da2899SCharles.Forsyth 		punt(i, SRCOP|DSTOP|THREOP, optab[i->op]);
88837da2899SCharles.Forsyth 		break;
88937da2899SCharles.Forsyth 	case INEWCB:
89037da2899SCharles.Forsyth 	case INEWCW:
89137da2899SCharles.Forsyth 	case INEWCF:
89237da2899SCharles.Forsyth 	case INEWCP:
89337da2899SCharles.Forsyth 	case INEWCL:
89437da2899SCharles.Forsyth 		punt(i, DSTOP|THREOP, optab[i->op]);
89537da2899SCharles.Forsyth 		break;
89637da2899SCharles.Forsyth 	case IEXIT:
89737da2899SCharles.Forsyth 		punt(i, 0, optab[i->op]);
89837da2899SCharles.Forsyth 		break;
89937da2899SCharles.Forsyth 	case ICVTWB:
90037da2899SCharles.Forsyth 		op13(i, Olw, Osb);
90137da2899SCharles.Forsyth 		break;
90237da2899SCharles.Forsyth 	case ICVTBW:
90337da2899SCharles.Forsyth 		op13(i, Olbu, Osw);
90437da2899SCharles.Forsyth 		break;
90537da2899SCharles.Forsyth 	case ICVTWS:
90637da2899SCharles.Forsyth 		op13(i, Olw, Osb);
90737da2899SCharles.Forsyth 		break;
90837da2899SCharles.Forsyth 	case ICVTSW:
90937da2899SCharles.Forsyth 		op13(i, Olhu, Osw);
91037da2899SCharles.Forsyth 		break;
91137da2899SCharles.Forsyth 	case IMOVB:
91237da2899SCharles.Forsyth 		op13(i, Olbu, Osb);
91337da2899SCharles.Forsyth 		break;
91437da2899SCharles.Forsyth 	case IMOVW:
91537da2899SCharles.Forsyth 		if(USRC(i->add) == AIMM && i->s.imm == 0) {
91637da2899SCharles.Forsyth 			op3(i, Osw, Rzero, 0);
91737da2899SCharles.Forsyth 			break;
91837da2899SCharles.Forsyth 		}
91937da2899SCharles.Forsyth 		op13(i, Olw, Osw);
92037da2899SCharles.Forsyth 		break;
92137da2899SCharles.Forsyth 	case ICVTLW:
92237da2899SCharles.Forsyth 		op1(i, Olea, Ro1, 1);
923*4eb166cfSCharles.Forsyth 		IRR(Olw, Blo,Ro1, Ro1);
92437da2899SCharles.Forsyth 		delay();
92537da2899SCharles.Forsyth 		op3(i, Osw, Ro1, 0);
92637da2899SCharles.Forsyth 		break;
92737da2899SCharles.Forsyth 	case ICVTWL:
92837da2899SCharles.Forsyth 		op1(i, Olw, Ro1, 0);
92937da2899SCharles.Forsyth 		op3(i, Olea, Ro2, 0);
93037da2899SCharles.Forsyth 		SRR(Osra, 31, Ro1, Ro3);
931*4eb166cfSCharles.Forsyth 		IRR(Osw, Blo,Ro2, Ro1);
932*4eb166cfSCharles.Forsyth 		IRR(Osw, Bhi,Ro2, Ro3);
93337da2899SCharles.Forsyth 		break;
93437da2899SCharles.Forsyth 	case IHEADM:
93537da2899SCharles.Forsyth 		op1(i, Olw, Ro1, 1);
93637da2899SCharles.Forsyth 		IRR(Oaddui, OA(List,data),Ro1,  Ro1);
93737da2899SCharles.Forsyth 		goto m1;
93837da2899SCharles.Forsyth 	case IMOVM:
93937da2899SCharles.Forsyth 		op1(i, Olea, Ro1, 0);
94037da2899SCharles.Forsyth 	m1:
94137da2899SCharles.Forsyth 		op2(i, Olw, Ro2, 0);
94237da2899SCharles.Forsyth 		op3(i, Olea, Ro3, 0);
94337da2899SCharles.Forsyth 		J(Ojal, base+macro[MacMOVM]);
94437da2899SCharles.Forsyth 		xchg();
94537da2899SCharles.Forsyth 		break;
94637da2899SCharles.Forsyth 	case IRET:
94737da2899SCharles.Forsyth 		J(Oj, base+macro[MacRET]);
94837da2899SCharles.Forsyth 		delay();
94937da2899SCharles.Forsyth 		break;
95037da2899SCharles.Forsyth 	case IFRAME:
95137da2899SCharles.Forsyth 		if(UXSRC(i->add) != SRC(AIMM)) {
95237da2899SCharles.Forsyth 			punt(i, SRCOP|DSTOP, optab[i->op]);
95337da2899SCharles.Forsyth 			break;
95437da2899SCharles.Forsyth 		}
95537da2899SCharles.Forsyth 		ldc((ulong)mod->type[i->s.imm], Ri);
95637da2899SCharles.Forsyth 		J(Ojal, base+macro[MacFRAM]);
95737da2899SCharles.Forsyth 		xchg();
95837da2899SCharles.Forsyth 		op3(i, Osw, Ro1, 0);
95937da2899SCharles.Forsyth 		tinit[i->s.imm] = 1;
96037da2899SCharles.Forsyth 		break;
96137da2899SCharles.Forsyth 	case ILEA:
96237da2899SCharles.Forsyth 		op13(i, Olea, Osw);
96337da2899SCharles.Forsyth 		break;
96437da2899SCharles.Forsyth 	case IHEADW:
96537da2899SCharles.Forsyth 		op1(i, Olw, Ro1, 1);
96637da2899SCharles.Forsyth 		IRR(Olw, OA(List,data),Ro1, Ro1);
96737da2899SCharles.Forsyth 		delay();
96837da2899SCharles.Forsyth 		op3(i, Osw, Ro1, 0);
96937da2899SCharles.Forsyth 		break;
97037da2899SCharles.Forsyth 	case IHEADF:
97137da2899SCharles.Forsyth 		op1(i, Olw, Ro1, 1);
97237da2899SCharles.Forsyth 		IRR(Olw, OA(List,data),Ro1, Ro2);
97337da2899SCharles.Forsyth 		IRR(Olw, OA(List,data)+4,Ro1, Ro3);
97437da2899SCharles.Forsyth 		op3(i, Olea, Ro1, 1);
97537da2899SCharles.Forsyth 		IRR(Osw, 0,Ro1, Ro2);
97637da2899SCharles.Forsyth 		IRR(Osw, 4,Ro1, Ro3);
97737da2899SCharles.Forsyth 		break;
97837da2899SCharles.Forsyth 	case IHEADB:
97937da2899SCharles.Forsyth 		op1(i, Olw, Ro1, 1);
98037da2899SCharles.Forsyth 		IRR(Olbu , OA(List,data),Ro1, Ro1);
98137da2899SCharles.Forsyth 		delay();
98237da2899SCharles.Forsyth 		op3(i, Osb, Ro1, 0);
98337da2899SCharles.Forsyth 		break;
98437da2899SCharles.Forsyth 	case ITAIL:
98537da2899SCharles.Forsyth 		op1(i, Olw, Ro1, 1);
98637da2899SCharles.Forsyth 		IRR(Olw, O(List,tail),Ro1, Ro1);
98737da2899SCharles.Forsyth 		goto movp;
98837da2899SCharles.Forsyth 	case IMOVP:
98937da2899SCharles.Forsyth 		op1(i, Olw, Ro1, 0);
99037da2899SCharles.Forsyth 		goto movp;
99137da2899SCharles.Forsyth 	case IHEADP:
99237da2899SCharles.Forsyth 		op1(i, Olw, Ro1, 1);
99337da2899SCharles.Forsyth 		IRR(Olw, OA(List,data),Ro1, Ro1);
99437da2899SCharles.Forsyth 	movp:
99537da2899SCharles.Forsyth 		ldc((ulong)H, Ro2);
99637da2899SCharles.Forsyth 		cp = code;
99737da2899SCharles.Forsyth 		BRRI(Obeq,Ro1,Ro2,0);
99837da2899SCharles.Forsyth 		ldbigc((ulong)&mutator, Ri);
99937da2899SCharles.Forsyth 		J(Ojal, base+macro[MacCOLR]);
100037da2899SCharles.Forsyth 		xchg();
100137da2899SCharles.Forsyth 		*cp |= (code - cp) - 1;
100237da2899SCharles.Forsyth 		op3(i, Olea, Ro3, 1);
100337da2899SCharles.Forsyth 		IRR(Olw, 0,Ro3, Ri);
100437da2899SCharles.Forsyth 		J(Ojal, base+macro[MacFRP]);
100537da2899SCharles.Forsyth 		IRR(Osw, 0,Ro3, Ro1);
100637da2899SCharles.Forsyth 		break;
100737da2899SCharles.Forsyth 	case ILENA:
100837da2899SCharles.Forsyth 		op1(i, Olw, Ri, 0);
100937da2899SCharles.Forsyth 		J(Ojal, base+macro[MacLENA]);
101037da2899SCharles.Forsyth 		xchg();
101137da2899SCharles.Forsyth 		op3(i, Osw, Ro1, 0);
101237da2899SCharles.Forsyth 		break;
101337da2899SCharles.Forsyth 	case ILENL:
101437da2899SCharles.Forsyth 		op1(i, Olw, Ro1, 0);
101537da2899SCharles.Forsyth 		ldc((ulong)H, Ro2);
101637da2899SCharles.Forsyth 		cp = code;
101737da2899SCharles.Forsyth 		BRRI(Obeq, Ro1,Ro2, 0);
101837da2899SCharles.Forsyth 		ldc(0, Ro3);
101937da2899SCharles.Forsyth 
102037da2899SCharles.Forsyth 		cp1 = code;
102137da2899SCharles.Forsyth 		IRR(Olw, O(List,tail),Ro1, Ro1);
102237da2899SCharles.Forsyth 		IRR(Oaddui, 1,Ro3, Ro3);
102337da2899SCharles.Forsyth 		BRRI(Obne, Ro1,Ro2, (cp1-code)-1);
102437da2899SCharles.Forsyth 		delay();
102537da2899SCharles.Forsyth 
102637da2899SCharles.Forsyth 		*cp |= (code - cp) - 1;
102737da2899SCharles.Forsyth 		op3(i, Osw, Ro3, 0);
102837da2899SCharles.Forsyth 		break;
102937da2899SCharles.Forsyth 	case IMOVL:
103037da2899SCharles.Forsyth 	case IMOVF:
103137da2899SCharles.Forsyth 		op1(i, Olea, Ro1, 1);
103237da2899SCharles.Forsyth 		IRR(Olw, 0,Ro1, Ro2);
103337da2899SCharles.Forsyth 		IRR(Olw, 4,Ro1, Ro3);
103437da2899SCharles.Forsyth 		op3(i, Olea, Ro1, 1);
103537da2899SCharles.Forsyth 		IRR(Osw, 0,Ro1, Ro2);
103637da2899SCharles.Forsyth 		IRR(Osw, 4,Ro1, Ro3);
103737da2899SCharles.Forsyth 		break;
103837da2899SCharles.Forsyth 	case ICVTFW:
103937da2899SCharles.Forsyth 		op1(i, Olea, Ro1, 1);
1040*4eb166cfSCharles.Forsyth 		IRR(Olf, Bhi,Ro1, Rf2+1);
1041*4eb166cfSCharles.Forsyth 		IRR(Olf, Blo,Ro1, Rf2);
104237da2899SCharles.Forsyth 		delay();
104337da2899SCharles.Forsyth 		FRRR(Ocvtfw, 0, Rf2, Rf2);
104437da2899SCharles.Forsyth 		op3(i, Olea, Ro2, 1);
104537da2899SCharles.Forsyth 		IRR(Osf, 0,Ro2, Rf2);
104637da2899SCharles.Forsyth 		break;
104737da2899SCharles.Forsyth 	case ICVTWF:
104837da2899SCharles.Forsyth 		op1(i, Olea, Ro1, 1);
104937da2899SCharles.Forsyth 		IRR(Olf, 0,Ro1, Rf2);
105037da2899SCharles.Forsyth 		delay();
105137da2899SCharles.Forsyth 		FRRR(Ocvtwf, 0, Rf2, Rf2);
105237da2899SCharles.Forsyth 		op3(i, Olea, Ro2, 1);
1053*4eb166cfSCharles.Forsyth 		IRR(Osf, Bhi,Ro2, Rf2+1);
1054*4eb166cfSCharles.Forsyth 		IRR(Osf, Blo,Ro2, Rf2);
105537da2899SCharles.Forsyth 		break;
105637da2899SCharles.Forsyth 	case INEGF:
105737da2899SCharles.Forsyth 		op1(i, Olea, Ro1, 1);
1058*4eb166cfSCharles.Forsyth 		IRR(Olf, Bhi,Ro1, Rf1+1);
1059*4eb166cfSCharles.Forsyth 		IRR(Olf, Blo,Ro1, Rf1);
106037da2899SCharles.Forsyth 		op3(i, Olea, Ro2, 1);
106137da2899SCharles.Forsyth 		FRRR(Onegf, 0, Rf1,Rf2);
1062*4eb166cfSCharles.Forsyth 		IRR(Osf, Bhi,Ro2, Rf2+1);
1063*4eb166cfSCharles.Forsyth 		IRR(Osf, Blo,Ro2, Rf2);
106437da2899SCharles.Forsyth 		break;
106537da2899SCharles.Forsyth 	case IXORL:
106637da2899SCharles.Forsyth 	case IORL:
106737da2899SCharles.Forsyth 	case IANDL:
106837da2899SCharles.Forsyth 	case IADDL:
106937da2899SCharles.Forsyth 	case ISUBL:
107037da2899SCharles.Forsyth 		op1(i, Olea, Ro1, 0);
107137da2899SCharles.Forsyth 		op2(i, Olea, Ro3, 0);
107237da2899SCharles.Forsyth 
1073*4eb166cfSCharles.Forsyth 		IRR(Olw, Blo,Ro1, Rj);	/* ls */
1074*4eb166cfSCharles.Forsyth 		IRR(Olw, Blo,Ro3, Ro2);
1075*4eb166cfSCharles.Forsyth 		IRR(Olw, Bhi,Ro1, Ri);	/* ms */
1076*4eb166cfSCharles.Forsyth 		IRR(Olw, Bhi,Ro3, Ro1);
107737da2899SCharles.Forsyth 
107837da2899SCharles.Forsyth 		switch(i->op) {
107937da2899SCharles.Forsyth 		case IXORL:
108037da2899SCharles.Forsyth 			o = Oxor;
108137da2899SCharles.Forsyth 			goto l1;
108237da2899SCharles.Forsyth 		case IORL:
108337da2899SCharles.Forsyth 			o = Oor;
108437da2899SCharles.Forsyth 			goto l1;
108537da2899SCharles.Forsyth 		case IANDL:
108637da2899SCharles.Forsyth 			o = Oand;
108737da2899SCharles.Forsyth 		l1:
108837da2899SCharles.Forsyth 			RRR(o, Ri,Ro1, Ro1);
108937da2899SCharles.Forsyth 			RRR(o, Rj,Ro2, Ro2);
109037da2899SCharles.Forsyth 			break;
109137da2899SCharles.Forsyth 		case IADDL:
109237da2899SCharles.Forsyth 			RRR(Oaddu, Ri,Ro1, Ro1);
109337da2899SCharles.Forsyth 			RRR(Oaddu, Rj,Ro2, Ro2);
109437da2899SCharles.Forsyth 			RRR(Osltu, Rj,Ro2, Ri);
109537da2899SCharles.Forsyth 			RRR(Oaddu, Ri,Ro1, Ro1);
109637da2899SCharles.Forsyth 			break;
109737da2899SCharles.Forsyth 		case ISUBL:
109837da2899SCharles.Forsyth 			RRR(Osubu, Ri,Ro1, Ro1);
109937da2899SCharles.Forsyth 			RRR(Osltu, Rj,Ro2, Ri);
110037da2899SCharles.Forsyth 			RRR(Osubu, Rj,Ro2, Ro2);
110137da2899SCharles.Forsyth 			RRR(Osubu, Ri,Ro1, Ro1);
110237da2899SCharles.Forsyth 			break;
110337da2899SCharles.Forsyth 		}
110437da2899SCharles.Forsyth 		if((i->add&ARM) != AXNON)
110537da2899SCharles.Forsyth 			op3(i, Olea, Ro3, 1);
1106*4eb166cfSCharles.Forsyth 		IRR(Osw, Bhi,Ro3, Ro1);
1107*4eb166cfSCharles.Forsyth 		IRR(Osw, Blo,Ro3, Ro2);
110837da2899SCharles.Forsyth 		break;
110937da2899SCharles.Forsyth 	case ISHLL:
111037da2899SCharles.Forsyth 		shll(i);
111137da2899SCharles.Forsyth 		break;
111237da2899SCharles.Forsyth 	case ISHRL:
111337da2899SCharles.Forsyth 		shrl(i);
111437da2899SCharles.Forsyth 		break;
111537da2899SCharles.Forsyth 	case IADDF:
111637da2899SCharles.Forsyth 	case ISUBF:
111737da2899SCharles.Forsyth 	case IMULF:
111837da2899SCharles.Forsyth 	case IDIVF:
111937da2899SCharles.Forsyth 	case IBEQF:
112037da2899SCharles.Forsyth 	case IBGEF:
112137da2899SCharles.Forsyth 	case IBGTF:
112237da2899SCharles.Forsyth 	case IBLEF:
112337da2899SCharles.Forsyth 	case IBLTF:
112437da2899SCharles.Forsyth 	case IBNEF:
112537da2899SCharles.Forsyth 		op1(i, Olea, Ro1, 0);
112637da2899SCharles.Forsyth 		op2(i, Olea, Ro2, 0);
1127*4eb166cfSCharles.Forsyth 		IRR(Olf, Bhi,Ro1, Rf1+1);
1128*4eb166cfSCharles.Forsyth 		IRR(Olf, Blo,Ro1, Rf1);
1129*4eb166cfSCharles.Forsyth 		IRR(Olf, Bhi,Ro2, Rf2+1);
1130*4eb166cfSCharles.Forsyth 		IRR(Olf, Blo,Ro2, Rf2);
113137da2899SCharles.Forsyth 		switch(i->op) {
113237da2899SCharles.Forsyth 		case IADDF:	o = Oaddf; goto f1;
113337da2899SCharles.Forsyth 		case ISUBF:	o = Osubf; goto f1;
113437da2899SCharles.Forsyth 		case IMULF:	o = Omulf; goto f1;
113537da2899SCharles.Forsyth 		case IDIVF:	o = Odivf; goto f1;
113637da2899SCharles.Forsyth 		case IBEQF:	o = Ofeq; q = Obrt; goto f2;
113737da2899SCharles.Forsyth 		case IBGEF:	o = Oflt; q = Obrf; goto f3;
113837da2899SCharles.Forsyth 		case IBGTF:	o = Oflt; q = Obrt; goto f2;
113937da2899SCharles.Forsyth 		case IBLEF:	o = Oflt; q = Obrf; goto f2;
114037da2899SCharles.Forsyth 		case IBLTF:	o = Oflt; q = Obrt; goto f3;
114137da2899SCharles.Forsyth 		case IBNEF:	o = Ofeq; q = Obrf; goto f2;
114237da2899SCharles.Forsyth 		f1:
114337da2899SCharles.Forsyth 			op3(i, Olea, Ro1, 0);
114437da2899SCharles.Forsyth 			FRRR(o, Rf1,Rf2, Rf2);
1145*4eb166cfSCharles.Forsyth 			IRR(Osf, Bhi,Ro1, Rf2+1);
1146*4eb166cfSCharles.Forsyth 			IRR(Osf, Blo,Ro1, Rf2);
114737da2899SCharles.Forsyth 			break;
114837da2899SCharles.Forsyth 		f2:
114937da2899SCharles.Forsyth 			delay();
115037da2899SCharles.Forsyth 			FRRR(o, Rf1,Rf2, 0);
115137da2899SCharles.Forsyth 			goto f4;
115237da2899SCharles.Forsyth 		f3:
115337da2899SCharles.Forsyth 			delay();
115437da2899SCharles.Forsyth 			FRRR(o, Rf2,Rf1, 0);
115537da2899SCharles.Forsyth 			goto f4;
115637da2899SCharles.Forsyth 		f4:
115737da2899SCharles.Forsyth 			delay();
115837da2899SCharles.Forsyth 			FI(q, branch(i));
115937da2899SCharles.Forsyth 			delay();
116037da2899SCharles.Forsyth 			break;
116137da2899SCharles.Forsyth 		}
116237da2899SCharles.Forsyth 		break;
116337da2899SCharles.Forsyth 
116437da2899SCharles.Forsyth 	case IBLTB:
116537da2899SCharles.Forsyth 	case IBLEB:
116637da2899SCharles.Forsyth 	case IBGTB:
116737da2899SCharles.Forsyth 	case IBGEB:
116837da2899SCharles.Forsyth 	case IBEQB:
116937da2899SCharles.Forsyth 	case IBNEB:
117037da2899SCharles.Forsyth 		b = 1;
117137da2899SCharles.Forsyth 		goto s1;
117237da2899SCharles.Forsyth 	case IBLTW:
117337da2899SCharles.Forsyth 	case IBLEW:
117437da2899SCharles.Forsyth 	case IBGTW:
117537da2899SCharles.Forsyth 	case IBGEW:
117637da2899SCharles.Forsyth 	case IBEQW:
117737da2899SCharles.Forsyth 	case IBNEW:
117837da2899SCharles.Forsyth 		b = 0;
117937da2899SCharles.Forsyth 	s1:
118037da2899SCharles.Forsyth 		op12(i, b, b);
118137da2899SCharles.Forsyth 		switch(i->op) {
118237da2899SCharles.Forsyth 		case IBLTB:
118337da2899SCharles.Forsyth 		case IBLTW:	o = Obne; goto b1;
118437da2899SCharles.Forsyth 		case IBGEB:
118537da2899SCharles.Forsyth 		case IBGEW:	o = Obeq; goto b1;
118637da2899SCharles.Forsyth 		case IBGTB:
118737da2899SCharles.Forsyth 		case IBGTW:	o = Obne; goto b2;
118837da2899SCharles.Forsyth 		case IBLEB:
118937da2899SCharles.Forsyth 		case IBLEW:	o = Obeq; goto b2;
119037da2899SCharles.Forsyth 		case IBEQB:
119137da2899SCharles.Forsyth 		case IBEQW:	o = Obeq; goto b3;
119237da2899SCharles.Forsyth 		case IBNEB:
119337da2899SCharles.Forsyth 		case IBNEW:	o = Obne; goto b3;
119437da2899SCharles.Forsyth 		b1:	RRR(Oslt, Ro2,Ro1, Ro3);
119537da2899SCharles.Forsyth 			BRI(o,Ro3, branch(i));
119637da2899SCharles.Forsyth 			break;
119737da2899SCharles.Forsyth 		b2:	RRR(Oslt, Ro1,Ro2, Ro3);
119837da2899SCharles.Forsyth 			BRI(o,Ro3, branch(i));
119937da2899SCharles.Forsyth 			break;
120037da2899SCharles.Forsyth 		b3:	BRRI(o, Ro2,Ro1, branch(i));
120137da2899SCharles.Forsyth 			break;
120237da2899SCharles.Forsyth 		}
120337da2899SCharles.Forsyth 		delay();
120437da2899SCharles.Forsyth 		break;
120537da2899SCharles.Forsyth 
120637da2899SCharles.Forsyth 	case IBEQL:
120737da2899SCharles.Forsyth 		cbral(i, Obeq, ANDAND);
120837da2899SCharles.Forsyth 		break;
120937da2899SCharles.Forsyth 	case IBNEL:
121037da2899SCharles.Forsyth 		cbral(i, Obne, OROR);
121137da2899SCharles.Forsyth 		break;
121237da2899SCharles.Forsyth 	case IBLEL:
121337da2899SCharles.Forsyth 		cbral(i, Obeq, EQAND|REV1);
121437da2899SCharles.Forsyth 		break;
121537da2899SCharles.Forsyth 	case IBGTL:
121637da2899SCharles.Forsyth 		cbral(i, Obne, EQAND);
121737da2899SCharles.Forsyth 		break;
121837da2899SCharles.Forsyth 	case IBLTL:
121937da2899SCharles.Forsyth 		cbral(i, Obne, EQAND|REV1|REV2);
122037da2899SCharles.Forsyth 		break;
122137da2899SCharles.Forsyth 	case IBGEL:
122237da2899SCharles.Forsyth 		cbral(i, Obeq, EQAND|REV2);
122337da2899SCharles.Forsyth 		break;
122437da2899SCharles.Forsyth 
122537da2899SCharles.Forsyth 	case ISUBB:
122637da2899SCharles.Forsyth 	case IADDB:
122737da2899SCharles.Forsyth 	case IANDB:
122837da2899SCharles.Forsyth 	case IORB:
122937da2899SCharles.Forsyth 	case IXORB:
123037da2899SCharles.Forsyth 	case IMODB:
123137da2899SCharles.Forsyth 	case IDIVB:
123237da2899SCharles.Forsyth 	case IMULB:
123337da2899SCharles.Forsyth 		b = 1;
123437da2899SCharles.Forsyth 		op12(i, b, b);
123537da2899SCharles.Forsyth 		goto s2;
123637da2899SCharles.Forsyth 	case ISHLB:
123737da2899SCharles.Forsyth 	case ISHRB:
123837da2899SCharles.Forsyth 		b = 1;
123937da2899SCharles.Forsyth 		op12(i, 0, b);
124037da2899SCharles.Forsyth 		goto s2;
124137da2899SCharles.Forsyth 	case ISUBW:
124237da2899SCharles.Forsyth 	case IADDW:
124337da2899SCharles.Forsyth 	case IANDW:
124437da2899SCharles.Forsyth 	case IORW:
124537da2899SCharles.Forsyth 	case IXORW:
124637da2899SCharles.Forsyth 	case ISHLW:
124737da2899SCharles.Forsyth 	case ISHRW:
124837da2899SCharles.Forsyth 	case IMODW:
124937da2899SCharles.Forsyth 	case IDIVW:
125037da2899SCharles.Forsyth 	case IMULW:
125137da2899SCharles.Forsyth 		b = 0;
125237da2899SCharles.Forsyth 		op12(i, b, b);
125337da2899SCharles.Forsyth 	s2:
125437da2899SCharles.Forsyth 		switch(i->op) {
125537da2899SCharles.Forsyth 		case IADDB:
125637da2899SCharles.Forsyth 		case IADDW:	o = Oaddu; goto c1;
125737da2899SCharles.Forsyth 		case ISUBB:
125837da2899SCharles.Forsyth 		case ISUBW:	o = Osubu; goto c1;
125937da2899SCharles.Forsyth 		case IANDB:
126037da2899SCharles.Forsyth 		case IANDW:	o = Oand; goto c1;
126137da2899SCharles.Forsyth 		case IORB:
126237da2899SCharles.Forsyth 		case IORW:	o = Oor; goto c1;
126337da2899SCharles.Forsyth 		case IXORB:
126437da2899SCharles.Forsyth 		case IXORW:	o = Oxor; goto c1;
126537da2899SCharles.Forsyth 		c1:
126637da2899SCharles.Forsyth 			RRR(o, Ro1,Ro2, Ro3);
126737da2899SCharles.Forsyth 			break;
126837da2899SCharles.Forsyth 		case ISHLB:
126937da2899SCharles.Forsyth 		case ISHLW:	o = Osllv; goto c2;
127037da2899SCharles.Forsyth 		case ILSRW:	o = Osrlv; goto c2;
127137da2899SCharles.Forsyth 		case ISHRB:
127237da2899SCharles.Forsyth 		case ISHRW:	o = Osrav; goto c2;
127337da2899SCharles.Forsyth 		c2:
127437da2899SCharles.Forsyth 			RRR(o, Ro2,Ro1, Ro3);
127537da2899SCharles.Forsyth 			break;
127637da2899SCharles.Forsyth 		case IMULB:
127737da2899SCharles.Forsyth 		case IMULW:	q = Omul; o = Omflo; goto c3;
127837da2899SCharles.Forsyth 		case IDIVB:
127937da2899SCharles.Forsyth 		case IDIVW:	q = Odiv; o = Omflo; goto c3;
128037da2899SCharles.Forsyth 		case IMODB:
128137da2899SCharles.Forsyth 		case IMODW:	q = Odiv; o = Omfhi; goto c3;
128237da2899SCharles.Forsyth 		c3:
128337da2899SCharles.Forsyth 			RRR(q, Ro1,Ro2, Rzero);
128437da2899SCharles.Forsyth 			RRR(o, Rzero,Rzero, Ro3);
128537da2899SCharles.Forsyth 			break;
128637da2899SCharles.Forsyth 		}
128737da2899SCharles.Forsyth 		op3(i, b? Osb: Osw, Ro3, 0);
128837da2899SCharles.Forsyth 		break;
128937da2899SCharles.Forsyth 	case ICALL:
129037da2899SCharles.Forsyth 		op1(i, Olw, Ro1, 0);
129137da2899SCharles.Forsyth 		ldbigc((ulong)(base+patch[i-mod->prog+1]), Ro2);
129237da2899SCharles.Forsyth 		IRR(Osw, O(Frame,lr),Ro1, Ro2);
129337da2899SCharles.Forsyth 		IRR(Osw, O(Frame,fp),Ro1, Rfp);
129437da2899SCharles.Forsyth 		J(Oj, base+patch[(Inst*)i->d.imm - mod->prog]);
129537da2899SCharles.Forsyth 		RRR(Oaddu, Ro1,Rzero, Rfp);
129637da2899SCharles.Forsyth 		break;
129737da2899SCharles.Forsyth 	case IJMP:
129837da2899SCharles.Forsyth 		J(Oj, base+patch[(Inst*)i->d.imm - mod->prog]);
129937da2899SCharles.Forsyth 		delay();
130037da2899SCharles.Forsyth 		break;
130137da2899SCharles.Forsyth 	case IGOTO:
130237da2899SCharles.Forsyth 		comgoto(i);
130337da2899SCharles.Forsyth 		break;
130437da2899SCharles.Forsyth 	case IINDX:
130537da2899SCharles.Forsyth 		op1(i, Olw, Ro1, 0);				/* Ro1 = a */
130637da2899SCharles.Forsyth 		op3(i, Olw, Ro3, 0);				/* Ro2 = i */
130737da2899SCharles.Forsyth 		J(Ojal, base+macro[MacINDX]);
130837da2899SCharles.Forsyth 		xchg();
130937da2899SCharles.Forsyth 		op2(i, Osw, Ro2, 0);
131037da2899SCharles.Forsyth 		break;
131137da2899SCharles.Forsyth 	case IINDB:
131237da2899SCharles.Forsyth 	case IINDF:
131337da2899SCharles.Forsyth 	case IINDW:
131437da2899SCharles.Forsyth 	case IINDL:
131537da2899SCharles.Forsyth 		op1(i, Olw, Ro1, 0);			/* Ro1 = a */
131637da2899SCharles.Forsyth 		op3(i, Olw, Ro3, 0);			/* Ro3 = i */
131737da2899SCharles.Forsyth 		IRR(Olw, O(Array,data),Ro1, Ro1);	/* Ro1 = a->data */
131837da2899SCharles.Forsyth 		switch(i->op) {
131937da2899SCharles.Forsyth 		case IINDL:
132037da2899SCharles.Forsyth 		case IINDF:
132137da2899SCharles.Forsyth 			SRR(Osll, 3, Ro3, Ro3);		/* Ro3 = i*8 */
132237da2899SCharles.Forsyth 			break;
132337da2899SCharles.Forsyth 		case IINDW:
132437da2899SCharles.Forsyth 			SRR(Osll, 2, Ro3, Ro3);		/* Ro3 = i*4 */
132537da2899SCharles.Forsyth 			break;
132637da2899SCharles.Forsyth 		case IINDB:
132737da2899SCharles.Forsyth 			delay();
132837da2899SCharles.Forsyth 			break;
132937da2899SCharles.Forsyth 		}
133037da2899SCharles.Forsyth 		RRR(Oaddu, Ro1,Ro3, Ro2);		/* Ro2 = i*size + data */
133137da2899SCharles.Forsyth 		op2(i, Osw, Ro2, 0);
133237da2899SCharles.Forsyth 		break;
133337da2899SCharles.Forsyth 	case ICASE:
133437da2899SCharles.Forsyth 		comcase(i, 1);
133537da2899SCharles.Forsyth 		break;
133637da2899SCharles.Forsyth 	case IRAISE:
133737da2899SCharles.Forsyth 		punt(i, SRCOP|WRTPC|NEWPC, optab[i->op]);
133837da2899SCharles.Forsyth 		break;
133937da2899SCharles.Forsyth 	case IMULX:
134037da2899SCharles.Forsyth 	case IDIVX:
134137da2899SCharles.Forsyth 	case ICVTXX:
134237da2899SCharles.Forsyth 	case IMULX0:
134337da2899SCharles.Forsyth 	case IDIVX0:
134437da2899SCharles.Forsyth 	case ICVTXX0:
134537da2899SCharles.Forsyth 	case IMULX1:
134637da2899SCharles.Forsyth 	case IDIVX1:
134737da2899SCharles.Forsyth 	case ICVTXX1:
134837da2899SCharles.Forsyth 	case ICVTFX:
134937da2899SCharles.Forsyth 	case ICVTXF:
135037da2899SCharles.Forsyth 	case IEXPW:
135137da2899SCharles.Forsyth 	case IEXPL:
135237da2899SCharles.Forsyth 	case IEXPF:
135337da2899SCharles.Forsyth 		punt(i, SRCOP|DSTOP|THREOP, optab[i->op]);
135437da2899SCharles.Forsyth 		break;
135537da2899SCharles.Forsyth 	case ISELF:
135637da2899SCharles.Forsyth 		punt(i, DSTOP, optab[i->op]);
135737da2899SCharles.Forsyth 		break;
135837da2899SCharles.Forsyth 	}
135937da2899SCharles.Forsyth }
136037da2899SCharles.Forsyth 
136137da2899SCharles.Forsyth static void
preamble(void)136237da2899SCharles.Forsyth preamble(void)
136337da2899SCharles.Forsyth {
136437da2899SCharles.Forsyth 	ldc((ulong)&R, Rreg);
136537da2899SCharles.Forsyth 	IRR(Olw, O(REG,PC),Rreg, Ri);
136637da2899SCharles.Forsyth 	IRR(Olw, O(REG,FP),Rreg, Rfp);
136737da2899SCharles.Forsyth 	IRR(Olw, O(REG,MP),Rreg, Rmp);
136837da2899SCharles.Forsyth 	IRR(Osw, O(REG,xpc),Rreg, Rlink);
136937da2899SCharles.Forsyth 	JR(Ojr, Ri);
137037da2899SCharles.Forsyth 	delay();
137137da2899SCharles.Forsyth }
137237da2899SCharles.Forsyth 
137337da2899SCharles.Forsyth static void
macfrp(void)137437da2899SCharles.Forsyth macfrp(void)
137537da2899SCharles.Forsyth {
137637da2899SCharles.Forsyth 	ulong *cp1, *cp2;
137737da2899SCharles.Forsyth 
137837da2899SCharles.Forsyth 	ldc((ulong)H, Ro1);
137937da2899SCharles.Forsyth 	cp1 = code;
138037da2899SCharles.Forsyth 	BRRI(Obeq, Ri,Ro1, 0);			// arg == $H
138137da2899SCharles.Forsyth 	delay();
138237da2899SCharles.Forsyth 
138337da2899SCharles.Forsyth 	IRR(Olw, O(Heap,ref)-sizeof(Heap),Ri, Ro2);
138437da2899SCharles.Forsyth 	ldc((ulong)1, Ro1);
138537da2899SCharles.Forsyth 	cp2 = code;
138637da2899SCharles.Forsyth 	BRRI(Obeq, Ro1,Ro2, 0);			// ref(arg) == $1
138737da2899SCharles.Forsyth 	IRR(Oaddui, -1,Ro2, Ro2);		// ref(arg)--
138837da2899SCharles.Forsyth 	JR(Ojr, Rlink);
138937da2899SCharles.Forsyth 	IRR(Osw, O(Heap,ref)-sizeof(Heap),Ri, Ro2);
139037da2899SCharles.Forsyth 
139137da2899SCharles.Forsyth 	*cp2 |= (code - cp2) - 1;
139237da2899SCharles.Forsyth 	IRR(Osw, O(REG,st),Rreg, Rlink);
139337da2899SCharles.Forsyth 	IRR(Osw, O(REG,FP),Rreg, Rfp);
139437da2899SCharles.Forsyth 
139537da2899SCharles.Forsyth 	ldc((ulong)rdestroy, Rpic);
139637da2899SCharles.Forsyth 	JR(Ojalr, Rpic);				// CALL	destroy
139737da2899SCharles.Forsyth 	IRR(Osw, O(REG,s),Rreg, Ri);
139837da2899SCharles.Forsyth 
139937da2899SCharles.Forsyth 	ldc((ulong)&R, Rreg);
140037da2899SCharles.Forsyth 	IRR(Olw, O(REG,st),Rreg, Rlink);
140137da2899SCharles.Forsyth 	IRR(Olw, O(REG,FP),Rreg, Rfp);
140237da2899SCharles.Forsyth 	IRR(Olw, O(REG,MP),Rreg, Rmp);
140337da2899SCharles.Forsyth 
140437da2899SCharles.Forsyth 	*cp1 |= (code - cp1) - 1;
140537da2899SCharles.Forsyth 	JR(Ojr, Rlink);
140637da2899SCharles.Forsyth 	delay();
140737da2899SCharles.Forsyth }
140837da2899SCharles.Forsyth 
140937da2899SCharles.Forsyth static void
macret(void)141037da2899SCharles.Forsyth macret(void)
141137da2899SCharles.Forsyth {
141237da2899SCharles.Forsyth 	ulong *cp1, *cp2, *cp3, *cp4, *cp5, *cp6;
141337da2899SCharles.Forsyth 	Inst i;
141437da2899SCharles.Forsyth 
141537da2899SCharles.Forsyth // NOTE this needs to be scheduled
141637da2899SCharles.Forsyth 
141737da2899SCharles.Forsyth 	IRR(Olw, O(Frame,t),Rfp, Ro1);
141837da2899SCharles.Forsyth 	delay();
141937da2899SCharles.Forsyth 	cp1 = code;
142037da2899SCharles.Forsyth 	BRRI(Obeq, Ro1,Rzero, 0);		// t(Rfp) == 0
142137da2899SCharles.Forsyth 	delay();
142237da2899SCharles.Forsyth 
142337da2899SCharles.Forsyth 	IRR(Olw, O(Type,destroy),Ro1, Rpic);
142437da2899SCharles.Forsyth 	delay();
142537da2899SCharles.Forsyth 	cp2 = code;
142637da2899SCharles.Forsyth 	BRRI(Obeq, Rpic,Rzero, 0);		// destroy(t(fp)) == 0
142737da2899SCharles.Forsyth 	delay();
142837da2899SCharles.Forsyth 
142937da2899SCharles.Forsyth 	IRR(Olw, O(Frame,fp),Rfp, Ro2);
143037da2899SCharles.Forsyth 	delay();
143137da2899SCharles.Forsyth 	cp3 = code;
143237da2899SCharles.Forsyth 	BRRI(Obeq, Ro2,Rzero, 0);		// fp(Rfp) == 0
143337da2899SCharles.Forsyth 	delay();
143437da2899SCharles.Forsyth 
143537da2899SCharles.Forsyth 	IRR(Olw, O(Frame,mr),Rfp, Ro3);
143637da2899SCharles.Forsyth 	delay();
143737da2899SCharles.Forsyth 	cp4 = code;
143837da2899SCharles.Forsyth 	BRRI(Obeq, Ro3,Rzero, 0);		// mr(Rfp) == 0
143937da2899SCharles.Forsyth 	delay();
144037da2899SCharles.Forsyth 
144137da2899SCharles.Forsyth 	IRR(Olw, O(REG,M),Rreg, Ro2);
144237da2899SCharles.Forsyth 	delay();
144337da2899SCharles.Forsyth 	IRR(Olw, O(Heap,ref)-sizeof(Heap),Ro2, Ro3);
144437da2899SCharles.Forsyth 	delay();
144537da2899SCharles.Forsyth 	IRR(Oaddui, -1,Ro3, Ro3);
144637da2899SCharles.Forsyth 	cp5 = code;
144737da2899SCharles.Forsyth 	BRRI(Obeq, Ro3,Rzero, 0);		// --ref(arg) == 0
144837da2899SCharles.Forsyth 	delay();
144937da2899SCharles.Forsyth 	IRR(Osw, O(Heap,ref)-sizeof(Heap),Ro2, Ro3);
145037da2899SCharles.Forsyth 
145137da2899SCharles.Forsyth 	IRR(Olw, O(Frame,mr),Rfp, Ro1);
145237da2899SCharles.Forsyth 	delay();
145337da2899SCharles.Forsyth 	IRR(Osw, O(REG,M),Rreg, Ro1);
145437da2899SCharles.Forsyth 	IRR(Olw, O(Modlink,compiled),Ro1, Ro2);	// check for uncompiled module
145537da2899SCharles.Forsyth 	IRR(Olw, O(Modlink,MP),Ro1, Rmp);
145637da2899SCharles.Forsyth 	cp6 = code;
145737da2899SCharles.Forsyth 	BRRI(Obeq, Ro2,Rzero, 0);
145837da2899SCharles.Forsyth 	IRR(Osw, O(REG,MP),Rreg, Rmp);
145937da2899SCharles.Forsyth 
146037da2899SCharles.Forsyth 	*cp4 |= (code - cp4) - 1;
146137da2899SCharles.Forsyth 	JR(Ojalr, Rpic);			// call destroy(t(fp))
146237da2899SCharles.Forsyth 	delay();
146337da2899SCharles.Forsyth 	IRR(Osw, O(REG,SP),Rreg, Rfp);
146437da2899SCharles.Forsyth 	IRR(Olw, O(Frame,lr),Rfp, Ro1);
146537da2899SCharles.Forsyth 	IRR(Olw, O(Frame,fp),Rfp, Rfp);
146637da2899SCharles.Forsyth 	IRR(Osw, O(REG,FP),Rreg, Rfp);
146737da2899SCharles.Forsyth 	JR(Ojr, Ro1);				// goto lr(Rfp)
146837da2899SCharles.Forsyth 	delay();
146937da2899SCharles.Forsyth 
147037da2899SCharles.Forsyth 	*cp6 |= (code - cp6) - 1;		// returning to uncompiled module
147137da2899SCharles.Forsyth 	JR(Ojalr, Rpic);			// call destroy(t(fp))
147237da2899SCharles.Forsyth 	delay();
147337da2899SCharles.Forsyth 	IRR(Osw, O(REG,SP),Rreg, Rfp);
147437da2899SCharles.Forsyth 	IRR(Olw, O(Frame,lr),Rfp, Ro1);
147537da2899SCharles.Forsyth 	IRR(Olw, O(Frame,fp),Rfp, Rfp);
147637da2899SCharles.Forsyth 	IRR(Osw, O(REG,FP),Rreg, Rfp);
147737da2899SCharles.Forsyth 	IRR(Olw, O(REG,xpc),Rreg, Ro2);
147837da2899SCharles.Forsyth 	JR(Ojr, Ro2);				// return to uncompiled code
147937da2899SCharles.Forsyth 	IRR(Osw, O(REG,PC),Rreg, Ro1);
148037da2899SCharles.Forsyth 
148137da2899SCharles.Forsyth 	*cp1 |= (code - cp1) - 1;
148237da2899SCharles.Forsyth 	*cp2 |= (code - cp2) - 1;
148337da2899SCharles.Forsyth 	*cp3 |= (code - cp3) - 1;
148437da2899SCharles.Forsyth 	*cp5 |= (code - cp5) - 1;
148537da2899SCharles.Forsyth 	i.add = AXNON;
148637da2899SCharles.Forsyth 	punt(&i, TCHECK|NEWPC, optab[IRET]);
148737da2899SCharles.Forsyth }
148837da2899SCharles.Forsyth 
148937da2899SCharles.Forsyth static void
macindx(void)149037da2899SCharles.Forsyth macindx(void)
149137da2899SCharles.Forsyth {
149237da2899SCharles.Forsyth 
149337da2899SCharles.Forsyth 	IRR(Olw, O(Array,t),Ro1, Ro2);
149437da2899SCharles.Forsyth 	IRR(Olw, O(Array,data),Ro1, Ro1);		// Ro1 = data
149537da2899SCharles.Forsyth 	IRR(Olw, O(Type,size),Ro2, Ro2);		// Ro2 = size
149637da2899SCharles.Forsyth 	delay();
149737da2899SCharles.Forsyth 
149837da2899SCharles.Forsyth 	RRR(Omul, Ro3,Ro2,Rzero);			// Ro2 = i*size
149937da2899SCharles.Forsyth 	RRR(Omflo, Rzero,Rzero,Ro2);
150037da2899SCharles.Forsyth 	JR(Ojr, Rlink);
150137da2899SCharles.Forsyth 	RRR(Oaddu, Ro1,Ro2,Ro2);			// Ro2 = i*size + data
150237da2899SCharles.Forsyth }
150337da2899SCharles.Forsyth 
150437da2899SCharles.Forsyth static void
maccase(void)150537da2899SCharles.Forsyth maccase(void)
150637da2899SCharles.Forsyth {
150737da2899SCharles.Forsyth 	ulong *cp1, *cp2, *cp3;
150837da2899SCharles.Forsyth 
150937da2899SCharles.Forsyth /*
151037da2899SCharles.Forsyth  * Ro1 = value (input arg), t
151137da2899SCharles.Forsyth  * Ro2 = count, n
151237da2899SCharles.Forsyth  * Ro3 = table pointer (input arg)
151337da2899SCharles.Forsyth  * Ri  = n/2, n2
151437da2899SCharles.Forsyth  * Rj  = pivot element t+n/2*3, l
151537da2899SCharles.Forsyth  */
151637da2899SCharles.Forsyth 
151737da2899SCharles.Forsyth 	IRR(Olw, 0,Ro3, Ro2);		// count
151837da2899SCharles.Forsyth 	IRR(Oaddui, 0,Ro3, Rlink);	// initial table pointer
151937da2899SCharles.Forsyth 
152037da2899SCharles.Forsyth 	cp1 = code;			// loop:
152137da2899SCharles.Forsyth 	BRI(Oblez,Ro2, 0);		// n <= 0? goto out
152237da2899SCharles.Forsyth 	SRR(Osra, 1, Ro2, Ri);		// n2 = n>>1
152337da2899SCharles.Forsyth 	SRR(Osll, 1, Ri, Rj);
152437da2899SCharles.Forsyth 	RRR(Oaddu, Rj, Ri, Rj);
152537da2899SCharles.Forsyth 	SRR(Osll, 2, Rj, Rj);
152637da2899SCharles.Forsyth 	RRR(Oaddu, Ro3, Rj, Rj);	// l = t + n2*3;
152737da2899SCharles.Forsyth 	IRR(Olw, 4,Rj, Rpic);
152837da2899SCharles.Forsyth 	delay();
152937da2899SCharles.Forsyth 	RRR(Oslt, Rpic, Ro1, Rpic);
153037da2899SCharles.Forsyth 	cp2 = code;
153137da2899SCharles.Forsyth 	BRI(Obne, Rpic, 0);		// v < l[1]? goto low
153237da2899SCharles.Forsyth 	delay();
153337da2899SCharles.Forsyth 
153437da2899SCharles.Forsyth 	IRR(Olw, 8,Rj, Rpic);
153537da2899SCharles.Forsyth 	delay();
153637da2899SCharles.Forsyth 	RRR(Oslt, Rpic, Ro1, Rpic);
153737da2899SCharles.Forsyth 	cp3 = code;
153837da2899SCharles.Forsyth 	BRI(Obeq, Rpic, 0);		// v >= l[2]? goto high
153937da2899SCharles.Forsyth 	delay();
154037da2899SCharles.Forsyth 
154137da2899SCharles.Forsyth 	IRR(Olw, 12,Rj, Ro3);		// found
154237da2899SCharles.Forsyth 	delay();
154337da2899SCharles.Forsyth 	JR(Ojr, Ro3);
154437da2899SCharles.Forsyth 	delay();
154537da2899SCharles.Forsyth 
154637da2899SCharles.Forsyth 	*cp2 |= (code - cp2) - 1;	// low:
154737da2899SCharles.Forsyth 	BRRI(Obeq, Rzero,Rzero, (cp1-code)-1);
154837da2899SCharles.Forsyth 	IRR(Oaddui, 0, Ri, Ro2);	// n = n2
154937da2899SCharles.Forsyth 
155037da2899SCharles.Forsyth 	*cp3 |= (code - cp3) - 1;	// high:
155137da2899SCharles.Forsyth 	IRR(Oaddui, 12, Rj, Ro3);	// t = l+3;
155237da2899SCharles.Forsyth 	IRR(Oaddui, 1, Ri, Rpic);
155337da2899SCharles.Forsyth 	BRRI(Obeq, Rzero,Rzero, (cp1-code)-1);
155437da2899SCharles.Forsyth 	RRR(Osubu, Rpic, Ro2, Ro2);	// n -= n2 + 1
155537da2899SCharles.Forsyth 
155637da2899SCharles.Forsyth 	*cp1 |= (code - cp1) - 1;	// out:
155737da2899SCharles.Forsyth 	IRR(Olw, 0,Rlink, Ro2);		// initial n
155837da2899SCharles.Forsyth 	delay();
155937da2899SCharles.Forsyth 	SRR(Osll, 1, Ro2, Ro3);
156037da2899SCharles.Forsyth 	RRR(Oaddu, Ro3, Ro2, Ro2);
156137da2899SCharles.Forsyth 	SRR(Osll, 2, Ro2, Ro2);
156237da2899SCharles.Forsyth 	RRR(Oaddu, Ro2, Rlink, Rlink);
156337da2899SCharles.Forsyth 	IRR(Olw, 4,Rlink, Ro3);		// (initital t)[n*3+1]
156437da2899SCharles.Forsyth 	delay();
156537da2899SCharles.Forsyth 	JR(Ojr, Ro3);
156637da2899SCharles.Forsyth 	delay();
156737da2899SCharles.Forsyth }
156837da2899SCharles.Forsyth 
156937da2899SCharles.Forsyth static void
maclena(void)157037da2899SCharles.Forsyth maclena(void)
157137da2899SCharles.Forsyth {
157237da2899SCharles.Forsyth 	ulong *cp;
157337da2899SCharles.Forsyth 
157437da2899SCharles.Forsyth 	ldc((ulong)H, Ro1);
157537da2899SCharles.Forsyth 	cp = code;
157637da2899SCharles.Forsyth 	BRRI(Obeq, Ri,Ro1, 0);
157737da2899SCharles.Forsyth 	delay();
157837da2899SCharles.Forsyth 	IRR(Olw, O(Array,len),Ri, Ro1);
157937da2899SCharles.Forsyth 	JR(Ojr, Rlink);
158037da2899SCharles.Forsyth 	delay();
158137da2899SCharles.Forsyth 	*cp |= (code - cp) - 1;
158237da2899SCharles.Forsyth 	JR(Ojr, Rlink);
158337da2899SCharles.Forsyth 	ldc(0, Ro1);
158437da2899SCharles.Forsyth }
158537da2899SCharles.Forsyth 
158637da2899SCharles.Forsyth static	void
macmcal(void)158737da2899SCharles.Forsyth macmcal(void)
158837da2899SCharles.Forsyth {
158937da2899SCharles.Forsyth 	ulong *cp1, *cp2;
159037da2899SCharles.Forsyth 
159137da2899SCharles.Forsyth 	IRR(Olw, O(Modlink,prog),Ri, Ro2);
159237da2899SCharles.Forsyth 	IRR(Osw, O(Frame,lr),Ro1, Rlink);	// f->lr = return
159337da2899SCharles.Forsyth 	cp1 = code;
159437da2899SCharles.Forsyth 	BRRI(Obne, Ro2, Rzero, 0);		// CMPL ml->m->prog != 0
159537da2899SCharles.Forsyth 	IRR(Oaddui, 0,Ro1, Rfp);		// R.FP = f
159637da2899SCharles.Forsyth 
159737da2899SCharles.Forsyth 	IRR(Osw, O(REG,st),Rreg, Rlink);
159837da2899SCharles.Forsyth 	ldc((ulong)rmcall, Rpic);
159937da2899SCharles.Forsyth 	IRR(Osw, O(REG,FP),Rreg, Ro1);
160037da2899SCharles.Forsyth 	IRR(Osw, O(REG,dt),Rreg, Rj);
160137da2899SCharles.Forsyth 	JR(Ojalr, Rpic);			// CALL	rmcall
160237da2899SCharles.Forsyth 	xchg();
160337da2899SCharles.Forsyth 	ldc((ulong)&R, Rreg);
160437da2899SCharles.Forsyth 	IRR(Olw, O(REG,st),Rreg, Rlink);
160537da2899SCharles.Forsyth 	IRR(Olw, O(REG,FP),Rreg, Rfp);
160637da2899SCharles.Forsyth 	IRR(Olw, O(REG,MP),Rreg, Rmp);
160737da2899SCharles.Forsyth 	JR(Ojr, Rlink);
160837da2899SCharles.Forsyth 	delay();
160937da2899SCharles.Forsyth 
161037da2899SCharles.Forsyth 	*cp1 |= (code - cp1) - 1;
161137da2899SCharles.Forsyth 	IRR(Olw, O(Heap,ref)-sizeof(Heap),Ri, Ro2);
161237da2899SCharles.Forsyth 	IRR(Osw, O(REG,M),Rreg, Ri);
161337da2899SCharles.Forsyth 	IRR(Oaddui, 1,Ro2, Ro2);
161437da2899SCharles.Forsyth 	IRR(Olw, O(Modlink,MP),Ri, Rmp);
161537da2899SCharles.Forsyth 	IRR(Olw, O(Modlink,compiled),Ri, Ro1);
161637da2899SCharles.Forsyth 	IRR(Osw, O(Heap,ref)-sizeof(Heap),Ri, Ro2);
161737da2899SCharles.Forsyth 	cp2 = code;
161837da2899SCharles.Forsyth 	BRRI(Obeq, Ro1,Rzero, 0);
161937da2899SCharles.Forsyth 	IRR(Osw, O(REG,MP),Rreg, Rmp);
162037da2899SCharles.Forsyth 
162137da2899SCharles.Forsyth 	JR(Ojr, Rj);
162237da2899SCharles.Forsyth 	delay();
162337da2899SCharles.Forsyth 
162437da2899SCharles.Forsyth 	*cp2 |= (code - cp2) - 1;
162537da2899SCharles.Forsyth 	IRR(Osw, O(REG,FP),Rreg, Rfp);		// call to uncompiled code
162637da2899SCharles.Forsyth 	IRR(Olw, O(REG,xpc),Rreg, Ro1);
162737da2899SCharles.Forsyth 	JR(Ojr, Ro1);
162837da2899SCharles.Forsyth 	IRR(Osw, O(REG,PC),Rreg, Rj);
162937da2899SCharles.Forsyth }
163037da2899SCharles.Forsyth 
163137da2899SCharles.Forsyth static	void
macmfra(void)163237da2899SCharles.Forsyth macmfra(void)
163337da2899SCharles.Forsyth {
163437da2899SCharles.Forsyth 	ldc((ulong)rmfram, Rpic);
163537da2899SCharles.Forsyth 	IRR(Osw, O(REG,st),Rreg, Rlink);
163637da2899SCharles.Forsyth 	IRR(Osw, O(REG,FP),Rreg, Rfp);
163737da2899SCharles.Forsyth 	IRR(Osw, O(REG,s),Rreg, Ri);
163837da2899SCharles.Forsyth 	IRR(Osw, O(REG,d),Rreg, Rj);
163937da2899SCharles.Forsyth 	JR(Ojalr, Rpic);			// CALL	rmfram
164037da2899SCharles.Forsyth 	xchg();
164137da2899SCharles.Forsyth 	ldc((ulong)&R, Rreg);
164237da2899SCharles.Forsyth 	IRR(Olw, O(REG,st),Rreg, Rlink);
164337da2899SCharles.Forsyth 	IRR(Olw, O(REG,FP),Rreg, Rfp);
164437da2899SCharles.Forsyth 	IRR(Olw, O(REG,MP),Rreg, Rmp);
164537da2899SCharles.Forsyth 	JR(Ojr, Rlink);
164637da2899SCharles.Forsyth 	delay();
164737da2899SCharles.Forsyth }
164837da2899SCharles.Forsyth 
164937da2899SCharles.Forsyth static void
macfram(void)165037da2899SCharles.Forsyth macfram(void)
165137da2899SCharles.Forsyth {
165237da2899SCharles.Forsyth 	ulong *cp;
165337da2899SCharles.Forsyth 
165437da2899SCharles.Forsyth 	/*
165537da2899SCharles.Forsyth 	 * Ri has t
165637da2899SCharles.Forsyth 	 */
165737da2899SCharles.Forsyth 	IRR(Olw, O(Type,initialize),Ri, Rj);
165837da2899SCharles.Forsyth 	IRR(Olw, O(Type,size),Ri, Ro3);		// MOVL $t->size, Ro3
165937da2899SCharles.Forsyth 	IRR(Olw, O(REG,SP),Rreg, Ro2);		// MOVL	R.SP, Ro2
166037da2899SCharles.Forsyth 	IRR(Olw, O(REG,TS),Rreg, Ro1);		// MOVL	R.TS, Ro1
166137da2899SCharles.Forsyth 	RRR(Oaddu,Ro3,Ro2, Ro2);		// ADDL $t->size, Ro2
166237da2899SCharles.Forsyth 	RRR(Osltu, Ro1,Ro2, Ro3);		// CMP Ro1,Ro2,Ro3
166337da2899SCharles.Forsyth 	cp = code;
166437da2899SCharles.Forsyth 	BRI(Obne,Ro3,0);			// BLT Ro3,**
166537da2899SCharles.Forsyth 	delay();
166637da2899SCharles.Forsyth 
166737da2899SCharles.Forsyth 	IRR(Osw, O(REG,s),Rreg, Ri);		// MOVL	t, R.s
166837da2899SCharles.Forsyth 	IRR(Osw, O(REG,st),Rreg, Rlink);	// MOVL	Rlink, R.st
166937da2899SCharles.Forsyth 	ldc((ulong)extend, Rpic);
167037da2899SCharles.Forsyth 	JR(Ojalr, Rpic);			// CALL	extend
167137da2899SCharles.Forsyth 	IRR(Osw, O(REG,FP),Rreg, Rfp);		// MOVL	RFP, R.FP
167237da2899SCharles.Forsyth 	ldc((ulong)&R, Rreg);
167337da2899SCharles.Forsyth 	IRR(Olw, O(REG,st),Rreg, Rlink);	// reload registers
167437da2899SCharles.Forsyth 	IRR(Olw, O(REG,FP),Rreg, Rfp);
167537da2899SCharles.Forsyth 	IRR(Olw, O(REG,MP),Rreg, Rmp);
167637da2899SCharles.Forsyth 	IRR(Olw, O(REG,s),Rreg, Ro1);		// return arg
167737da2899SCharles.Forsyth 	JR(Ojr, Rlink);
167837da2899SCharles.Forsyth 	delay();
167937da2899SCharles.Forsyth 
168037da2899SCharles.Forsyth 	*cp |= (code - cp) - 1;
168137da2899SCharles.Forsyth 	IRR(Olw, O(REG,SP),Rreg, Ro1);
168237da2899SCharles.Forsyth 	IRR(Osw, O(REG,SP),Rreg, Ro2);
168337da2899SCharles.Forsyth 	IRR(Osw, O(Frame,mr),Ro1, Rzero);
168437da2899SCharles.Forsyth 	JR(Ojr, Rj);				// return from tinit to main program
168537da2899SCharles.Forsyth 	IRR(Osw, O(Frame,t),Ro1, Ri);
168637da2899SCharles.Forsyth }
168737da2899SCharles.Forsyth 
168837da2899SCharles.Forsyth static void
macmovm(void)168937da2899SCharles.Forsyth macmovm(void)
169037da2899SCharles.Forsyth {
169137da2899SCharles.Forsyth 	ulong *cp1, *cp2;
169237da2899SCharles.Forsyth 
169337da2899SCharles.Forsyth 	/*
169437da2899SCharles.Forsyth 	 * from = Ro1
169537da2899SCharles.Forsyth 	 * to = Ro3
169637da2899SCharles.Forsyth 	 * count = Ro2
169737da2899SCharles.Forsyth 	 */
169837da2899SCharles.Forsyth 
169937da2899SCharles.Forsyth 	cp1 = code;
170037da2899SCharles.Forsyth 	BRRI(Obeq, Ro2, Rzero, 0);
170137da2899SCharles.Forsyth 	delay();
170237da2899SCharles.Forsyth 
170337da2899SCharles.Forsyth 	cp2 = code;
170437da2899SCharles.Forsyth 	IRR(Olbu, 0,Ro1, Ri);
170537da2899SCharles.Forsyth 	IRR(Oaddui, -1,Ro2, Ro2);
170637da2899SCharles.Forsyth 	IRR(Osb, 0,Ro3, Ri);
170737da2899SCharles.Forsyth 	IRR(Oaddui, 1,Ro1, Ro1);
170837da2899SCharles.Forsyth 	BRRI(Obne, Ro2, Rzero, (cp2-code)-1);
170937da2899SCharles.Forsyth 	IRR(Oaddui, 1,Ro3, Ro3);
171037da2899SCharles.Forsyth 
171137da2899SCharles.Forsyth 	*cp1 |= (code - cp1) - 1;
171237da2899SCharles.Forsyth 	JR(Ojr, Rlink);
171337da2899SCharles.Forsyth 	delay();
171437da2899SCharles.Forsyth }
171537da2899SCharles.Forsyth 
171637da2899SCharles.Forsyth static void
maccolr(void)171737da2899SCharles.Forsyth maccolr(void)
171837da2899SCharles.Forsyth {
171937da2899SCharles.Forsyth 	ulong *cp;
172037da2899SCharles.Forsyth 
172137da2899SCharles.Forsyth 	IRR(Olw, 0,Ri, Ri);
172237da2899SCharles.Forsyth 	IRR(Olw, O(Heap,color)-sizeof(Heap),Ro1, Ro3);
172337da2899SCharles.Forsyth 
172437da2899SCharles.Forsyth 	IRR(Olw, O(Heap,ref)-sizeof(Heap),Ro1, Ro2);
172537da2899SCharles.Forsyth 
172637da2899SCharles.Forsyth 	cp = code;
172737da2899SCharles.Forsyth 	BRRI(Obeq, Ri, Ro3, 0);
172837da2899SCharles.Forsyth 	IRR(Oaddui, 1,Ro2, Ro2);
172937da2899SCharles.Forsyth 
173037da2899SCharles.Forsyth 	ldc(propagator, Ro3);
173137da2899SCharles.Forsyth 	IRR(Osw, O(Heap,color)-sizeof(Heap),Ro1, Ro3);
173237da2899SCharles.Forsyth 	ldc((ulong)&nprop, Ro3);
173337da2899SCharles.Forsyth 	IRR(Osw, 0,Ro3, Ro1);
173437da2899SCharles.Forsyth 
173537da2899SCharles.Forsyth 	*cp |= (code - cp) - 1;
173637da2899SCharles.Forsyth 	JR(Ojr, Rlink);
173737da2899SCharles.Forsyth 	IRR(Osw, O(Heap,ref)-sizeof(Heap),Ro1, Ro2);
173837da2899SCharles.Forsyth }
173937da2899SCharles.Forsyth 
174037da2899SCharles.Forsyth static void
macend(void)174137da2899SCharles.Forsyth macend(void)
174237da2899SCharles.Forsyth {
174337da2899SCharles.Forsyth }
174437da2899SCharles.Forsyth 
174537da2899SCharles.Forsyth void
comd(Type * t)174637da2899SCharles.Forsyth comd(Type *t)
174737da2899SCharles.Forsyth {
174837da2899SCharles.Forsyth 	int i, j, m, c;
174937da2899SCharles.Forsyth 
175037da2899SCharles.Forsyth 	IRR(Osw, O(REG,dt),Rreg, Rlink);
175137da2899SCharles.Forsyth 	for(i = 0; i < t->np; i++) {
175237da2899SCharles.Forsyth 		c = t->map[i];
175337da2899SCharles.Forsyth 		j = i<<5;
175437da2899SCharles.Forsyth 		for(m = 0x80; m != 0; m >>= 1) {
175537da2899SCharles.Forsyth 			if(c & m) {
175637da2899SCharles.Forsyth 				J(Ojal, base+macro[MacFRP]);
175737da2899SCharles.Forsyth 				IRR(Olw, j,Rfp, Ri);
175837da2899SCharles.Forsyth 			}
175937da2899SCharles.Forsyth 			j += sizeof(WORD*);
176037da2899SCharles.Forsyth 		}
176137da2899SCharles.Forsyth 	}
176237da2899SCharles.Forsyth 	IRR(Olw, O(REG,dt),Rreg, Rlink);
176337da2899SCharles.Forsyth 	delay();
176437da2899SCharles.Forsyth 	JR(Ojr, Rlink);
176537da2899SCharles.Forsyth 	delay();
176637da2899SCharles.Forsyth }
176737da2899SCharles.Forsyth 
176837da2899SCharles.Forsyth void
comi(Type * t)176937da2899SCharles.Forsyth comi(Type *t)
177037da2899SCharles.Forsyth {
177137da2899SCharles.Forsyth 	int i, j, m, c;
177237da2899SCharles.Forsyth 
177337da2899SCharles.Forsyth 	ldc((ulong)H, Ri);
177437da2899SCharles.Forsyth 	for(i = 0; i < t->np; i++) {
177537da2899SCharles.Forsyth 		c = t->map[i];
177637da2899SCharles.Forsyth 		j = i<<5;
177737da2899SCharles.Forsyth 		for(m = 0x80; m != 0; m >>= 1) {
177837da2899SCharles.Forsyth 			if(c & m)
177937da2899SCharles.Forsyth 				IRR(Osw, j,Ro1, Ri);
178037da2899SCharles.Forsyth 			j += sizeof(WORD*);
178137da2899SCharles.Forsyth 		}
178237da2899SCharles.Forsyth 	}
178337da2899SCharles.Forsyth 	JR(Ojr, Rlink);
178437da2899SCharles.Forsyth 	xchg();
178537da2899SCharles.Forsyth }
178637da2899SCharles.Forsyth 
178737da2899SCharles.Forsyth void
typecom(Type * t)178837da2899SCharles.Forsyth typecom(Type *t)
178937da2899SCharles.Forsyth {
179037da2899SCharles.Forsyth 	int n;
179137da2899SCharles.Forsyth 	ulong *tmp, *start;
179237da2899SCharles.Forsyth 
179337da2899SCharles.Forsyth 	if(t == nil || t->initialize != 0)
179437da2899SCharles.Forsyth 		return;
179537da2899SCharles.Forsyth 
179637da2899SCharles.Forsyth 	tmp = mallocz(4096, 0);
179737da2899SCharles.Forsyth 	if(tmp == nil)
179837da2899SCharles.Forsyth 		return;
179937da2899SCharles.Forsyth 	code = tmp;
180037da2899SCharles.Forsyth 	comi(t);
180137da2899SCharles.Forsyth 	n = code - tmp;
180237da2899SCharles.Forsyth 	code = tmp;
180337da2899SCharles.Forsyth 	comd(t);
180437da2899SCharles.Forsyth 	n += code - tmp;
180537da2899SCharles.Forsyth 	free(tmp);
180637da2899SCharles.Forsyth 
180737da2899SCharles.Forsyth 	n *= sizeof(*code);
180837da2899SCharles.Forsyth 	code = mallocz(n, 0);
180937da2899SCharles.Forsyth 	if(code == nil)
181037da2899SCharles.Forsyth 		return;
181137da2899SCharles.Forsyth 
181237da2899SCharles.Forsyth 	start = code;
181337da2899SCharles.Forsyth 	t->initialize = code;
181437da2899SCharles.Forsyth 	comi(t);
181537da2899SCharles.Forsyth 	t->destroy = code;
181637da2899SCharles.Forsyth 	comd(t);
181737da2899SCharles.Forsyth 
181837da2899SCharles.Forsyth 	segflush(start, n);
181937da2899SCharles.Forsyth 
182037da2899SCharles.Forsyth 	if(cflag > 1)
182137da2899SCharles.Forsyth 		print("typ= %.8p %4d i %.8p d %.8p asm=%d\n",
182237da2899SCharles.Forsyth 			t, t->size, t->initialize, t->destroy, n);
182337da2899SCharles.Forsyth }
182437da2899SCharles.Forsyth 
182537da2899SCharles.Forsyth static void
patchex(Module * m,ulong * p)182637da2899SCharles.Forsyth patchex(Module *m, ulong *p)
182737da2899SCharles.Forsyth {
182837da2899SCharles.Forsyth 	Handler *h;
182937da2899SCharles.Forsyth 	Except *e;
183037da2899SCharles.Forsyth 
183137da2899SCharles.Forsyth 	if((h = m->htab) == nil)
183237da2899SCharles.Forsyth 		return;
183337da2899SCharles.Forsyth 	for( ; h->etab != nil; h++){
183437da2899SCharles.Forsyth 		h->pc1 = p[h->pc1];
183537da2899SCharles.Forsyth 		h->pc2 = p[h->pc2];
183637da2899SCharles.Forsyth 		for(e = h->etab; e->s != nil; e++)
183737da2899SCharles.Forsyth 			e->pc = p[e->pc];
183837da2899SCharles.Forsyth 		if(e->pc != -1)
183937da2899SCharles.Forsyth 			e->pc = p[e->pc];
184037da2899SCharles.Forsyth 	}
184137da2899SCharles.Forsyth }
184237da2899SCharles.Forsyth 
184337da2899SCharles.Forsyth int
compile(Module * m,int size,Modlink * ml)184437da2899SCharles.Forsyth compile(Module *m, int size, Modlink *ml)
184537da2899SCharles.Forsyth {
184637da2899SCharles.Forsyth 	Link *l;
184737da2899SCharles.Forsyth 	Modl *e;
184837da2899SCharles.Forsyth 	int i, n;
184937da2899SCharles.Forsyth 	ulong *s, tmp[512];
185037da2899SCharles.Forsyth 
185137da2899SCharles.Forsyth 	patch = mallocz(size*sizeof(*patch), 0);
185237da2899SCharles.Forsyth 	tinit = malloc(m->ntype*sizeof(*tinit));
185337da2899SCharles.Forsyth 	base = 0;
185437da2899SCharles.Forsyth 
185537da2899SCharles.Forsyth 	if(!comvec) {
185637da2899SCharles.Forsyth 		i = 10;		/* length of comvec */
185737da2899SCharles.Forsyth 		code = malloc(i*sizeof(*code));
185837da2899SCharles.Forsyth 		s = code;
185937da2899SCharles.Forsyth 		preamble();
186037da2899SCharles.Forsyth 		if(code >= (ulong*)(s + i))
186137da2899SCharles.Forsyth 			urk("preamble");
186237da2899SCharles.Forsyth 		comvec = (void*)s;
186337da2899SCharles.Forsyth 		segflush(s, i*sizeof(*s));
186437da2899SCharles.Forsyth 		if(cflag > 1) {
186537da2899SCharles.Forsyth 			print("comvec\n");
186637da2899SCharles.Forsyth 			while(s < code)
186737da2899SCharles.Forsyth 				das(s++);
186837da2899SCharles.Forsyth 		}/**/
186937da2899SCharles.Forsyth 	}
187037da2899SCharles.Forsyth 
187137da2899SCharles.Forsyth 	mod = m;
187237da2899SCharles.Forsyth 	n = 0;
187337da2899SCharles.Forsyth 	regdelay = 0;
187437da2899SCharles.Forsyth 	pass = 0;
187537da2899SCharles.Forsyth 	nlit = 0;
187637da2899SCharles.Forsyth 
187737da2899SCharles.Forsyth 	for(i = 0; i < size; i++) {
187837da2899SCharles.Forsyth 		code = tmp;
187937da2899SCharles.Forsyth 		comp(&m->prog[i]);
188037da2899SCharles.Forsyth 		if(code >= &tmp[nelem(tmp)]) {
188137da2899SCharles.Forsyth 			print("%3d %D\n", i, &m->prog[i]);
188237da2899SCharles.Forsyth 			urk("tmp ovflo");
188337da2899SCharles.Forsyth 		}
188437da2899SCharles.Forsyth 		patch[i] = n;
188537da2899SCharles.Forsyth 		n += code - tmp;
188637da2899SCharles.Forsyth 	}
188737da2899SCharles.Forsyth 
188837da2899SCharles.Forsyth 	for(i=0; macinit[i].f; i++) {
188937da2899SCharles.Forsyth 		code = tmp;
189037da2899SCharles.Forsyth 		(*macinit[i].f)();
189137da2899SCharles.Forsyth 		macro[macinit[i].o] = n;
189237da2899SCharles.Forsyth 		n += code - tmp;
189337da2899SCharles.Forsyth 	}
189437da2899SCharles.Forsyth 
189537da2899SCharles.Forsyth 	base = malloc((n+nlit)*sizeof(*base));
189637da2899SCharles.Forsyth 	if(cflag > 1)
189737da2899SCharles.Forsyth 		print("dis=%5d %5d mips=%5d asm=%.8p lit=%d: %s\n",
189837da2899SCharles.Forsyth 			size, size*sizeof(Inst), n, base, nlit, m->name);
189937da2899SCharles.Forsyth 
190037da2899SCharles.Forsyth 	pass++;
190137da2899SCharles.Forsyth 	code = base;
190237da2899SCharles.Forsyth 	litpool = base+n;
190337da2899SCharles.Forsyth 	n = 0;
190437da2899SCharles.Forsyth 	nlit = 0;
190537da2899SCharles.Forsyth 	regdelay = 0;
190637da2899SCharles.Forsyth 
190737da2899SCharles.Forsyth 	for(i = 0; i < size; i++) {
190837da2899SCharles.Forsyth 		s = code;
190937da2899SCharles.Forsyth 		comp(&m->prog[i]);
191037da2899SCharles.Forsyth 		if(patch[i] != n) {
191137da2899SCharles.Forsyth 			print("%3d %D\n", i, &m->prog[i]);
191237da2899SCharles.Forsyth 			urk(exCphase);
191337da2899SCharles.Forsyth 		}
191437da2899SCharles.Forsyth 		n += code - s;
191537da2899SCharles.Forsyth 		if(cflag > 1) {
191637da2899SCharles.Forsyth 			print("%3d %D\n", i, &m->prog[i]);
191737da2899SCharles.Forsyth 			while(s < code)
191837da2899SCharles.Forsyth 				das(s++);
191937da2899SCharles.Forsyth 		}/**/
192037da2899SCharles.Forsyth 	}
192137da2899SCharles.Forsyth 
192237da2899SCharles.Forsyth 	for(i=0; macinit[i].f; i++) {
192337da2899SCharles.Forsyth 		if(macro[macinit[i].o] != n) {
192437da2899SCharles.Forsyth 			print("macinit %d\n", macinit[i].o);
192537da2899SCharles.Forsyth 			urk(exCphase);
192637da2899SCharles.Forsyth 		}
192737da2899SCharles.Forsyth 		s = code;
192837da2899SCharles.Forsyth 		(*macinit[i].f)();
192937da2899SCharles.Forsyth 		n += code - s;
193037da2899SCharles.Forsyth 		if(cflag > 1) {
193137da2899SCharles.Forsyth 			print("macinit %d\n", macinit[i].o);
193237da2899SCharles.Forsyth 			while(s < code)
193337da2899SCharles.Forsyth 				das(s++);
193437da2899SCharles.Forsyth 		}/**/
193537da2899SCharles.Forsyth 	}
193637da2899SCharles.Forsyth 
193737da2899SCharles.Forsyth 	for(l = m->ext; l->name; l++) {
193837da2899SCharles.Forsyth 		l->u.pc = (Inst*)(base+patch[l->u.pc-m->prog]);
193937da2899SCharles.Forsyth 		typecom(l->frame);
194037da2899SCharles.Forsyth 	}
194137da2899SCharles.Forsyth 	if(ml != nil) {
194237da2899SCharles.Forsyth 		e = &ml->links[0];
194337da2899SCharles.Forsyth 		for(i = 0; i < ml->nlinks; i++) {
194437da2899SCharles.Forsyth 			e->u.pc = (Inst*)(base+patch[e->u.pc-m->prog]);
194537da2899SCharles.Forsyth 			typecom(e->frame);
194637da2899SCharles.Forsyth 			e++;
194737da2899SCharles.Forsyth 		}
194837da2899SCharles.Forsyth 	}
194937da2899SCharles.Forsyth 	for(i = 0; i < m->ntype; i++) {
195037da2899SCharles.Forsyth 		if(tinit[i] != 0)
195137da2899SCharles.Forsyth 			typecom(m->type[i]);
195237da2899SCharles.Forsyth 	}
195337da2899SCharles.Forsyth 	patchex(m, patch);
195437da2899SCharles.Forsyth 	m->entry = (Inst*)(base+patch[mod->entry-mod->prog]);
195537da2899SCharles.Forsyth 	free(patch);
195637da2899SCharles.Forsyth 	free(tinit);
195737da2899SCharles.Forsyth 	free(m->prog);
195837da2899SCharles.Forsyth 	m->prog = (Inst*)base;
195937da2899SCharles.Forsyth 	m->compiled = 1;
196037da2899SCharles.Forsyth 	segflush(base, n*sizeof(*base));
196137da2899SCharles.Forsyth 	return 1;
196237da2899SCharles.Forsyth }
1963