xref: /netbsd/sys/arch/alpha/alpha/db_disasm.c (revision bf9ec67e)
1 /* $NetBSD: db_disasm.c,v 1.10 2000/08/09 20:00:30 tv Exp $ */
2 
3 /*
4  * Mach Operating System
5  * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
6  * All Rights Reserved.
7  *
8  * Permission to use, copy, modify and distribute this software and its
9  * documentation is hereby granted, provided that both the copyright
10  * notice and this permission notice appear in all copies of the
11  * software, derivative works or modified versions, and any portions
12  * thereof, and that both notices appear in supporting documentation.
13  *
14  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
16  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17  *
18  * Carnegie Mellon requests users of this software to return to
19  *
20  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
21  *  School of Computer Science
22  *  Carnegie Mellon University
23  *  Pittsburgh PA 15213-3890
24  *
25  * any improvements or extensions that they make and grant Carnegie Mellon
26  * the rights to redistribute these changes.
27  */
28 
29 /*
30  *	File: db_disasm.c
31  * 	Author: Alessandro Forin, Carnegie Mellon University
32  *	Date:	11/91
33  *
34  *	Disassembler for Alpha
35  *
36  *	Modified for NetBSD/alpha by:
37  *
38  *	Christopher G. Demetriou, Carnegie Mellon University
39  *
40  *	Jason R. Thorpe, Numerical Aerospace Simulation Facility,
41  *	NASA Ames Research Center
42  *
43  *	This code was derived exclusively from information available in
44  *	"Alpha Architecture Reference Manual", Richard L. Sites ed.
45  *	Digital Press, Burlington, MA 01803
46  *	ISBN 1-55558-098-X, Order no. EY-L520E-DP
47  */
48 
49 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
50 
51 __KERNEL_RCSID(0, "$NetBSD: db_disasm.c,v 1.10 2000/08/09 20:00:30 tv Exp $");
52 
53 #include <sys/param.h>
54 #include <sys/systm.h>
55 #include <sys/proc.h>
56 #include <machine/db_machdep.h>
57 #include <alpha/alpha/db_instruction.h>
58 
59 #include <machine/pal.h>
60 
61 #include <ddb/db_access.h>
62 #include <ddb/db_sym.h>
63 #include <ddb/db_output.h>
64 #include <ddb/db_interface.h>
65 
66 /*
67  * This would belong in a header file, except noone else needs it
68  *
69  * XXX THESE SHOULD BE CONVERTED TO ra, rb, rc FORMAT.
70  */
71 typedef union {
72 	/*
73 	 *	All instructions are 32 bits wide, PAL included
74 	 */
75 	unsigned int	bits;
76 
77 	/*
78 	 *	Internal processor register access instrs
79 	 *	specify the IPR index, doubly specify the
80 	 *	(same) GP register as src/dest, and qualifiers
81 	 *	for the IPR set involved (abox/ibox/tmp)
82 	 */
83 	struct {
84 		unsigned	index : 5,
85 				regset : 3, /* a,i,p */
86 				xxx : 8,
87 				rs : 5,
88 				rd : 5,
89 				opcode : 6;
90 	} mXpr_format;
91 
92 	/*
93 	 *	Load/store instructions have a 12 bit displacement,
94 	 *	and two register specifiers just as normal ld/st.
95 	 *	Four bits have special meanings:
96 	 *		phy: bypass the MMU (physical access)
97 	 *		alt: use mode in ALT register for checks,
98 	 *		     or if PHY is also on locked/linked access
99 	 *		rwc: read-with-write-check (probew)
100 	 *		qw:  quadword access
101 	 */
102 	struct {
103 		signed int	displacement : 12;
104 		unsigned	qw : 1,
105 				qualif : 3,
106 				rs : 5,
107 				rd : 5,
108 				opcode : 6;
109 	} mem_format;
110 
111 	/*
112 	 *	Return from exception or interrupt has
113 	 *	a branch-like encoding, but only one
114 	 *	instantiation is actually usable.
115 	 */
116 	struct {
117 		unsigned	xxx : 14,
118 				zero : 1,	/* branch prediction! */
119 				one : 1,
120 				rb : 5,		/* r31 or stall */
121 				ra : 5,		/* r31 or stall */
122 				opcode : 6;
123 	} rei_format;
124 
125 } pal_instruction;
126 
127 /*
128  * Major opcodes
129  */
130 static char *op_name[64] = {
131 /* 0 */	"call_pal", "op1", "op2", "op3", "op4",	"op5",	"op6",	"op7",
132 /* 8 */	"lda",	"ldah",	"ldbu",	"ldq_u","ldwu",	"stw",	"stb",	"stq_u",
133 /*16 */	"arit",	"logical","bit","mul",	"op20",	"vaxf",	"ieeef","anyf",
134 /*24 */	"spec",	"hw_mfpr","jump","hw_ld","intmisc","hw_mtpr","hw_rei","hw_st",
135 /*32 */	"ldf",	"ldg",	"lds",	"ldt",	"stf",	"stg",	"sts",	"stt",
136 /*40 */	"ldl",	"ldq",	"ldl_l","ldq_l","stl",	"stq",	"stl_c","stq_c",
137 /*48 */	"br",	"fbeq",	"fblt",	"fble",	"bsr",	"fbne",	"fbge",	"fbgt",
138 /*56 */	"blbc",	"beq",	"blt",	"ble",	"blbs",	"bne",	"bge",	"bgt"
139 };
140 
141 /*
142  * The function field is too big (7 or 11 bits), so the sub-tables
143  * are addressed in a somewhat complicated manner to save
144  * space.  After all, alu operations is what RISCs are good at.
145  */
146 
147 struct tbl {
148 	const char	*name;
149 	int		code;
150 };
151 
152 static const struct tbl pal_op_tbl[] = {
153 	/* Common PAL function codes. */
154 	{ "halt",		PAL_halt },
155 	{ "cflush",		PAL_cflush },
156 	{ "draina",		PAL_draina },
157 	{ "cserve",		PAL_cserve, },
158 	{ "swppal",		PAL_swppal },
159 	{ "ipir",		PAL_ipir },
160 	{ "bpt",		PAL_bpt },
161 	{ "bugchk",		PAL_bugchk },
162 	{ "imb",		PAL_imb },
163 	{ "rdunique",		PAL_rdunique },
164 	{ "wrunique",		PAL_wrunique },
165 	{ "gentrap",		PAL_gentrap },
166 
167 	/* OSF/1 PAL function codes. */
168 	{ "osf1_rdmces",	PAL_OSF1_rdmces },
169 	{ "osf1_wrmces",	PAL_OSF1_wrmces },
170 	{ "osf1_wrfen",		PAL_OSF1_wrfen },
171 	{ "osf1_wrvptptr",	PAL_OSF1_wrvptptr },
172 	{ "osf1_swpctx",	PAL_OSF1_swpctx },
173 	{ "osf1_wrval",		PAL_OSF1_wrval },
174 	{ "osf1_rdval",		PAL_OSF1_rdval },
175 	{ "osf1_tbi",		PAL_OSF1_tbi },
176 	{ "osf1_wrent",		PAL_OSF1_wrent },
177 	{ "osf1_swpipl",	PAL_OSF1_swpipl },
178 	{ "osf1_rdps",		PAL_OSF1_rdps },
179 	{ "osf1_wrkgp",		PAL_OSF1_wrkgp },
180 	{ "osf1_wrusp",		PAL_OSF1_wrusp },
181 	{ "osf1_wrperfmon",	PAL_OSF1_wrperfmon },
182 	{ "osf1_rdusp",		PAL_OSF1_rdusp },
183 	{ "osf1_whami",		PAL_OSF1_whami },
184 	{ "osf1_retsys",	PAL_OSF1_retsys },
185 	{ "osf1_rti",		PAL_OSF1_rti },
186 	{ "osf1_callsys",	PAL_OSF1_callsys },
187 
188 	{ NULL,			-1 },
189 };
190 
191 static const char *
192 pal_opname(int op)
193 {
194 	static char unk[8];
195 	int i;
196 
197 	for (i = 0; pal_op_tbl[i].name != NULL; i++) {
198 		if (pal_op_tbl[i].code == op)
199 			return (pal_op_tbl[i].name);
200 	}
201 
202 	sprintf(unk, "0x%x", op);
203 	return (unk);
204 }
205 
206 /* HW (PAL) instruction qualifiers, stright tables */
207 static const char *mXpr_name[8] = {
208 	"", "/i", "/a", "/ai", "/p", "/pi", "/pa", "/pai"
209 };
210 static const char *hwlds_name[8] = {
211 	"", "/r", "/a", "/ar", "/p", "/p?r", "_l-c", "_l-c/?r"
212 };
213 
214 /*
215  * For this one we take the low nibble (valid values 0/2/9/b/d)
216  * and shift it down one to get the row index.  Within a row
217  * we can just take the high nibble deprived of the high bit
218  * (valid values 0/1/2/3/4/6).  We could have used a flat 64
219  * entry array, but in this way we use just 48 pointers.
220  * BUGFIX: the 'cmpbge 0x0f' opcode fits in here too
221  */
222 static const char *arit_c0[8] = {
223 	"addl", 0, "addq", 0, "addl/v", 0, "addq/v",
224 };
225 static const char *arit_c2[8] = {
226 	"s4addl", "s8addl", "s4addq", "s8addq",
227 };
228 static const char *arit_c9[8] = {
229 	"subl", 0, "subq", 0, "subl/v", 0, "subq/v",
230 };
231 static const char *arit_cB[8] = {
232 	"s4subl", "s8subl", "s4subq", "s8subq",
233 };
234 static const char *arit_cD[8] = {
235 	0, "cmpult", "cmpeq", "cmpule", "cmplt", 0, "cmple",
236 };
237 static const char *arit_cF[1] = {
238 	"cmpbge"
239 };
240 static const char **arit_opname[8] = {
241 	arit_c0, arit_c2, 0, 0, arit_c9, arit_cB, arit_cD, arit_cF
242 };
243 
244 static const char *
245 arit_name(int op)
246 {
247 	static char unk[32];
248 	const char *name = NULL;
249 
250 	if (arit_opname[((op)&0xe)>>1])
251 		name = arit_opname[((op)&0xe)>>1][((op)&0x70)>>4];
252 
253 	if (name != NULL)
254 		return (name);
255 
256 	sprintf(unk, "?arit 0x%x?", op);
257 	return (unk);
258 }
259 
260 /*
261  * Something similar for this one, except there are only
262  * 16 entries so the row indexing is done by enumeration
263  * of the low nibble (valid values 0/4/6/8).  Then we can
264  * just shift the high nibble to index inside the row
265  * (valid values are 0/2/4 or 1/2/4/6)
266  *
267  * There are two functions that don't play by these simple rules,
268  * so we special-case them.
269  */
270 static const char *logical_c0[4] = {
271 	"and", "or", "xor", 0
272 };
273 static const char *logical_c4[4] = {
274 	"cmovlbs", "cmoveq", "cmovlt", "cmovle"
275 };
276 static const char *logical_c6[4] = {
277 	"cmovlbc", "cmovne", "cmovge", "cmovgt"
278 };
279 static const char *logical_c8[4] = {
280 	"andnot", "ornot", "xornot", 0
281 };
282 
283 static const char *
284 logical_name(int op)
285 {
286 	static char unk[32];
287 	const char *name = NULL;
288 
289 	if (op == op_amask)
290 		return ("amask");
291 	else if (op == op_implver)
292 		return ("implver");
293 
294 	switch (op & 0xf) {
295 	case 0: name = logical_c0[((op)>>5)&3]; break;
296 	case 4: name = logical_c4[((op)>>5)&3]; break;
297 	case 6: name = logical_c6[((op)>>5)&3]; break;
298 	case 8: name = logical_c8[((op)>>5)&3]; break;
299 	}
300 
301 	if (name != NULL)
302 		return (name);
303 
304 	sprintf(unk, "?logical 0x%x?", op);
305 	return (unk);
306 }
307 
308 /*
309  * This is the messy one. First, we single out the dense
310  * case of a 3 in the high nibble (valid values 0/1/2/4/6/9/b/c).
311  * Then the case of a 2 in the low nibble (valid values 0/1/2/5/6/7).
312  * For the remaining codes (6/7/a/b) we do as above: high
313  * nibble has valid values 0/1/2 or 5/6/7.  The low nibble
314  * can be used as row index picking bits 0 and 2, for the
315  * high one just the lower two bits.
316  */
317 static const char *bitop_c3[8] = {
318 	"zapnot", "mskql", "srl", "extql", "sll", "insql", "sra", 0
319 };
320 static const char *bitop_c2[8] = {
321 	"mskbl", "mskwl", "mskll", 0/*mskql*/, 0, "mskwh", "msklh", "mskqh"
322 };
323 static const char *bitop_c67ab[4][4] = {
324 /* a */	{ 0, "extwh", "extlh", "extqh"},
325 /* b */	{ "insbl", "inswl", "insll", 0 },
326 /* 6 */	{ "extbl", "extwl", "extll", 0 },
327 /* 7 */	{ 0, "inswh", "inslh", "insqh" },
328 };
329 
330 static const char *
331 bitop_name(int op)
332 {
333 	static char unk[32];
334 	const char *name = NULL;
335 
336 	if ((op & 0x70) == 0x30)
337 		name = (op == op_zap) ? "zap" : bitop_c3[((op)&0xe)>>1];
338 	else if ((op & 0xf) == 0x02)
339 		name = bitop_c2[(op)>>4];
340 	else
341 		name =
342 		    bitop_c67ab[(((op)&1)|(((op)&0x4)>>1))][(((op)&0x30)>>4)];
343 
344 	if (name != NULL)
345 		return (name);
346 
347 	sprintf(unk, "?bit 0x%x?", op);
348 	return (unk);
349 }
350 
351 /*
352  * Only 5 entries in this one
353  */
354 static const char *mul_opname[4] = {
355 	"mull", "mulq", "mull/v", "mulq/v"
356 };
357 
358 static const char *
359 mul_name(int op)
360 {
361 	static char unk[32];
362 	const char *name = NULL;
363 
364 	name = (op == op_umulh) ? "umulh" : mul_opname[((op)>>5)&3];
365 
366 	if (name != NULL)
367 		return (name);
368 
369 	sprintf(unk, "?mul 0x%x?", op);
370 	return (unk);
371 }
372 
373 /*
374  * These are few, the high nibble is usually enough to dispatch.
375  * We single out the `f' case to halve the table size, as
376  * well as the cases in which the high nibble isn't enough.
377  */
378 static const char *special_opname[8] = {
379 	"trapb", 0, "mb", 0, "fetch", "fetch_m", "rpcc", "rc"
380 };
381 
382 static const char *
383 special_name(int op)
384 {
385 	static char unk[32];
386 	const char *name;
387 
388 	switch (op) {
389 	case op_excb:		name = "excb";		break;
390 	case op_wmb:		name = "wmb";		break;
391 	case op_ecb:		name = "ecb";		break;
392 	case op_rs:		name = "rs";		break;
393 	case op_wh64:		name = "wh64";		break;
394 	default:
395 		name = special_opname[(op)>>13];
396 	}
397 
398 	if (name != NULL)
399 		return (name);
400 
401 	sprintf(unk, "?special 0x%x?", op);
402 	return (unk);
403 }
404 
405 /*
406  * This is trivial
407  */
408 static const char *jump_opname[4] = {
409 	"jmp", "jsr", "ret", "jcr"
410 };
411 #define jump_name(ix)	jump_opname[ix]
412 
413 /*
414  * For all but 4 of these, we can dispatch on the lower nibble of
415  * the "function".
416  */
417 static const char *intmisc_opname_3x[16] = {
418 	"ctpop", "perr", "ctlz", "cttz", "unpkbw", "unpkbl", "pkwb",
419 	"pklb", "minsb8", "minsw4", "minub8", "minuw4", "maxub8",
420 	"maxuw4", "maxsb8", "maxsw4",
421 };
422 
423 static const char *
424 intmisc_name(int op)
425 {
426 	static char unk[32];
427 
428 	if ((op & 0xf0) == 0x30)
429 		return (intmisc_opname_3x[op & 0x0f]);
430 
431 	switch (op) {
432 	case op_sextb: return ("sextb");
433 	case op_sextw: return ("sextw");
434 	case op_ftoit: return ("ftoit");
435 	case op_ftois: return ("ftois");
436 	}
437 
438 	sprintf(unk, "?intmisc 0x%x?", op);
439 	return (unk);
440 }
441 
442 static const char *
443 float_name(const struct tbl *tbl, int op, const char *type)
444 {
445 	static char unk[32];
446 	int i;
447 
448 	for (i = 0; tbl[i].name != NULL; i++) {
449 		if (tbl[i].code == op)
450 			return (tbl[i].name);
451 	}
452 
453 	sprintf(unk, "?%s 0x%x?", type, op);
454 	return (unk);
455 }
456 
457 #define vaxf_name(op)	float_name(vaxf_tbl, op, "vaxfl")
458 #define ieeef_name(op)	float_name(ieeef_tbl, op, "ieeefl")
459 #define anyf_name(op)	float_name(anyf_tbl, op, "anyfl")
460 
461 static const struct tbl anyf_tbl[] = {
462 	{ "cvtlq",	0x010},
463 	{ "cpys",	0x020},
464 	{ "cpysn",	0x021},
465 	{ "cpyse",	0x022},
466 	{ "mt_fpcr",	0x024},
467 	{ "mf_fpcr",	0x025},
468 	{ "fcmoveq",	0x02a},
469 	{ "fcmovne",	0x02b},
470 	{ "fcmovlt",	0x02c},
471 	{ "fcmovge",	0x02d},
472 	{ "fcmovle",	0x02e},
473 	{ "fcmovgt",	0x02f},
474 	{ "cvtql",	0x030},
475 	{ "cvtql/v",	0x130},
476 	{ "cvtql/sv",	0x330},
477 	{ 0, 0},
478 };
479 
480 static const struct tbl ieeef_tbl[] = {
481 	{ "adds/c",	0x000},
482 	{ "subs/c",	0x001},
483 	{ "muls/c",	0x002},
484 	{ "divs/c",	0x003},
485 	{ "addt/c",	0x020},
486 	{ "subt/c",	0x021},
487 	{ "mult/c",	0x022},
488 	{ "divt/c",	0x023},
489 	{ "cvtts/c",	0x02c},
490 	{ "cvttq/c",	0x02f},
491 	{ "cvtqs/c",	0x03c},
492 	{ "cvtqt/c",	0x03e},
493 	{ "adds/m",	0x040},
494 	{ "subs/m",	0x041},
495 	{ "muls/m",	0x042},
496 	{ "divs/m",	0x043},
497 	{ "addt/m",	0x060},
498 	{ "subt/m",	0x061},
499 	{ "mult/m",	0x062},
500 	{ "divt/m",	0x063},
501 	{ "cvtts/m",	0x06c},
502 	{ "cvtqs/m",	0x07c},
503 	{ "cvtqt/m",	0x07e},
504 	{ "adds",	0x080},
505 	{ "subs",	0x081},
506 	{ "muls",	0x082},
507 	{ "divs",	0x083},
508 	{ "addt",	0x0a0},
509 	{ "subt",	0x0a1},
510 	{ "mult",	0x0a2},
511 	{ "divt",	0x0a3},
512 	{ "cmptun",	0x0a4},
513 	{ "cmpteq",	0x0a5},
514 	{ "cmptlt",	0x0a6},
515 	{ "cmptle",	0x0a7},
516 	{ "cvtts",	0x0ac},
517 	{ "cvttq",	0x0af},
518 	{ "cvtqs",	0x0bc},
519 	{ "cvtqt",	0x0be},
520 	{ "adds/d",	0x0c0},
521 	{ "subs/d",	0x0c1},
522 	{ "muls/d",	0x0c2},
523 	{ "divs/d",	0x0c3},
524 	{ "addt/d",	0x0e0},
525 	{ "subt/d",	0x0e1},
526 	{ "mult/d",	0x0e2},
527 	{ "divt/d",	0x0e3},
528 	{ "cvtts/d",	0x0ec},
529 	{ "cvtqs/d",	0x0fc},
530 	{ "cvtqt/d",	0x0fe},
531 	{ "adds/uc",	0x100},
532 	{ "subs/uc",	0x101},
533 	{ "muls/uc",	0x102},
534 	{ "divs/uc",	0x103},
535 	{ "addt/uc",	0x120},
536 	{ "subt/uc",	0x121},
537 	{ "mult/uc",	0x122},
538 	{ "divt/uc",	0x123},
539 	{ "cvtts/uc",	0x12c},
540 	{ "cvttq/vc",	0x12f},
541 	{ "adds/um",	0x140},
542 	{ "subs/um",	0x141},
543 	{ "muls/um",	0x142},
544 	{ "divs/um",	0x143},
545 	{ "addt/um",	0x160},
546 	{ "subt/um",	0x161},
547 	{ "mult/um",	0x162},
548 	{ "divt/um",	0x163},
549 	{ "cvtts/um",	0x16c},
550 	{ "adds/u",	0x180},
551 	{ "subs/u",	0x181},
552 	{ "muls/u",	0x182},
553 	{ "divs/u",	0x183},
554 	{ "addt/u",	0x1a0},
555 	{ "subt/u",	0x1a1},
556 	{ "mult/u",	0x1a2},
557 	{ "divt/u",	0x1a3},
558 	{ "cvtts/u",	0x1ac},
559 	{ "cvttq/v",	0x1af},
560 	{ "adds/ud",	0x1c0},
561 	{ "subs/ud",	0x1c1},
562 	{ "muls/ud",	0x1c2},
563 	{ "divs/ud",	0x1c3},
564 	{ "addt/ud",	0x1e0},
565 	{ "subt/ud",	0x1e1},
566 	{ "mult/ud",	0x1e2},
567 	{ "divt/ud",	0x1e3},
568 	{ "cvtts/ud",	0x1ec},
569 	{ "adds/suc",	0x500},
570 	{ "subs/suc",	0x501},
571 	{ "muls/suc",	0x502},
572 	{ "divs/suc",	0x503},
573 	{ "addt/suc",	0x520},
574 	{ "subt/suc",	0x521},
575 	{ "mult/suc",	0x522},
576 	{ "divt/suc",	0x523},
577 	{ "cvtts/suc",	0x52c},
578 	{ "cvttq/svc",	0x52f},
579 	{ "adds/sum",	0x540},
580 	{ "subs/sum",	0x541},
581 	{ "muls/sum",	0x542},
582 	{ "divs/sum",	0x543},
583 	{ "addt/sum",	0x560},
584 	{ "subt/sum",	0x561},
585 	{ "mult/sum",	0x562},
586 	{ "divt/sum",	0x563},
587 	{ "cvtts/sum",	0x56c},
588 	{ "adds/su",	0x580},
589 	{ "subs/su",	0x581},
590 	{ "muls/su",	0x582},
591 	{ "divs/su",	0x583},
592 	{ "addt/su",	0x5a0},
593 	{ "subt/su",	0x5a1},
594 	{ "mult/su",	0x5a2},
595 	{ "divt/su",	0x5a3},
596 	{ "cmptun/su",	0x5a4},
597 	{ "cmpteq/su",	0x5a5},
598 	{ "cmptlt/su",	0x5a6},
599 	{ "cmptle/su",	0x5a7},
600 	{ "cvtts/su",	0x5ac},
601 	{ "cvttq/sv",	0x5af},
602 	{ "adds/sud",	0x5c0},
603 	{ "subs/sud",	0x5c1},
604 	{ "muls/sud",	0x5c2},
605 	{ "divs/sud",	0x5c3},
606 	{ "addt/sud",	0x5e0},
607 	{ "subt/sud",	0x5e1},
608 	{ "mult/sud",	0x5e2},
609 	{ "divt/sud",	0x5e3},
610 	{ "cvtts/sud",	0x5ec},
611 	{ "adds/suic",	0x700},
612 	{ "subs/suic",	0x701},
613 	{ "muls/suic",	0x702},
614 	{ "divs/suic",	0x703},
615 	{ "addt/suic",	0x720},
616 	{ "subt/suic",	0x721},
617 	{ "mult/suic",	0x722},
618 	{ "divt/suic",	0x723},
619 	{ "cvtts/suic",	0x72c},
620 	{ "cvttq/svic",	0x72f},
621 	{ "cvtqs/suic",	0x73c},
622 	{ "cvtqt/suic",	0x73e},
623 	{ "adds/suim",	0x740},
624 	{ "subs/suim",	0x741},
625 	{ "muls/suim",	0x742},
626 	{ "divs/suim",	0x743},
627 	{ "addt/suim",	0x760},
628 	{ "subt/suim",	0x761},
629 	{ "mult/suim",	0x762},
630 	{ "divt/suim",	0x763},
631 	{ "cvtts/suim",	0x76c},
632 	{ "cvtqs/suim",	0x77c},
633 	{ "cvtqt/suim",	0x77e},
634 	{ "adds/sui",	0x780},
635 	{ "subs/sui",	0x781},
636 	{ "muls/sui",	0x782},
637 	{ "divs/sui",	0x783},
638 	{ "addt/sui",	0x7a0},
639 	{ "subt/sui",	0x7a1},
640 	{ "mult/sui",	0x7a2},
641 	{ "divt/sui",	0x7a3},
642 	{ "cvtts/sui",	0x7ac},
643 	{ "cvttq/svi",	0x7af},
644 	{ "cvtqs/sui",	0x7bc},
645 	{ "cvtqt/sui",	0x7be},
646 	{ "adds/suid",	0x7c0},
647 	{ "subs/suid",	0x7c1},
648 	{ "muls/suid",	0x7c2},
649 	{ "divs/suid",	0x7c3},
650 	{ "addt/suid",	0x7e0},
651 	{ "subt/suid",	0x7e1},
652 	{ "mult/suid",	0x7e2},
653 	{ "divt/suid",	0x7e3},
654 	{ "cvtts/suid",	0x7ec},
655 	{ "cvtqs/suid",	0x7fc},
656 	{ "cvtqt/suid",	0x7fe},
657 	{ 0, 0}
658 };
659 
660 static const struct tbl vaxf_tbl[] = {
661 	{ "addf/c",	0x000},
662 	{ "subf/c",	0x001},
663 	{ "mulf/c",	0x002},
664 	{ "divf/c",	0x003},
665 	{ "cvtdg/c",	0x01e},
666 	{ "addg/c",	0x020},
667 	{ "subg/c",	0x021},
668 	{ "mulg/c",	0x022},
669 	{ "divg/c",	0x023},
670 	{ "cvtgf/c",	0x02c},
671 	{ "cvtgd/c",	0x02d},
672 	{ "cvtgq/c",	0x02f},
673 	{ "cvtqf/c",	0x03c},
674 	{ "cvtqg/c",	0x03e},
675 	{ "addf",	0x080},
676 	{ "subf",	0x081},
677 	{ "mulf",	0x082},
678 	{ "divf",	0x083},
679 	{ "cvtdg",	0x09e},
680 	{ "addg",	0x0a0},
681 	{ "subg",	0x0a1},
682 	{ "mulg",	0x0a2},
683 	{ "divg",	0x0a3},
684 	{ "cmpgeq",	0x0a5},
685 	{ "cmpglt",	0x0a6},
686 	{ "cmpgle",	0x0a7},
687 	{ "cvtgf",	0x0ac},
688 	{ "cvtgd",	0x0ad},
689 	{ "cvtgq",	0x0af},
690 	{ "cvtqf",	0x0bc},
691 	{ "cvtqg",	0x0be},
692 	{ "addf/uc",	0x100},
693 	{ "subf/uc",	0x101},
694 	{ "mulf/uc",	0x102},
695 	{ "divf/uc",	0x103},
696 	{ "cvtdg/uc",	0x11e},
697 	{ "addg/uc",	0x120},
698 	{ "subg/uc",	0x121},
699 	{ "mulg/uc",	0x122},
700 	{ "divg/uc",	0x123},
701 	{ "cvtgf/uc",	0x12c},
702 	{ "cvtgd/uc",	0x12d},
703 	{ "cvtgq/vc",	0x12f},
704 	{ "addf/u",	0x180},
705 	{ "subf/u",	0x181},
706 	{ "mulf/u",	0x182},
707 	{ "divf/u",	0x183},
708 	{ "cvtdg/u",	0x19e},
709 	{ "addg/u",	0x1a0},
710 	{ "subg/u",	0x1a1},
711 	{ "mulg/u",	0x1a2},
712 	{ "divg/u",	0x1a3},
713 	{ "cvtgf/u",	0x1ac},
714 	{ "cvtgd/u",	0x1ad},
715 	{ "cvtgq/v",	0x1af},
716 	{ "addf/sc",	0x400},
717 	{ "subf/sc",	0x401},
718 	{ "mulf/sc",	0x402},
719 	{ "divf/sc",	0x403},
720 	{ "cvtdg/sc",	0x41e},
721 	{ "addg/sc",	0x420},
722 	{ "subg/sc",	0x421},
723 	{ "mulg/sc",	0x422},
724 	{ "divg/sc",	0x423},
725 	{ "cvtgf/sc",	0x42c},
726 	{ "cvtgd/sc",	0x42d},
727 	{ "cvtgq/sc",	0x42f},
728 	{ "cvtqf/sc",	0x43c},
729 	{ "cvtqg/sc",	0x43e},
730 	{ "addf/s",	0x480},
731 	{ "subf/s",	0x481},
732 	{ "mulf/s",	0x482},
733 	{ "divf/s",	0x483},
734 	{ "cvtdg/s",	0x49e},
735 	{ "addg/s",	0x4a0},
736 	{ "subg/s",	0x4a1},
737 	{ "mulg/s",	0x4a2},
738 	{ "divg/s",	0x4a3},
739 	{ "cmpgeq/s",	0x4a5},
740 	{ "cmpglt/s",	0x4a6},
741 	{ "cmpgle/s",	0x4a7},
742 	{ "cvtgf/s",	0x4ac},
743 	{ "cvtgd/s",	0x4ad},
744 	{ "cvtgq/s",	0x4af},
745 	{ "cvtqf/s",	0x4bc},
746 	{ "cvtqg/s",	0x4be},
747 	{ "addf/suc",	0x500},
748 	{ "subf/suc",	0x501},
749 	{ "mulf/suc",	0x502},
750 	{ "divf/suc",	0x503},
751 	{ "cvtdg/suc",	0x51e},
752 	{ "addg/suc",	0x520},
753 	{ "subg/suc",	0x521},
754 	{ "mulg/suc",	0x522},
755 	{ "divg/suc",	0x523},
756 	{ "cvtgf/suc",	0x52c},
757 	{ "cvtgd/suc",	0x52d},
758 	{ "cvtgq/svc",	0x52f},
759 	{ "addf/su",	0x580},
760 	{ "subf/su",	0x581},
761 	{ "mulf/su",	0x582},
762 	{ "divf/su",	0x583},
763 	{ "cvtdg/su",	0x59e},
764 	{ "addg/su",	0x5a0},
765 	{ "subg/su",	0x5a1},
766 	{ "mulg/su",	0x5a2},
767 	{ "divg/su",	0x5a3},
768 	{ "cvtgf/su",	0x5ac},
769 	{ "cvtgd/su",	0x5ad},
770 	{ "cvtgq/sv",	0x5af},
771 	{ 0, 0}
772 };
773 
774 /*
775  * General purpose registers
776  */
777 static const char *name_of_register[32] = {
778 	"v0",	"t0",	"t1",	"t2",	"t3",	"t4",	"t5",	"t6",
779 	"t7",	"s0",	"s1",	"s2",	"s3",	"s4",	"s5",	"s6",
780 	"a0",	"a1",	"a2",	"a3",	"a4",	"a5",	"t8",	"t9",
781 	"t10",	"t11",	"ra",	"pv",	"at",	"gp",	"sp",	"zero"
782 };
783 
784 static int regcount;		/* how many regs used in this inst */
785 static int regnum[3];		/* which regs used in this inst */
786 
787 static const char *
788 register_name(int ireg)
789 {
790 	int	i;
791 
792 	for (i = 0; i < regcount; i++)
793 		if (regnum[i] == ireg)
794 			break;
795 	if (i >= regcount)
796 		regnum[regcount++] = ireg;
797 	return (name_of_register[ireg]);
798 }
799 
800 /*
801  * Disassemble instruction at 'loc'.  'altfmt' specifies an
802  * (optional) alternate format.  Return address of start of
803  * next instruction.
804  */
805 
806 static int
807 alpha_print_instruction(db_addr_t iadr, alpha_instruction i,
808     boolean_t showregs)
809 {
810 	const char	*opcode;
811 	int		ireg;
812 	long		signed_immediate;
813 	boolean_t	fstore;
814 	pal_instruction	p;
815 
816 	regcount = 0;
817 	fstore = FALSE;
818 	opcode = op_name[i.mem_format.opcode];
819 
820 	/*
821 	 *	Dispatch directly on the opcode, save code
822 	 *	duplication sometimes via "harmless gotos".
823 	 */
824 	switch (i.mem_format.opcode) {
825 	case op_pal:
826 		/* "call_pal" is a long string; just use a space. */
827 		db_printf("%s %s", opcode, pal_opname(i.pal_format.function));
828 		break;
829 	case op_lda:
830 	case op_ldah:
831 	case op_ldbu:
832 	case op_ldq_u:
833 	case op_ldwu:
834 	case op_stw:
835 	case op_stb:
836 	case op_stq_u:
837 		/*
838 		 * These loadstores are here to make compiling the
839 		 * switch a bit easier.  Could embellish the output
840 		 * someday, too.
841 		 */
842 		goto loadstore;
843 		break;
844 	case op_arit:
845 		/*
846 		 * For this and the following three groups we
847 		 * just need different opcode strings
848 		 */
849 		opcode = arit_name(i.operate_lit_format.function);
850 		goto operate;
851 		break;
852 	case op_logical:
853 		opcode = logical_name(i.operate_lit_format.function);
854 		goto operate;
855 		break;
856 	case op_bit:
857 		opcode = bitop_name(i.operate_lit_format.function);
858 		goto operate;
859 		break;
860 	case op_mul:
861 		opcode = mul_name(i.operate_lit_format.function);
862 operate:
863 		/*
864 		 * Nice and uniform, just check for literals
865 		 */
866 		db_printf("%s\t%s,", opcode,
867 		    register_name(i.operate_lit_format.ra));
868 		if (i.operate_lit_format.one)
869 			db_printf("#0x%x", i.operate_lit_format.literal);
870 		else
871 			db_printf("%s", register_name(i.operate_reg_format.rb));
872 		db_printf(",%s", register_name(i.operate_lit_format.rc));
873 		break;
874 	case op_vax_float:
875 		/*
876 		 * The three floating point groups are even simpler
877 		 */
878 		opcode = vaxf_name(i.float_format.function);
879 		goto foperate;
880 		break;
881 	case op_ieee_float:
882 		opcode = ieeef_name(i.float_format.function);
883 		goto foperate;
884 		break;
885 	case op_any_float:
886 		opcode = anyf_name(i.float_format.function);
887 foperate:
888 		db_printf("%s\tf%d,f%d,f%d", opcode,
889 			i.float_format.fa,
890 			i.float_format.fb,
891 			i.float_format.fc);
892 		break;
893 	case op_special:
894 		/*
895 		 * Miscellaneous.
896 		 */
897 		{
898 			register unsigned int code;
899 
900 			code = (i.mem_format.displacement)&0xffff;
901 			opcode = special_name(code);
902 
903 			switch (code) {
904 			case op_ecb:
905 				db_printf("%s\t(%s)", opcode,
906 					register_name(i.mem_format.rb));
907 				break;
908 			case op_fetch:
909 			case op_fetch_m:
910 				db_printf("%s\t0(%s)", opcode,
911 					register_name(i.mem_format.rb));
912 				break;
913 			case op_rpcc:
914 			case op_rc:
915 			case op_rs:
916 				db_printf("%s\t%s", opcode,
917 					register_name(i.mem_format.ra));
918 				break;
919 			default:
920 				db_printf("%s", opcode);
921 			break;
922 			}
923 		}
924 		break;
925 	case op_j:
926 		/*
927 		 * Jump instructions really are of two sorts,
928 		 * depending on the use of the hint info.
929 		 */
930 		opcode = jump_name(i.jump_format.action);
931 		switch (i.jump_format.action) {
932 		case op_jmp:
933 		case op_jsr:
934 			db_printf("%s\t%s,(%s),", opcode,
935 				register_name(i.jump_format.ra),
936 				register_name(i.jump_format.rb));
937 			signed_immediate = i.jump_format.hint;
938 			goto branch_displacement;
939 			break;
940 		case op_ret:
941 		case op_jcr:
942 			db_printf("%s\t%s,(%s)", opcode,
943 				register_name(i.jump_format.ra),
944 				register_name(i.jump_format.rb));
945 			break;
946 		}
947 		break;
948 	case op_intmisc:
949 		/*
950 		 * These are just in "operate" format.
951 		 */
952 		opcode = intmisc_name(i.operate_lit_format.function);
953 		goto operate;
954 		break;
955 			/* HW instructions, possibly chip-specific XXXX */
956 	case op_pal19:	/* "hw_mfpr" */
957 	case op_pal1d:	/* "hw_mtpr" */
958 		p.bits = i.bits;
959 		db_printf("\t%s%s\t%s, %d", opcode,
960 			mXpr_name[p.mXpr_format.regset],
961 			register_name(p.mXpr_format.rd),
962 			p.mXpr_format.index);
963 		break;
964 	case op_pal1b:	/* "hw_ld" */
965 	case op_pal1f:	/* "hw_st" */
966 		p.bits = i.bits;
967 		db_printf("\t%s%c%s\t%s,", opcode,
968 			(p.mem_format.qw) ? 'q' : 'l',
969 			hwlds_name[p.mem_format.qualif],
970 			register_name(p.mem_format.rd));
971 		signed_immediate = (long)p.mem_format.displacement;
972 		goto loadstore_address;
973 
974 	case op_pal1e:	/* "hw_rei" */
975 		db_printf("\t%s", opcode);
976 		break;
977 
978 	case op_ldf:
979 	case op_ldg:
980 	case op_lds:
981 	case op_ldt:
982 	case op_stf:
983 	case op_stg:
984 	case op_sts:
985 	case op_stt:
986 		fstore = TRUE;
987 		/* fall through */
988 	case op_ldl:
989 	case op_ldq:
990 	case op_ldl_l:
991 	case op_ldq_l:
992 	case op_stl:
993 	case op_stq:
994 	case op_stl_c:
995 	case op_stq_c:
996 		/*
997 		 * Memory operations, including floats
998 		 */
999 loadstore:
1000 		if (fstore)
1001 		    db_printf("%s\tf%d,", opcode, i.mem_format.ra);
1002 		else
1003 		    db_printf("%s\t%s,", opcode,
1004 		        register_name(i.mem_format.ra));
1005 		signed_immediate = (long)i.mem_format.displacement;
1006 loadstore_address:
1007 		{
1008 			char tbuf[24];
1009 
1010 			db_format_hex(tbuf, 24, signed_immediate, FALSE);
1011 			db_printf("%s(%s)", tbuf,
1012 				register_name(i.mem_format.rb));
1013 		}
1014 		/*
1015 		 * For convenience, do the address computation
1016 		 */
1017 		if (showregs) {
1018 			if (i.mem_format.opcode == op_ldah)
1019 				signed_immediate <<= 16;
1020 			db_printf(" <0x%lx>", signed_immediate +
1021 			    db_register_value(DDB_REGS, i.mem_format.rb));
1022 		}
1023 		break;
1024 	case op_br:
1025 	case op_fbeq:
1026 	case op_fblt:
1027 	case op_fble:
1028 	case op_bsr:
1029 	case op_fbne:
1030 	case op_fbge:
1031 	case op_fbgt:
1032 	case op_blbc:
1033 	case op_beq:
1034 	case op_blt:
1035 	case op_ble:
1036 	case op_blbs:
1037 	case op_bne:
1038 	case op_bge:
1039 	case op_bgt:
1040 		/*
1041 		 * We want to know where we are branching to
1042 		 */
1043 		signed_immediate = (long)i.branch_format.displacement;
1044 		db_printf("%s\t%s,", opcode,
1045 			  register_name(i.branch_format.ra));
1046 branch_displacement:
1047 		db_printsym(iadr + sizeof(alpha_instruction) +
1048 		    (signed_immediate << 2), DB_STGY_PROC, db_printf);
1049 		break;
1050 	default:
1051 		/*
1052 		 * Shouldn't happen
1053 		 */
1054 		db_printf("? 0x%x ?", i.bits);
1055 	}
1056 
1057 	/*
1058 	 *	Print out the registers used in this instruction
1059 	 */
1060 	if (showregs && regcount > 0) {
1061 		db_printf("\t<");
1062 		for (ireg = 0; ireg < regcount; ireg++) {
1063 			if (ireg != 0)
1064 				db_printf(",");
1065 			db_printf("%s=0x%lx",
1066 			    name_of_register[regnum[ireg]],
1067 			    db_register_value(DDB_REGS, regnum[ireg]));
1068 		}
1069 		db_printf(">");
1070 	}
1071 	db_printf("\n");
1072 	return (sizeof(alpha_instruction));
1073 }
1074 
1075 db_addr_t
1076 db_disasm(db_addr_t loc, boolean_t altfmt)
1077 {
1078 	alpha_instruction inst;
1079 
1080 	inst.bits = db_get_value(loc, 4, 0);
1081 
1082 	loc += alpha_print_instruction(loc, inst, altfmt);
1083 	return (loc);
1084 }
1085