xref: /inferno-os/libinterp/das-sparc.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsyth #include <lib9.h>
2*37da2899SCharles.Forsyth 
3*37da2899SCharles.Forsyth 	/* Sparc disassembler and related functions */
4*37da2899SCharles.Forsyth 
5*37da2899SCharles.Forsyth typedef struct instr Instr;
6*37da2899SCharles.Forsyth 
7*37da2899SCharles.Forsyth struct opcode
8*37da2899SCharles.Forsyth {
9*37da2899SCharles.Forsyth 	char	*mnemonic;
10*37da2899SCharles.Forsyth 	void	(*f)(Instr*, char*);
11*37da2899SCharles.Forsyth 	int	flag;
12*37da2899SCharles.Forsyth };
13*37da2899SCharles.Forsyth 
14*37da2899SCharles.Forsyth static	char FRAMENAME[] = ".frame";
15*37da2899SCharles.Forsyth 
16*37da2899SCharles.Forsyth 
17*37da2899SCharles.Forsyth struct instr
18*37da2899SCharles.Forsyth {
19*37da2899SCharles.Forsyth 	uchar	op;		/* bits 31-30 */
20*37da2899SCharles.Forsyth 	uchar	rd;		/* bits 29-25 */
21*37da2899SCharles.Forsyth 	uchar	op2;		/* bits 24-22 */
22*37da2899SCharles.Forsyth 	uchar	a;		/* bit  29    */
23*37da2899SCharles.Forsyth 	uchar	cond;		/* bits 28-25 */
24*37da2899SCharles.Forsyth 	uchar	op3;		/* bits 24-19 */
25*37da2899SCharles.Forsyth 	uchar	rs1;		/* bits 18-14 */
26*37da2899SCharles.Forsyth 	uchar	i;		/* bit  13    */
27*37da2899SCharles.Forsyth 	uchar	asi;		/* bits 12-05 */
28*37da2899SCharles.Forsyth 	uchar	rs2;		/* bits 04-00 */
29*37da2899SCharles.Forsyth 	short	simm13;		/* bits 12-00, signed */
30*37da2899SCharles.Forsyth 	ushort	opf;		/* bits 13-05 */
31*37da2899SCharles.Forsyth 	ulong	immdisp22;	/* bits 21-00 */
32*37da2899SCharles.Forsyth 	ulong	simmdisp22;	/* bits 21-00, signed */
33*37da2899SCharles.Forsyth 	ulong	disp30;		/* bits 30-00 */
34*37da2899SCharles.Forsyth 	ulong	imm32;		/* SETHI+ADD constant */
35*37da2899SCharles.Forsyth 	int	target;		/* SETHI+ADD dest reg */
36*37da2899SCharles.Forsyth 	long	w0;
37*37da2899SCharles.Forsyth 	long	w1;
38*37da2899SCharles.Forsyth 	ulong	addr;		/* pc of instruction */
39*37da2899SCharles.Forsyth 	char*	curr;		/* current fill level in output buffer */
40*37da2899SCharles.Forsyth 	char*	end;		/* end of buffer */
41*37da2899SCharles.Forsyth 	int 	size;		/* number of longs in instr */
42*37da2899SCharles.Forsyth 	char*	err;		/* errmsg */
43*37da2899SCharles.Forsyth };
44*37da2899SCharles.Forsyth 
45*37da2899SCharles.Forsyth static	int	dascase;
46*37da2899SCharles.Forsyth 
47*37da2899SCharles.Forsyth static int	mkinstr(ulong*, Instr*);
48*37da2899SCharles.Forsyth static void	bra1(Instr*, char*, char*[]);
49*37da2899SCharles.Forsyth static void	bra(Instr*, char*);
50*37da2899SCharles.Forsyth static void	fbra(Instr*, char*);
51*37da2899SCharles.Forsyth static void	cbra(Instr*, char*);
52*37da2899SCharles.Forsyth static void	unimp(Instr*, char*);
53*37da2899SCharles.Forsyth static void	fpop(Instr*, char*);
54*37da2899SCharles.Forsyth static void	shift(Instr*, char*);
55*37da2899SCharles.Forsyth static void	sethi(Instr*, char*);
56*37da2899SCharles.Forsyth static void	load(Instr*, char*);
57*37da2899SCharles.Forsyth static void	loada(Instr*, char*);
58*37da2899SCharles.Forsyth static void	store(Instr*, char*);
59*37da2899SCharles.Forsyth static void	storea(Instr*, char*);
60*37da2899SCharles.Forsyth static void	add(Instr*, char*);
61*37da2899SCharles.Forsyth static void	cmp(Instr*, char*);
62*37da2899SCharles.Forsyth static void	wr(Instr*, char*);
63*37da2899SCharles.Forsyth static void	jmpl(Instr*, char*);
64*37da2899SCharles.Forsyth static void	rd(Instr*, char*);
65*37da2899SCharles.Forsyth static void	loadf(Instr*, char*);
66*37da2899SCharles.Forsyth static void	storef(Instr*, char*);
67*37da2899SCharles.Forsyth static void	loadc(Instr*, char*);
68*37da2899SCharles.Forsyth static void	loadcsr(Instr*, char*);
69*37da2899SCharles.Forsyth static void	trap(Instr*, char*);
70*37da2899SCharles.Forsyth 
71*37da2899SCharles.Forsyth static struct opcode sparcop0[8] = {
72*37da2899SCharles.Forsyth 	/* [0] */	"UNIMP",	unimp,	0,	/* page 137 */
73*37da2899SCharles.Forsyth 		0,		0,	0,
74*37da2899SCharles.Forsyth 	/* [2] */	"B",		bra,	0,	/* page 119 */
75*37da2899SCharles.Forsyth 		0,		0,	0,
76*37da2899SCharles.Forsyth 	/* [4] */	"SETHI",	sethi,	0,	/* page 104 */
77*37da2899SCharles.Forsyth 		0,		0,	0,
78*37da2899SCharles.Forsyth 	/* [6] */	"FB",		fbra,	0,	/* page 121 */
79*37da2899SCharles.Forsyth 	/* [7] */	"CB",		cbra,	0,	/* page 123 */
80*37da2899SCharles.Forsyth };
81*37da2899SCharles.Forsyth 
82*37da2899SCharles.Forsyth static struct opcode sparcop2[64] = {
83*37da2899SCharles.Forsyth 	/* [0x00] */	"ADD",		add,	0,	/* page 108 */
84*37da2899SCharles.Forsyth 	/* [0x01] */	"AND",		add,	0,	/* page 106 */
85*37da2899SCharles.Forsyth 	/* [0x02] */	"OR",		add,	0,
86*37da2899SCharles.Forsyth 	/* [0x03] */	"XOR",		add,	0,
87*37da2899SCharles.Forsyth 	/* [0x04] */	"SUB",		add,	0,	/* page 110 */
88*37da2899SCharles.Forsyth 	/* [0x05] */	"ANDN",		add,	0,
89*37da2899SCharles.Forsyth 	/* [0x06] */	"ORN",		add,	0,
90*37da2899SCharles.Forsyth 	/* [0x07] */	"XORN",		add,	0,
91*37da2899SCharles.Forsyth 	/* [0x08] */	"ADDX",		add,	0,
92*37da2899SCharles.Forsyth 			0,		0,	0,
93*37da2899SCharles.Forsyth 	/* [0x0A] */	"UMUL",		add,	0,	/* page 113 */
94*37da2899SCharles.Forsyth 	/* [0x0B] */	"SMUL",		add,	0,
95*37da2899SCharles.Forsyth 	/* [0x0C] */	"SUBX",		add,	0,
96*37da2899SCharles.Forsyth 			0,		0,	0,
97*37da2899SCharles.Forsyth 	/* [0x0E] */	"UDIV",		add,	0,	/* page 115 */
98*37da2899SCharles.Forsyth 	/* [0x0F] */	"SDIV",		add,	0,
99*37da2899SCharles.Forsyth 	/* [0x10] */	"ADDCC",	add,	0,
100*37da2899SCharles.Forsyth 	/* [0x11] */	"ANDCC",	add,	0,
101*37da2899SCharles.Forsyth 	/* [0x12] */	"ORCC",		add,	0,
102*37da2899SCharles.Forsyth 	/* [0x13] */	"XORCC",	add,	0,
103*37da2899SCharles.Forsyth 	/* [0x14] */	"SUBCC",	cmp,	0,
104*37da2899SCharles.Forsyth 	/* [0x15] */	"ANDNCC",	add,	0,
105*37da2899SCharles.Forsyth 	/* [0x16] */	"ORNCC",	add,	0,
106*37da2899SCharles.Forsyth 	/* [0x17] */	"XORNCC",	add,	0,
107*37da2899SCharles.Forsyth 	/* [0x18] */	"ADDXCC",	add,	0,
108*37da2899SCharles.Forsyth 			0,		0,	0,
109*37da2899SCharles.Forsyth 	/* [0x1A] */	"UMULCC",	add,	0,
110*37da2899SCharles.Forsyth 	/* [0x1B] */	"SMULCC",	add,	0,
111*37da2899SCharles.Forsyth 	/* [0x1C] */	"SUBXCC",	add,	0,
112*37da2899SCharles.Forsyth 			0,		0,	0,
113*37da2899SCharles.Forsyth 	/* [0x1E] */	"UDIVCC",	add,	0,
114*37da2899SCharles.Forsyth 	/* [0x1F] */	"SDIVCC",	add,	0,
115*37da2899SCharles.Forsyth 	/* [0x20] */	"TADD",		add,	0,	/* page 109 */
116*37da2899SCharles.Forsyth 	/* [0x21] */	"TSUB",		add,	0,	/* page 111 */
117*37da2899SCharles.Forsyth 	/* [0x22] */	"TADDCCTV",	add,	0,
118*37da2899SCharles.Forsyth 	/* [0x23] */	"TSUBCCTV",	add,	0,
119*37da2899SCharles.Forsyth 	/* [0x24] */	"MULSCC",	add,	0,	/* page 112 */
120*37da2899SCharles.Forsyth 	/* [0x25] */	"SLL",		shift,	0,	/* page 107 */
121*37da2899SCharles.Forsyth 	/* [0x26] */	"SRL",		shift,	0,
122*37da2899SCharles.Forsyth 	/* [0x27] */	"SRA",		shift,	0,
123*37da2899SCharles.Forsyth 	/* [0x28] */	"rdy",		rd,	0,	/* page 131 */
124*37da2899SCharles.Forsyth 	/* [0x29] */	"rdpsr",	rd,	0,
125*37da2899SCharles.Forsyth 	/* [0x2A] */	"rdwim",	rd,	0,
126*37da2899SCharles.Forsyth 	/* [0x2B] */	"rdtbr",	rd,	0,
127*37da2899SCharles.Forsyth 			0,		0,	0,
128*37da2899SCharles.Forsyth 			0,		0,	0,
129*37da2899SCharles.Forsyth 			0,		0,	0,
130*37da2899SCharles.Forsyth 			0,		0,	0,
131*37da2899SCharles.Forsyth 	/* [0x30] */	"wry",		wr,	0,	/* page 133 */
132*37da2899SCharles.Forsyth 	/* [0x31] */	"wrpsr",	wr,	0,
133*37da2899SCharles.Forsyth 	/* [0x32] */	"wrwim",	wr,	0,
134*37da2899SCharles.Forsyth 	/* [0x33] */	"wrtbr",	wr,	0,
135*37da2899SCharles.Forsyth 	/* [0x34] */	"FPOP",		fpop,	0,	/* page 140 */
136*37da2899SCharles.Forsyth 	/* [0x35] */	"FPOP",		fpop,	0,
137*37da2899SCharles.Forsyth 			0,		0,	0,
138*37da2899SCharles.Forsyth 			0,		0,	0,
139*37da2899SCharles.Forsyth 	/* [0x38] */	"JMPL",		jmpl,	0,	/* page 126 */
140*37da2899SCharles.Forsyth 	/* [0x39] */	"RETT",		add,	0,	/* page 127 */
141*37da2899SCharles.Forsyth 	/* [0x3A] */	"T",		trap,	0,	/* page 129 */
142*37da2899SCharles.Forsyth 	/* [0x3B] */	"flush",	add,	0,	/* page 138 */
143*37da2899SCharles.Forsyth 	/* [0x3C] */	"SAVE",		add,	0,	/* page 117 */
144*37da2899SCharles.Forsyth 	/* [0x3D] */	"RESTORE",	add,	0,
145*37da2899SCharles.Forsyth };
146*37da2899SCharles.Forsyth 
147*37da2899SCharles.Forsyth static struct opcode sparcop3[64]={
148*37da2899SCharles.Forsyth 	/* [0x00] */	"ld",		load,	0,
149*37da2899SCharles.Forsyth 	/* [0x01] */	"ldub",		load,	0,
150*37da2899SCharles.Forsyth 	/* [0x02] */	"lduh",		load,	0,
151*37da2899SCharles.Forsyth 	/* [0x03] */	"ldd",		load,	0,
152*37da2899SCharles.Forsyth 	/* [0x04] */	"st",		store,	0,
153*37da2899SCharles.Forsyth 	/* [0x05] */	"stb",		store,	0,	/* page 95 */
154*37da2899SCharles.Forsyth 	/* [0x06] */	"sth",		store,	0,
155*37da2899SCharles.Forsyth 	/* [0x07] */	"std",		store,	0,
156*37da2899SCharles.Forsyth 			0,		0,	0,
157*37da2899SCharles.Forsyth 	/* [0x09] */	"ldsb",		load,	0,	/* page 90 */
158*37da2899SCharles.Forsyth 	/* [0x0A] */	"ldsh",		load,	0,
159*37da2899SCharles.Forsyth 			0,		0,	0,
160*37da2899SCharles.Forsyth 			0,		0,	0,
161*37da2899SCharles.Forsyth 	/* [0x0D] */	"ldstub",	store,	0,	/* page 101 */
162*37da2899SCharles.Forsyth 			0,		0,	0,
163*37da2899SCharles.Forsyth 	/* [0x0F] */	"swap",		load,	0,	/* page 102 */
164*37da2899SCharles.Forsyth 	/* [0x10] */	"lda",		loada,	0,
165*37da2899SCharles.Forsyth 	/* [0x11] */	"lduba",	loada,	0,
166*37da2899SCharles.Forsyth 	/* [0x12] */	"lduha",	loada,	0,
167*37da2899SCharles.Forsyth 	/* [0x13] */	"ldda",		loada,	0,
168*37da2899SCharles.Forsyth 	/* [0x14] */	"sta",		storea,	0,
169*37da2899SCharles.Forsyth 	/* [0x15] */	"stba",		storea,	0,
170*37da2899SCharles.Forsyth 	/* [0x16] */	"stha",		storea,	0,
171*37da2899SCharles.Forsyth 	/* [0x17] */	"stda",		storea,	0,
172*37da2899SCharles.Forsyth 			0,		0,	0,
173*37da2899SCharles.Forsyth 	/* [0x19] */	"ldsba",	loada,	0,
174*37da2899SCharles.Forsyth 	/* [0x1A] */	"ldsha",	loada,	0,
175*37da2899SCharles.Forsyth 			0,		0,	0,
176*37da2899SCharles.Forsyth 			0,		0,	0,
177*37da2899SCharles.Forsyth 	/* [0x1D] */	"ldstuba",	storea,	0,
178*37da2899SCharles.Forsyth 			0,		0,	0,
179*37da2899SCharles.Forsyth 	/* [0x1F] */	"swapa",	loada,	0,
180*37da2899SCharles.Forsyth 	/* [0x20] */	"ldf",		loadf,	0,	/* page 92 */
181*37da2899SCharles.Forsyth 	/* [0x21] */	"ldfsr",	loadf,	0,
182*37da2899SCharles.Forsyth 			0,		0,	0,
183*37da2899SCharles.Forsyth 	/* [0x23] */	"lddf",		loadf,	0,
184*37da2899SCharles.Forsyth 	/* [0x24] */	"stf",		storef,	0,	/* page 97 */
185*37da2899SCharles.Forsyth 	/* [0x25] */	"stfsr",	storef,	0,
186*37da2899SCharles.Forsyth 	/* [0x26] */	"stdfq",	storef,	0,
187*37da2899SCharles.Forsyth 	/* [0x27] */	"stdf",		storef,	0,
188*37da2899SCharles.Forsyth 			0,		0,	0,
189*37da2899SCharles.Forsyth 			0,		0,	0,
190*37da2899SCharles.Forsyth 			0,		0,	0,
191*37da2899SCharles.Forsyth 			0,		0,	0,
192*37da2899SCharles.Forsyth 			0,		0,	0,
193*37da2899SCharles.Forsyth 			0,		0,	0,
194*37da2899SCharles.Forsyth 			0,		0,	0,
195*37da2899SCharles.Forsyth 			0,		0,	0,
196*37da2899SCharles.Forsyth 	/* [0x30] */	"ldc",		loadc,	0,	/* page 94 */
197*37da2899SCharles.Forsyth 	/* [0x31] */	"ldcsr",	loadcsr,0,
198*37da2899SCharles.Forsyth 			0,		0,	0,
199*37da2899SCharles.Forsyth 	/* [0x33] */	"lddc",		loadc,	0,
200*37da2899SCharles.Forsyth 	/* [0x34] */	"stc",		loadc,	0,	/* page 99 */
201*37da2899SCharles.Forsyth 	/* [0x35] */	"stcsr",	loadcsr,0,
202*37da2899SCharles.Forsyth 	/* [0x36] */	"stdcq",	loadcsr,0,
203*37da2899SCharles.Forsyth 	/* [0x37] */	"stdc",		loadc,	0,
204*37da2899SCharles.Forsyth };
205*37da2899SCharles.Forsyth 
206*37da2899SCharles.Forsyth static void
bprint(Instr * i,char * fmt,...)207*37da2899SCharles.Forsyth bprint(Instr *i, char *fmt, ...)
208*37da2899SCharles.Forsyth {
209*37da2899SCharles.Forsyth 	va_list arg;
210*37da2899SCharles.Forsyth 
211*37da2899SCharles.Forsyth 	va_start(arg, fmt);
212*37da2899SCharles.Forsyth 	i->curr = vseprint(i->curr, i->end, fmt, arg);
213*37da2899SCharles.Forsyth 	va_end(arg);
214*37da2899SCharles.Forsyth }
215*37da2899SCharles.Forsyth 
216*37da2899SCharles.Forsyth static int
decode(ulong * pc,Instr * i)217*37da2899SCharles.Forsyth decode(ulong *pc, Instr *i)
218*37da2899SCharles.Forsyth {
219*37da2899SCharles.Forsyth 	ulong w;
220*37da2899SCharles.Forsyth 
221*37da2899SCharles.Forsyth 	w = *pc;
222*37da2899SCharles.Forsyth 
223*37da2899SCharles.Forsyth 	i->op = (w >> 30) & 0x03;
224*37da2899SCharles.Forsyth 	i->rd = (w >> 25) & 0x1F;
225*37da2899SCharles.Forsyth 	i->op2 = (w >> 22) & 0x07;
226*37da2899SCharles.Forsyth 	i->a = (w >> 29) & 0x01;
227*37da2899SCharles.Forsyth 	i->cond = (w >> 25) & 0x0F;
228*37da2899SCharles.Forsyth 	i->op3 = (w >> 19) & 0x3F;
229*37da2899SCharles.Forsyth 	i->rs1 = (w >> 14) & 0x1F;
230*37da2899SCharles.Forsyth 	i->i = (w >> 13) & 0x01;
231*37da2899SCharles.Forsyth 	i->asi = (w >> 5) & 0xFF;
232*37da2899SCharles.Forsyth 	i->rs2 = (w >> 0) & 0x1F;
233*37da2899SCharles.Forsyth 	i->simm13 = (w >> 0) & 0x1FFF;
234*37da2899SCharles.Forsyth 	if(i->simm13 & (1<<12))
235*37da2899SCharles.Forsyth 		i->simm13 |= ~((1<<13)-1);
236*37da2899SCharles.Forsyth 	i->opf = (w >> 5) & 0x1FF;
237*37da2899SCharles.Forsyth 	i->immdisp22 = (w >> 0) & 0x3FFFFF;
238*37da2899SCharles.Forsyth 	i->simmdisp22 = i->immdisp22;
239*37da2899SCharles.Forsyth 	if(i->simmdisp22 & (1<<21))
240*37da2899SCharles.Forsyth 		i->simmdisp22 |= ~((1<<22)-1);
241*37da2899SCharles.Forsyth 	i->disp30 = (w >> 0) & 0x3FFFFFFF;
242*37da2899SCharles.Forsyth 	i->w0 = w;
243*37da2899SCharles.Forsyth 	i->target = -1;
244*37da2899SCharles.Forsyth 	i->addr = (ulong)pc;
245*37da2899SCharles.Forsyth 	i->size = 1;
246*37da2899SCharles.Forsyth 	return 1;
247*37da2899SCharles.Forsyth }
248*37da2899SCharles.Forsyth 
249*37da2899SCharles.Forsyth static int
mkinstr(ulong * pc,Instr * i)250*37da2899SCharles.Forsyth mkinstr(ulong *pc, Instr *i)
251*37da2899SCharles.Forsyth {
252*37da2899SCharles.Forsyth 	Instr xi;
253*37da2899SCharles.Forsyth 
254*37da2899SCharles.Forsyth 	if (decode(pc, i) < 0)
255*37da2899SCharles.Forsyth 		return -1;
256*37da2899SCharles.Forsyth 	if(i->op==0 && i->op2==4 && !dascase){		/* SETHI */
257*37da2899SCharles.Forsyth 		if(decode(pc+1, &xi) < 0)
258*37da2899SCharles.Forsyth 			return -1;
259*37da2899SCharles.Forsyth 		if(xi.op == 2 && xi.op3 == 0)		/* ADD */
260*37da2899SCharles.Forsyth 		if(xi.i == 1 && xi.rs1 == i->rd){	/* immediate to same reg */
261*37da2899SCharles.Forsyth 			i->imm32 = xi.simm13 + (i->immdisp22<<10);
262*37da2899SCharles.Forsyth 			i->target = xi.rd;
263*37da2899SCharles.Forsyth 			i->w1 = xi.w0;
264*37da2899SCharles.Forsyth 			i->size++;
265*37da2899SCharles.Forsyth 			return 1;
266*37da2899SCharles.Forsyth 		}
267*37da2899SCharles.Forsyth 	}
268*37da2899SCharles.Forsyth 	if(i->op==2 && i->opf==1 && !dascase){		/* FMOVS */
269*37da2899SCharles.Forsyth 		if (decode(pc+1, &xi) < 0)
270*37da2899SCharles.Forsyth 			return -1;
271*37da2899SCharles.Forsyth 		if(i->op==2 && i->opf==1)		/* FMOVS */
272*37da2899SCharles.Forsyth 		if(xi.rd==i->rd+1 && xi.rs2==i->rs2+1){	/* next pair */
273*37da2899SCharles.Forsyth 			i->w1 = xi.w0;
274*37da2899SCharles.Forsyth 			i->size++;
275*37da2899SCharles.Forsyth 		}
276*37da2899SCharles.Forsyth 	}
277*37da2899SCharles.Forsyth 	return 1;
278*37da2899SCharles.Forsyth }
279*37da2899SCharles.Forsyth 
280*37da2899SCharles.Forsyth static int
inst(ulong * pc)281*37da2899SCharles.Forsyth inst(ulong *pc)
282*37da2899SCharles.Forsyth {
283*37da2899SCharles.Forsyth 	long disp;
284*37da2899SCharles.Forsyth 	Instr instr;
285*37da2899SCharles.Forsyth 	static char buf[128];
286*37da2899SCharles.Forsyth 	void (*f)(Instr*, char*);
287*37da2899SCharles.Forsyth 
288*37da2899SCharles.Forsyth 	memset(&instr, 0, sizeof(instr));
289*37da2899SCharles.Forsyth 	instr.curr = buf;
290*37da2899SCharles.Forsyth 	instr.end = buf+sizeof(buf)-1;
291*37da2899SCharles.Forsyth 	if(mkinstr(pc, &instr) < 0)
292*37da2899SCharles.Forsyth 		return 4;
293*37da2899SCharles.Forsyth 	switch(instr.op){
294*37da2899SCharles.Forsyth 	case 0:
295*37da2899SCharles.Forsyth 		f = sparcop0[instr.op2].f;
296*37da2899SCharles.Forsyth 		if(f)
297*37da2899SCharles.Forsyth 			(*f)(&instr, sparcop0[instr.op2].mnemonic);
298*37da2899SCharles.Forsyth 		else
299*37da2899SCharles.Forsyth 			bprint(&instr, "unknown 0x%lux", instr.w0);
300*37da2899SCharles.Forsyth 		break;
301*37da2899SCharles.Forsyth 
302*37da2899SCharles.Forsyth 	case 1:
303*37da2899SCharles.Forsyth 		disp = instr.disp30;
304*37da2899SCharles.Forsyth 		disp = (disp<<2)>>2;
305*37da2899SCharles.Forsyth 		bprint(&instr, "CALL\t0x%lux", pc+disp);
306*37da2899SCharles.Forsyth 		if (!dascase)
307*37da2899SCharles.Forsyth 			bprint(&instr, "(SB)");
308*37da2899SCharles.Forsyth 		break;
309*37da2899SCharles.Forsyth 
310*37da2899SCharles.Forsyth 	case 2:
311*37da2899SCharles.Forsyth 		f = sparcop2[instr.op3].f;
312*37da2899SCharles.Forsyth 		if(f)
313*37da2899SCharles.Forsyth 			(*f)(&instr, sparcop2[instr.op3].mnemonic);
314*37da2899SCharles.Forsyth 		else
315*37da2899SCharles.Forsyth 			bprint(&instr, "unknown 0x%lux", instr.w0);
316*37da2899SCharles.Forsyth 		break;
317*37da2899SCharles.Forsyth 
318*37da2899SCharles.Forsyth 	case 3:
319*37da2899SCharles.Forsyth 		f = sparcop3[instr.op3].f;
320*37da2899SCharles.Forsyth 		if(f)
321*37da2899SCharles.Forsyth 			(*f)(&instr, sparcop3[instr.op3].mnemonic);
322*37da2899SCharles.Forsyth 		else
323*37da2899SCharles.Forsyth 			bprint(&instr, "unknown 0x%lux", instr.w0);
324*37da2899SCharles.Forsyth 		break;
325*37da2899SCharles.Forsyth 	}
326*37da2899SCharles.Forsyth 	if (instr.err) {
327*37da2899SCharles.Forsyth 		if (instr.curr != buf)
328*37da2899SCharles.Forsyth 			bprint(&instr, "\t\t;");
329*37da2899SCharles.Forsyth 		bprint(&instr, instr.err);
330*37da2899SCharles.Forsyth 	}
331*37da2899SCharles.Forsyth 	print("\t%.8lux %s\n", (ulong)pc, buf);
332*37da2899SCharles.Forsyth 
333*37da2899SCharles.Forsyth 	return instr.size;
334*37da2899SCharles.Forsyth }
335*37da2899SCharles.Forsyth 
336*37da2899SCharles.Forsyth void
das(ulong * pc,int n)337*37da2899SCharles.Forsyth das(ulong *pc, int n)
338*37da2899SCharles.Forsyth {
339*37da2899SCharles.Forsyth 	ulong *e;
340*37da2899SCharles.Forsyth 
341*37da2899SCharles.Forsyth 	e = pc + n;
342*37da2899SCharles.Forsyth 	while(pc < e)
343*37da2899SCharles.Forsyth 		pc += inst(pc);
344*37da2899SCharles.Forsyth }
345*37da2899SCharles.Forsyth 
346*37da2899SCharles.Forsyth static void
address(Instr * i)347*37da2899SCharles.Forsyth address(Instr *i)
348*37da2899SCharles.Forsyth {
349*37da2899SCharles.Forsyth 	bprint(i, "0x%lux(R%d)", i->simm13, i->rs1);
350*37da2899SCharles.Forsyth }
351*37da2899SCharles.Forsyth 
352*37da2899SCharles.Forsyth static void
unimp(Instr * i,char * m)353*37da2899SCharles.Forsyth unimp(Instr *i, char *m)
354*37da2899SCharles.Forsyth {
355*37da2899SCharles.Forsyth 	bprint(i, "%s", m);
356*37da2899SCharles.Forsyth }
357*37da2899SCharles.Forsyth 
358*37da2899SCharles.Forsyth static char	*bratab[16] = {	/* page 91 */
359*37da2899SCharles.Forsyth 	/* [0x0] */	"N",
360*37da2899SCharles.Forsyth 	/* [0x1] */	"E",
361*37da2899SCharles.Forsyth 	/* [0x2] */	"LE",
362*37da2899SCharles.Forsyth 	/* [0x3] */	"L",
363*37da2899SCharles.Forsyth 	/* [0x4] */	"LEU",
364*37da2899SCharles.Forsyth 	/* [0x5] */	"CS",
365*37da2899SCharles.Forsyth 	/* [0x6] */	"NEG",
366*37da2899SCharles.Forsyth 	/* [0x7] */	"VS",
367*37da2899SCharles.Forsyth 	/* [0x8] */	"A",
368*37da2899SCharles.Forsyth 	/* [0x9] */	"NE",
369*37da2899SCharles.Forsyth 	/* [0xA] */	"G",
370*37da2899SCharles.Forsyth 	/* [0xB] */	"GE",
371*37da2899SCharles.Forsyth 	/* [0xC] */	"GU",
372*37da2899SCharles.Forsyth 	/* [0xD] */	"CC",
373*37da2899SCharles.Forsyth 	/* [0xE] */	"POS",
374*37da2899SCharles.Forsyth 	/* [0xF] */	"VC",
375*37da2899SCharles.Forsyth };
376*37da2899SCharles.Forsyth 
377*37da2899SCharles.Forsyth static char	*fbratab[16] = {	/* page 91 */
378*37da2899SCharles.Forsyth 	/* [0x0] */	"N",
379*37da2899SCharles.Forsyth 	/* [0x1] */	"NE",
380*37da2899SCharles.Forsyth 	/* [0x2] */	"LG",
381*37da2899SCharles.Forsyth 	/* [0x3] */	"UL",
382*37da2899SCharles.Forsyth 	/* [0x4] */	"L",
383*37da2899SCharles.Forsyth 	/* [0x5] */	"UG",
384*37da2899SCharles.Forsyth 	/* [0x6] */	"G",
385*37da2899SCharles.Forsyth 	/* [0x7] */	"U",
386*37da2899SCharles.Forsyth 	/* [0x8] */	"A",
387*37da2899SCharles.Forsyth 	/* [0x9] */	"E",
388*37da2899SCharles.Forsyth 	/* [0xA] */	"UE",
389*37da2899SCharles.Forsyth 	/* [0xB] */	"GE",
390*37da2899SCharles.Forsyth 	/* [0xC] */	"UGE",
391*37da2899SCharles.Forsyth 	/* [0xD] */	"LE",
392*37da2899SCharles.Forsyth 	/* [0xE] */	"ULE",
393*37da2899SCharles.Forsyth 	/* [0xF] */	"O",
394*37da2899SCharles.Forsyth };
395*37da2899SCharles.Forsyth 
396*37da2899SCharles.Forsyth static char	*cbratab[16] = {	/* page 91 */
397*37da2899SCharles.Forsyth 	/* [0x0] */	"N",
398*37da2899SCharles.Forsyth 	/* [0x1] */	"123",
399*37da2899SCharles.Forsyth 	/* [0x2] */	"12",
400*37da2899SCharles.Forsyth 	/* [0x3] */	"13",
401*37da2899SCharles.Forsyth 	/* [0x4] */	"1",
402*37da2899SCharles.Forsyth 	/* [0x5] */	"23",
403*37da2899SCharles.Forsyth 	/* [0x6] */	"2",
404*37da2899SCharles.Forsyth 	/* [0x7] */	"3",
405*37da2899SCharles.Forsyth 	/* [0x8] */	"A",
406*37da2899SCharles.Forsyth 	/* [0x9] */	"0",
407*37da2899SCharles.Forsyth 	/* [0xA] */	"03",
408*37da2899SCharles.Forsyth 	/* [0xB] */	"02",
409*37da2899SCharles.Forsyth 	/* [0xC] */	"023",
410*37da2899SCharles.Forsyth 	/* [0xD] */	"01",
411*37da2899SCharles.Forsyth 	/* [0xE] */	"013",
412*37da2899SCharles.Forsyth 	/* [0xF] */	"012",
413*37da2899SCharles.Forsyth };
414*37da2899SCharles.Forsyth 
415*37da2899SCharles.Forsyth static void
bra1(Instr * i,char * m,char * tab[])416*37da2899SCharles.Forsyth bra1(Instr *i, char *m, char *tab[])
417*37da2899SCharles.Forsyth {
418*37da2899SCharles.Forsyth 	long imm;
419*37da2899SCharles.Forsyth 
420*37da2899SCharles.Forsyth 	imm = i->simmdisp22;
421*37da2899SCharles.Forsyth 	if(i->a)
422*37da2899SCharles.Forsyth 		bprint(i, "%s%s.%c\t", m, tab[i->cond], 'A'+dascase);
423*37da2899SCharles.Forsyth 	else
424*37da2899SCharles.Forsyth 		bprint(i, "%s%s\t", m, tab[i->cond]);
425*37da2899SCharles.Forsyth 	bprint(i, "0x%lux", i->addr+4*imm);
426*37da2899SCharles.Forsyth 	if (!dascase)
427*37da2899SCharles.Forsyth 		bprint(i, "(SB)");
428*37da2899SCharles.Forsyth }
429*37da2899SCharles.Forsyth 
430*37da2899SCharles.Forsyth static void
bra(Instr * i,char * m)431*37da2899SCharles.Forsyth bra(Instr *i, char *m)			/* page 91 */
432*37da2899SCharles.Forsyth {
433*37da2899SCharles.Forsyth 	bra1(i, m, bratab);
434*37da2899SCharles.Forsyth }
435*37da2899SCharles.Forsyth 
436*37da2899SCharles.Forsyth static void
fbra(Instr * i,char * m)437*37da2899SCharles.Forsyth fbra(Instr *i, char *m)			/* page 93 */
438*37da2899SCharles.Forsyth {
439*37da2899SCharles.Forsyth 	bra1(i, m, fbratab);
440*37da2899SCharles.Forsyth }
441*37da2899SCharles.Forsyth 
442*37da2899SCharles.Forsyth static void
cbra(Instr * i,char * m)443*37da2899SCharles.Forsyth cbra(Instr *i, char *m)			/* page 95 */
444*37da2899SCharles.Forsyth {
445*37da2899SCharles.Forsyth 	bra1(i, m, cbratab);
446*37da2899SCharles.Forsyth }
447*37da2899SCharles.Forsyth 
448*37da2899SCharles.Forsyth static void
trap(Instr * i,char * m)449*37da2899SCharles.Forsyth trap(Instr *i, char *m)			/* page 101 */
450*37da2899SCharles.Forsyth {
451*37da2899SCharles.Forsyth 	if(i->i == 0)
452*37da2899SCharles.Forsyth 		bprint(i, "%s%s\tR%d+R%d", m, bratab[i->cond], i->rs2, i->rs1);
453*37da2899SCharles.Forsyth 	else
454*37da2899SCharles.Forsyth 		bprint(i, "%s%s\t$0x%lux+R%d", m, bratab[i->cond], i->simm13, i->rs1);
455*37da2899SCharles.Forsyth }
456*37da2899SCharles.Forsyth 
457*37da2899SCharles.Forsyth static void
sethi(Instr * i,char * m)458*37da2899SCharles.Forsyth sethi(Instr *i, char *m)		/* page 89 */
459*37da2899SCharles.Forsyth {
460*37da2899SCharles.Forsyth 	ulong imm;
461*37da2899SCharles.Forsyth 
462*37da2899SCharles.Forsyth 	imm = i->immdisp22<<10;
463*37da2899SCharles.Forsyth 	if(dascase){
464*37da2899SCharles.Forsyth 		bprint(i, "%s\t0x%lux, R%d", m, imm, i->rd);
465*37da2899SCharles.Forsyth 		return;
466*37da2899SCharles.Forsyth 	}
467*37da2899SCharles.Forsyth 	if(imm==0 && i->rd==0){
468*37da2899SCharles.Forsyth 		bprint(i, "NOP");
469*37da2899SCharles.Forsyth 		return;
470*37da2899SCharles.Forsyth 	}
471*37da2899SCharles.Forsyth 	if(i->target < 0){
472*37da2899SCharles.Forsyth 		bprint(i, "MOVW\t$0x%lux, R%d", imm, i->rd);
473*37da2899SCharles.Forsyth 		return;
474*37da2899SCharles.Forsyth 	}
475*37da2899SCharles.Forsyth 	bprint(i, "MOVW\t$0x%lux, R%d", i->imm32, i->target);
476*37da2899SCharles.Forsyth }
477*37da2899SCharles.Forsyth 
478*37da2899SCharles.Forsyth static char ldtab[] = {
479*37da2899SCharles.Forsyth 	'W',
480*37da2899SCharles.Forsyth 	'B',
481*37da2899SCharles.Forsyth 	'H',
482*37da2899SCharles.Forsyth 	'D',
483*37da2899SCharles.Forsyth };
484*37da2899SCharles.Forsyth 
485*37da2899SCharles.Forsyth static char*
moveinstr(int op3,char * m)486*37da2899SCharles.Forsyth moveinstr(int op3, char *m)
487*37da2899SCharles.Forsyth {
488*37da2899SCharles.Forsyth 	char *s;
489*37da2899SCharles.Forsyth 	int c;
490*37da2899SCharles.Forsyth 	static char buf[8];
491*37da2899SCharles.Forsyth 
492*37da2899SCharles.Forsyth 	if(!dascase){
493*37da2899SCharles.Forsyth 		/* batshit cases */
494*37da2899SCharles.Forsyth 		if(op3 == 0xF || op3 == 0x1F)
495*37da2899SCharles.Forsyth 			return "SWAP";
496*37da2899SCharles.Forsyth 		if(op3 == 0xD || op3 == 0x1D)
497*37da2899SCharles.Forsyth 			return "TAS";	/* really LDSTUB */
498*37da2899SCharles.Forsyth 		c = ldtab[op3&3];
499*37da2899SCharles.Forsyth 		s = "";
500*37da2899SCharles.Forsyth 		if((op3&11)==1 || (op3&11)==2)
501*37da2899SCharles.Forsyth 			s="U";
502*37da2899SCharles.Forsyth 		sprint(buf, "MOV%c%s", c, s);
503*37da2899SCharles.Forsyth 		return buf;
504*37da2899SCharles.Forsyth 	}
505*37da2899SCharles.Forsyth 	return m;
506*37da2899SCharles.Forsyth }
507*37da2899SCharles.Forsyth 
508*37da2899SCharles.Forsyth static void
load(Instr * i,char * m)509*37da2899SCharles.Forsyth load(Instr *i, char *m)			/* page 68 */
510*37da2899SCharles.Forsyth {
511*37da2899SCharles.Forsyth 	m = moveinstr(i->op3, m);
512*37da2899SCharles.Forsyth 	if(i->i == 0)
513*37da2899SCharles.Forsyth 		bprint(i, "%s\t(R%d+R%d), R%d", m, i->rs1, i->rs2, i->rd);
514*37da2899SCharles.Forsyth 	else{
515*37da2899SCharles.Forsyth 		bprint(i, "%s\t", m);
516*37da2899SCharles.Forsyth 		address(i);
517*37da2899SCharles.Forsyth 		bprint(i, ", R%d", i->rd);
518*37da2899SCharles.Forsyth 	}
519*37da2899SCharles.Forsyth }
520*37da2899SCharles.Forsyth 
521*37da2899SCharles.Forsyth static void
loada(Instr * i,char * m)522*37da2899SCharles.Forsyth loada(Instr *i, char *m)		/* page 68 */
523*37da2899SCharles.Forsyth {
524*37da2899SCharles.Forsyth 	m = moveinstr(i->op3, m);
525*37da2899SCharles.Forsyth 	if(i->i == 0)
526*37da2899SCharles.Forsyth 		bprint(i, "%s\t(R%d+R%d, %d), R%d", m, i->rs1, i->rs2, i->asi, i->rd);
527*37da2899SCharles.Forsyth 	else
528*37da2899SCharles.Forsyth 		bprint(i, "unknown ld asi 0x%lux", i->w0);
529*37da2899SCharles.Forsyth }
530*37da2899SCharles.Forsyth 
531*37da2899SCharles.Forsyth static void
store(Instr * i,char * m)532*37da2899SCharles.Forsyth store(Instr *i, char *m)		/* page 74 */
533*37da2899SCharles.Forsyth {
534*37da2899SCharles.Forsyth 	m = moveinstr(i->op3, m);
535*37da2899SCharles.Forsyth 	if(i->i == 0)
536*37da2899SCharles.Forsyth 		bprint(i, "%s\tR%d, (R%d+R%d)",
537*37da2899SCharles.Forsyth 				m, i->rd, i->rs1, i->rs2);
538*37da2899SCharles.Forsyth 	else{
539*37da2899SCharles.Forsyth 		bprint(i, "%s\tR%d, ", m, i->rd);
540*37da2899SCharles.Forsyth 		address(i);
541*37da2899SCharles.Forsyth 	}
542*37da2899SCharles.Forsyth }
543*37da2899SCharles.Forsyth 
544*37da2899SCharles.Forsyth static void
storea(Instr * i,char * m)545*37da2899SCharles.Forsyth storea(Instr *i, char *m)		/* page 74 */
546*37da2899SCharles.Forsyth {
547*37da2899SCharles.Forsyth 	m = moveinstr(i->op3, m);
548*37da2899SCharles.Forsyth 	if(i->i == 0)
549*37da2899SCharles.Forsyth 		bprint(i, "%s\tR%d, (R%d+R%d, %d)", m, i->rd, i->rs1, i->rs2, i->asi);
550*37da2899SCharles.Forsyth 	else
551*37da2899SCharles.Forsyth 		bprint(i, "%s\tR%d, %d(R%d, %d), ???", m, i->rd, i->simm13, i->rs1, i->asi);
552*37da2899SCharles.Forsyth }
553*37da2899SCharles.Forsyth 
554*37da2899SCharles.Forsyth static void
shift(Instr * i,char * m)555*37da2899SCharles.Forsyth shift(Instr *i, char *m)	/* page 88 */
556*37da2899SCharles.Forsyth {
557*37da2899SCharles.Forsyth 	if(i->i == 0){
558*37da2899SCharles.Forsyth 		if(i->rs1 == i->rd)
559*37da2899SCharles.Forsyth 			if(dascase)
560*37da2899SCharles.Forsyth 				bprint(i, "%s\tR%d, R%d", m, i->rs1, i->rs2);
561*37da2899SCharles.Forsyth 			else
562*37da2899SCharles.Forsyth 				bprint(i, "%s\tR%d, R%d", m, i->rs2, i->rs1);
563*37da2899SCharles.Forsyth 		else
564*37da2899SCharles.Forsyth 			if(dascase)
565*37da2899SCharles.Forsyth 				bprint(i, "%s\tR%d, R%d, R%d", m, i->rs1, i->rs2, i->rd);
566*37da2899SCharles.Forsyth 			else
567*37da2899SCharles.Forsyth 				bprint(i, "%s\tR%d, R%d, R%d", m, i->rs2, i->rs1, i->rd);
568*37da2899SCharles.Forsyth 	}else{
569*37da2899SCharles.Forsyth 		if(i->rs1 == i->rd)
570*37da2899SCharles.Forsyth 			if(dascase)
571*37da2899SCharles.Forsyth 				bprint(i, "%s\t$%d,R%d", m, i->simm13&0x1F, i->rs1);
572*37da2899SCharles.Forsyth 			else
573*37da2899SCharles.Forsyth 				bprint(i, "%s\tR%d, $%d", m,  i->rs1, i->simm13&0x1F);
574*37da2899SCharles.Forsyth 		else
575*37da2899SCharles.Forsyth 			if(dascase)
576*37da2899SCharles.Forsyth 				bprint(i, "%s\tR%d, $%d, R%d",m,i->rs1,i->simm13&0x1F,i->rd);
577*37da2899SCharles.Forsyth 			else
578*37da2899SCharles.Forsyth 				bprint(i, "%s\t$%d, R%d, R%d",m,i->simm13&0x1F,i->rs1,i->rd);
579*37da2899SCharles.Forsyth 	}
580*37da2899SCharles.Forsyth }
581*37da2899SCharles.Forsyth 
582*37da2899SCharles.Forsyth static void
add(Instr * i,char * m)583*37da2899SCharles.Forsyth add(Instr *i, char *m)	/* page 82 */
584*37da2899SCharles.Forsyth {
585*37da2899SCharles.Forsyth 	if(i->i == 0){
586*37da2899SCharles.Forsyth 		if(dascase)
587*37da2899SCharles.Forsyth 			bprint(i, "%s\tR%d, R%d", m, i->rs1, i->rs2);
588*37da2899SCharles.Forsyth 		else
589*37da2899SCharles.Forsyth 			if(i->op3==2 && i->rs1==0 && i->rd)  /* OR R2, R0, R1 */
590*37da2899SCharles.Forsyth 				bprint(i, "MOVW\tR%d", i->rs2);
591*37da2899SCharles.Forsyth 			else
592*37da2899SCharles.Forsyth 				bprint(i, "%s\tR%d, R%d", m, i->rs2, i->rs1);
593*37da2899SCharles.Forsyth 	}else{
594*37da2899SCharles.Forsyth 		if(dascase)
595*37da2899SCharles.Forsyth 			bprint(i, "%s\tR%d, $0x%lux", m, i->rs1, i->simm13);
596*37da2899SCharles.Forsyth 		else
597*37da2899SCharles.Forsyth 			if(i->op3==0 && i->rd && i->rs1==0)	/* ADD $x, R0, R1 */
598*37da2899SCharles.Forsyth 				bprint(i, "MOVW\t$0x%lux", i->simm13);
599*37da2899SCharles.Forsyth 			else if(i->op3==0 && i->rd && i->rs1==2){
600*37da2899SCharles.Forsyth 				/* ADD $x, R2, R1 -> MOVW $x(SB), R1 */
601*37da2899SCharles.Forsyth 				bprint(i, "MOVW\t$");
602*37da2899SCharles.Forsyth 				address(i);
603*37da2899SCharles.Forsyth 			} else
604*37da2899SCharles.Forsyth 				bprint(i, "%s\t$0x%lux, R%d", m, i->simm13, i->rs1);
605*37da2899SCharles.Forsyth 	}
606*37da2899SCharles.Forsyth 	if(i->rs1 != i->rd)
607*37da2899SCharles.Forsyth 		bprint(i, ", R%d", i->rd);
608*37da2899SCharles.Forsyth }
609*37da2899SCharles.Forsyth 
610*37da2899SCharles.Forsyth static void
cmp(Instr * i,char * m)611*37da2899SCharles.Forsyth cmp(Instr *i, char *m)
612*37da2899SCharles.Forsyth {
613*37da2899SCharles.Forsyth 	if(dascase || i->rd){
614*37da2899SCharles.Forsyth 		add(i, m);
615*37da2899SCharles.Forsyth 		return;
616*37da2899SCharles.Forsyth 	}
617*37da2899SCharles.Forsyth 	if(i->i == 0)
618*37da2899SCharles.Forsyth 		bprint(i, "CMP\tR%d, R%d", i->rs1, i->rs2);
619*37da2899SCharles.Forsyth 	else
620*37da2899SCharles.Forsyth 		bprint(i, "CMP\tR%d, $0x%lux", i->rs1, i->simm13);
621*37da2899SCharles.Forsyth }
622*37da2899SCharles.Forsyth 
623*37da2899SCharles.Forsyth static char *regtab[4] =
624*37da2899SCharles.Forsyth {
625*37da2899SCharles.Forsyth 	"Y",
626*37da2899SCharles.Forsyth 	"PSR",
627*37da2899SCharles.Forsyth 	"WIM",
628*37da2899SCharles.Forsyth 	"TBR",
629*37da2899SCharles.Forsyth };
630*37da2899SCharles.Forsyth 
631*37da2899SCharles.Forsyth static void
wr(Instr * i,char * m)632*37da2899SCharles.Forsyth wr(Instr *i, char *m)		/* page 82 */
633*37da2899SCharles.Forsyth {
634*37da2899SCharles.Forsyth 	if(dascase){
635*37da2899SCharles.Forsyth 		if(i->i == 0)
636*37da2899SCharles.Forsyth 			bprint(i, "%s\tR%d, R%d", m, i->rs1, i->rs2);
637*37da2899SCharles.Forsyth 		else
638*37da2899SCharles.Forsyth 			bprint(i, "%s\tR%d, $0x%lux", m, i->rs1, i->simm13);
639*37da2899SCharles.Forsyth 	}else{
640*37da2899SCharles.Forsyth 		if(i->i && i->simm13==0)
641*37da2899SCharles.Forsyth 			bprint(i, "MOVW\tR%d", i->rs1);
642*37da2899SCharles.Forsyth 		else if(i->i == 0)
643*37da2899SCharles.Forsyth 			bprint(i, "wr\tR%d, R%d", i->rs2, i->rs1);
644*37da2899SCharles.Forsyth 		else
645*37da2899SCharles.Forsyth 			bprint(i, "wr\t$0x%lux, R%d", i->simm13, i->rs1);
646*37da2899SCharles.Forsyth 	}
647*37da2899SCharles.Forsyth 	bprint(i, ", %s", regtab[i->op3&3]);
648*37da2899SCharles.Forsyth }
649*37da2899SCharles.Forsyth 
650*37da2899SCharles.Forsyth static void
rd(Instr * i,char * m)651*37da2899SCharles.Forsyth rd(Instr *i, char *m)		/* page 103 */
652*37da2899SCharles.Forsyth {
653*37da2899SCharles.Forsyth 	if(i->rs1==15 && i->rd==0){
654*37da2899SCharles.Forsyth 		m = "stbar";
655*37da2899SCharles.Forsyth 		if(!dascase)
656*37da2899SCharles.Forsyth 			m = "STBAR";
657*37da2899SCharles.Forsyth 		bprint(i, "%s", m);
658*37da2899SCharles.Forsyth 	}else{
659*37da2899SCharles.Forsyth 		if(!dascase)
660*37da2899SCharles.Forsyth 			m = "MOVW";
661*37da2899SCharles.Forsyth 		bprint(i, "%s\t%s, R%d", m, regtab[i->op3&3], i->rd);
662*37da2899SCharles.Forsyth 	}
663*37da2899SCharles.Forsyth }
664*37da2899SCharles.Forsyth 
665*37da2899SCharles.Forsyth static void
jmpl(Instr * i,char * m)666*37da2899SCharles.Forsyth jmpl(Instr *i, char *m)		/* page 82 */
667*37da2899SCharles.Forsyth {
668*37da2899SCharles.Forsyth 	if(i->i == 0){
669*37da2899SCharles.Forsyth 		if(i->rd == 15)
670*37da2899SCharles.Forsyth 			bprint(i, "CALL\t(R%d+R%d)", i->rs2, i->rs1);
671*37da2899SCharles.Forsyth 		else
672*37da2899SCharles.Forsyth 			bprint(i, "%s\t(R%d+R%d), R%d", m, i->rs2, i->rs1, i->rd);
673*37da2899SCharles.Forsyth 	}else{
674*37da2899SCharles.Forsyth 		if(!dascase && i->simm13==8 && i->rs1==15 && i->rd==0)
675*37da2899SCharles.Forsyth 			bprint(i, "RETURN");
676*37da2899SCharles.Forsyth 		else{
677*37da2899SCharles.Forsyth 			bprint(i, "%s\t", m);
678*37da2899SCharles.Forsyth 			address(i);
679*37da2899SCharles.Forsyth 			bprint(i, ", R%d", i->rd);
680*37da2899SCharles.Forsyth 		}
681*37da2899SCharles.Forsyth 	}
682*37da2899SCharles.Forsyth }
683*37da2899SCharles.Forsyth 
684*37da2899SCharles.Forsyth static void
loadf(Instr * i,char * m)685*37da2899SCharles.Forsyth loadf(Instr *i, char *m)		/* page 70 */
686*37da2899SCharles.Forsyth {
687*37da2899SCharles.Forsyth 	if(!dascase){
688*37da2899SCharles.Forsyth 		m = "FMOVD";
689*37da2899SCharles.Forsyth 		if(i->op3 == 0x20)
690*37da2899SCharles.Forsyth 			m = "FMOVF";
691*37da2899SCharles.Forsyth 		else if(i->op3 == 0x21)
692*37da2899SCharles.Forsyth 			m = "MOVW";
693*37da2899SCharles.Forsyth 	}
694*37da2899SCharles.Forsyth 	if(i->i == 0)
695*37da2899SCharles.Forsyth 		bprint(i, "%s\t(R%d+R%d)", m, i->rs1, i->rs2);
696*37da2899SCharles.Forsyth 	else{
697*37da2899SCharles.Forsyth 		bprint(i, "%s\t", m);
698*37da2899SCharles.Forsyth 		address(i);
699*37da2899SCharles.Forsyth 	}
700*37da2899SCharles.Forsyth 	if(i->op3 == 0x21)
701*37da2899SCharles.Forsyth 		bprint(i, ", FSR");
702*37da2899SCharles.Forsyth 	else
703*37da2899SCharles.Forsyth 		bprint(i, ", R%d", i->rd);
704*37da2899SCharles.Forsyth }
705*37da2899SCharles.Forsyth 
706*37da2899SCharles.Forsyth static
storef(Instr * i,char * m)707*37da2899SCharles.Forsyth void storef(Instr *i, char *m)		/* page 70 */
708*37da2899SCharles.Forsyth {
709*37da2899SCharles.Forsyth 	if(!dascase){
710*37da2899SCharles.Forsyth 		m = "FMOVD";
711*37da2899SCharles.Forsyth 		if(i->op3 == 0x25 || i->op3 == 0x26)
712*37da2899SCharles.Forsyth 			m = "MOVW";
713*37da2899SCharles.Forsyth 		else if(i->op3 == 0x24)
714*37da2899SCharles.Forsyth 			m = "FMOVF";
715*37da2899SCharles.Forsyth 	}
716*37da2899SCharles.Forsyth 	bprint(i, "%s\t", m);
717*37da2899SCharles.Forsyth 	if(i->op3 == 0x25)
718*37da2899SCharles.Forsyth 		bprint(i, "FSR, ");
719*37da2899SCharles.Forsyth 	else if(i->op3 == 0x26)
720*37da2899SCharles.Forsyth 		bprint(i, "FQ, ");
721*37da2899SCharles.Forsyth 	else
722*37da2899SCharles.Forsyth 		bprint(i, "R%d, ", i->rd);
723*37da2899SCharles.Forsyth 	if(i->i == 0)
724*37da2899SCharles.Forsyth 		bprint(i, "(R%d+R%d)", i->rs1, i->rs2);
725*37da2899SCharles.Forsyth 	else
726*37da2899SCharles.Forsyth 		address(i);
727*37da2899SCharles.Forsyth }
728*37da2899SCharles.Forsyth 
729*37da2899SCharles.Forsyth static
loadc(Instr * i,char * m)730*37da2899SCharles.Forsyth void loadc(Instr *i, char *m)			/* page 72 */
731*37da2899SCharles.Forsyth {
732*37da2899SCharles.Forsyth 	if(i->i == 0)
733*37da2899SCharles.Forsyth 		bprint(i, "%s\t(R%d+R%d), C%d", m, i->rs1, i->rs2, i->rd);
734*37da2899SCharles.Forsyth 	else{
735*37da2899SCharles.Forsyth 		bprint(i, "%s\t", m);
736*37da2899SCharles.Forsyth 		address(i);
737*37da2899SCharles.Forsyth 		bprint(i, ", C%d", i->rd);
738*37da2899SCharles.Forsyth 	}
739*37da2899SCharles.Forsyth }
740*37da2899SCharles.Forsyth 
741*37da2899SCharles.Forsyth static
loadcsr(Instr * i,char * m)742*37da2899SCharles.Forsyth void loadcsr(Instr *i, char *m)			/* page 72 */
743*37da2899SCharles.Forsyth {
744*37da2899SCharles.Forsyth 	if(i->i == 0)
745*37da2899SCharles.Forsyth 		bprint(i, "%s\t(R%d+R%d), CSR", m, i->rs1, i->rs2);
746*37da2899SCharles.Forsyth 	else{
747*37da2899SCharles.Forsyth 		bprint(i, "%s\t", m);
748*37da2899SCharles.Forsyth 		address(i);
749*37da2899SCharles.Forsyth 		bprint(i, ", CSR");
750*37da2899SCharles.Forsyth 	}
751*37da2899SCharles.Forsyth }
752*37da2899SCharles.Forsyth 
753*37da2899SCharles.Forsyth static struct
754*37da2899SCharles.Forsyth {
755*37da2899SCharles.Forsyth 	int	opf;
756*37da2899SCharles.Forsyth 	char	*name;
757*37da2899SCharles.Forsyth } fptab1[] = {			/* ignores rs1 */
758*37da2899SCharles.Forsyth 	0xC4,	"FITOS",	/* page 109 */
759*37da2899SCharles.Forsyth 	0xC8,	"FITOD",
760*37da2899SCharles.Forsyth 	0xCC,	"FITOX",
761*37da2899SCharles.Forsyth 
762*37da2899SCharles.Forsyth 	0xD1,	"FSTOI",	/* page 110 */
763*37da2899SCharles.Forsyth 	0xD2,	"FDTOI",
764*37da2899SCharles.Forsyth 	0xD3,	"FXTOI",
765*37da2899SCharles.Forsyth 
766*37da2899SCharles.Forsyth 	0xC9,	"FSTOD",	/* page 111 */
767*37da2899SCharles.Forsyth 	0xCD,	"FSTOX",
768*37da2899SCharles.Forsyth 	0xC6,	"FDTOS",
769*37da2899SCharles.Forsyth 	0xCE,	"FDTOX",
770*37da2899SCharles.Forsyth 	0xC7,	"FXTOS",
771*37da2899SCharles.Forsyth 	0xCB,	"FXTOD",
772*37da2899SCharles.Forsyth 
773*37da2899SCharles.Forsyth 	0x01,	"FMOVS",	/* page 112 */
774*37da2899SCharles.Forsyth 	0x05,	"FNEGS",
775*37da2899SCharles.Forsyth 	0x09,	"FABSS",
776*37da2899SCharles.Forsyth 
777*37da2899SCharles.Forsyth 	0x29,	"FSQRTS", 	/* page 113 */
778*37da2899SCharles.Forsyth 	0x2A,	"FSQRTD",
779*37da2899SCharles.Forsyth 	0x2B,	"FSQRTX",
780*37da2899SCharles.Forsyth 
781*37da2899SCharles.Forsyth 	0,	0,
782*37da2899SCharles.Forsyth };
783*37da2899SCharles.Forsyth 
784*37da2899SCharles.Forsyth static struct{
785*37da2899SCharles.Forsyth 	int	opf;
786*37da2899SCharles.Forsyth 	char	*name;
787*37da2899SCharles.Forsyth } fptab2[] = {			/* uses rs1 */
788*37da2899SCharles.Forsyth 
789*37da2899SCharles.Forsyth 	0x41,	"FADDS",	/* page 114 */
790*37da2899SCharles.Forsyth 	0x42,	"FADDD",
791*37da2899SCharles.Forsyth 	0x43,	"FADDX",
792*37da2899SCharles.Forsyth 	0x45,	"FSUBS",
793*37da2899SCharles.Forsyth 	0x46,	"FSUBD",
794*37da2899SCharles.Forsyth 	0x47,	"FSUBX",
795*37da2899SCharles.Forsyth 
796*37da2899SCharles.Forsyth 	0x49,	"FMULS",	/* page 115 */
797*37da2899SCharles.Forsyth 	0x4A,	"FMULD",
798*37da2899SCharles.Forsyth 	0x4B,	"FMULX",
799*37da2899SCharles.Forsyth 	0x4D,	"FDIVS",
800*37da2899SCharles.Forsyth 	0x4E,	"FDIVD",
801*37da2899SCharles.Forsyth 	0x4F,	"FDIVX",
802*37da2899SCharles.Forsyth 
803*37da2899SCharles.Forsyth 	0x51,	"FCMPS",	/* page 116 */
804*37da2899SCharles.Forsyth 	0x52,	"FCMPD",
805*37da2899SCharles.Forsyth 	0x53,	"FCMPX",
806*37da2899SCharles.Forsyth 	0x55,	"FCMPES",
807*37da2899SCharles.Forsyth 	0x56,	"FCMPED",
808*37da2899SCharles.Forsyth 	0x57,	"FCMPEX",
809*37da2899SCharles.Forsyth 
810*37da2899SCharles.Forsyth 	0, 0
811*37da2899SCharles.Forsyth };
812*37da2899SCharles.Forsyth 
813*37da2899SCharles.Forsyth static void
fpop(Instr * i,char * m)814*37da2899SCharles.Forsyth fpop(Instr *i, char *m)	/* page 108-116 */
815*37da2899SCharles.Forsyth {
816*37da2899SCharles.Forsyth 	int j;
817*37da2899SCharles.Forsyth 
818*37da2899SCharles.Forsyth 	if(dascase==0 && i->size==2){
819*37da2899SCharles.Forsyth 		bprint(i, "FMOVD\tF%d, F%d", i->rs2, i->rd);
820*37da2899SCharles.Forsyth 		return;
821*37da2899SCharles.Forsyth 	}
822*37da2899SCharles.Forsyth 	for(j=0; fptab1[j].name; j++)
823*37da2899SCharles.Forsyth 		if(fptab1[j].opf == i->opf){
824*37da2899SCharles.Forsyth 			bprint(i, "%s\tF%d, F%d", fptab1[j].name, i->rs2, i->rd);
825*37da2899SCharles.Forsyth 			return;
826*37da2899SCharles.Forsyth 		}
827*37da2899SCharles.Forsyth 	for(j=0; fptab2[j].name; j++)
828*37da2899SCharles.Forsyth 		if(fptab2[j].opf == i->opf){
829*37da2899SCharles.Forsyth 			bprint(i, "%s\tF%d, F%d, F%d", fptab2[j].name, i->rs1, i->rs2, i->rd);
830*37da2899SCharles.Forsyth 			return;
831*37da2899SCharles.Forsyth 		}
832*37da2899SCharles.Forsyth 	bprint(i, "%s%ux\tF%d, F%d, F%d", m, i->opf, i->rs1, i->rs2, i->rd);
833*37da2899SCharles.Forsyth }
834