xref: /plan9/sys/src/libmach/alphadb.c (revision 473d4f4b3fed09ca133e03643ec71c9150b33bcc)
1*473d4f4bSDavid du Colombier #include <u.h>
2*473d4f4bSDavid du Colombier #include <libc.h>
3*473d4f4bSDavid du Colombier #include <bio.h>
4*473d4f4bSDavid du Colombier #include <mach.h>
5*473d4f4bSDavid du Colombier /*
6*473d4f4bSDavid du Colombier  * Alpha-specific debugger interface
7*473d4f4bSDavid du Colombier  */
8*473d4f4bSDavid du Colombier 
9*473d4f4bSDavid du Colombier static 	char	*alphaexcep(Map*, Rgetter);
10*473d4f4bSDavid du Colombier static	int	alphafoll(Map*, uvlong, Rgetter, uvlong*);
11*473d4f4bSDavid du Colombier static	int	alphainst(Map*, uvlong, char, char*, int);
12*473d4f4bSDavid du Colombier static	int	alphadas(Map*, uvlong, char*, int);
13*473d4f4bSDavid du Colombier static	int	alphainstlen(Map*, uvlong);
14*473d4f4bSDavid du Colombier /*
15*473d4f4bSDavid du Colombier  *	Debugger interface
16*473d4f4bSDavid du Colombier  */
17*473d4f4bSDavid du Colombier Machdata alphamach =
18*473d4f4bSDavid du Colombier {
19*473d4f4bSDavid du Colombier 	{0x80, 0, 0, 0},		/* break point */
20*473d4f4bSDavid du Colombier 	4,			/* break point size */
21*473d4f4bSDavid du Colombier 
22*473d4f4bSDavid du Colombier 	leswab,			/* short to local byte order */
23*473d4f4bSDavid du Colombier 	leswal,			/* long to local byte order */
24*473d4f4bSDavid du Colombier 	leswav,			/* vlong to local byte order */
25*473d4f4bSDavid du Colombier 	risctrace,		/* C traceback */
26*473d4f4bSDavid du Colombier 	riscframe,		/* Frame finder */
27*473d4f4bSDavid du Colombier 	alphaexcep,		/* print exception */
28*473d4f4bSDavid du Colombier 	0,			/* breakpoint fixup */
29*473d4f4bSDavid du Colombier 	leieeesftos,		/* single precision float printer */
30*473d4f4bSDavid du Colombier 	leieeedftos,		/* double precisioin float printer */
31*473d4f4bSDavid du Colombier 	alphafoll,		/* following addresses */
32*473d4f4bSDavid du Colombier 	alphainst,		/* print instruction */
33*473d4f4bSDavid du Colombier 	alphadas,		/* dissembler */
34*473d4f4bSDavid du Colombier 	alphainstlen,		/* instruction size */
35*473d4f4bSDavid du Colombier };
36*473d4f4bSDavid du Colombier 
37*473d4f4bSDavid du Colombier static char *illegaltype[] = {
38*473d4f4bSDavid du Colombier 	"breakpoint",
39*473d4f4bSDavid du Colombier 	"bugchk",
40*473d4f4bSDavid du Colombier 	"gentrap",
41*473d4f4bSDavid du Colombier 	"fen",
42*473d4f4bSDavid du Colombier 	"illegal instruction",
43*473d4f4bSDavid du Colombier };
44*473d4f4bSDavid du Colombier 
45*473d4f4bSDavid du Colombier static char *
alphaexcep(Map * map,Rgetter rget)46*473d4f4bSDavid du Colombier alphaexcep(Map *map, Rgetter rget)
47*473d4f4bSDavid du Colombier {
48*473d4f4bSDavid du Colombier 	ulong type, a0, a1;
49*473d4f4bSDavid du Colombier 	static char buf[256];
50*473d4f4bSDavid du Colombier 
51*473d4f4bSDavid du Colombier 	type = (*rget)(map, "TYPE");
52*473d4f4bSDavid du Colombier 	a0 = (*rget)(map, "A0");
53*473d4f4bSDavid du Colombier 	a1 = (*rget)(map, "A1");
54*473d4f4bSDavid du Colombier /*	a2 = (*rget)(map, "A2"); */
55*473d4f4bSDavid du Colombier 
56*473d4f4bSDavid du Colombier 	switch (type) {
57*473d4f4bSDavid du Colombier 	case 1:	/* arith */
58*473d4f4bSDavid du Colombier 		sprint(buf, "trap: arithmetic trap 0x%lux", a0);
59*473d4f4bSDavid du Colombier 		break;
60*473d4f4bSDavid du Colombier 	case 2:	/* bad instr or FEN */
61*473d4f4bSDavid du Colombier 		if (a0 <= 4)
62*473d4f4bSDavid du Colombier 			return illegaltype[a0];
63*473d4f4bSDavid du Colombier 		else
64*473d4f4bSDavid du Colombier 			sprint(buf, "illegal instr trap, unknown type %lud", a0);
65*473d4f4bSDavid du Colombier 		break;
66*473d4f4bSDavid du Colombier 	case 3:	/* intr */
67*473d4f4bSDavid du Colombier 		sprint(buf, "interrupt type %lud", a0);
68*473d4f4bSDavid du Colombier 		break;
69*473d4f4bSDavid du Colombier 	case 4:	/* memory fault */
70*473d4f4bSDavid du Colombier 		sprint(buf, "fault %s addr=0x%lux", (a1&1)?"write":"read", a0);
71*473d4f4bSDavid du Colombier 		break;
72*473d4f4bSDavid du Colombier 	case 5:	/* syscall() */
73*473d4f4bSDavid du Colombier 		return "system call";
74*473d4f4bSDavid du Colombier 	case 6:	/* alignment fault */
75*473d4f4bSDavid du Colombier 		sprint(buf, "unaligned op 0x%lux addr 0x%lux", a1, a0);
76*473d4f4bSDavid du Colombier 		break;
77*473d4f4bSDavid du Colombier 	default:	/* cannot happen */
78*473d4f4bSDavid du Colombier 		sprint(buf, "unknown exception type %lud", type);
79*473d4f4bSDavid du Colombier 		break;
80*473d4f4bSDavid du Colombier 	}
81*473d4f4bSDavid du Colombier 	return buf;
82*473d4f4bSDavid du Colombier }
83*473d4f4bSDavid du Colombier 
84*473d4f4bSDavid du Colombier 	/* alpha disassembler and related functions */
85*473d4f4bSDavid du Colombier 
86*473d4f4bSDavid du Colombier static	char FRAMENAME[] = ".frame";
87*473d4f4bSDavid du Colombier 
88*473d4f4bSDavid du Colombier typedef struct {
89*473d4f4bSDavid du Colombier 	uvlong addr;
90*473d4f4bSDavid du Colombier 	uchar op;			/* bits 31-26 */
91*473d4f4bSDavid du Colombier 	uchar ra;			/* bits 25-21 */
92*473d4f4bSDavid du Colombier 	uchar rb;			/* bits 20-16 */
93*473d4f4bSDavid du Colombier 	uchar rc;			/* bits 4-0 */
94*473d4f4bSDavid du Colombier 	long mem;			/* bits 15-0 */
95*473d4f4bSDavid du Colombier 	long branch;			/* bits 20-0 */
96*473d4f4bSDavid du Colombier 	uchar function;			/* bits 11-5 */
97*473d4f4bSDavid du Colombier 	uchar literal;			/* bits 20-13 */
98*473d4f4bSDavid du Colombier 	uchar islit;			/* bit 12 */
99*473d4f4bSDavid du Colombier 	uchar fpfn;			/* bits 10-5 */
100*473d4f4bSDavid du Colombier 	uchar fpmode;			/* bits 15-11 */
101*473d4f4bSDavid du Colombier 	long w0;
102*473d4f4bSDavid du Colombier 	long w1;
103*473d4f4bSDavid du Colombier 	int size;			/* instruction size */
104*473d4f4bSDavid du Colombier 	char *curr;			/* fill point in buffer */
105*473d4f4bSDavid du Colombier 	char *end;			/* end of buffer */
106*473d4f4bSDavid du Colombier 	char *err;			/* error message */
107*473d4f4bSDavid du Colombier } Instr;
108*473d4f4bSDavid du Colombier 
109*473d4f4bSDavid du Colombier static Map *mymap;
110*473d4f4bSDavid du Colombier 
111*473d4f4bSDavid du Colombier static int
decode(uvlong pc,Instr * i)112*473d4f4bSDavid du Colombier decode(uvlong pc, Instr *i)
113*473d4f4bSDavid du Colombier {
114*473d4f4bSDavid du Colombier 	ulong w;
115*473d4f4bSDavid du Colombier 
116*473d4f4bSDavid du Colombier 	if (get4(mymap, pc, &w) < 0) {
117*473d4f4bSDavid du Colombier 		werrstr("can't read instruction: %r");
118*473d4f4bSDavid du Colombier 		return -1;
119*473d4f4bSDavid du Colombier 	}
120*473d4f4bSDavid du Colombier 	i->addr = pc;
121*473d4f4bSDavid du Colombier 	i->size = 1;
122*473d4f4bSDavid du Colombier 	i->op = (w >> 26) & 0x3F;
123*473d4f4bSDavid du Colombier 	i->ra = (w >> 21) & 0x1F;
124*473d4f4bSDavid du Colombier 	i->rb = (w >> 16) & 0x1F;
125*473d4f4bSDavid du Colombier 	i->rc = w & 0x1F;
126*473d4f4bSDavid du Colombier 	i->function = (w >> 5) & 0x7F;
127*473d4f4bSDavid du Colombier 	i->mem = w & 0xFFFF;
128*473d4f4bSDavid du Colombier 	if (i->mem & 0x8000)
129*473d4f4bSDavid du Colombier 		i->mem -= 0x10000;
130*473d4f4bSDavid du Colombier 	i->branch = w & 0x1FFFFF;
131*473d4f4bSDavid du Colombier 	if (i->branch & 0x100000)
132*473d4f4bSDavid du Colombier 		i->branch -= 0x200000;
133*473d4f4bSDavid du Colombier 	i->function = (w >> 5) & 0x7F;
134*473d4f4bSDavid du Colombier 	i->literal = (w >> 13) & 0xFF;
135*473d4f4bSDavid du Colombier 	i->islit = (w >> 12) & 0x01;
136*473d4f4bSDavid du Colombier 	i->fpfn = (w >> 5) & 0x3F;
137*473d4f4bSDavid du Colombier 	i->fpmode = (w >> 11) & 0x1F;
138*473d4f4bSDavid du Colombier 	i->w0 = w;
139*473d4f4bSDavid du Colombier 	return 1;
140*473d4f4bSDavid du Colombier }
141*473d4f4bSDavid du Colombier 
142*473d4f4bSDavid du Colombier static int
mkinstr(uvlong pc,Instr * i)143*473d4f4bSDavid du Colombier mkinstr(uvlong pc, Instr *i)
144*473d4f4bSDavid du Colombier {
145*473d4f4bSDavid du Colombier /*	Instr x; */
146*473d4f4bSDavid du Colombier 
147*473d4f4bSDavid du Colombier 	if (decode(pc, i) < 0)
148*473d4f4bSDavid du Colombier 		return -1;
149*473d4f4bSDavid du Colombier 
150*473d4f4bSDavid du Colombier #ifdef	frommips
151*473d4f4bSDavid du Colombier /* we probably want to do something like this for alpha... */
152*473d4f4bSDavid du Colombier 	/*
153*473d4f4bSDavid du Colombier 	 * if it's a LUI followed by an ORI,
154*473d4f4bSDavid du Colombier 	 * it's an immediate load of a large constant.
155*473d4f4bSDavid du Colombier 	 * fix the LUI immediate in any case.
156*473d4f4bSDavid du Colombier 	 */
157*473d4f4bSDavid du Colombier 	if (i->op == 0x0F) {
158*473d4f4bSDavid du Colombier 		if (decode(pc+4, &x) < 0)
159*473d4f4bSDavid du Colombier 			return 0;
160*473d4f4bSDavid du Colombier 		i->immediate <<= 16;
161*473d4f4bSDavid du Colombier 		if (x.op == 0x0D && x.rs == x.rt && x.rt == i->rt) {
162*473d4f4bSDavid du Colombier 			i->immediate |= (x.immediate & 0xFFFF);
163*473d4f4bSDavid du Colombier 			i->w1 = x.w0;
164*473d4f4bSDavid du Colombier 			i->size++;
165*473d4f4bSDavid du Colombier 			return 1;
166*473d4f4bSDavid du Colombier 		}
167*473d4f4bSDavid du Colombier 	}
168*473d4f4bSDavid du Colombier #endif
169*473d4f4bSDavid du Colombier 	return 1;
170*473d4f4bSDavid du Colombier }
171*473d4f4bSDavid du Colombier 
172*473d4f4bSDavid du Colombier #pragma	varargck	argpos	bprint		2
173*473d4f4bSDavid du Colombier 
174*473d4f4bSDavid du Colombier static void
bprint(Instr * i,char * fmt,...)175*473d4f4bSDavid du Colombier bprint(Instr *i, char *fmt, ...)
176*473d4f4bSDavid du Colombier {
177*473d4f4bSDavid du Colombier 	va_list arg;
178*473d4f4bSDavid du Colombier 
179*473d4f4bSDavid du Colombier 	va_start(arg, fmt);
180*473d4f4bSDavid du Colombier 	i->curr = vseprint(i->curr, i->end, fmt, arg);
181*473d4f4bSDavid du Colombier 	va_end(arg);
182*473d4f4bSDavid du Colombier }
183*473d4f4bSDavid du Colombier 
184*473d4f4bSDavid du Colombier typedef struct Opcode Opcode;
185*473d4f4bSDavid du Colombier 
186*473d4f4bSDavid du Colombier struct Opcode {
187*473d4f4bSDavid du Colombier 	char *mnemonic;
188*473d4f4bSDavid du Colombier 	void (*f)(Opcode *, Instr *);
189*473d4f4bSDavid du Colombier 	char *ken;
190*473d4f4bSDavid du Colombier };
191*473d4f4bSDavid du Colombier 
192*473d4f4bSDavid du Colombier static void format(char *, Instr *, char *);
193*473d4f4bSDavid du Colombier 
194*473d4f4bSDavid du Colombier static int
plocal(Instr * i,char * m,char r,int store)195*473d4f4bSDavid du Colombier plocal(Instr *i, char *m, char r, int store)
196*473d4f4bSDavid du Colombier {
197*473d4f4bSDavid du Colombier 	int offset;
198*473d4f4bSDavid du Colombier 	char *reg;
199*473d4f4bSDavid du Colombier 	Symbol s;
200*473d4f4bSDavid du Colombier 
201*473d4f4bSDavid du Colombier 	if (!findsym(i->addr, CTEXT, &s) || !findlocal(&s, FRAMENAME, &s))
202*473d4f4bSDavid du Colombier 		return 0;
203*473d4f4bSDavid du Colombier 	if (s.value > i->mem) {
204*473d4f4bSDavid du Colombier 		if(!getauto(&s, s.value-i->mem, CAUTO, &s))
205*473d4f4bSDavid du Colombier 			return 0;
206*473d4f4bSDavid du Colombier 		reg = "(SP)";
207*473d4f4bSDavid du Colombier 		offset = i->mem;
208*473d4f4bSDavid du Colombier 	} else {
209*473d4f4bSDavid du Colombier 		offset = i->mem-s.value-8;
210*473d4f4bSDavid du Colombier 		if (!getauto(&s, offset, CPARAM, &s))
211*473d4f4bSDavid du Colombier 			return 0;
212*473d4f4bSDavid du Colombier 		reg = "(FP)";
213*473d4f4bSDavid du Colombier 	}
214*473d4f4bSDavid du Colombier 	if (store)
215*473d4f4bSDavid du Colombier 		bprint(i, "%s\t%c%d,%s+%d%s", m, r, i->ra, s.name, offset, reg);
216*473d4f4bSDavid du Colombier 	else
217*473d4f4bSDavid du Colombier 		bprint(i, "%s\t%s+%d%s,%c%d", m, s.name, offset, reg, r, i->ra);
218*473d4f4bSDavid du Colombier 	return 1;
219*473d4f4bSDavid du Colombier }
220*473d4f4bSDavid du Colombier 
221*473d4f4bSDavid du Colombier static void
_load(Opcode * o,Instr * i,char r)222*473d4f4bSDavid du Colombier _load(Opcode *o, Instr *i, char r)
223*473d4f4bSDavid du Colombier {
224*473d4f4bSDavid du Colombier 	char *m;
225*473d4f4bSDavid du Colombier 
226*473d4f4bSDavid du Colombier 	m = o->mnemonic;
227*473d4f4bSDavid du Colombier 	if (i->rb == 30 && plocal(i, m, r, 0))
228*473d4f4bSDavid du Colombier 		return;
229*473d4f4bSDavid du Colombier 	if (i->rb == 29 && mach->sb) {
230*473d4f4bSDavid du Colombier 		bprint(i, "%s\t", m);
231*473d4f4bSDavid du Colombier 		i->curr += symoff(i->curr, i->end-i->curr, i->mem+mach->sb, CANY);
232*473d4f4bSDavid du Colombier 		bprint(i, "(SB),%c%d", r, i->ra);
233*473d4f4bSDavid du Colombier 		return;
234*473d4f4bSDavid du Colombier 	}
235*473d4f4bSDavid du Colombier 	format(m, i, o->ken);
236*473d4f4bSDavid du Colombier }
237*473d4f4bSDavid du Colombier 
238*473d4f4bSDavid du Colombier static void
load(Opcode * o,Instr * i)239*473d4f4bSDavid du Colombier load(Opcode *o, Instr *i)
240*473d4f4bSDavid du Colombier {
241*473d4f4bSDavid du Colombier 	_load(o, i, 'R');
242*473d4f4bSDavid du Colombier }
243*473d4f4bSDavid du Colombier 
244*473d4f4bSDavid du Colombier static void
loadf(Opcode * o,Instr * i)245*473d4f4bSDavid du Colombier loadf(Opcode *o, Instr *i)
246*473d4f4bSDavid du Colombier {
247*473d4f4bSDavid du Colombier 	_load(o, i, 'F');
248*473d4f4bSDavid du Colombier }
249*473d4f4bSDavid du Colombier 
250*473d4f4bSDavid du Colombier static void
_store(Opcode * o,Instr * i,char r)251*473d4f4bSDavid du Colombier _store(Opcode *o, Instr *i, char r)
252*473d4f4bSDavid du Colombier {
253*473d4f4bSDavid du Colombier 	char *m;
254*473d4f4bSDavid du Colombier 
255*473d4f4bSDavid du Colombier 	m = o->mnemonic;
256*473d4f4bSDavid du Colombier 	if (i->rb == 30 && plocal(i, m, r, 1))
257*473d4f4bSDavid du Colombier 		return;
258*473d4f4bSDavid du Colombier 	if (i->rb == 29 && mach->sb) {
259*473d4f4bSDavid du Colombier 		bprint(i, "%s\t%c%d,", m, r, i->ra);
260*473d4f4bSDavid du Colombier 		i->curr += symoff(i->curr, i->end-i->curr, i->mem+mach->sb, CANY);
261*473d4f4bSDavid du Colombier 		bprint(i, "(SB)");
262*473d4f4bSDavid du Colombier 		return;
263*473d4f4bSDavid du Colombier 	}
264*473d4f4bSDavid du Colombier 	format(o->mnemonic, i, o->ken);
265*473d4f4bSDavid du Colombier }
266*473d4f4bSDavid du Colombier 
267*473d4f4bSDavid du Colombier static void
store(Opcode * o,Instr * i)268*473d4f4bSDavid du Colombier store(Opcode *o, Instr *i)
269*473d4f4bSDavid du Colombier {
270*473d4f4bSDavid du Colombier 	_store(o, i, 'R');
271*473d4f4bSDavid du Colombier }
272*473d4f4bSDavid du Colombier 
273*473d4f4bSDavid du Colombier static void
storef(Opcode * o,Instr * i)274*473d4f4bSDavid du Colombier storef(Opcode *o, Instr *i)
275*473d4f4bSDavid du Colombier {
276*473d4f4bSDavid du Colombier 	_store(o, i, 'F');
277*473d4f4bSDavid du Colombier }
278*473d4f4bSDavid du Colombier 
279*473d4f4bSDavid du Colombier static void
misc(Opcode * o,Instr * i)280*473d4f4bSDavid du Colombier misc(Opcode *o, Instr *i)
281*473d4f4bSDavid du Colombier {
282*473d4f4bSDavid du Colombier 	char *f;
283*473d4f4bSDavid du Colombier 
284*473d4f4bSDavid du Colombier 	USED(o);
285*473d4f4bSDavid du Colombier 	switch (i->mem&0xFFFF) {
286*473d4f4bSDavid du Colombier 	case 0x0000:
287*473d4f4bSDavid du Colombier 		f = "TRAPB";
288*473d4f4bSDavid du Colombier 		break;
289*473d4f4bSDavid du Colombier 	case 0x4000:
290*473d4f4bSDavid du Colombier 		f = "MB";
291*473d4f4bSDavid du Colombier 		break;
292*473d4f4bSDavid du Colombier 	case 0x8000:
293*473d4f4bSDavid du Colombier 		f = "FETCH\t0(R%b)";
294*473d4f4bSDavid du Colombier 		break;
295*473d4f4bSDavid du Colombier 	case 0xA000:
296*473d4f4bSDavid du Colombier 		f = "FETCH_M\t0(R%b)";
297*473d4f4bSDavid du Colombier 		break;
298*473d4f4bSDavid du Colombier 	case 0xC000:
299*473d4f4bSDavid du Colombier 		f = "RPCC\tR%a";
300*473d4f4bSDavid du Colombier 		break;
301*473d4f4bSDavid du Colombier 	case 0xE000:
302*473d4f4bSDavid du Colombier 		f = "RC\tR%a";
303*473d4f4bSDavid du Colombier 		break;
304*473d4f4bSDavid du Colombier 	case 0xF000:
305*473d4f4bSDavid du Colombier 		f = "RS\tR%a";
306*473d4f4bSDavid du Colombier 		break;
307*473d4f4bSDavid du Colombier 	default:
308*473d4f4bSDavid du Colombier 		f = "%w";
309*473d4f4bSDavid du Colombier 	}
310*473d4f4bSDavid du Colombier 	format(0, i, f);
311*473d4f4bSDavid du Colombier }
312*473d4f4bSDavid du Colombier 
313*473d4f4bSDavid du Colombier static char	*jmpcode[4] = { "JMP", "JSR", "RET", "JSR_COROUTINE" };
314*473d4f4bSDavid du Colombier 
315*473d4f4bSDavid du Colombier static void
jmp(Opcode * o,Instr * i)316*473d4f4bSDavid du Colombier jmp(Opcode *o, Instr *i)
317*473d4f4bSDavid du Colombier {
318*473d4f4bSDavid du Colombier 	int hint;
319*473d4f4bSDavid du Colombier 	char *m;
320*473d4f4bSDavid du Colombier 
321*473d4f4bSDavid du Colombier 	USED(o);
322*473d4f4bSDavid du Colombier 	hint = (i->mem >> 14) & 3;
323*473d4f4bSDavid du Colombier 	m = jmpcode[hint];
324*473d4f4bSDavid du Colombier 	if (i->ra == 31) {
325*473d4f4bSDavid du Colombier 		if (hint == 2 && i->rb == 29)
326*473d4f4bSDavid du Colombier 			bprint(i, m);
327*473d4f4bSDavid du Colombier 		else
328*473d4f4bSDavid du Colombier 			format(m, i, "(R%b)");
329*473d4f4bSDavid du Colombier 	}
330*473d4f4bSDavid du Colombier 	else
331*473d4f4bSDavid du Colombier 		format(m, i, "R%a,(R%b)");
332*473d4f4bSDavid du Colombier }
333*473d4f4bSDavid du Colombier 
334*473d4f4bSDavid du Colombier static void
br(Opcode * o,Instr * i)335*473d4f4bSDavid du Colombier br(Opcode *o, Instr *i)
336*473d4f4bSDavid du Colombier {
337*473d4f4bSDavid du Colombier 	if (i->ra == 31)
338*473d4f4bSDavid du Colombier 		format(o->mnemonic, i, "%B");
339*473d4f4bSDavid du Colombier 	else
340*473d4f4bSDavid du Colombier 		format(o->mnemonic, i, o->ken);
341*473d4f4bSDavid du Colombier }
342*473d4f4bSDavid du Colombier 
343*473d4f4bSDavid du Colombier static void
bsr(Opcode * o,Instr * i)344*473d4f4bSDavid du Colombier bsr(Opcode *o, Instr *i)
345*473d4f4bSDavid du Colombier {
346*473d4f4bSDavid du Colombier 	if (i->ra == 26)
347*473d4f4bSDavid du Colombier 		format(o->mnemonic, i, "%B");
348*473d4f4bSDavid du Colombier 	else
349*473d4f4bSDavid du Colombier 		format(o->mnemonic, i, o->ken);
350*473d4f4bSDavid du Colombier }
351*473d4f4bSDavid du Colombier 
352*473d4f4bSDavid du Colombier static void
mult(Opcode * o,Instr * i)353*473d4f4bSDavid du Colombier mult(Opcode *o, Instr *i)
354*473d4f4bSDavid du Colombier {
355*473d4f4bSDavid du Colombier 	char *m;
356*473d4f4bSDavid du Colombier 
357*473d4f4bSDavid du Colombier 	switch (i->function) {
358*473d4f4bSDavid du Colombier 	case 0x00:
359*473d4f4bSDavid du Colombier 		m = "MULL";
360*473d4f4bSDavid du Colombier 		break;
361*473d4f4bSDavid du Colombier 	case 0x20:
362*473d4f4bSDavid du Colombier 		m = "MULQ";
363*473d4f4bSDavid du Colombier 		break;
364*473d4f4bSDavid du Colombier 	case 0x40:
365*473d4f4bSDavid du Colombier 		m = "MULL/V";
366*473d4f4bSDavid du Colombier 		break;
367*473d4f4bSDavid du Colombier 	case 0x60:
368*473d4f4bSDavid du Colombier 		m = "MULQ/V";
369*473d4f4bSDavid du Colombier 		break;
370*473d4f4bSDavid du Colombier 	case 0x30:
371*473d4f4bSDavid du Colombier 		m = "UMULH";
372*473d4f4bSDavid du Colombier 		break;
373*473d4f4bSDavid du Colombier 	default:
374*473d4f4bSDavid du Colombier 		format("???", i, "%w");
375*473d4f4bSDavid du Colombier 		return;
376*473d4f4bSDavid du Colombier 	}
377*473d4f4bSDavid du Colombier 	format(m, i, o->ken);
378*473d4f4bSDavid du Colombier }
379*473d4f4bSDavid du Colombier 
380*473d4f4bSDavid du Colombier static char	alphaload[] = "%l,R%a";
381*473d4f4bSDavid du Colombier static char	alphafload[] = "%l,F%a";
382*473d4f4bSDavid du Colombier static char	alphastore[] = "R%a,%l";
383*473d4f4bSDavid du Colombier static char	alphafstore[] = "F%a,%l";
384*473d4f4bSDavid du Colombier static char	alphabranch[] = "R%a,%B";
385*473d4f4bSDavid du Colombier static char	alphafbranch[] = "F%a,%B";
386*473d4f4bSDavid du Colombier static char	alphaint[] = "%v,R%a,R%c";
387*473d4f4bSDavid du Colombier static char	alphafp[] = "F%b,F%a,F%c";
388*473d4f4bSDavid du Colombier static char	alphafp2[] = "F%b,F%c";
389*473d4f4bSDavid du Colombier static char	alphaxxx[] = "%w";
390*473d4f4bSDavid du Colombier 
391*473d4f4bSDavid du Colombier static Opcode opcodes[64] = {
392*473d4f4bSDavid du Colombier 	"PAL",		0,	alphaxxx,
393*473d4f4bSDavid du Colombier 	"OPC01",	0,	alphaxxx,
394*473d4f4bSDavid du Colombier 	"OPC02",	0,	alphaxxx,
395*473d4f4bSDavid du Colombier 	"OPC03",	0,	alphaxxx,
396*473d4f4bSDavid du Colombier 	"OPC04",	0,	alphaxxx,
397*473d4f4bSDavid du Colombier 	"OPC05",	0,	alphaxxx,
398*473d4f4bSDavid du Colombier 	"OPC06",	0,	alphaxxx,
399*473d4f4bSDavid du Colombier 	"OPC07",	0,	alphaxxx,
400*473d4f4bSDavid du Colombier 	"MOVQA",	load,	alphaload,
401*473d4f4bSDavid du Colombier 	"MOVQAH",	load,	alphaload,
402*473d4f4bSDavid du Colombier 	"MOVBU",	load,	alphaload,		/* v 3 */
403*473d4f4bSDavid du Colombier 	"MOVQU",	load,	alphaload,
404*473d4f4bSDavid du Colombier 	"MOVWU",	load,	alphaload,		/* v 3 */
405*473d4f4bSDavid du Colombier 	"MOVWU",	store,	alphastore,		/* v 3 */
406*473d4f4bSDavid du Colombier 	"MOVBU",	store,	alphastore,		/* v 3 */
407*473d4f4bSDavid du Colombier 	"MOVQU",	store,	alphastore,
408*473d4f4bSDavid du Colombier 	0,		0,	0,			/* int arith */
409*473d4f4bSDavid du Colombier 	0,		0,	0,			/* logical */
410*473d4f4bSDavid du Colombier 	0,		0,	0,			/* shift */
411*473d4f4bSDavid du Colombier 	0,		mult,	alphaint,
412*473d4f4bSDavid du Colombier 	"OPC14",	0,	alphaxxx,
413*473d4f4bSDavid du Colombier 	"vax",		0,	alphafp,		/* vax */
414*473d4f4bSDavid du Colombier 	0,		0,	0,			/* ieee */
415*473d4f4bSDavid du Colombier 	0,		0,	0,			/* fp */
416*473d4f4bSDavid du Colombier 	0,		misc,	alphaxxx,
417*473d4f4bSDavid du Colombier 	"PAL19 [HW_MFPR]",0,	alphaxxx,
418*473d4f4bSDavid du Colombier 	"JSR",		jmp,	0,
419*473d4f4bSDavid du Colombier 	"PAL1B [HW_LD]",0,	alphaxxx,
420*473d4f4bSDavid du Colombier 	"OPC1C",	0,	alphaxxx,
421*473d4f4bSDavid du Colombier 	"PAL1D [HW_MTPR]",0,	alphaxxx,
422*473d4f4bSDavid du Colombier 	"PAL1E [HW_REI]",0,	alphaxxx,
423*473d4f4bSDavid du Colombier 	"PAL1F [HW_ST]",0,	alphaxxx,
424*473d4f4bSDavid du Colombier 	"MOVF",		loadf,	alphafload,
425*473d4f4bSDavid du Colombier 	"MOVG",		loadf,	alphafload,
426*473d4f4bSDavid du Colombier 	"MOVS",		loadf,	alphafload,
427*473d4f4bSDavid du Colombier 	"MOVT",		loadf,	alphafload,
428*473d4f4bSDavid du Colombier 	"MOVF",		storef,	alphafstore,
429*473d4f4bSDavid du Colombier 	"MOVG",		storef,	alphafstore,
430*473d4f4bSDavid du Colombier 	"MOVS",		storef,	alphafstore,
431*473d4f4bSDavid du Colombier 	"MOVT",		storef,	alphafstore,
432*473d4f4bSDavid du Colombier 	"MOVL",		load,	alphaload,
433*473d4f4bSDavid du Colombier 	"MOVQ",		load,	alphaload,
434*473d4f4bSDavid du Colombier 	"MOVLL",	load,	alphaload,
435*473d4f4bSDavid du Colombier 	"MOVQL",	load,	alphaload,
436*473d4f4bSDavid du Colombier 	"MOVL",		store,	alphastore,
437*473d4f4bSDavid du Colombier 	"MOVQ",		store,	alphastore,
438*473d4f4bSDavid du Colombier 	"MOVLC",	store,	alphastore,
439*473d4f4bSDavid du Colombier 	"MOVQC",	store,	alphastore,
440*473d4f4bSDavid du Colombier 	"JMP",		br,	alphabranch,
441*473d4f4bSDavid du Colombier 	"FBEQ",		0,	alphafbranch,
442*473d4f4bSDavid du Colombier 	"FBLT",		0,	alphafbranch,
443*473d4f4bSDavid du Colombier 	"FBLE",		0,	alphafbranch,
444*473d4f4bSDavid du Colombier 	"JSR",		bsr,	alphabranch,
445*473d4f4bSDavid du Colombier 	"FBNE",		0,	alphafbranch,
446*473d4f4bSDavid du Colombier 	"FBGE",		0,	alphafbranch,
447*473d4f4bSDavid du Colombier 	"FBGT",		0,	alphafbranch,
448*473d4f4bSDavid du Colombier 	"BLBC",		0,	alphafbranch,
449*473d4f4bSDavid du Colombier 	"BEQ",		0,	alphabranch,
450*473d4f4bSDavid du Colombier 	"BLT",		0,	alphabranch,
451*473d4f4bSDavid du Colombier 	"BLE",		0,	alphabranch,
452*473d4f4bSDavid du Colombier 	"BLBS",		0,	alphabranch,
453*473d4f4bSDavid du Colombier 	"BNE",		0,	alphabranch,
454*473d4f4bSDavid du Colombier 	"BGE",		0,	alphabranch,
455*473d4f4bSDavid du Colombier 	"BGT",		0,	alphabranch,
456*473d4f4bSDavid du Colombier };
457*473d4f4bSDavid du Colombier 
458*473d4f4bSDavid du Colombier static Opcode fpopcodes[64] = {
459*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
460*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
461*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
462*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
463*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
464*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
465*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
466*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
467*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
468*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
469*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
470*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
471*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
472*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
473*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
474*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
475*473d4f4bSDavid du Colombier 
476*473d4f4bSDavid du Colombier 	"CVTLQ",	0,	alphafp2,
477*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
478*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
479*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
480*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
481*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
482*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
483*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
484*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
485*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
486*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
487*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
488*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
489*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
490*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
491*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
492*473d4f4bSDavid du Colombier 
493*473d4f4bSDavid du Colombier 	"CPYS",		0,	alphafp,
494*473d4f4bSDavid du Colombier 	"CPYSN",	0,	alphafp,
495*473d4f4bSDavid du Colombier 	"CPYSE",	0,	alphafp,
496*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
497*473d4f4bSDavid du Colombier 	"MOVT",		0,	"FPCR,F%a",
498*473d4f4bSDavid du Colombier 	"MOVT",		0,	"F%a,FPCR",
499*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
500*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
501*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
502*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
503*473d4f4bSDavid du Colombier 	"FCMOVEQ",	0,	alphafp,
504*473d4f4bSDavid du Colombier 	"FCMOVNE",	0,	alphafp,
505*473d4f4bSDavid du Colombier 	"FCMOVLT",	0,	alphafp,
506*473d4f4bSDavid du Colombier 	"FCMOVGE",	0,	alphafp,
507*473d4f4bSDavid du Colombier 	"FCMOVLE",	0,	alphafp,
508*473d4f4bSDavid du Colombier 	"FCMOVGT",	0,	alphafp,
509*473d4f4bSDavid du Colombier 
510*473d4f4bSDavid du Colombier 	"CVTQL",	0,	alphafp2,
511*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
512*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
513*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
514*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
515*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
516*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
517*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
518*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
519*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
520*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
521*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
522*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
523*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
524*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
525*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
526*473d4f4bSDavid du Colombier };
527*473d4f4bSDavid du Colombier 
528*473d4f4bSDavid du Colombier static Opcode ieeeopcodes[64] = {
529*473d4f4bSDavid du Colombier 	"ADDS",		0,	alphafp,
530*473d4f4bSDavid du Colombier 	"SUBS",		0,	alphafp,
531*473d4f4bSDavid du Colombier 	"MULS",		0,	alphafp,
532*473d4f4bSDavid du Colombier 	"DIVS",		0,	alphafp,
533*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
534*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
535*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
536*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
537*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
538*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
539*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
540*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
541*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
542*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
543*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
544*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
545*473d4f4bSDavid du Colombier 
546*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
547*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
548*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
549*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
550*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
551*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
552*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
553*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
554*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
555*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
556*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
557*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
558*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
559*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
560*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
561*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
562*473d4f4bSDavid du Colombier 
563*473d4f4bSDavid du Colombier 	"ADDT",		0,	alphafp,
564*473d4f4bSDavid du Colombier 	"SUBT",		0,	alphafp,
565*473d4f4bSDavid du Colombier 	"MULT",		0,	alphafp,
566*473d4f4bSDavid du Colombier 	"DIVT",		0,	alphafp,
567*473d4f4bSDavid du Colombier 	"CMPTUN",	0,	alphafp,
568*473d4f4bSDavid du Colombier 	"CMPTEQ",	0,	alphafp,
569*473d4f4bSDavid du Colombier 	"CMPTLT",	0,	alphafp,
570*473d4f4bSDavid du Colombier 	"CMPTLE",	0,	alphafp,
571*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
572*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
573*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
574*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
575*473d4f4bSDavid du Colombier 	"CVTTS",	0,	alphafp2,
576*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
577*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
578*473d4f4bSDavid du Colombier 	"CVTTQ",	0,	alphafp2,
579*473d4f4bSDavid du Colombier 
580*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
581*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
582*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
583*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
584*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
585*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
586*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
587*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
588*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
589*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
590*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
591*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
592*473d4f4bSDavid du Colombier 	"CVTQS",	0,	alphafp2,
593*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
594*473d4f4bSDavid du Colombier 	"CVTQT",	0,	alphafp2,
595*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
596*473d4f4bSDavid du Colombier };
597*473d4f4bSDavid du Colombier 
598*473d4f4bSDavid du Colombier static uchar	amap[128] = {
599*473d4f4bSDavid du Colombier 	[0x00]	1,
600*473d4f4bSDavid du Colombier 	[0x40]	2,
601*473d4f4bSDavid du Colombier 	[0x20]	3,
602*473d4f4bSDavid du Colombier 	[0x60]	4,
603*473d4f4bSDavid du Colombier 	[0x09]	5,
604*473d4f4bSDavid du Colombier 	[0x49]	6,
605*473d4f4bSDavid du Colombier 	[0x29]	7,
606*473d4f4bSDavid du Colombier 	[0x69]	8,
607*473d4f4bSDavid du Colombier 	[0x2D]	9,
608*473d4f4bSDavid du Colombier 	[0x4D]	10,
609*473d4f4bSDavid du Colombier 	[0x6D]	11,
610*473d4f4bSDavid du Colombier 	[0x1D]	12,
611*473d4f4bSDavid du Colombier 	[0x3D]	13,
612*473d4f4bSDavid du Colombier 	[0x0F]	14,
613*473d4f4bSDavid du Colombier 	[0x02]	15,
614*473d4f4bSDavid du Colombier 	[0x0B]	16,
615*473d4f4bSDavid du Colombier 	[0x12]	17,
616*473d4f4bSDavid du Colombier 	[0x1B]	18,
617*473d4f4bSDavid du Colombier 	[0x22]	19,
618*473d4f4bSDavid du Colombier 	[0x2B]	20,
619*473d4f4bSDavid du Colombier 	[0x32]	21,
620*473d4f4bSDavid du Colombier 	[0x3B]	22,
621*473d4f4bSDavid du Colombier };
622*473d4f4bSDavid du Colombier 
623*473d4f4bSDavid du Colombier static Opcode arithopcodes[64] = {
624*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
625*473d4f4bSDavid du Colombier 	"ADDL",		0,	alphaint,
626*473d4f4bSDavid du Colombier 	"ADDL/V",	0,	alphaint,
627*473d4f4bSDavid du Colombier 	"ADDQ",		0,	alphaint,
628*473d4f4bSDavid du Colombier 	"ADDQ/V",	0,	alphaint,
629*473d4f4bSDavid du Colombier 	"SUBL",		0,	alphaint,
630*473d4f4bSDavid du Colombier 	"SUBL/V",	0,	alphaint,
631*473d4f4bSDavid du Colombier 	"SUBQ",		0,	alphaint,
632*473d4f4bSDavid du Colombier 	"SUBQ/V",	0,	alphaint,
633*473d4f4bSDavid du Colombier 	"CMPEQ",	0,	alphaint,
634*473d4f4bSDavid du Colombier 	"CMPLT",	0,	alphaint,
635*473d4f4bSDavid du Colombier 	"CMPLE",	0,	alphaint,
636*473d4f4bSDavid du Colombier 	"CMPULT",	0,	alphaint,
637*473d4f4bSDavid du Colombier 	"CMPULE",	0,	alphaint,
638*473d4f4bSDavid du Colombier 	"CMPBGE",	0,	alphaint,
639*473d4f4bSDavid du Colombier 	"S4ADDL",	0,	alphaint,
640*473d4f4bSDavid du Colombier 	"S4SUBL",	0,	alphaint,
641*473d4f4bSDavid du Colombier 	"S8ADDL",	0,	alphaint,
642*473d4f4bSDavid du Colombier 	"S8SUBL",	0,	alphaint,
643*473d4f4bSDavid du Colombier 	"S4ADDQ",	0,	alphaint,
644*473d4f4bSDavid du Colombier 	"S4SUBQ",	0,	alphaint,
645*473d4f4bSDavid du Colombier 	"S8ADDQ",	0,	alphaint,
646*473d4f4bSDavid du Colombier 	"S8SUBQ",	0,	alphaint,
647*473d4f4bSDavid du Colombier };
648*473d4f4bSDavid du Colombier 
649*473d4f4bSDavid du Colombier static uchar	lmap[128] = {
650*473d4f4bSDavid du Colombier 	[0x00]	1,
651*473d4f4bSDavid du Colombier 	[0x20]	2,
652*473d4f4bSDavid du Colombier 	[0x40]	3,
653*473d4f4bSDavid du Colombier 	[0x08]	4,
654*473d4f4bSDavid du Colombier 	[0x28]	5,
655*473d4f4bSDavid du Colombier 	[0x48]	6,
656*473d4f4bSDavid du Colombier 	[0x24]	7,
657*473d4f4bSDavid du Colombier 	[0x44]	8,
658*473d4f4bSDavid du Colombier 	[0x64]	9,
659*473d4f4bSDavid du Colombier 	[0x26]	7,
660*473d4f4bSDavid du Colombier 	[0x46]	8,
661*473d4f4bSDavid du Colombier 	[0x66]	9,
662*473d4f4bSDavid du Colombier 	[0x14]	10,
663*473d4f4bSDavid du Colombier 	[0x16]	11,
664*473d4f4bSDavid du Colombier };
665*473d4f4bSDavid du Colombier 
666*473d4f4bSDavid du Colombier static Opcode logicalopcodes[64] = {
667*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
668*473d4f4bSDavid du Colombier 	"AND",		0,	alphaint,
669*473d4f4bSDavid du Colombier 	"OR",		0,	alphaint,
670*473d4f4bSDavid du Colombier 	"XOR",		0,	alphaint,
671*473d4f4bSDavid du Colombier 	"ANDNOT",	0,	alphaint,
672*473d4f4bSDavid du Colombier 	"ORNOT",	0,	alphaint,
673*473d4f4bSDavid du Colombier 	"XORNOT",	0,	alphaint,
674*473d4f4bSDavid du Colombier 	"CMOVEQ",	0,	alphaint,
675*473d4f4bSDavid du Colombier 	"CMOVLT",	0,	alphaint,
676*473d4f4bSDavid du Colombier 	"CMOVLE",	0,	alphaint,
677*473d4f4bSDavid du Colombier 	"CMOVNE",	0,	alphaint,
678*473d4f4bSDavid du Colombier 	"CMOVGE",	0,	alphaint,
679*473d4f4bSDavid du Colombier 	"CMOVGT",	0,	alphaint,
680*473d4f4bSDavid du Colombier 	"CMOVLBS",	0,	alphaint,
681*473d4f4bSDavid du Colombier 	"CMOVLBC",	0,	alphaint,
682*473d4f4bSDavid du Colombier };
683*473d4f4bSDavid du Colombier 
684*473d4f4bSDavid du Colombier static uchar	smap[128] = {
685*473d4f4bSDavid du Colombier 	[0x39]	1,
686*473d4f4bSDavid du Colombier 	[0x3C]	2,
687*473d4f4bSDavid du Colombier 	[0x34]	3,
688*473d4f4bSDavid du Colombier 	[0x06]	4,
689*473d4f4bSDavid du Colombier 	[0x16]	5,
690*473d4f4bSDavid du Colombier 	[0x26]	6,
691*473d4f4bSDavid du Colombier 	[0x36]	7,
692*473d4f4bSDavid du Colombier 	[0x5A]	8,
693*473d4f4bSDavid du Colombier 	[0x6A]	9,
694*473d4f4bSDavid du Colombier 	[0x7A]	10,
695*473d4f4bSDavid du Colombier 	[0x0B]	11,
696*473d4f4bSDavid du Colombier 	[0x1B]	12,
697*473d4f4bSDavid du Colombier 	[0x2B]	13,
698*473d4f4bSDavid du Colombier 	[0x3B]	14,
699*473d4f4bSDavid du Colombier 	[0x57]	15,
700*473d4f4bSDavid du Colombier 	[0x67]	16,
701*473d4f4bSDavid du Colombier 	[0x77]	17,
702*473d4f4bSDavid du Colombier 	[0x02]	18,
703*473d4f4bSDavid du Colombier 	[0x12]	19,
704*473d4f4bSDavid du Colombier 	[0x22]	20,
705*473d4f4bSDavid du Colombier 	[0x32]	21,
706*473d4f4bSDavid du Colombier 	[0x52]	22,
707*473d4f4bSDavid du Colombier 	[0x62]	23,
708*473d4f4bSDavid du Colombier 	[0x72]	24,
709*473d4f4bSDavid du Colombier 	[0x30]	25,
710*473d4f4bSDavid du Colombier 	[0x31]	26,
711*473d4f4bSDavid du Colombier };
712*473d4f4bSDavid du Colombier 
713*473d4f4bSDavid du Colombier static Opcode shiftopcodes[64] = {
714*473d4f4bSDavid du Colombier 	"???",		0,	alphaxxx,
715*473d4f4bSDavid du Colombier 	"SLLQ",		0,	alphaint,
716*473d4f4bSDavid du Colombier 	"SRAQ",		0,	alphaint,
717*473d4f4bSDavid du Colombier 	"SRLQ",		0,	alphaint,
718*473d4f4bSDavid du Colombier 	"EXTBL",	0,	alphaint,
719*473d4f4bSDavid du Colombier 	"EXTWL",	0,	alphaint,
720*473d4f4bSDavid du Colombier 	"EXTLL",	0,	alphaint,
721*473d4f4bSDavid du Colombier 	"EXTQL",	0,	alphaint,
722*473d4f4bSDavid du Colombier 	"EXTWH",	0,	alphaint,
723*473d4f4bSDavid du Colombier 	"EXTLH",	0,	alphaint,
724*473d4f4bSDavid du Colombier 	"EXTQH",	0,	alphaint,
725*473d4f4bSDavid du Colombier 	"INSBL",	0,	alphaint,
726*473d4f4bSDavid du Colombier 	"INSWL",	0,	alphaint,
727*473d4f4bSDavid du Colombier 	"INSLL",	0,	alphaint,
728*473d4f4bSDavid du Colombier 	"INSQL",	0,	alphaint,
729*473d4f4bSDavid du Colombier 	"INSWH",	0,	alphaint,
730*473d4f4bSDavid du Colombier 	"INSLH",	0,	alphaint,
731*473d4f4bSDavid du Colombier 	"INSQH",	0,	alphaint,
732*473d4f4bSDavid du Colombier 	"MSKBL",	0,	alphaint,
733*473d4f4bSDavid du Colombier 	"MSKWL",	0,	alphaint,
734*473d4f4bSDavid du Colombier 	"MSKLL",	0,	alphaint,
735*473d4f4bSDavid du Colombier 	"MSKQL",	0,	alphaint,
736*473d4f4bSDavid du Colombier 	"MSKWH",	0,	alphaint,
737*473d4f4bSDavid du Colombier 	"MSKLH",	0,	alphaint,
738*473d4f4bSDavid du Colombier 	"MSKQH",	0,	alphaint,
739*473d4f4bSDavid du Colombier 	"ZAP",		0,	alphaint,
740*473d4f4bSDavid du Colombier 	"ZAPNOT",	0,	alphaint,
741*473d4f4bSDavid du Colombier };
742*473d4f4bSDavid du Colombier 
743*473d4f4bSDavid du Colombier static void
format(char * mnemonic,Instr * i,char * f)744*473d4f4bSDavid du Colombier format(char *mnemonic, Instr *i, char *f)
745*473d4f4bSDavid du Colombier {
746*473d4f4bSDavid du Colombier 	if (mnemonic)
747*473d4f4bSDavid du Colombier 		format(0, i, mnemonic);
748*473d4f4bSDavid du Colombier 	if (f == 0)
749*473d4f4bSDavid du Colombier 		return;
750*473d4f4bSDavid du Colombier 	if (mnemonic)
751*473d4f4bSDavid du Colombier 		if (i->curr < i->end)
752*473d4f4bSDavid du Colombier 			*i->curr++ = '\t';
753*473d4f4bSDavid du Colombier 	for ( ; *f && i->curr < i->end; f++) {
754*473d4f4bSDavid du Colombier 		if (*f != '%') {
755*473d4f4bSDavid du Colombier 			*i->curr++ = *f;
756*473d4f4bSDavid du Colombier 			continue;
757*473d4f4bSDavid du Colombier 		}
758*473d4f4bSDavid du Colombier 		switch (*++f) {
759*473d4f4bSDavid du Colombier 
760*473d4f4bSDavid du Colombier 		case 'a':
761*473d4f4bSDavid du Colombier 			bprint(i, "%d", i->ra);
762*473d4f4bSDavid du Colombier 			break;
763*473d4f4bSDavid du Colombier 
764*473d4f4bSDavid du Colombier 		case 'b':
765*473d4f4bSDavid du Colombier 			bprint(i, "%d", i->rb);
766*473d4f4bSDavid du Colombier 			break;
767*473d4f4bSDavid du Colombier 
768*473d4f4bSDavid du Colombier 		case 'c':
769*473d4f4bSDavid du Colombier 			bprint(i, "%d", i->rc);
770*473d4f4bSDavid du Colombier 			break;
771*473d4f4bSDavid du Colombier 
772*473d4f4bSDavid du Colombier 		case 'v':
773*473d4f4bSDavid du Colombier 			if (i->islit)
774*473d4f4bSDavid du Colombier 				bprint(i, "$%ux", i->literal);
775*473d4f4bSDavid du Colombier 			else
776*473d4f4bSDavid du Colombier 				bprint(i, "R%d", i->rb);
777*473d4f4bSDavid du Colombier 			break;
778*473d4f4bSDavid du Colombier 
779*473d4f4bSDavid du Colombier 		case 'l':
780*473d4f4bSDavid du Colombier 			bprint(i, "%lx(R%d)", i->mem, i->rb);
781*473d4f4bSDavid du Colombier 			break;
782*473d4f4bSDavid du Colombier 
783*473d4f4bSDavid du Colombier 		case 'i':
784*473d4f4bSDavid du Colombier 			bprint(i, "$%lx", i->mem);
785*473d4f4bSDavid du Colombier 			break;
786*473d4f4bSDavid du Colombier 
787*473d4f4bSDavid du Colombier 		case 'B':
788*473d4f4bSDavid du Colombier 			i->curr += symoff(i->curr, i->end-i->curr,
789*473d4f4bSDavid du Colombier 				(i->branch<<2)+i->addr+4, CANY);
790*473d4f4bSDavid du Colombier 			break;
791*473d4f4bSDavid du Colombier 
792*473d4f4bSDavid du Colombier 		case 'w':
793*473d4f4bSDavid du Colombier 			bprint(i, "[%lux]", i->w0);
794*473d4f4bSDavid du Colombier 			break;
795*473d4f4bSDavid du Colombier 
796*473d4f4bSDavid du Colombier 		case '\0':
797*473d4f4bSDavid du Colombier 			*i->curr++ = '%';
798*473d4f4bSDavid du Colombier 			return;
799*473d4f4bSDavid du Colombier 
800*473d4f4bSDavid du Colombier 		default:
801*473d4f4bSDavid du Colombier 			bprint(i, "%%%c", *f);
802*473d4f4bSDavid du Colombier 			break;
803*473d4f4bSDavid du Colombier 		}
804*473d4f4bSDavid du Colombier 	}
805*473d4f4bSDavid du Colombier 	*i->curr = 0;
806*473d4f4bSDavid du Colombier }
807*473d4f4bSDavid du Colombier 
808*473d4f4bSDavid du Colombier static int
printins(Map * map,uvlong pc,char * buf,int n)809*473d4f4bSDavid du Colombier printins(Map *map, uvlong pc, char *buf, int n)
810*473d4f4bSDavid du Colombier {
811*473d4f4bSDavid du Colombier 	Instr i;
812*473d4f4bSDavid du Colombier 	Opcode *o;
813*473d4f4bSDavid du Colombier 	uchar op;
814*473d4f4bSDavid du Colombier 
815*473d4f4bSDavid du Colombier 	i.curr = buf;
816*473d4f4bSDavid du Colombier 	i.end = buf+n-1;
817*473d4f4bSDavid du Colombier 	mymap = map;
818*473d4f4bSDavid du Colombier 	if (mkinstr(pc, &i) < 0)
819*473d4f4bSDavid du Colombier 		return -1;
820*473d4f4bSDavid du Colombier 	switch (i.op) {
821*473d4f4bSDavid du Colombier 
822*473d4f4bSDavid du Colombier 	case 0x10:					/* INTA */
823*473d4f4bSDavid du Colombier 		o = arithopcodes;
824*473d4f4bSDavid du Colombier 		op = amap[i.function];
825*473d4f4bSDavid du Colombier 		break;
826*473d4f4bSDavid du Colombier 
827*473d4f4bSDavid du Colombier 	case 0x11:					/* INTL */
828*473d4f4bSDavid du Colombier 		o = logicalopcodes;
829*473d4f4bSDavid du Colombier 		op = lmap[i.function];
830*473d4f4bSDavid du Colombier 		break;
831*473d4f4bSDavid du Colombier 
832*473d4f4bSDavid du Colombier 	case 0x12:					/* INTS */
833*473d4f4bSDavid du Colombier 		o = shiftopcodes;
834*473d4f4bSDavid du Colombier 		op = smap[i.function];
835*473d4f4bSDavid du Colombier 		break;
836*473d4f4bSDavid du Colombier 
837*473d4f4bSDavid du Colombier 	case 0x16:					/* FLTI */
838*473d4f4bSDavid du Colombier 		o = ieeeopcodes;
839*473d4f4bSDavid du Colombier 		op = i.fpfn;
840*473d4f4bSDavid du Colombier 		break;
841*473d4f4bSDavid du Colombier 
842*473d4f4bSDavid du Colombier 	case 0x17:					/* FLTL */
843*473d4f4bSDavid du Colombier 		o = fpopcodes;
844*473d4f4bSDavid du Colombier 		op = i.fpfn;
845*473d4f4bSDavid du Colombier 		break;
846*473d4f4bSDavid du Colombier 
847*473d4f4bSDavid du Colombier 	default:
848*473d4f4bSDavid du Colombier 		o = opcodes;
849*473d4f4bSDavid du Colombier 		op = i.op;
850*473d4f4bSDavid du Colombier 		break;
851*473d4f4bSDavid du Colombier 	}
852*473d4f4bSDavid du Colombier 	if (o[op].f)
853*473d4f4bSDavid du Colombier 		(*o[op].f)(&o[op], &i);
854*473d4f4bSDavid du Colombier 	else
855*473d4f4bSDavid du Colombier 		format(o[op].mnemonic, &i, o[op].ken);
856*473d4f4bSDavid du Colombier 	return i.size*4;
857*473d4f4bSDavid du Colombier }
858*473d4f4bSDavid du Colombier 
859*473d4f4bSDavid du Colombier static int
alphainst(Map * map,uvlong pc,char modifier,char * buf,int n)860*473d4f4bSDavid du Colombier alphainst(Map *map, uvlong pc, char modifier, char *buf, int n)
861*473d4f4bSDavid du Colombier {
862*473d4f4bSDavid du Colombier 	USED(modifier);
863*473d4f4bSDavid du Colombier 	return printins(map, pc, buf, n);
864*473d4f4bSDavid du Colombier }
865*473d4f4bSDavid du Colombier 
866*473d4f4bSDavid du Colombier static int
alphadas(Map * map,uvlong pc,char * buf,int n)867*473d4f4bSDavid du Colombier alphadas(Map *map, uvlong pc, char *buf, int n)
868*473d4f4bSDavid du Colombier {
869*473d4f4bSDavid du Colombier 	Instr i;
870*473d4f4bSDavid du Colombier 
871*473d4f4bSDavid du Colombier 	i.curr = buf;
872*473d4f4bSDavid du Colombier 	i.end = buf+n;
873*473d4f4bSDavid du Colombier 	mymap = map;
874*473d4f4bSDavid du Colombier 	if (mkinstr(pc, &i) < 0)
875*473d4f4bSDavid du Colombier 		return -1;
876*473d4f4bSDavid du Colombier 	if (i.end-i.curr > 8)
877*473d4f4bSDavid du Colombier 		i.curr = _hexify(buf, i.w0, 7);
878*473d4f4bSDavid du Colombier 	if (i.size == 2 && i.end-i.curr > 9) {
879*473d4f4bSDavid du Colombier 		*i.curr++ = ' ';
880*473d4f4bSDavid du Colombier 		i.curr = _hexify(i.curr, i.w1, 7);
881*473d4f4bSDavid du Colombier 	}
882*473d4f4bSDavid du Colombier 	*i.curr = 0;
883*473d4f4bSDavid du Colombier 	return i.size*4;
884*473d4f4bSDavid du Colombier }
885*473d4f4bSDavid du Colombier 
886*473d4f4bSDavid du Colombier static int
alphainstlen(Map * map,uvlong pc)887*473d4f4bSDavid du Colombier alphainstlen(Map *map, uvlong pc)
888*473d4f4bSDavid du Colombier {
889*473d4f4bSDavid du Colombier 	Instr i;
890*473d4f4bSDavid du Colombier 
891*473d4f4bSDavid du Colombier 	mymap = map;
892*473d4f4bSDavid du Colombier 	if (mkinstr(pc, &i) < 0)
893*473d4f4bSDavid du Colombier 		return -1;
894*473d4f4bSDavid du Colombier 	return i.size*4;
895*473d4f4bSDavid du Colombier }
896*473d4f4bSDavid du Colombier 
897*473d4f4bSDavid du Colombier static int
alphafoll(Map * map,uvlong pc,Rgetter rget,uvlong * foll)898*473d4f4bSDavid du Colombier alphafoll(Map *map, uvlong pc, Rgetter rget, uvlong *foll)
899*473d4f4bSDavid du Colombier {
900*473d4f4bSDavid du Colombier 	char buf[8];
901*473d4f4bSDavid du Colombier 	Instr i;
902*473d4f4bSDavid du Colombier 
903*473d4f4bSDavid du Colombier 	mymap = map;
904*473d4f4bSDavid du Colombier 	if (mkinstr(pc, &i) < 0)
905*473d4f4bSDavid du Colombier 		return -1;
906*473d4f4bSDavid du Colombier 
907*473d4f4bSDavid du Colombier 	switch(i.op) {
908*473d4f4bSDavid du Colombier 	case 0x1A:				/* JMP/JSR/RET */
909*473d4f4bSDavid du Colombier 		sprint(buf, "R%d", i.rb);
910*473d4f4bSDavid du Colombier 		foll[0] = (*rget)(map, buf);
911*473d4f4bSDavid du Colombier 		return 1;
912*473d4f4bSDavid du Colombier 	case 0x30:				/* BR */
913*473d4f4bSDavid du Colombier 	case 0x34:				/* BSR */
914*473d4f4bSDavid du Colombier 		foll[0] = pc+4 + (i.branch<<2);
915*473d4f4bSDavid du Colombier 		return 1;
916*473d4f4bSDavid du Colombier 	default:
917*473d4f4bSDavid du Colombier 		if (i.op > 0x30) {		/* cond */
918*473d4f4bSDavid du Colombier 			foll[0] = pc+4;
919*473d4f4bSDavid du Colombier 			foll[1] = pc+4 + (i.branch<<2);
920*473d4f4bSDavid du Colombier 			return 2;
921*473d4f4bSDavid du Colombier 		}
922*473d4f4bSDavid du Colombier 		foll[0] = pc+i.size*4;
923*473d4f4bSDavid du Colombier 		return 1;
924*473d4f4bSDavid du Colombier 	}
925*473d4f4bSDavid du Colombier }
926