db_disasm.c revision 1.5
1/*	$OpenBSD: db_disasm.c,v 1.5 1997/07/09 02:57:28 deraadt Exp $	*/
2
3/*
4 * Copyright (c) 1997 Niklas Hallqvist.  All rights reserverd.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 *    must display the following acknowledgement:
16 *	This product includes software developed by Niklas Hallqvist.
17 * 4. The name of the author may not be used to endorse or promote products
18 *    derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include <sys/types.h>
33#include <sys/systm.h>
34
35#include <machine/db_machdep.h>
36
37#include <ddb/db_interface.h>
38#include <ddb/db_output.h>
39
40static struct opcode {
41	enum opc_fmt { OPC_PAL, OPC_RES, OPC_MEM, OPC_OP, OPC_BR } opc_fmt;
42	char *opc_name;
43	int opc_print;
44} opcode[] = {
45	{ OPC_PAL, "call_pal", 0 },	/* 00 */
46	{ OPC_RES, "opc01", 0 },	/* 01 */
47	{ OPC_RES, "opc02", 0 },	/* 02 */
48	{ OPC_RES, "opc03", 0 },	/* 03 */
49	{ OPC_RES, "opc04", 0 },	/* 04 */
50	{ OPC_RES, "opc05", 0 },	/* 05 */
51	{ OPC_RES, "opc06", 0 },	/* 06 */
52	{ OPC_RES, "opc07", 0 },	/* 07 */
53	{ OPC_MEM, "lda", 1 },		/* 08 */
54	{ OPC_MEM, "ldah", 1 },		/* 09 */
55	{ OPC_RES, "opc0a", 0 },	/* 0A */
56	{ OPC_MEM, "ldq_u", 1 },	/* 0B */
57	{ OPC_RES, "opc0c", 0 },	/* 0C */
58	{ OPC_RES, "opc0d", 0 },	/* 0D */
59	{ OPC_RES, "opc0e", 0 },	/* 0E */
60	{ OPC_MEM, "stq_u", 1 },	/* 0F */
61	{ OPC_OP, "inta", 1 },		/* 10 */
62	{ OPC_OP, "intl", 1 },		/* 11 */
63	{ OPC_OP, "ints", 1 },		/* 12 */
64	{ OPC_OP, "intm", 1 },		/* 13 */
65	{ OPC_RES, "opc14", 0 },	/* 14 */
66	{ OPC_OP, "fltv", 1 },		/* 15 */
67	{ OPC_OP, "flti", 1 },		/* 16 */
68	{ OPC_OP, "fltl", 1 },		/* 17 */
69	{ OPC_MEM, "misc", 0 },		/* 18 */
70	{ OPC_PAL, "pal19", 0 },	/* 19 */
71	{ OPC_MEM, "jsr", 0 },		/* 1A */
72	{ OPC_PAL, "pal1b", 0 },	/* 1B */
73	{ OPC_RES, "opc1c", 0 },	/* 1C */
74	{ OPC_PAL, "pal1d", 0 },	/* 1D */
75	{ OPC_PAL, "pal1e", 0 },	/* 1E */
76	{ OPC_PAL, "pal1f", 0 },	/* 1F */
77	{ OPC_MEM, "ldf", 1 },		/* 20 */
78	{ OPC_MEM, "ldg", 1 },		/* 21 */
79	{ OPC_MEM, "lds", 1 },		/* 22 */
80	{ OPC_MEM, "ldt", 1 },		/* 23 */
81	{ OPC_MEM, "stf", 1 },		/* 24 */
82	{ OPC_MEM, "stg", 1 },		/* 25 */
83	{ OPC_MEM, "sts", 1 },		/* 26 */
84	{ OPC_MEM, "stt", 1 },		/* 27 */
85	{ OPC_MEM, "ldl", 1 },		/* 28 */
86	{ OPC_MEM, "ldq", 1 },		/* 29 */
87	{ OPC_MEM, "ldl_l", 1 },	/* 2A */
88	{ OPC_MEM, "ldq_l", 1 },	/* 2B */
89	{ OPC_MEM, "stl", 1 },		/* 2C */
90	{ OPC_MEM, "stq", 1 },		/* 2D */
91	{ OPC_MEM, "stl_c", 1 },	/* 2E */
92	{ OPC_MEM, "stq_c", 1 },	/* 2F */
93	{ OPC_BR, "br", 1 },		/* 30 */
94	{ OPC_BR, "fbeq", 1 },		/* 31 */
95	{ OPC_BR, "fblt", 1 },		/* 32 */
96	{ OPC_BR, "fble", 1 },		/* 33 */
97	{ OPC_BR, "bsr", 1 },		/* 34 */
98	{ OPC_BR, "fbne", 1 },		/* 35 */
99	{ OPC_BR, "fbge", 1 },		/* 36 */
100	{ OPC_BR, "fbgt", 1 },		/* 37 */
101	{ OPC_BR, "blbc", 1 },		/* 38 */
102	{ OPC_BR, "beq", 1 },		/* 39 */
103	{ OPC_BR, "blt", 1 },		/* 3A */
104	{ OPC_BR, "ble", 1 },		/* 3B */
105	{ OPC_BR, "blbs", 1 },		/* 3C */
106	{ OPC_BR, "bne", 1 },		/* 3D */
107	{ OPC_BR, "bge", 1 },		/* 3E */
108	{ OPC_BR, "bgt", 1 },		/* 3F */
109};
110
111char *jsr_names[] = { "jmp", "jsr", "ret", "jsr_coroutine" };
112
113vm_offset_t
114db_disasm(loc, flag)
115	vm_offset_t loc;
116	boolean_t flag;
117{
118	u_int32_t ins = *(u_int32_t *)loc;
119	int opc = ins >> 26;
120	int arg = ins & 0x3ffffff;
121	int ra, rb, rc, disp, func;
122
123	if (opcode[opc].opc_print)
124		db_printf("%s\t", opcode[opc].opc_name);
125	switch (opcode[opc].opc_fmt) {
126	case OPC_PAL:
127		switch (arg) {
128		case 0x0000000:
129			db_printf("halt");
130			break;
131		case 0x0000080:
132			db_printf("bpt");
133			break;
134		case 0x0000086:
135			db_printf("imb");
136			break;
137		default:
138			db_printf("%08x", ins);
139			break;
140		}
141		break;
142	case OPC_RES:
143		db_printf("0x%08x", ins);
144		break;
145	case OPC_MEM:
146		ra = arg >> 21;
147		rb = (arg >> 16) & 0x1f;
148		disp = arg & 0xffff;
149		switch (opc) {
150		case 0x18:
151			/* Memory fmt with a function code */
152			switch (disp) {
153			case 0x0000:
154				db_printf("trapb");
155				break;
156			case 0x4000:
157				db_printf("mb");
158				break;
159			case 0x8000:
160				db_printf("fetch\t0($%d)", rb);
161				break;
162			case 0xa000:
163				db_printf("fetch_m\t0($%d)", rb);
164				break;
165			case 0xc000:
166				db_printf("rpcc\t$%d", ra);
167				break;
168			case 0xe000:
169				db_printf("rc\t$%d", ra);
170				break;
171			case 0xf000:
172				db_printf("rs\t$%d", ra);
173				break;
174			default:
175				db_printf("%08x", ins);
176			        break;
177			}
178			break;
179		case 0x1a:
180			db_printf("%s\t$%d,($%d),0x%x", jsr_names[disp >> 14],
181			    ra, rb, disp & 0x3fff);
182			break;
183		default:
184			db_printf("\t$%d,0x%x($%d)", ra, disp, rb);
185			break;
186		}
187		break;
188	case OPC_OP:
189		ra = arg >> 21;
190		rb = (arg >> 16) & 0x1f;
191		func = (arg >> 5) & 0x7ff;
192		rc = arg & 0x1f;
193		db_printf("\t%03x,$%d,$%d,$%d", func, ra, rb, rc);
194		break;
195	case OPC_BR:
196		ra = arg >> 21;
197		disp = arg & 0x1fffff;
198		db_printf("\t$%d,0x%x", ra, disp);
199		break;
200	}
201	db_printf("\n");
202	return (loc + 4);
203}
204