1/*	$NetBSD: db_disasm.c,v 1.47 2023/09/26 14:33:55 tsutsui Exp $	*/
2
3/*
4 * Copyright (c) 1994 Christian E. Hopps
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 *    must display the following acknowledgement:
17 *      This product includes software developed by Christian E. Hopps.
18 * 4. The name of the author may not be used to endorse or promote products
19 *    derived from this software without specific prior written permission
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32/*
33 * Notes:
34 *
35 * Much can be done with this format, with a lot of hacking even
36 * a moto emul. could be built.  However things like symbol lookup
37 * and reference are needed right away.
38 *
39 * the only functions that use the "get_xxx()" notation should be
40 * ones that modify things in a dis_buffer_t besides the buffers.
41 * (namely the used field)
42 *
43 * An attempt has been made to *always* increment dbuf->used++ immediately
44 * after referencing a value beyond the current "short *" address.
45 * this meant either only referencing the value once or placing it in
46 * a local var.  If you play with this keep this style. Its very useful
47 * in eliminating a very easy to make hard to find logic error.
48 *
49 * I broke style in 2 ways with one macro ``addchar()''
50 * However it makes sense, consider that it is called *a lot* and
51 * commonly with things like ","'s
52 *
53 * *dbuf->casm++ = ','; || ADDCHAR(dbuf,','); || addchar(dbuf,',');
54 * I chose:
55 *	addchar(',');
56 *
57 * If this is not enough to convince you, please load up you emacs or
58 * vi and do a fancy regex-replace, and compare for yourself.
59 * (The 2 rules of style I broke if you failed to notice are:
60 *  1: lower case macro name 2: implicit reference to local var name.)
61 *
62 * (chopps - March 1, 1994)
63 */
64
65#include <sys/cdefs.h>
66__KERNEL_RCSID(0, "$NetBSD: db_disasm.c,v 1.47 2023/09/26 14:33:55 tsutsui Exp $");
67
68#include <sys/param.h>
69#ifdef _KERNEL
70#include <sys/systm.h>
71#endif
72
73#include <machine/db_machdep.h>
74
75#include <ddb/db_interface.h>
76#include <ddb/db_output.h>
77#include <ddb/db_sym.h>
78#include <m68k/m68k/db_disasm.h>
79
80static void	get_modregstr(dis_buffer_t *, int, int, int, int);
81static void	get_modregstr_moto(dis_buffer_t *, int, int, int, int);
82static void	get_modregstr_mit(dis_buffer_t *, int, int, int, int);
83#if 0
84static u_long	get_areg_val(int reg);
85#endif
86static void	get_immed(dis_buffer_t *, int);
87static void	get_fpustdGEN(dis_buffer_t *, u_short, const char *);
88static void	addstr(dis_buffer_t *, const char *s);
89static void	prints(dis_buffer_t *, int, int);
90static void	printu(dis_buffer_t *, u_int, int);
91static void	prints_wb(dis_buffer_t *, int, int, int);
92static void	printu_wb(dis_buffer_t *, u_int, int, int);
93static void	prints_bf(dis_buffer_t *, int, int, int);
94static void	printu_bf(dis_buffer_t *, u_int, int, int);
95static void	iaddstr(dis_buffer_t *, const char *s);
96#if 0
97static void	iprints(dis_buffer_t *, int, int);
98#endif
99static void	iprintu(dis_buffer_t *, u_int, int);
100#if 0
101static void	iprints_wb(dis_buffer_t *, int, int, int);
102#endif
103static void	iprintu_wb(dis_buffer_t *, u_int, int, int);
104static void	make_cond(dis_buffer_t *, int , const char *);
105static void	print_fcond(dis_buffer_t *, char);
106static void	print_mcond(dis_buffer_t *, char);
107static void	print_disp(dis_buffer_t *, int, int, int);
108static void	print_addr(dis_buffer_t *, u_long);
109static void	print_reglist(dis_buffer_t *, int, u_short);
110static void	print_freglist(dis_buffer_t *, int, u_short, int);
111static void	print_fcode(dis_buffer_t *, u_short);
112
113/* groups */
114static void	opcode_bitmanip(dis_buffer_t *, u_short);
115static void	opcode_move(dis_buffer_t *, u_short);
116static void	opcode_misc(dis_buffer_t *, u_short);
117static void	opcode_branch(dis_buffer_t *, u_short);
118static void	opcode_coproc(dis_buffer_t *, u_short);
119static void	opcode_0101(dis_buffer_t *, u_short);
120static void	opcode_1000(dis_buffer_t *, u_short);
121static void	opcode_addsub(dis_buffer_t *, u_short);
122static void	opcode_1010(dis_buffer_t *, u_short);
123static void	opcode_1011(dis_buffer_t *, u_short);
124static void	opcode_1100(dis_buffer_t *, u_short);
125static void	opcode_1110(dis_buffer_t *, u_short);
126static void	opcode_fpu(dis_buffer_t *, u_short);
127static void	opcode_mmu(dis_buffer_t *, u_short);
128static void	opcode_mmu040(dis_buffer_t *, u_short);
129static void	opcode_move16(dis_buffer_t *, u_short);
130
131/* subs of groups */
132static void	opcode_movec(dis_buffer_t *, u_short);
133static void	opcode_divmul(dis_buffer_t *, u_short);
134static void	opcode_movem(dis_buffer_t *, u_short);
135static void	opcode_fmove_ext(dis_buffer_t *, u_short, u_short);
136static void	opcode_pmove(dis_buffer_t *, u_short, u_short);
137static void	opcode_pflush(dis_buffer_t *, u_short, u_short);
138
139#define addchar(ch) (*dbuf->casm++ = ch)
140#define iaddchar(ch) (*dbuf->cinfo++ = ch)
141
142typedef void dis_func_t(dis_buffer_t *, u_short);
143
144static dis_func_t *const opcode_map[16] = {
145	opcode_bitmanip, opcode_move, opcode_move, opcode_move,
146	opcode_misc, opcode_0101, opcode_branch, opcode_move,
147	opcode_1000, opcode_addsub, opcode_1010, opcode_1011,
148	opcode_1100, opcode_addsub, opcode_1110, opcode_coproc
149};
150
151static const char *const cc_table[16] = {
152	"t", "f", "hi", "ls",
153	"cc", "cs", "ne", "eq",
154	"vc", "vs", "pl", "mi",
155	"ge", "lt", "gt", "le"
156};
157
158static const char *const fpcc_table[32] = {
159	"f", "eq", "ogt", "oge", "olt", "ole", "ogl", "or",
160	"un", "ueq", "ugt", "uge", "ult", "ule", "ne", "t",
161	"sf", "seq", "gt", "ge", "lt", "le", "gl", "gle",
162	"ngle", "ngl", "nle", "nlt", "nge", "ngt", "sne", "st" };
163
164static const char *const mmcc_table[16] = {
165	"bs", "bc", "ls", "lc", "ss", "sc", "as", "sc",
166	"ws", "wc", "is", "ic", "gs", "gc", "cs", "cc" };
167
168
169static const char *const aregs[8] = {"a0","a1","a2","a3","a4","a5","a6","sp"};
170static const char *const dregs[8] = {"d0","d1","d2","d3","d4","d5","d6","d7"};
171static const char *const fpregs[8] = {
172	"fp0","fp1","fp2","fp3","fp4","fp5","fp6","fp7" };
173static const char *const fpcregs[3] = { "fpiar", "fpsr", "fpcr" };
174#ifndef _KERNEL
175static const char hexdigits[] = "0123456789abcdef";
176#endif
177
178/*
179 * Disassemble instruction at location ``loc''.
180 * Returns location of next instruction.
181 */
182
183static char asm_buffer[256];
184static char info_buffer[256];
185
186db_addr_t
187db_disasm(db_addr_t loc, bool moto_syntax)
188{
189	u_short opc;
190	dis_func_t *func;
191	dis_buffer_t dbuf;
192
193	dbuf.casm = dbuf.dasm = asm_buffer;
194	dbuf.cinfo = dbuf.info = info_buffer;
195	dbuf.used = 0;
196	dbuf.val = (short *)loc;
197	dbuf.mit = moto_syntax ? 0 : 1;
198
199	dbuf.dasm[0] = 0;
200	dbuf.info[0] = 0;
201
202	opc = *dbuf.val;
203	dbuf.used++;
204
205	func = opcode_map[OPCODE_MAP(opc)];
206	func(&dbuf, opc);
207
208	db_printf("%s",asm_buffer);
209	if (info_buffer[0])
210		db_printf("\t[%s]\n",info_buffer);
211	else
212		db_printf("\n");
213	return loc + sizeof(short) * dbuf.used;
214}
215/*
216 * Bit manipulation/MOVEP/Immediate.
217 */
218static void
219opcode_bitmanip(dis_buffer_t *dbuf, u_short opc)
220{
221	const char *tmp;
222	u_short ext;
223	int sz;
224
225	tmp = NULL;
226
227	switch (opc) {
228	case ANDITOCCR_INST:
229		tmp = "andib\t";
230		break;
231	case ANDIROSR_INST:
232		tmp = "andiw\t";
233		break;
234	case EORITOCCR_INST:
235		tmp = "eorib\t";
236		break;
237	case EORITOSR_INST:
238		tmp = "eoriw\t";
239		break;
240	case ORITOCCR_INST:
241		tmp = "orib\t";
242		break;
243	case ORITOSR_INST:
244		tmp = "oriw\t";
245		break;
246	}
247	if (tmp) {
248		addstr(dbuf, tmp);
249		if (ISBITSET(opc,6)) {
250			get_immed(dbuf, SIZE_WORD);
251			addstr(dbuf, ",sr");
252		} else {
253			get_immed(dbuf, SIZE_BYTE);
254			addstr(dbuf, ",ccr");
255		}
256		return;
257	}
258
259	if (IS_INST(RTM,opc)) {
260		addstr(dbuf, "rtm\t");
261		if (ISBITSET(opc,3))
262			PRINT_AREG(dbuf, BITFIELD(opc,2,0));
263		else
264			PRINT_DREG(dbuf, BITFIELD(opc,2,0));
265		return;
266	}
267
268	if (IS_INST(MOVEP,opc)) {
269		addstr(dbuf, "movp");
270		if (ISBITSET(opc,6))
271			addchar('l');
272		else
273			addchar('w');
274		addchar('\t');
275		if (ISBITSET(opc,7)) {
276			PRINT_DREG(dbuf, BITFIELD(opc, 11, 9));
277			addchar(',');
278		}
279		PRINT_AREG(dbuf, BITFIELD(opc, 2, 0));
280		addchar('@');
281		addchar('(');
282		print_disp(dbuf, *(dbuf->val + 1), SIZE_WORD,
283		    BITFIELD(opc, 2, 0));
284		dbuf->used++;
285		addchar(')');
286		if (!ISBITSET(opc,7)) {
287			addchar(',');
288			PRINT_DREG(dbuf, BITFIELD(opc, 11, 9));
289		}
290		return;
291	}
292
293	switch (opc & BCHGD_MASK) {
294	case BCHGD_INST:
295		tmp = "bchg\t";
296		break;
297	case BCLRD_INST:
298		tmp = "bclr\t";
299		break;
300	case BSETD_INST:
301		tmp = "bset\t";
302		break;
303	case BTSTD_INST:
304		tmp = "btst\t";
305		break;
306	}
307	if (tmp) {
308		addstr(dbuf, tmp);
309		PRINT_DREG(dbuf, BITFIELD(opc,11,9));
310		addchar(',');
311		get_modregstr(dbuf,5,GETMOD_BEFORE,0,0);
312		return;
313	}
314
315	switch (opc & BCHGS_MASK) {
316	case BCHGS_INST:
317		tmp = "bchg\t";
318		break;
319	case BCLRS_INST:
320		tmp = "bclr\t";
321		break;
322	case BSETS_INST:
323		tmp = "bset\t";
324		break;
325	case BTSTS_INST:
326		tmp = "btst\t";
327		break;
328	}
329	if (tmp) {
330		addstr(dbuf, tmp);
331		get_immed(dbuf, SIZE_BYTE);
332		addchar(',');
333		get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 1);
334		return;
335	}
336
337	if (IS_INST(CAS2,opc)) {
338		u_short ext2;
339
340		ext = *(dbuf->val + 1);
341		ext2 = *(dbuf->val + 2);
342		dbuf->used += 2;
343
344		if (ISBITSET(opc,9))
345			addstr(dbuf, "cas2l\t");
346		else
347			addstr(dbuf, "cas2w\t");
348
349		PRINT_DREG(dbuf, BITFIELD(ext,2,0));
350		addchar(':');
351		PRINT_DREG(dbuf, BITFIELD(ext2,2,0));
352		addchar(',');
353
354		PRINT_DREG(dbuf, BITFIELD(ext,8,6));
355		addchar(':');
356		PRINT_DREG(dbuf, BITFIELD(ext2,8,6));
357		addchar(',');
358
359		if (ISBITSET(ext,15))
360			PRINT_AREG(dbuf, BITFIELD(ext,14,12));
361		else
362			PRINT_DREG(dbuf, BITFIELD(ext,14,12));
363		addchar('@');
364		addchar(':');
365		if (ISBITSET(ext2,15))
366			PRINT_AREG(dbuf, BITFIELD(ext2,14,12));
367		else
368			PRINT_DREG(dbuf, BITFIELD(ext2,14,12));
369		addchar('@');
370		return;
371	}
372
373	switch (opc & CAS_MASK) {
374	case CAS_INST:
375		ext = *(dbuf->val + 1);
376		dbuf->used++;
377
378		addstr(dbuf,"cas");
379		sz = BITFIELD(opc,10,9);
380		if (sz == 0) {
381			sz = SIZE_BYTE;
382			addchar('b');
383		} else if (sz == 1) {
384			sz = SIZE_WORD;
385			addchar('w');
386		} else {
387			sz = SIZE_LONG;
388			addchar('l');
389		}
390		addchar('\t');
391		PRINT_DREG(dbuf, BITFIELD(ext, 2, 0));
392		addchar(',');
393		PRINT_DREG(dbuf, BITFIELD(ext, 8, 6));
394		addchar(',');
395		get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 1);
396		return;
397	case CHK2_INST:
398	/* case CMP2_INST: */
399		ext = *(dbuf->val + 1);
400		dbuf->used++;
401
402		if (ISBITSET(ext,11))
403			addstr(dbuf,"chk2");
404		else
405			addstr(dbuf,"cmp2");
406
407		sz = BITFIELD(opc,10,9);
408		if (sz == 0) {
409			sz = SIZE_BYTE;
410			addchar('b');
411		} else if (sz == 1) {
412			sz = SIZE_WORD;
413			addchar('w');
414		} else {
415			sz = SIZE_LONG;
416			addchar('l');
417		}
418		addchar('\t');
419		get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 1);
420
421		addchar(',');
422		if(ISBITSET(ext,15))
423			PRINT_AREG(dbuf, BITFIELD(ext, 14, 12));
424		else
425			PRINT_DREG(dbuf, BITFIELD(ext, 14, 12));
426		return;
427	}
428
429	switch (ADDI_MASK & opc) {
430	case MOVES_INST:
431		addstr(dbuf, "movs");
432		sz = BITFIELD(opc,7,6);
433		if (sz == 0) {
434			addchar('b');
435			sz = SIZE_BYTE;
436		} else if (sz == 1) {
437			addchar('w');
438			sz = SIZE_WORD;
439		} else {
440			addchar ('l');
441			sz = SIZE_LONG;
442		}
443		addchar('\t');
444
445		ext = *(dbuf->val + 1);
446		dbuf->used++;
447
448		if (ISBITSET(ext,11)) {
449			if (ISBITSET(ext,15))
450				PRINT_AREG(dbuf,BITFIELD(ext,14,12));
451			else
452				PRINT_DREG(dbuf,BITFIELD(ext,14,12));
453			addchar(',');
454			get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 1);
455		} else {
456			get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 1);
457			addchar(',');
458			if (ISBITSET(ext,15))
459				PRINT_AREG(dbuf,BITFIELD(ext,14,12));
460			else
461				PRINT_DREG(dbuf,BITFIELD(ext,14,12));
462		}
463		return;
464	case ADDI_INST:
465		tmp = "addi";
466		break;
467	case ANDI_INST:
468		tmp = "andi";
469		break;
470	case CMPI_INST:
471		tmp = "cmpi";
472		break;
473	case EORI_INST:
474		tmp = "eori";
475		break;
476	case ORI_INST:
477		tmp = "ori";
478		break;
479	case SUBI_INST:
480		tmp = "subi";
481		break;
482	}
483	if (tmp) {
484		addstr(dbuf, tmp);
485		sz = BITFIELD(opc,7,6);
486		switch (sz) {
487		case 0:
488			addchar('b');
489			addchar('\t');
490			sz = SIZE_BYTE;
491			break;
492		case 1:
493			addchar('w');
494			addchar('\t');
495			sz = SIZE_WORD;
496			break;
497		case 2:
498			addchar ('l');
499			addchar('\t');
500			get_immed(dbuf,SIZE_LONG);
501			addchar(',');
502			get_modregstr(dbuf,5,GETMOD_BEFORE,SIZE_LONG,2);
503			return;
504		}
505		get_immed(dbuf,sz);
506		addchar(',');
507		get_modregstr(dbuf,5,GETMOD_BEFORE,sz,1);
508		return;
509	}
510}
511
512/*
513 * move byte/word/long and q
514 * 00xx (01==.b 10==.l 11==.w) and 0111(Q)
515 */
516static void
517opcode_move(dis_buffer_t *dbuf, u_short opc)
518{
519	int sz, lused;
520
521	sz = 0;
522	switch (OPCODE_MAP(opc)) {
523	case 0x1:		/* move.b */
524		sz = SIZE_BYTE;
525		break;
526	case 0x3:		/* move.w */
527		sz = SIZE_WORD;
528		break;
529	case 0x2:		/* move.l */
530		sz = SIZE_LONG;
531		break;
532	case 0x7:		/* moveq */
533		addstr(dbuf, "movq\t#");
534		prints_bf(dbuf, opc, 7, 0);
535		addchar(',');
536		PRINT_DREG(dbuf,BITFIELD(opc,11,9));
537		return;
538	}
539	addstr(dbuf, "mov");
540
541	if (BITFIELD(opc,8,6) == AR_DIR)
542		addchar('a');
543
544	if (sz == SIZE_BYTE)
545		addchar('b');
546	else if (sz == SIZE_WORD)
547		addchar('w');
548	else
549		addchar('l');
550
551	addchar('\t');
552	lused = dbuf->used;
553	get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 0);
554	addchar(',');
555	get_modregstr(dbuf, 11, GETMOD_AFTER, sz, dbuf->used - lused);
556}
557
558/*
559 * misc opcodes.
560 */
561static void
562opcode_misc(dis_buffer_t *dbuf, u_short opc)
563{
564	const char *tmp;
565	int sz;
566
567	tmp = NULL;
568
569	/* Check against no option instructions */
570	switch (opc) {
571	case BGND_INST:
572		tmp = "bgnd";
573		break;
574	case ILLEGAL_INST:
575		tmp = "illegal";
576		break;
577	case MOVEFRC_INST:
578	case MOVETOC_INST:
579		opcode_movec(dbuf, opc);
580		return;
581	case NOP_INST:
582		tmp = "nop";
583		break;
584	case RESET_INST:
585		tmp = "reset";
586		break;
587	case RTD_INST:
588		addstr(dbuf, "rtd\t");
589		get_immed(dbuf, SIZE_WORD);
590		return;
591	case RTE_INST:
592		tmp = "rte";
593		break;
594	case RTR_INST:
595		tmp = "rtr";
596		break;
597	case RTS_INST:
598		tmp = "rts";
599		break;
600	case STOP_INST:
601		addstr(dbuf, "stop\t");
602		get_immed(dbuf, SIZE_WORD);
603		return;
604	case TRAPV_INST:
605		tmp = "trapv";
606		break;
607	default:
608		break;
609	}
610	if (tmp) {
611		addstr(dbuf, tmp);
612		return;
613	}
614
615	switch (opc & BKPT_MASK) {
616	case BKPT_INST:
617		addstr(dbuf, "bkpt\t#");
618		printu_bf(dbuf, opc, 2, 0);
619		return;
620	case EXTBW_INST:
621		addstr(dbuf, "extw\t");
622		get_modregstr(dbuf,2,DR_DIR,0,0);
623		return;
624	case EXTWL_INST:
625		addstr(dbuf, "extl\t");
626		get_modregstr(dbuf,2,DR_DIR,0,0);
627		return;
628	case EXTBL_INST:
629		addstr(dbuf, "extbl\t");
630		get_modregstr(dbuf,2,DR_DIR,0,0);
631		return;
632	case LINKW_INST:
633	case LINKL_INST:
634		if ((LINKW_MASK & opc) == LINKW_INST) {
635			addstr(dbuf, "linkw\t");
636			get_modregstr(dbuf, 2, AR_DIR, 0, 1);
637		} else {
638			addstr(dbuf, "linkl\t");
639			get_modregstr(dbuf, 2, AR_DIR, 0, 2);
640		}
641		addchar(',');
642		if ((LINKW_MASK & opc) == LINKW_INST)
643			get_immed(dbuf, SIZE_WORD);
644		else
645			get_immed(dbuf,SIZE_LONG);
646		return;
647	case MOVETOUSP_INST:
648	case MOVEFRUSP_INST:
649		addstr(dbuf, "movl\t");
650		if (!ISBITSET(opc,3)) {
651			get_modregstr(dbuf, 2, AR_DIR, 0, 0);
652			addchar(',');
653		}
654		addstr(dbuf, "usp");
655		if (ISBITSET(opc,3)) {
656			addchar(',');
657			get_modregstr(dbuf, 2, AR_DIR, 0, 0);
658		}
659		return;
660	case SWAP_INST:
661		addstr(dbuf, "swap\t");
662		get_modregstr(dbuf, 2, DR_DIR, 0, 0);
663		return;
664	case UNLK_INST:
665		addstr(dbuf, "unlk\t");
666		get_modregstr(dbuf, 2, AR_DIR, 0, 0);
667		return;
668	}
669
670	if ((opc & TRAP_MASK) == TRAP_INST) {
671		addstr(dbuf, "trap\t#");
672		printu_bf(dbuf, opc, 3, 0);
673		return;
674	}
675
676	sz = 0;
677	switch (DIVSL_MASK & opc) {
678	case DIVSL_INST:
679	case MULSL_INST:
680		opcode_divmul(dbuf, opc);
681		return;
682	case JMP_INST:
683		tmp = "jmp\t";
684		break;
685	case JSR_INST:
686		tmp = "jsr\t";
687		break;
688	case MOVEFRCCR_INST:
689		tmp = "mov\tccr,";
690		break;
691	case MOVEFRSR_INST:
692		tmp = "mov\tsr,";
693		break;
694	case NBCD_INST:
695		tmp = "nbcd\t";
696		break;
697	case PEA_INST:
698		tmp = "pea\t";
699		break;
700	case TAS_INST:
701		tmp = "tas\t";
702		break;
703	case MOVETOCCR_INST:
704	case MOVETOSR_INST:
705		tmp = "mov\t";
706		sz = SIZE_WORD;
707		break;
708	}
709	if (tmp) {
710		addstr(dbuf, tmp);
711		get_modregstr(dbuf,5, GETMOD_BEFORE, sz, 0);
712		if(IS_INST(MOVETOSR,opc))
713			addstr(dbuf, ",sr");
714		else if(IS_INST(MOVETOCCR,opc))
715			addstr(dbuf, ",ccr");
716		return;
717	}
718
719	if ((opc & MOVEM_MASK) == MOVEM_INST) {
720		opcode_movem(dbuf, opc);
721		return;
722	}
723
724	switch (opc & CLR_MASK) {
725	case CLR_INST:
726		tmp = "clr";
727		break;
728	case NEG_INST:
729		tmp = "neg";
730		break;
731	case NEGX_INST:
732		tmp = "negx";
733		break;
734	case NOT_INST:
735		tmp = "not";
736		break;
737	case TST_INST:
738		tmp = "tst";
739		break;
740	}
741	if (tmp) {
742		int msz;
743
744		addstr(dbuf, tmp);
745
746		msz = BITFIELD(opc,7,6);
747		if (msz == 0) {
748			tmp = "b\t";
749			sz = SIZE_BYTE;
750		} else if (msz == 1) {
751			tmp = "w\t";
752			sz = SIZE_WORD;
753		} else {
754			tmp = "l\t";
755			sz = SIZE_LONG;
756		}
757		addstr(dbuf, tmp);
758		get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 0);
759		return;
760	}
761
762	if ((opc & LEA_MASK) == LEA_INST) {
763		addstr(dbuf, "lea\t");
764		get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_LONG, 0);
765		addchar(',');
766		get_modregstr(dbuf, 11, AR_DIR, 0, 0);
767		return;
768	} else if ((opc & CHK_MASK) == CHK_INST) {
769		if (BITFIELD(opc,8,7) == 0x3) {
770			addstr(dbuf, "chkw\t");
771			get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_WORD, 0);
772		} else {
773			addstr(dbuf, "chkl\t");
774			get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_LONG, 0);
775		}
776		addchar(',');
777		get_modregstr(dbuf, 11, DR_DIR, 0, 0);
778		return;
779	}
780}
781
782/*
783 * ADDQ/SUBQ/Scc/DBcc/TRAPcc
784 */
785static void
786opcode_0101(dis_buffer_t *dbuf, u_short opc)
787{
788	int data;
789
790	if (IS_INST(TRAPcc, opc) && BITFIELD(opc,2,0) > 1) {
791		int opmode;
792
793		opmode = BITFIELD(opc,2,0);
794		make_cond(dbuf,11,"trap");
795
796		if (opmode == 0x2) {
797			addchar('w');
798			addchar('\t');
799			get_immed(dbuf, SIZE_WORD);
800		} else if (opmode == 0x3) {
801			addchar('l');
802			addchar('\t');
803			get_immed(dbuf, SIZE_LONG);
804		}
805		return;
806	} else if (IS_INST(DBcc, opc)) {
807		make_cond(dbuf,11,"db");
808		addchar('\t');
809		PRINT_DREG(dbuf, BITFIELD(opc,2,0));
810		addchar(',');
811		print_disp(dbuf, *(dbuf->val + 1), SIZE_WORD, -1);
812		dbuf->used++;
813		return;
814	} else if (IS_INST(Scc,opc)) {
815		make_cond(dbuf,11,"s");
816		addchar('\t');
817		get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_BYTE, 0);
818		return;
819	} else if (IS_INST(ADDQ, opc) || IS_INST(SUBQ, opc)) {
820		int size = BITFIELD(opc,7,6);
821
822		if (IS_INST(SUBQ, opc))
823			addstr(dbuf, "subq");
824		else
825			addstr(dbuf, "addq");
826
827		if (size == 0x1)
828			addchar('w');
829		else if (size == 0x2)
830			addchar('l');
831		else
832			addchar('b');
833
834		addchar('\t');
835		addchar('#');
836		data = BITFIELD(opc,11,9);
837		if (data == 0)
838			data = 8;
839		printu(dbuf, data, SIZE_BYTE);
840		addchar(',');
841		get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 0);
842
843		return;
844	}
845}
846
847/*
848 * Bcc/BSR/BRA
849 */
850static void
851opcode_branch(dis_buffer_t *dbuf, u_short opc)
852{
853	int disp;
854
855	if (IS_INST(BRA,opc))
856		addstr(dbuf, "bra");
857	else if (IS_INST(BSR,opc))
858		addstr(dbuf, "bsr");
859	else
860		make_cond(dbuf,11,"b");
861
862	disp = BITFIELD(opc,7,0);
863	if (disp == 0) {
864		/* 16-bit signed displacement */
865		disp = *(dbuf->val + 1);
866		dbuf->used++;
867		addchar('w');
868	} else if (disp == 0xff) {
869		/* 32-bit signed displacement */
870		disp = *(long *)(dbuf->val + 1);
871		dbuf->used += 2;
872		addchar('l');
873	} else {
874		/* 8-bit signed displacement in opcode. */
875		/* Needs to be sign-extended... */
876		if (ISBITSET(disp,7))
877			disp -= 256;
878		addchar('b');
879	}
880	addchar('\t');
881	print_addr(dbuf, disp + (u_long)dbuf->val + 2);
882}
883
884/*
885 * ADD/ADDA/ADDX/SUB/SUBA/SUBX
886 */
887static void
888opcode_addsub(dis_buffer_t *dbuf, u_short opc)
889{
890	int sz, ch, amode;
891
892	sz = BITFIELD(opc,7,6);
893	amode = 0;
894
895	if (sz == 0) {
896		ch = 'b';
897		sz = SIZE_BYTE;
898	} else if (sz == 1) {
899		ch = 'w';
900		sz = SIZE_WORD;
901	} else if (sz == 2) {
902		ch = 'l';
903		sz = SIZE_LONG;
904	} else {
905		amode = 1;
906		if (!ISBITSET(opc,8))  {
907			sz = SIZE_WORD;
908			ch = 'w';
909		} else {
910			sz = SIZE_LONG;
911			ch = 'l';
912		}
913	}
914
915	if (!amode && (IS_INST(ADDX,opc) || IS_INST(SUBX,opc))) {
916		if (IS_INST(ADDX,opc))
917			addstr(dbuf,"addx");
918		else
919			addstr(dbuf,"subx");
920
921		addchar(ch);
922		addchar('\t');
923
924		if (ISBITSET(opc,3)) {
925			PRINT_AREG(dbuf,BITFIELD(opc,2,0));
926			addchar('@');
927			addchar('-');
928			addchar(',');
929			PRINT_AREG(dbuf,BITFIELD(opc,11,9));
930			addchar('@');
931			addchar('-');
932		} else {
933			PRINT_DREG(dbuf,BITFIELD(opc,2,0));
934			addchar(',');
935			PRINT_DREG(dbuf,BITFIELD(opc,11,9));
936		}
937	} else {
938		if (IS_INST(ADD,opc))
939			addstr(dbuf, "add");
940		else
941			addstr(dbuf, "sub");
942
943		if (amode)
944			addchar('a');
945		addchar(ch);
946		addchar('\t');
947
948		if (ISBITSET(opc,8) && amode == 0) {
949			PRINT_DREG(dbuf,BITFIELD(opc,11,9));
950			addchar(',');
951			get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 0);
952		} else {
953			get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 0);
954			addchar(',');
955			if (amode)
956				PRINT_AREG(dbuf,BITFIELD(opc,11,9));
957			else
958				PRINT_DREG(dbuf,BITFIELD(opc,11,9));
959		}
960	}
961	return;
962}
963
964/*
965 * Shift/Rotate/Bit Field
966 */
967static void
968opcode_1110(dis_buffer_t *dbuf, u_short opc)
969{
970	const char *tmp;
971	u_short ext;
972	int type, sz;
973
974	tmp = NULL;
975
976	switch (opc & BFCHG_MASK) {
977	case BFCHG_INST:
978		tmp = "bfchg";
979		break;
980	case BFCLR_INST:
981		tmp = "bfclr";
982		break;
983	case BFEXTS_INST:
984		tmp = "bfexts";
985		break;
986	case BFEXTU_INST:
987		tmp = "bfextu";
988		break;
989	case BFFFO_INST:
990		tmp = "bfffo";
991		break;
992	case BFINS_INST:
993		tmp = "bfins";
994		break;
995	case BFSET_INST:
996		tmp = "bfset";
997		break;
998	case BFTST_INST:
999		tmp = "bftst";
1000		break;
1001	}
1002	if (tmp) {
1003		short bf;
1004
1005		addstr(dbuf, tmp);
1006		addchar('\t');
1007
1008		ext = *(dbuf->val + 1);
1009		dbuf->used++;
1010
1011		if (IS_INST(BFINS,opc)) {
1012			PRINT_DREG(dbuf, BITFIELD(ext,14,12));
1013			addchar(',');
1014		}
1015		get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 1);
1016		addchar('{');
1017
1018		bf = BITFIELD(ext,10,6);
1019		if (ISBITSET(ext, 11))
1020			PRINT_DREG(dbuf, bf);
1021		else
1022			printu_wb(dbuf, bf, SIZE_BYTE, 10);
1023
1024		addchar(':');
1025
1026		bf = BITFIELD(ext, 4, 0);
1027		if (ISBITSET(ext, 5))
1028			PRINT_DREG(dbuf, bf);
1029		else {
1030			if (bf == 0)
1031				bf = 32;
1032			printu_wb(dbuf, bf, SIZE_BYTE, 10);
1033		}
1034		addchar('}');
1035		if (ISBITSET(opc,8) && !IS_INST(BFINS,opc)) {
1036			addchar(',');
1037			PRINT_DREG(dbuf, BITFIELD(ext,14,12));
1038		} else
1039			*dbuf->casm = 0;
1040		return;
1041	}
1042	sz = BITFIELD(opc,7,6);
1043	if (sz == 0x3)
1044		type = BITFIELD(opc, 10, 9);
1045	else
1046		type = BITFIELD(opc, 4, 3);
1047
1048	switch (type) {
1049	case AS_TYPE:
1050		addchar('a');
1051		addchar('s');
1052		break;
1053	case LS_TYPE:
1054		addchar('l');
1055		addchar('s');
1056		break;
1057	case RO_TYPE:
1058		addchar('r');
1059		addchar('o');
1060		break;
1061	case ROX_TYPE:
1062		addchar('r');
1063		addchar('o');
1064		addchar('x');
1065		break;
1066	}
1067
1068	if (ISBITSET(opc,8))
1069		addchar('l');
1070	else
1071		addchar('r');
1072
1073	switch (sz) {
1074	case 0:
1075		sz = SIZE_BYTE;
1076		addchar('b');
1077		break;
1078	case 3:
1079	case 1:
1080		sz = SIZE_WORD;
1081		addchar('w');
1082		break;
1083	case 2:
1084		sz = SIZE_LONG;
1085		addchar('l');
1086		break;
1087
1088	}
1089	addchar('\t');
1090	if(BITFIELD(opc,7,6) == 0x3) {
1091		get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 0);
1092		return;
1093	} else if (ISBITSET(opc,5))
1094		PRINT_DREG(dbuf, BITFIELD(opc,11,9));
1095	else {
1096		addchar('#');
1097		sz = BITFIELD(opc,11,9);
1098		if (sz == 0)
1099			sz = 8;
1100		printu_wb(dbuf, sz, SIZE_BYTE, 10);
1101	}
1102	addchar(',');
1103	PRINT_DREG(dbuf, BITFIELD(opc,2,0));
1104	return;
1105}
1106
1107/*
1108 * CMP/CMPA/EOR
1109 */
1110static void
1111opcode_1011(dis_buffer_t *dbuf, u_short opc)
1112{
1113	int sz;
1114
1115	if (IS_INST(CMPA,opc)) {
1116		addstr(dbuf, "cmpa");
1117
1118		if (ISBITSET(opc, 8)) {
1119			addchar('l');
1120			sz = SIZE_LONG;
1121		} else {
1122			addchar('w');
1123			sz = SIZE_WORD;
1124		}
1125		addchar('\t');
1126	} else {
1127		if (IS_INST(CMP, opc))
1128			addstr(dbuf, "cmp");
1129		else
1130			addstr(dbuf, "eor");
1131
1132		sz = BITFIELD(opc,7,6);
1133		switch (sz) {
1134		case 0:
1135			addchar('b');
1136			sz = SIZE_BYTE;
1137			break;
1138		case 1:
1139			addchar('w');
1140			sz = SIZE_WORD;
1141			break;
1142		case 2:
1143			addchar('l');
1144			sz = SIZE_LONG;
1145			break;
1146		}
1147		addchar('\t');
1148		if (IS_INST(EOR,opc)) {
1149			PRINT_DREG(dbuf, BITFIELD(opc,11,9));
1150			addchar(',');
1151		}
1152	}
1153	get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 0);
1154
1155	if (IS_INST(CMPA,opc)) {
1156		addchar(',');
1157		PRINT_AREG(dbuf, BITFIELD(opc,11,9));
1158	} else if (IS_INST(CMP,opc)) {
1159		addchar(',');
1160		PRINT_DREG(dbuf, BITFIELD(opc,11,9));
1161	}
1162	return;
1163}
1164
1165/*
1166 * OR/DIV/SBCD
1167 */
1168static void
1169opcode_1000(dis_buffer_t *dbuf, u_short opc)
1170{
1171	int sz;
1172
1173	if (IS_INST(UNPKA,opc)) {
1174		addstr(dbuf, "unpk\t");
1175		PRINT_AREG(dbuf,BITFIELD(opc,2,0));
1176		addstr(dbuf, "@-,");
1177		PRINT_AREG(dbuf,BITFIELD(opc,11,9));
1178		addstr(dbuf, "@-,");
1179		get_immed(dbuf,SIZE_WORD);
1180	} else if (IS_INST(UNPKD,opc)) {
1181		addstr(dbuf, "unpk\t");
1182		PRINT_DREG(dbuf,BITFIELD(opc,2,0));
1183		addchar(',');
1184		PRINT_DREG(dbuf,BITFIELD(opc,11,9));
1185		addchar(',');
1186		get_immed(dbuf,SIZE_WORD);
1187	} else if (IS_INST(SBCDA,opc)) {
1188		addstr(dbuf, "sbcd\t");
1189		PRINT_AREG(dbuf,BITFIELD(opc,2,0));
1190		addstr(dbuf, "@-,");
1191		PRINT_AREG(dbuf,BITFIELD(opc,11,9));
1192		addstr(dbuf, "@-");
1193	} else if (IS_INST(SBCDD,opc)) {
1194		addstr(dbuf, "sbcd\t");
1195		PRINT_DREG(dbuf,BITFIELD(opc,2,0));
1196		addchar(',');
1197		PRINT_DREG(dbuf,BITFIELD(opc,11,9));
1198	} else if (IS_INST(DIVSW,opc) || IS_INST(DIVUW,opc)) {
1199		if (IS_INST(DIVSW,opc))
1200			addstr(dbuf, "divsw\t");
1201		else
1202			addstr(dbuf, "divuw\t");
1203		get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_WORD, 0);
1204		addchar(',');
1205		PRINT_DREG(dbuf, BITFIELD(opc,11,9));
1206	} else {
1207		addstr(dbuf, "or");
1208
1209		sz = BITFIELD(opc,7,6);
1210		switch (sz) {
1211		case 0:
1212			addchar('b');
1213			sz = SIZE_BYTE;
1214			break;
1215		case 1:
1216			addchar('w');
1217			sz = SIZE_WORD;
1218			break;
1219		case 2:
1220			addchar('l');
1221			sz = SIZE_LONG;
1222			break;
1223		}
1224		addchar('\t');
1225		if (ISBITSET(opc,8)) {
1226			PRINT_DREG(dbuf, BITFIELD(opc,11,9));
1227			addchar(',');
1228		}
1229		get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 0);
1230		if (!ISBITSET(opc,8)) {
1231			addchar(',');
1232			PRINT_DREG(dbuf, BITFIELD(opc,11,9));
1233		}
1234	}
1235}
1236
1237/*
1238 * AND/MUL/ABCD/EXG (1100)
1239 */
1240static void
1241opcode_1100(dis_buffer_t *dbuf, u_short opc)
1242{
1243	int sz;
1244
1245	if (IS_INST(ABCDA,opc)) {
1246		addstr(dbuf, "abcd\t");
1247		PRINT_AREG(dbuf,BITFIELD(opc,2,0));
1248		addstr(dbuf, "@-,");
1249		PRINT_AREG(dbuf,BITFIELD(opc,11,9));
1250		addstr(dbuf, "@-");
1251	} else if (IS_INST(ABCDD,opc)) {
1252		addstr(dbuf, "abcd\t");
1253		PRINT_DREG(dbuf,BITFIELD(opc,2,0));
1254		addchar(',');
1255		PRINT_DREG(dbuf,BITFIELD(opc,11,9));
1256	} else if (IS_INST(MULSW,opc) || IS_INST(MULUW,opc)) {
1257		if (IS_INST(MULSW,opc))
1258			addstr(dbuf, "mulsw\t");
1259		else
1260			addstr(dbuf, "muluw\t");
1261		get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_WORD, 0);
1262		addchar(',');
1263		PRINT_DREG(dbuf, BITFIELD(opc,11,9));
1264	} else if (IS_INST(EXG,opc)) {
1265		addstr(dbuf, "exg\t");
1266		if (ISBITSET(opc,7)) {
1267			PRINT_DREG(dbuf,BITFIELD(opc,11,9));
1268			addchar(',');
1269			PRINT_AREG(dbuf,BITFIELD(opc,2,0));
1270		} else if (ISBITSET(opc,3)) {
1271			PRINT_AREG(dbuf,BITFIELD(opc,11,9));
1272			addchar(',');
1273			PRINT_AREG(dbuf,BITFIELD(opc,2,0));
1274		} else {
1275			PRINT_DREG(dbuf,BITFIELD(opc,11,9));
1276			addchar(',');
1277			PRINT_DREG(dbuf,BITFIELD(opc,2,0));
1278		}
1279	} else {
1280		addstr(dbuf, "and");
1281
1282		sz = BITFIELD(opc,7,6);
1283		switch (sz) {
1284		case 0:
1285			addchar('b');
1286			sz = SIZE_BYTE;
1287			break;
1288		case 1:
1289			addchar('w');
1290			sz = SIZE_WORD;
1291			break;
1292		case 2:
1293			addchar('l');
1294			sz = SIZE_LONG;
1295			break;
1296		}
1297		addchar('\t');
1298
1299		if (ISBITSET(opc,8)) {
1300			PRINT_DREG(dbuf, BITFIELD(opc,11,9));
1301			addchar(',');
1302		}
1303		get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 0);
1304		if (!ISBITSET(opc,8)) {
1305			addchar(',');
1306			PRINT_DREG(dbuf, BITFIELD(opc,11,9));
1307		}
1308	}
1309}
1310
1311/*
1312 * Coprocessor instruction
1313 */
1314static void
1315opcode_coproc(dis_buffer_t *dbuf, u_short opc)
1316{
1317	switch (BITFIELD(*dbuf->val,11,9)) {
1318	case 1:
1319		opcode_fpu(dbuf, opc);
1320		return;
1321	case 0:
1322		opcode_mmu(dbuf, opc);
1323		return;
1324	case 2:
1325		opcode_mmu040(dbuf, opc);
1326		return;
1327	case 3:
1328		opcode_move16(dbuf, opc);
1329		return;
1330	}
1331	switch (BITFIELD(opc,8,6)) {
1332	case 0:
1333		dbuf->used++;
1334		break;
1335	case 3:
1336		dbuf->used++;
1337		/*FALLTHROUGH*/
1338	case 2:
1339		dbuf->used++;
1340		break;
1341	case 1:
1342		dbuf->used++;
1343	case 4:
1344	case 5:
1345	default:
1346		/* Nothing */ ;
1347	}
1348	addstr(dbuf, "UNKNOWN COPROC OPCODE");
1349	return;
1350}
1351
1352/*
1353 * Resvd
1354 */
1355static void
1356opcode_1010(dis_buffer_t *dbuf, u_short opc)
1357{
1358	addstr(dbuf, "RSVD");
1359	dbuf->used++;
1360}
1361
1362static void
1363opcode_fpu(dis_buffer_t *dbuf, u_short opc)
1364{
1365	u_short ext;
1366	int type, opmode;
1367
1368	type = BITFIELD(opc,8,6);
1369	switch (type) {
1370	/* cpGEN */
1371	case 0:
1372		ext = *(dbuf->val + 1);
1373		dbuf->used++;
1374		opmode = BITFIELD(ext,5,0);
1375
1376		if (BITFIELD(opc,5,0) == 0 && BITFIELD(ext,15,10) == 0x17) {
1377			addstr(dbuf,"fmovcrx #");
1378			printu(dbuf,BITFIELD(ext,6,0),SIZE_BYTE);
1379			return;
1380		}
1381		if (ISBITSET(ext,15) || ISBITSET(ext,13)) {
1382			opcode_fmove_ext(dbuf, opc, ext);
1383			return;
1384		}
1385
1386		switch(opmode) {
1387		case FMOVE:
1388			get_fpustdGEN(dbuf,ext,"fmov");
1389			return;
1390		case FABS:
1391			get_fpustdGEN(dbuf,ext,"fabs");
1392			return;
1393		case FACOS:
1394			get_fpustdGEN(dbuf,ext,"facos");
1395			return;
1396		case FADD:
1397			get_fpustdGEN(dbuf,ext,"fadd");
1398			return;
1399		case FASIN:
1400			get_fpustdGEN(dbuf,ext,"fasin");
1401			return;
1402		case FATAN:
1403			get_fpustdGEN(dbuf,ext,"fatan");
1404			return;
1405		case FATANH:
1406			get_fpustdGEN(dbuf,ext,"fatanh");
1407			return;
1408		case FCMP:
1409			get_fpustdGEN(dbuf,ext,"fcmp");
1410			return;
1411		case FCOS:
1412			get_fpustdGEN(dbuf,ext,"fcos");
1413			return;
1414		case FCOSH:
1415			get_fpustdGEN(dbuf,ext,"fcosh");
1416			return;
1417		case FDIV:
1418			get_fpustdGEN(dbuf,ext,"fdiv");
1419			return;
1420		case FETOX:
1421			get_fpustdGEN(dbuf,ext,"fetox");
1422			return;
1423		case FGETEXP:
1424			get_fpustdGEN(dbuf,ext,"fgetexp");
1425			return;
1426		case FGETMAN:
1427			get_fpustdGEN(dbuf,ext,"fgetman");
1428			return;
1429		case FINT:
1430			get_fpustdGEN(dbuf,ext,"fint");
1431			return;
1432		case FINTRZ:
1433			get_fpustdGEN(dbuf,ext,"fintrz");
1434			return;
1435		case FLOG10:
1436			get_fpustdGEN(dbuf,ext,"flog10");
1437			return;
1438		case FLOG2:
1439			get_fpustdGEN(dbuf,ext,"flog2");
1440			return;
1441		case FLOGN:
1442			get_fpustdGEN(dbuf,ext,"flogn");
1443			return;
1444		case FLOGNP1:
1445			get_fpustdGEN(dbuf,ext,"flognp1");
1446			return;
1447		case FMOD:
1448			get_fpustdGEN(dbuf,ext,"fmod");
1449			return;
1450		case FMUL:
1451			get_fpustdGEN(dbuf,ext,"fmul");
1452			return;
1453		case FNEG:
1454			get_fpustdGEN(dbuf,ext,"fneg");
1455			return;
1456		case FREM:
1457			get_fpustdGEN(dbuf,ext,"frem");
1458			return;
1459		case FSCALE:
1460			get_fpustdGEN(dbuf,ext,"fscale");
1461			return;
1462		case FSGLDIV:
1463			get_fpustdGEN(dbuf,ext,"fsgldiv");
1464			return;
1465		case FSGLMUL:
1466			get_fpustdGEN(dbuf,ext,"fsglmul");
1467			return;
1468		case FSIN:
1469			get_fpustdGEN(dbuf,ext,"fsin");
1470			return;
1471		case FSINH:
1472			get_fpustdGEN(dbuf,ext,"fsinh");
1473			return;
1474		case FSQRT:
1475			get_fpustdGEN(dbuf,ext,"fsqrt");
1476			return;
1477		case FSUB:
1478			get_fpustdGEN(dbuf,ext,"fsub");
1479			return;
1480		case FTAN:
1481			get_fpustdGEN(dbuf,ext,"ftan");
1482			return;
1483		case FTANH:
1484			get_fpustdGEN(dbuf,ext,"ftanh");
1485			return;
1486		case FTENTOX:
1487			get_fpustdGEN(dbuf,ext,"ftentox");
1488			return;
1489		case FTST:
1490			get_fpustdGEN(dbuf,ext,"ftst");
1491			return;
1492		case FTWOTOX:
1493			get_fpustdGEN(dbuf,ext,"ftwotox");
1494			return;
1495
1496		}
1497		/* FALLTHROUGH */
1498	/* cpBcc */
1499	case 2:
1500		if (BITFIELD(opc,5,0) == 0 && *(dbuf->val + 1) == 0) {
1501			dbuf->used++;
1502			addstr (dbuf, "fnop");
1503			return;
1504		}
1505		/* FALLTHROUGH */
1506	case 3:
1507		addstr(dbuf, "fb");
1508		print_fcond(dbuf, BITFIELD(opc,5,0));
1509		if (type == 2) {
1510			addchar('w');
1511			addchar('\t');
1512			print_disp(dbuf,*(dbuf->val + 1), SIZE_WORD, -1);
1513			dbuf->used++;
1514		} else {
1515			addchar('l');
1516			addchar('\t');
1517			print_disp(dbuf,*(long *)(dbuf->val + 1), SIZE_LONG,
1518				 -1);
1519			dbuf->used += 2;
1520		}
1521		return;
1522	/* cpDBcc/cpScc/cpTrap */
1523	case 1:
1524		ext = *(dbuf->val + 1);
1525		dbuf->used++;
1526
1527		if (BITFIELD(opc,5,3) == 0x1) {
1528			/* fdbcc */
1529			addstr(dbuf,"fdb");
1530			print_fcond(dbuf,BITFIELD(ext,5,0));
1531			addchar('\t');
1532			PRINT_DREG(dbuf, BITFIELD(opc,2,0));
1533			addchar(',');
1534			print_disp(dbuf, *(dbuf->val + 2), SIZE_WORD, -1);
1535			dbuf->used++;
1536		} else if (BITFIELD(opc,5,3) == 0x7 &&
1537		    BITFIELD(opc,2,0) > 1) {
1538			addstr(dbuf,"ftrap");
1539			print_fcond(dbuf,BITFIELD(ext,5,0));
1540
1541			if (BITFIELD(opc,2,0) == 0x2) {
1542				addchar('w');
1543				addchar('\t');
1544				dbuf->val++;
1545				get_immed(dbuf, SIZE_WORD);
1546				dbuf->val--;
1547			} else if (BITFIELD(opc,2,0) == 0x3) {
1548				addchar('l');
1549				addchar('\t');
1550				dbuf->val++;
1551				get_immed(dbuf, SIZE_LONG);
1552				dbuf->val--;
1553			}
1554		} else {
1555			addstr(dbuf,"fs");
1556			print_fcond(dbuf,BITFIELD(ext,5,0));
1557			addchar('\t');
1558			get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_BYTE, 1);
1559		}
1560		return;
1561	case 4:
1562		addstr(dbuf,"fsave\t");
1563		get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 0);
1564		return;
1565	case 5:
1566		addstr(dbuf,"frestor\t");
1567		get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 0);
1568		return;
1569	}
1570}
1571
1572/*
1573 * XXX - This screws up on:  fmovem  a0@(312),fpcr/fpsr/fpi
1574 */
1575static void
1576opcode_fmove_ext(dis_buffer_t *dbuf, u_short opc, u_short ext)
1577{
1578	int sz;
1579
1580	sz = 0;
1581	if (BITFIELD(ext,15,13) == 3) {
1582		/* fmove r ==> m */
1583		addstr(dbuf, "fmov");
1584		switch (BITFIELD(ext,12,10)) {
1585		case 0:
1586			addchar('l');
1587			sz = SIZE_LONG;
1588			break;
1589		case 1:
1590			addchar('s');
1591			sz = SIZE_SINGLE;
1592			break;
1593		case 2:
1594			addchar('x');
1595			sz = SIZE_EXTENDED;
1596			break;
1597		case 7:
1598		case 3:
1599			addchar('p');
1600			sz = SIZE_PACKED;
1601			break;
1602		case 4:
1603			addchar('w');
1604			sz = SIZE_WORD;
1605			break;
1606		case 5:
1607			addchar('d');
1608			sz = SIZE_DOUBLE;
1609			break;
1610		case 6:
1611			addchar('b');
1612			sz = SIZE_BYTE;
1613			break;
1614		}
1615		addchar('\t');
1616		PRINT_FPREG(dbuf, BITFIELD(ext,9,7));
1617		addchar(',');
1618		get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 1);
1619		if (sz == SIZE_PACKED) {
1620			addchar('{');
1621			if (ISBITSET(ext,12)) {
1622				PRINT_DREG(dbuf,BITFIELD(ext,6,4));
1623			} else {
1624				addchar('#');
1625				prints_bf(dbuf, ext, 6, 4);
1626			}
1627			addchar('}');
1628		}
1629		return;
1630	}
1631	addstr(dbuf,"fmovm");
1632
1633	if (!ISBITSET(ext,14)) {
1634		/* fmove[m] control reg */
1635		addchar('l');
1636		addchar('\t');
1637
1638		if (ISBITSET(ext,13)) {
1639			print_freglist(dbuf, AR_DEC, BITFIELD(ext,12,10), 1);
1640			addchar(',');
1641		}
1642		get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_LONG, 1);
1643		if (!ISBITSET(ext,13)) {
1644			addchar(',');
1645			print_freglist(dbuf, AR_DEC, BITFIELD(ext,12,10), 1);
1646		}
1647		return;
1648	}
1649	addchar('x');
1650	addchar('\t');
1651
1652	if (ISBITSET(ext,11)) {
1653		if (ISBITSET(ext,13)) {
1654			PRINT_DREG(dbuf,BITFIELD(ext,6,4));
1655			addchar(',');
1656		}
1657		get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_EXTENDED, 1);
1658		if (!ISBITSET(ext,13)) {
1659			addchar(',');
1660			PRINT_DREG(dbuf,BITFIELD(ext,6,4));
1661		}
1662	} else {
1663		if (ISBITSET(ext,13)) {
1664			print_freglist(dbuf, BITFIELD(opc,5,3),
1665			    BITFIELD(ext,7,0), 0);
1666			addchar(',');
1667		}
1668		get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_EXTENDED, 1);
1669		if (!ISBITSET(ext,13)) {
1670			addchar(',');
1671			print_freglist(dbuf, BITFIELD(opc,5,3),
1672			    BITFIELD(ext,7,0), 0);
1673		}
1674	}
1675}
1676
1677static void
1678opcode_mmu(dis_buffer_t *dbuf, u_short opc)
1679{
1680	u_short ext;
1681	int type;
1682
1683	type = BITFIELD(opc,8,6);
1684	switch (type) {
1685	/* cpGEN? */
1686	case 0:
1687		ext = *(dbuf->val + 1);
1688		dbuf->used++;
1689
1690		switch(BITFIELD(ext,15,13)) {
1691		case 5:
1692		case 1:
1693			opcode_pflush(dbuf, opc, ext);
1694			return;
1695		case 0:
1696		case 3:
1697		case 2:
1698			opcode_pmove(dbuf, opc, ext);
1699			return;
1700		case 4:
1701			addstr(dbuf, "ptest");
1702			if (ISBITSET(ext,9))
1703				addchar('r');
1704			else
1705				addchar('w');
1706			addchar('\t');
1707			print_fcode(dbuf, BITFIELD(ext, 5, 0));
1708			addchar(',');
1709			get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 1);
1710			addchar(',');
1711			addchar('#');
1712			printu_bf(dbuf, ext, 12, 10);
1713			if (ISBITSET(ext, 8)) {
1714				addchar(',');
1715				PRINT_AREG(dbuf, BITFIELD(ext, 7, 5));
1716			}
1717		}
1718		return;
1719	case 2:
1720	case 3:
1721		addstr(dbuf, "pb");
1722		print_mcond(dbuf, BITFIELD(opc,5,0));
1723		if (type == 2) {
1724			addchar('w');
1725			addchar('\t');
1726			print_disp(dbuf,*(dbuf->val + 1), SIZE_WORD, -1);
1727			dbuf->used++;
1728		} else {
1729			addchar('l');
1730			addchar('\t');
1731			print_disp(dbuf,*(long *)(dbuf->val + 1), SIZE_LONG,
1732				 -1);
1733			dbuf->used += 2;
1734		}
1735		return;
1736	case 1:
1737		ext = *(dbuf->val + 1);
1738		dbuf->used++;
1739
1740		if (BITFIELD(opc,5,3) == 0x1) {
1741			/* fdbcc */
1742			addstr(dbuf,"pdb");
1743			print_fcond(dbuf,BITFIELD(ext,5,0));
1744			addchar('\t');
1745			PRINT_DREG(dbuf, BITFIELD(opc,2,0));
1746			addchar(',');
1747			print_disp(dbuf, *(dbuf->val + 2), SIZE_WORD, -1);
1748			dbuf->used++;
1749		} else if (BITFIELD(opc,5,3) == 0x7 &&
1750		    BITFIELD(opc,2,0) > 1) {
1751			addstr(dbuf,"ptrap");
1752			print_fcond(dbuf,BITFIELD(ext,5,0));
1753
1754			if (BITFIELD(opc,2,0) == 0x2) {
1755				addchar('w');
1756				addchar('\t');
1757				dbuf->val++;
1758				get_immed(dbuf, SIZE_WORD);
1759				dbuf->val--;
1760			} else if (BITFIELD(opc,2,0) == 0x3) {
1761				addchar('l');
1762				addchar('\t');
1763				dbuf->val++;
1764				get_immed(dbuf, SIZE_LONG);
1765				dbuf->val--;
1766			}
1767		} else {
1768			addstr(dbuf,"ps");
1769			print_fcond(dbuf,BITFIELD(ext,5,0));
1770			addchar('\t');
1771			get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_BYTE, 1);
1772		}
1773		return;
1774	case 4:
1775		addstr(dbuf,"psave\t");
1776		get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 0);
1777		return;
1778	case 5:
1779		addstr(dbuf,"prestore\t");
1780		get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 0);
1781		return;
1782	}
1783}
1784
1785static void
1786opcode_pflush(dis_buffer_t *dbuf, u_short opc, u_short ext)
1787{
1788	u_short mode, mask, fc;
1789
1790	mode = BITFIELD(ext,12,10);
1791	mask = BITFIELD(ext,8,5);
1792	fc = BITFIELD(ext, 5, 0);
1793
1794	if (ext == 0xa000) {
1795		addstr(dbuf,"pflushr\t");
1796		get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_LONG, 1);
1797		return;
1798	}
1799
1800	if (mode == 0) {
1801		addstr(dbuf,"pload");
1802		if (ISBITSET(ext,9))
1803			addchar('r');
1804		else
1805			addchar('w');
1806		addchar(' ');
1807		print_fcode(dbuf, fc);
1808	}
1809
1810	addstr(dbuf,"pflush");
1811	switch (mode) {
1812	case 1:
1813		addchar('a');
1814		*dbuf->casm = 0;
1815		break;
1816	case 7:
1817	case 5:
1818		addchar('s');
1819		/*FALLTHROUGH*/
1820	case 6:
1821	case 4:
1822		addchar('\t');
1823		print_fcode(dbuf, fc);
1824		addchar(',');
1825		addchar('#');
1826		printu(dbuf, mask, SIZE_BYTE);
1827		if (!ISBITSET(mode,1))
1828			break;
1829		addchar(',');
1830		get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_LONG, 1);
1831	}
1832}
1833
1834static void
1835opcode_pmove(dis_buffer_t *dbuf, u_short opc, u_short ext)
1836{
1837	const char *reg;
1838	int rtom, sz, preg;
1839
1840	reg  = "???";
1841	sz   = 0;
1842	rtom = ISBITSET(ext, 9);
1843	preg = BITFIELD(ext, 12, 10);
1844
1845	addstr(dbuf,"pmov");
1846	if (ISBITSET(ext,8)) {
1847		addchar('f');
1848		addchar('d');
1849	}
1850	switch (BITFIELD(ext, 15, 13)) {
1851	case 0: /* tt regs 030o */
1852		switch (preg) {
1853		case 2:
1854			reg = "tt0";
1855			break;
1856		case 3:
1857			reg = "tt1";
1858			break;
1859		}
1860		sz = SIZE_LONG;
1861		break;
1862	case 2:
1863		switch (preg) {
1864		case 0:
1865			reg = "tc";
1866			sz = SIZE_LONG;
1867			break;
1868		case 1:
1869			reg = "drp";
1870			sz = SIZE_QUAD;
1871			break;
1872		case 2:
1873			reg = "srp";
1874			sz = SIZE_QUAD;
1875			break;
1876		case 3:
1877			reg = "crp";
1878			sz = SIZE_QUAD;
1879			break;
1880		case 4:
1881			reg = "cal";
1882			sz = SIZE_BYTE;
1883			break;
1884		case 5:
1885			reg = "val";
1886			sz = SIZE_BYTE;
1887			break;
1888		case 6:
1889			reg = "scc";
1890			sz = SIZE_BYTE;
1891			break;
1892		case 7:
1893			reg = "ac";
1894			sz = SIZE_WORD;
1895		}
1896		break;
1897	case 3:
1898		switch (preg) {
1899		case 0:
1900			reg = "mmusr";
1901			break;
1902		case 1:
1903			reg = "pcsr";
1904			break;
1905		case 4:
1906			reg = "bad";
1907			break;
1908		case 5:
1909			reg = "bac";
1910			break;
1911		}
1912		sz = SIZE_WORD;
1913		break;
1914	}
1915	switch (sz) {
1916	case SIZE_BYTE:
1917		addchar ('b');
1918		break;
1919	case SIZE_WORD:
1920		addchar ('w');
1921		break;
1922	case SIZE_LONG:
1923		addchar ('l');
1924		break;
1925	case SIZE_QUAD:
1926		addchar ('d');
1927		break;
1928	}
1929	addchar('\t');
1930
1931	if (!rtom) {
1932		get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 1);
1933		addchar(',');
1934	}
1935	addstr(dbuf, reg);
1936	if (BITFIELD(ext, 15, 13) == 3 && preg > 1)
1937		printu_bf(dbuf, ext, 4, 2);
1938	if (rtom) {
1939		addchar(',');
1940		get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 1);
1941	}
1942	return;
1943}
1944
1945static void
1946print_fcode(dis_buffer_t *dbuf, u_short fc)
1947{
1948	if (ISBITSET(fc, 4))
1949		printu_bf(dbuf, fc, 3, 0);
1950	else if (ISBITSET(fc, 3))
1951		PRINT_DREG(dbuf, BITFIELD(fc, 2, 0));
1952	else if (fc == 1)
1953		addstr(dbuf, "sfc");
1954	else
1955		addstr(dbuf, "dfc");
1956}
1957
1958static void
1959opcode_mmu040(dis_buffer_t *dbuf, u_short opc)
1960{
1961	if (ISBITSET(opc, 6)) {
1962		addstr(dbuf, "ptest");
1963		if (ISBITSET(opc, 5))
1964			addchar('r');
1965		else
1966			addchar('w');
1967		addchar('\t');
1968		PRINT_AREG(dbuf, BITFIELD(opc,2,0));
1969		addchar('@');
1970	} else {
1971		addstr(dbuf, "pflush");
1972		switch (BITFIELD(opc, 4, 3)) {
1973		case 3:
1974			addchar('a');
1975			break;
1976		case 2:
1977			addchar('a');
1978			addchar('n');
1979			break;
1980		case 0:
1981			addchar('n');
1982			/*FALLTHROUGH*/
1983		case 1:
1984			addchar('\t');
1985			PRINT_AREG(dbuf, BITFIELD(opc,2,0));
1986			addchar('@');
1987			break;
1988		}
1989	}
1990	*dbuf->casm = 0;
1991}
1992
1993/*
1994 * disassemble long format (64b) divs/muls divu/mulu opcode.
1995 * Note: opcode's dbuf->used already accounted for.
1996 */
1997static void
1998opcode_divmul(dis_buffer_t *dbuf, u_short opc)
1999{
2000	u_short ext;
2001	int iq, hr;
2002
2003	ext = *(dbuf->val + 1);
2004	dbuf->used++;
2005
2006	iq = BITFIELD(ext,14,12);
2007	hr = BITFIELD(ext,2,0);
2008
2009	if (IS_INST(DIVSL,opc))
2010		addstr(dbuf, "div");
2011	else
2012		addstr(dbuf, "mul");
2013	if (ISBITSET(ext,11))
2014		addchar('s');
2015	else
2016		addchar('u');
2017	addchar('l');
2018	if (IS_INST(DIVSL,opc) && !ISBITSET(ext,10) && iq != hr)
2019		addchar('l');
2020	addchar('\t');
2021
2022	get_modregstr(dbuf,5,GETMOD_BEFORE,SIZE_LONG,1);
2023	addchar(',');
2024
2025	if (ISBITSET(ext,10) ||
2026	    (iq != hr && IS_INST(DIVSL,opc))) {
2027		/* 64 bit version */
2028		PRINT_DREG(dbuf, hr);
2029		if (dbuf->mit)
2030			addchar(',');
2031		else
2032			addchar(':');
2033	}
2034	PRINT_DREG(dbuf, iq);
2035}
2036
2037static void
2038print_reglist(dis_buffer_t *dbuf, int mod, u_short rl)
2039{
2040	static const char *const regs[16] = {
2041		"d0","d1","d2","d3","d4","d5","d6","d7",
2042		"a0","a1","a2","a3","a4","a5","a6","a7" };
2043	int bit, list;
2044
2045	if (mod == AR_DEC) {
2046		list = rl;
2047		rl = 0;
2048		/* I am sure there is some trick... */
2049		for (bit = 0; bit < 16; bit++)
2050			if (list & (1 << bit))
2051				rl |= (0x8000 >> bit);
2052	}
2053	for (bit = 0, list = 0; bit < 16; bit++) {
2054		if (ISBITSET(rl,bit) && bit != 8) {
2055			if (list == 0) {
2056				list = 1;
2057				addstr(dbuf, regs[bit]);
2058			} else if (list == 1) {
2059				list++;
2060				addchar('-');
2061			}
2062		} else {
2063			if (list) {
2064				if (list > 1)
2065					addstr(dbuf, regs[bit-1]);
2066				addchar('/');
2067				list = 0;
2068			}
2069			if (ISBITSET(rl,bit)) {
2070				addstr(dbuf, regs[bit]);
2071				list = 1;
2072			}
2073		}
2074	}
2075	if (list > 1)
2076		addstr(dbuf, regs[15]);
2077
2078	if (dbuf->casm[-1] == '/' || dbuf->casm[-1] == '-')
2079		dbuf->casm--;
2080	*dbuf->casm = 0;
2081}
2082
2083static void
2084print_freglist(dis_buffer_t *dbuf, int mod, u_short rl, int cntl)
2085{
2086	const char *const * regs;
2087	int bit, list, upper;
2088
2089	regs = cntl ? fpcregs : fpregs;
2090	upper = cntl ? 3 : 8;
2091
2092	if (!cntl && mod != AR_DEC) {
2093		list = rl;
2094		rl = 0;
2095		/* I am sure there is some trick... */
2096		for (bit = 0; bit < upper; bit++)
2097			if (list & (1 << bit))
2098				rl |= (0x80 >> bit);
2099	}
2100	for (bit = 0, list = 0; bit < upper; bit++) {
2101		if (ISBITSET(rl,bit)) {
2102			if (list == 0) {
2103				addstr(dbuf, regs[bit]);
2104				if (cntl)
2105					addchar('/');
2106				else
2107					list = 1;
2108			} else if (list == 1) {
2109				list++;
2110				addchar('-');
2111			}
2112		} else {
2113			if (list) {
2114				if (list > 1)
2115					addstr(dbuf, regs[bit-1]);
2116				addchar('/');
2117				list = 0;
2118			}
2119		}
2120	}
2121	if (list > 1)
2122		addstr(dbuf, regs[upper-1]);
2123
2124	if (dbuf->casm[-1] == '/' || dbuf->casm[-1] == '-')
2125		dbuf->casm--;
2126	*dbuf->casm = 0;
2127}
2128
2129/*
2130 * disassemble movem opcode.
2131 */
2132static void
2133opcode_movem(dis_buffer_t *dbuf, u_short opc)
2134{
2135	u_short rl;
2136
2137	rl = *(dbuf->val + 1);
2138	dbuf->used++;
2139
2140	if (ISBITSET(opc,6))
2141		addstr(dbuf, "movml\t");
2142	else
2143		addstr(dbuf, "movmw\t");
2144	if (ISBITSET(opc,10)) {
2145		get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 1);
2146		addchar(',');
2147		print_reglist(dbuf, BITFIELD(opc,5,3), rl);
2148	} else {
2149		print_reglist(dbuf, BITFIELD(opc,5,3), rl);
2150		addchar(',');
2151		get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 1);
2152	}
2153}
2154
2155/*
2156 * disassemble movec opcode.
2157 */
2158static void
2159opcode_movec(dis_buffer_t *dbuf, u_short opc)
2160{
2161	const char *tmp;
2162	u_short ext;
2163
2164	ext = *(dbuf->val + 1);
2165	dbuf->used++;
2166
2167	addstr(dbuf, "movc\t");
2168	if (ISBITSET(opc,0)) {
2169		dbuf->val++;
2170		if (ISBITSET(ext,15))
2171			get_modregstr(dbuf,14,AR_DIR,0,0);
2172		else
2173			get_modregstr(dbuf,14,DR_DIR,0,0);
2174		dbuf->val--;
2175		addchar(',');
2176	}
2177	switch (BITFIELD(ext,11,0)) {
2178		/* 010/020/030/040/CPU32/060 */
2179	case 0x000:
2180		tmp = "sfc";
2181		break;
2182	case 0x001:
2183		tmp = "dfc";
2184		break;
2185	case 0x800:
2186		tmp = "usp";
2187		break;
2188	case 0x801:
2189		tmp = "vbr";
2190		break;
2191		/* 020/030 */
2192	case 0x802:
2193		tmp = "caar";
2194		break;
2195		/* 020/030/040/060 */
2196	case 0x002:
2197		tmp = "cacr";
2198		break;
2199		/* 020/030/040 */
2200	case 0x803:
2201		tmp = "msp";
2202		break;
2203	case 0x804:
2204		tmp = "isp";
2205		break;
2206		/* 040/060 */
2207	case 0x003:
2208		tmp = "tc";
2209		break;
2210	case 0x004:
2211		tmp = "itt0";
2212		break;
2213	case 0x005:
2214		tmp = "itt1";
2215		break;
2216	case 0x006:
2217		tmp = "dtt0";
2218		break;
2219	case 0x007:
2220		tmp = "dtt1";
2221		break;
2222		/* 040 */
2223	case 0x805:
2224		tmp = "mmusr";
2225		break;
2226		/* 040/060 */
2227	case 0x806:
2228		tmp = "urp";
2229		break;
2230	case 0x807:
2231		tmp = "srp";
2232		break;
2233		/* 060 */
2234	case 0x008:
2235		tmp = "buscr";
2236		break;
2237	case 0x808:
2238		tmp = "pcr";
2239		break;
2240	default:
2241		tmp = "INVALID";
2242		break;
2243	}
2244	addstr(dbuf, tmp);
2245	if (!ISBITSET(opc,0)) {
2246		dbuf->val++;
2247		addchar(',');
2248		if (ISBITSET(ext,15))
2249			get_modregstr(dbuf,14,AR_DIR,0,0);
2250		else
2251			get_modregstr(dbuf,14,DR_DIR,0,0);
2252		dbuf->val--;
2253	}
2254}
2255
2256/*
2257 * disassemble move16 opcode.
2258 */
2259static void
2260opcode_move16(dis_buffer_t *dbuf, u_short opc)
2261{
2262	u_short ext;
2263
2264	addstr(dbuf, "move16\t");
2265
2266	if (ISBITSET(opc, 5)) {
2267		PRINT_AREG(dbuf, BITFIELD(opc,2,0));
2268		addstr(dbuf, "@+,");
2269		ext = *(dbuf->val + 1);
2270		PRINT_AREG(dbuf, BITFIELD(ext,14,12));
2271		addstr(dbuf, "@+");
2272		dbuf->used++;
2273	} else {
2274		switch (BITFIELD(opc,4,3)) {
2275		case 0:
2276			PRINT_AREG(dbuf, BITFIELD(opc,2,0));
2277			addstr(dbuf, "@+,");
2278			get_immed(dbuf, SIZE_LONG);
2279			break;
2280		case 1:
2281			get_immed(dbuf, SIZE_LONG);
2282			addchar(',');
2283			PRINT_AREG(dbuf, BITFIELD(opc,2,0));
2284			addstr(dbuf, "@+");
2285			break;
2286		case 2:
2287			PRINT_AREG(dbuf, BITFIELD(opc,2,0));
2288			addstr(dbuf, "@,");
2289			get_immed(dbuf, SIZE_LONG);
2290			break;
2291		case 3:
2292			get_immed(dbuf, SIZE_LONG);
2293			addchar(',');
2294			PRINT_AREG(dbuf, BITFIELD(opc,2,0));
2295			addchar('@');
2296			break;
2297		}
2298	}
2299}
2300
2301/*
2302 * copy const string 's' into ``dbuf''->casm
2303 */
2304static void
2305addstr(dis_buffer_t *dbuf, const char *s)
2306{
2307	while ((*dbuf->casm++ = *s++))
2308		;
2309	dbuf->casm--;
2310}
2311
2312/*
2313 * copy const string 's' into ``dbuf''->cinfo
2314 */
2315static void
2316iaddstr(dis_buffer_t *dbuf, const char *s)
2317{
2318	while ((*dbuf->cinfo++ = *s++))
2319		;
2320	dbuf->cinfo--;
2321}
2322
2323static void
2324get_modregstr_moto(dis_buffer_t *dbuf, int bit, int mod, int sz, int dd)
2325{
2326	u_char scale, idx;
2327	const short *nval;
2328	u_short ext;
2329	int disp, odisp, bd, od, reg;
2330
2331	odisp = 0;
2332
2333	/* check to see if we have been given the mod */
2334	if (mod != GETMOD_BEFORE && mod != GETMOD_AFTER)
2335		reg = BITFIELD(*dbuf->val, bit, bit-2);
2336	else if (mod == GETMOD_BEFORE) {
2337		mod = BITFIELD(*dbuf->val, bit, bit-2);
2338		reg = BITFIELD(*dbuf->val, bit-3, bit-5);
2339	} else {
2340		reg = BITFIELD(*dbuf->val, bit, bit-2);
2341		mod = BITFIELD(*dbuf->val, bit-3, bit-5);
2342	}
2343	switch (mod) {
2344	case DR_DIR:
2345	case AR_DIR:
2346		if (mod == DR_DIR)
2347			PRINT_DREG(dbuf, reg);
2348		else
2349			PRINT_AREG(dbuf, reg);
2350		break;
2351	case AR_DIS:
2352		print_disp(dbuf, *(dbuf->val + 1 + dd), SIZE_WORD,reg);
2353		dbuf->used++;
2354		/*FALLTHROUGH*/
2355	case AR_IND:
2356	case AR_INC:
2357	case AR_DEC:
2358		if (mod == AR_DEC)
2359			addchar('-');
2360		addchar('(');
2361		PRINT_AREG(dbuf, reg);
2362		addchar(')');
2363		if (mod == AR_INC)
2364			addchar('+');
2365		break;
2366	/* mod 6 & 7 are the biggies. */
2367	case MOD_SPECIAL:
2368		if (reg == 0) {
2369			/* abs short addr */
2370			print_addr(dbuf, *(dbuf->val + 1 + dd));
2371			dbuf->used++;
2372			addchar('.');
2373			addchar('w');
2374			break;
2375		} else if (reg == 1) {
2376			/* abs long addr */
2377			print_addr(dbuf, *(u_long *)(dbuf->val + 1 + dd));
2378			dbuf->used += 2;
2379			addchar('.');
2380			addchar('l');
2381			break;
2382		} else if (reg == 2) {
2383			/* pc ind displ. xxx(PC) */
2384			dbuf->used++;
2385			print_disp(dbuf, *(dbuf->val + 1 + dd), SIZE_WORD,
2386				   -1);
2387			addstr(dbuf,"(pc)");
2388			break;
2389		} else if (reg == 4) {
2390			/* uses ``sz'' to figure immediate data. */
2391			if (sz == SIZE_BYTE) {
2392				addchar('#');
2393				prints(dbuf,
2394				    *((char *)dbuf->val + 3+ (dd * 2)), sz);
2395				dbuf->used++;
2396			} else if (sz == SIZE_WORD) {
2397				addchar('#');
2398				prints(dbuf, *(dbuf->val + 1 + dd), sz);
2399				dbuf->used++;
2400			} else if (sz == SIZE_LONG) {
2401				addchar('#');
2402				prints(dbuf, *(long *)(dbuf->val + 1 + dd),
2403				    sz);
2404				dbuf->used += 2;
2405			} else if (sz == SIZE_QUAD) {
2406				dbuf->used += 4;
2407				addstr(dbuf,"#<quad>");
2408			} else if (sz == SIZE_SINGLE) {
2409				dbuf->used += 2;
2410				addstr(dbuf,"#<single>");
2411			} else if (sz == SIZE_DOUBLE) {
2412				dbuf->used += 4;
2413				addstr(dbuf,"#<double>");
2414			} else if (sz == SIZE_PACKED) {
2415				dbuf->used += 6;
2416				addstr(dbuf,"#<packed>");
2417			} else if (sz == SIZE_EXTENDED) {
2418				dbuf->used += 6;
2419				addstr(dbuf,"#<extended>");
2420			}
2421			break;
2422		}
2423		/* standrd PC stuff. */
2424		/*FALLTHROUGH*/
2425	case AR_IDX:
2426		ext = *(dbuf->val + 1 + dd);
2427		dbuf->used++;
2428		nval = dbuf->val + 2 + dd; /* set to possible displacements */
2429		scale = BITFIELD(ext,10,9);
2430		idx = BITFIELD(ext,14,12);
2431
2432		if (ISBITSET(ext,8)) {
2433			/* either base disp, or memory indirect */
2434			bd = BITFIELD(ext,5,4);
2435			od = BITFIELD(ext,1,0);
2436			if (bd == 1)
2437				disp = 0;
2438			else if (bd == 2) {
2439				dbuf->used++;
2440				disp = *nval++;
2441			} else {
2442				dbuf->used += 2;
2443				disp = *(const long *)nval;
2444				nval += 2;
2445			}
2446
2447			if (od == 1)
2448				odisp = 0;
2449			else if (od == 2) {
2450				dbuf->used++;
2451				odisp = *nval++;
2452			} else if (od == 3) {
2453				dbuf->used += 2;
2454				odisp = *(const long *)nval;
2455				nval += 2;
2456			}
2457		} else {
2458			/*
2459			 * We set od and bd to zero, these values are
2460			 * not allowed in opcodes that use base and
2461			 * outer displacement, e.g. we can tell if we
2462			 * are using on of those modes by checking
2463			 * `bd' and `od'.
2464			 */
2465			od = 0;
2466			bd = 0;
2467			disp = (char)BITFIELD(ext,7,0);
2468		}
2469		/*
2470		 * write everything into buf
2471		 */
2472		addchar('(');
2473		if (od)
2474			addchar('['); /* begin memory indirect xxx-indexed */
2475		prints(dbuf, disp,
2476		    bd == 2 ? SIZE_WORD :
2477		    bd == 3 ? SIZE_LONG :
2478		    SIZE_BYTE);
2479		addchar(',');
2480		if (bd && ISBITSET(ext,7)) {
2481			addchar('z');
2482			if (mod != MOD_SPECIAL)
2483				PRINT_AREG(dbuf,reg);
2484			else {
2485				addchar('p');
2486				addchar('c');
2487			}
2488		} else if (mod == AR_IDX)
2489			PRINT_AREG(dbuf, reg);
2490		else {
2491			addchar('p');
2492			addchar('c');
2493		}
2494
2495		if (od && ISBITSET(ext,2))
2496			addchar(']'); /* post-indexed. */
2497		addchar(',');
2498		if (bd && ISBITSET(ext,6))
2499			addchar('0');
2500		else {
2501			if (0x8000 & ext)
2502				PRINT_AREG(dbuf, idx);
2503			else
2504				PRINT_DREG(dbuf, idx);
2505			addchar('.');
2506			addchar(0x800 & ext ? 'l' : 'w');
2507			if (scale) {
2508				addchar('*');
2509				addchar('0' + (1 << scale));
2510			}
2511		}
2512		if (od) {
2513			if (!ISBITSET(ext,2))
2514				addchar(']'); /* pre-indexed */
2515			addchar(',');
2516			prints(dbuf, odisp,
2517			    od == 2 ? SIZE_WORD :
2518			    od == 3 ? SIZE_LONG :
2519			    SIZE_BYTE);
2520		}
2521		addchar(')');
2522		break;
2523	}
2524	*dbuf->casm = 0;
2525}
2526
2527/* mit syntax makes for spaghetti parses */
2528static void
2529get_modregstr_mit(dis_buffer_t *dbuf, int bit, int mod, int sz, int dd)
2530{
2531	u_char scale, idx;
2532	const short *nval;
2533	u_short ext;
2534	int disp, odisp, bd, od, reg;
2535
2536	disp = odisp = 0;
2537	/* check to see if we have been given the mod */
2538	if (mod != GETMOD_BEFORE && mod != GETMOD_AFTER)
2539		reg = BITFIELD(*dbuf->val, bit, bit-2);
2540	else if (mod == GETMOD_BEFORE) {
2541		mod = BITFIELD(*dbuf->val, bit, bit-2);
2542		reg = BITFIELD(*dbuf->val, bit-3, bit-5);
2543	} else {
2544		reg = BITFIELD(*dbuf->val, bit, bit-2);
2545		mod = BITFIELD(*dbuf->val, bit-3, bit-5);
2546	}
2547	switch (mod) {
2548	case DR_DIR:
2549	case AR_DIR:
2550		if (mod == DR_DIR)
2551			PRINT_DREG(dbuf, reg);
2552		else
2553			PRINT_AREG(dbuf, reg);
2554		break;
2555	case AR_DIS:
2556		dbuf->used++;	/* tell caller we used an ext word. */
2557		disp = *(dbuf->val + 1 + dd);
2558		/*FALLTHROUGH*/
2559	case AR_IND:
2560	case AR_INC:
2561	case AR_DEC:
2562		PRINT_AREG(dbuf, reg);
2563		addchar('@' );
2564		if (mod == AR_DEC)
2565			addchar('-');
2566		else if (mod == AR_INC)
2567			addchar('+');
2568		else if (mod == AR_DIS) {
2569			addchar('(');
2570			print_disp(dbuf, disp, SIZE_WORD, reg);
2571			addchar(')');
2572		}
2573		break;
2574	/* mod 6 & 7 are the biggies. */
2575	case MOD_SPECIAL:
2576		if (reg == 0) {
2577			/* abs short addr */
2578			print_addr(dbuf, *(dbuf->val + 1 + dd));
2579			dbuf->used++;
2580			break;
2581		} else if (reg == 1) {
2582			/* abs long addr */
2583			print_addr(dbuf, *(u_long *)(dbuf->val + 1 + dd));
2584			dbuf->used += 2;
2585			break;
2586		} else if (reg == 2) {
2587			/* pc ind displ. pc@(xxx) */
2588			addstr(dbuf,"pc@(");
2589			print_disp(dbuf, *(dbuf->val + 1 + dd), SIZE_WORD, -1);
2590			dbuf->used++;
2591			addchar(')');
2592			break;
2593		} else if (reg == 4) {
2594			/* uses ``sz'' to figure immediate data. */
2595			if (sz == SIZE_BYTE) {
2596				addchar('#');
2597				prints(dbuf,
2598				    *((char *)dbuf->val + 3 + (dd * 2)), sz);
2599				dbuf->used++;
2600			} else if (sz == SIZE_WORD) {
2601				addchar('#');
2602				prints(dbuf, *(dbuf->val + 1 + dd), sz);
2603				dbuf->used++;
2604			} else if (sz == SIZE_LONG) {
2605				addchar('#');
2606				prints(dbuf, *(long *)(dbuf->val + 1 + dd),
2607				    sz);
2608				dbuf->used += 2;
2609			} else if (sz == SIZE_QUAD) {
2610				dbuf->used += 4;
2611				addstr(dbuf,"#<quad>");
2612			} else if (sz == SIZE_SINGLE) {
2613				dbuf->used += 2;
2614				addstr(dbuf,"#<single>");
2615			} else if (sz == SIZE_DOUBLE) {
2616				dbuf->used += 4;
2617				addstr(dbuf,"#<double>");
2618			} else if (sz == SIZE_PACKED) {
2619				dbuf->used += 6;
2620				addstr(dbuf,"#<packed>");
2621			} else if (sz == SIZE_EXTENDED) {
2622				dbuf->used += 6;
2623				addstr(dbuf,"#<extended>");
2624			}
2625			break;
2626		}
2627		/* standrd PC stuff. */
2628		/*FALLTHROUGH*/
2629	case AR_IDX:
2630		dbuf->used++;	/* indicate use of ext word. */
2631		ext = *(dbuf->val + 1 + dd);
2632		nval = dbuf->val + 2 + dd; /* set to possible displacements */
2633		scale = BITFIELD(ext,10,9);
2634		idx = BITFIELD(ext,14,12);
2635
2636		if (ISBITSET(ext,8)) {
2637			/* either base disp, or memory indirect */
2638			bd = BITFIELD(ext,5,4);
2639			od = BITFIELD(ext,1,0);
2640			if (bd == 1)
2641				disp = 0;
2642			else if (bd == 2) {
2643				dbuf->used++;
2644				disp = *nval++;
2645			} else {
2646				dbuf->used += 2;
2647				disp = *(const long *)nval;
2648				nval += 2;
2649			}
2650
2651			if (od == 1)
2652				odisp = 0;
2653			else if (od == 2) {
2654				dbuf->used++;
2655				odisp = *nval++;
2656			} else if (od == 3) {
2657				dbuf->used += 2;
2658				odisp = *(const long *)nval;
2659				nval += 2;
2660			}
2661		} else {
2662			/*
2663			 * We set od and bd to zero, these values are
2664			 * not allowed in opcodes that use base and
2665			 * outer displacement, e.g. we can tell if we
2666			 * are using on of those modes by checking
2667			 * `bd' and `od'.
2668			 */
2669			od = 0;
2670			bd = 0;
2671			disp = (char)BITFIELD(ext,7,0);
2672		}
2673		/*
2674		 * write everything into buf
2675		 */
2676		/* if base register not suppresed */
2677		if (mod == AR_IDX && (!bd || !ISBITSET(ext,7)))
2678			PRINT_AREG(dbuf, reg);
2679		else if (mod == MOD_SPECIAL && ISBITSET(ext,7)) {
2680			addchar('z');
2681			addchar('p');
2682			addchar('c');
2683		} else if (mod == MOD_SPECIAL) {
2684			addchar('p');
2685			addchar('c');
2686		}
2687		addchar('@');
2688		addchar('(');
2689
2690		if (bd && bd != 1) {
2691			prints(dbuf, disp,
2692			    bd == 2 ? SIZE_WORD :
2693			    bd == 3 ? SIZE_LONG :
2694			    SIZE_BYTE);
2695			if (od && !ISBITSET(ext,6) && !ISBITSET(ext,2))
2696				/* Pre-indexed and not suppressing index */
2697				addchar(',');
2698			else if (od && ISBITSET(ext,2)) {
2699				/* Post-indexed */
2700				addchar(')');
2701				addchar('@');
2702				addchar('(');
2703			} else if (!od)
2704				addchar(',');
2705		} else if (!bd) {
2706			/* don't forget simple 8 bit displacement. */
2707			prints(dbuf, disp,
2708			    bd == 2 ? SIZE_WORD :
2709			    bd == 3 ? SIZE_LONG :
2710			    SIZE_BYTE);
2711			addchar(',');
2712		}
2713
2714		/* Post-indexed? */
2715		if (od && ISBITSET(ext,2)) {
2716			/* have displacement? */
2717			if (od != 1) {
2718				prints(dbuf, odisp,
2719				    od == 2 ? SIZE_WORD :
2720				    od == 3 ? SIZE_LONG :
2721				    SIZE_BYTE);
2722				addchar(',');
2723			}
2724		}
2725
2726		if (!bd || !ISBITSET(ext,6)) {
2727			if (ISBITSET(ext,15))
2728				PRINT_AREG(dbuf,idx);
2729			else
2730				PRINT_DREG(dbuf,idx);
2731			addchar(':');
2732			addchar(ISBITSET(ext,11) ? 'l' : 'w');
2733			if (scale) {
2734				addchar(':');
2735				addchar('0' + (1 << scale));
2736			}
2737		}
2738		/* pre-indexed? */
2739		if (od && !ISBITSET(ext,2)) {
2740			if (od != 1) {
2741				addchar(')');
2742				addchar('@');
2743				addchar('(');
2744				prints(dbuf, odisp,
2745				    od == 2 ? SIZE_WORD :
2746				    od == 3 ? SIZE_LONG :
2747				    SIZE_BYTE);
2748			}
2749		}
2750		addchar(')');
2751		break;
2752	}
2753	*dbuf->casm = 0;
2754}
2755
2756/*
2757 * Given a disassembly buffer ``dbuf'' and a starting bit of the
2758 * mod|reg field ``bit'' (or just a reg field if ``mod'' is not
2759 * GETMOD_BEFORE or GETMOD_AFTER), disassemble and write into ``dbuf''
2760 * the mod|reg pair.
2761 */
2762static void
2763get_modregstr(dis_buffer_t *dbuf, int bit, int mod, int sz, int dispdisp)
2764{
2765	if (dbuf->mit)
2766		get_modregstr_mit(dbuf,bit,mod,sz,dispdisp);
2767	else
2768		get_modregstr_moto(dbuf,bit,mod,sz,dispdisp);
2769}
2770
2771/*
2772 * given a bit position ``bit'' in the current ``dbuf''->val
2773 * and the ``base'' string of the opcode, append the full
2774 * opcode name including condition found at ``bit''.
2775 */
2776static void
2777make_cond(dis_buffer_t *dbuf, int bit, const char *base)
2778{
2779	int cc;
2780	const char *ccs;
2781
2782	cc = BITFIELD(*dbuf->val,bit,bit-3);
2783	ccs = cc_table[cc&15];
2784
2785	addstr(dbuf, base);
2786	addstr(dbuf, ccs);
2787}
2788
2789static void
2790print_fcond(dis_buffer_t *dbuf, char cp)
2791{
2792	addstr(dbuf,fpcc_table[cp&31]);		/* XXX - not 63 ?*/
2793}
2794
2795static void
2796print_mcond(dis_buffer_t *dbuf, char cp)
2797{
2798	addstr(dbuf,mmcc_table[cp&15]);
2799}
2800
2801/*
2802 * given dis_buffer_t ``dbuf'' get the immediate value from the
2803 * extension words following current instruction, output a
2804 * hash (``#'') sign and the value.  Increment the ``dbuf''->used
2805 * field accordingly.
2806 */
2807static void
2808get_immed(dis_buffer_t *dbuf,int sz)
2809{
2810	addchar('#');
2811	switch (sz) {
2812	case SIZE_BYTE:
2813		prints(dbuf, BITFIELD(*(dbuf->val + 1),7,0), SIZE_BYTE);
2814		dbuf->used++;
2815		break;
2816	case SIZE_WORD:
2817		prints(dbuf, *(dbuf->val + 1), SIZE_WORD);
2818		dbuf->used++;
2819		break;
2820	case SIZE_LONG:
2821		prints(dbuf, *(long *)(dbuf->val + 1), SIZE_LONG);
2822		dbuf->used += 2;
2823		break;
2824	}
2825	return;
2826}
2827
2828static void
2829get_fpustdGEN(dis_buffer_t *dbuf, u_short ext, const char *name)
2830{
2831	int sz;
2832
2833	/*
2834	 * If bit seven is set, its a 040 s/d opcode, then if bit 2 is
2835	 * set its "d".  This is not documented, however thats the way
2836	 * it is.
2837	 */
2838
2839	sz = 0;
2840	addchar(*name++);
2841	if (ISBITSET(ext,7)) {
2842		if(ISBITSET(ext,2))
2843			addchar('d');
2844		else
2845			addchar('s');
2846	}
2847	addstr(dbuf,name);
2848
2849	if (ISBITSET(ext,14)) {
2850		switch (BITFIELD(ext,12,10)) {
2851		case 0:
2852			addchar('l');
2853			sz = SIZE_LONG;
2854			break;
2855		case 1:
2856			addchar('s');
2857			sz = SIZE_SINGLE;
2858			break;
2859		case 2:
2860			addchar('x');
2861			sz = SIZE_EXTENDED;
2862			break;
2863		case 3:
2864			addchar('p');
2865			sz = SIZE_PACKED;
2866			break;
2867		case 4:
2868			addchar('w');
2869			sz = SIZE_WORD;
2870			break;
2871		case 5:
2872			addchar('d');
2873			sz = SIZE_DOUBLE;
2874			break;
2875		case 6:
2876			addchar('b');
2877			sz = SIZE_BYTE;
2878			break;
2879		}
2880		addchar('\t');
2881		get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 1);
2882		if (BITFIELD(ext,6,3) == 6) {
2883			addchar(',');
2884			PRINT_FPREG(dbuf, BITFIELD(ext,2,0));
2885			addchar(':');
2886			PRINT_FPREG(dbuf, BITFIELD(ext,9,7));
2887		} else if (BITFIELD(ext,5,0) != FTST) {
2888			addchar(',');
2889			PRINT_FPREG(dbuf, BITFIELD(ext,9,7));
2890		}
2891	} else {
2892		addchar('x');
2893		addchar('\t');
2894		PRINT_FPREG(dbuf, BITFIELD(ext,12,10));
2895		if (BITFIELD(ext,6,3) == 6) {
2896			addchar(',');
2897			PRINT_FPREG(dbuf, BITFIELD(ext,2,0));
2898			addchar(':');
2899			PRINT_FPREG(dbuf, BITFIELD(ext,9,7));
2900		} else if (BITFIELD(ext,5,0) != FTST) {
2901			addchar(',');
2902			PRINT_FPREG(dbuf, BITFIELD(ext,9,7));
2903		}
2904	}
2905}
2906
2907#if 0
2908static u_long
2909get_areg_val(int reg)
2910{
2911	return 0;
2912}
2913#endif
2914
2915/*
2916 * given value ``disp'' print it to ``dbuf''->buf. ``rel'' is a
2917 * register number 0-7 (a0-a7), or -1 (pc). Thus possible extra info
2918 * could be output to the ``dbuf''->info buffer.
2919 */
2920static void
2921print_disp(dis_buffer_t *dbuf, int disp, int sz, int rel)
2922{
2923	db_expr_t diff;
2924	db_sym_t sym;
2925	const char *symname;
2926	u_long nv;
2927
2928	prints(dbuf, disp, sz);
2929
2930	if (rel == -1)
2931		/* XXX This may be wrong for a couple inst. */
2932		nv = disp + (u_int)dbuf->val + 2;
2933	else
2934		return; /* nv = get_areg_val(rel); */
2935
2936	diff = INT_MAX;
2937	symname = NULL;
2938	sym = db_search_symbol(nv, DB_STGY_PROC, &diff);
2939	db_symbol_values(sym, &symname, 0);
2940
2941	if (symname) {
2942		iaddstr(dbuf, "disp:");
2943		iaddstr(dbuf, symname);
2944		iaddchar('+');
2945		iprintu(dbuf, diff, SIZE_LONG);
2946		iaddchar(' ');
2947		*dbuf->cinfo = 0;
2948	}
2949}
2950
2951static void
2952print_addr(dis_buffer_t *dbuf, u_long addr)
2953{
2954	db_expr_t diff;
2955	db_sym_t sym;
2956	const char *symname;
2957
2958	diff = INT_MAX;
2959	symname = NULL;
2960	sym = db_search_symbol(addr, DB_STGY_ANY, &diff);
2961	db_symbol_values(sym, &symname, 0);
2962
2963	if (symname) {
2964		if (diff == 0)
2965			addstr(dbuf,symname);
2966		else {
2967			addchar('<');
2968			addstr(dbuf,symname);
2969			addchar('+');
2970			printu(dbuf, diff, SIZE_LONG);
2971			addchar('>');
2972			*dbuf->casm = 0;
2973		}
2974		iaddstr(dbuf,"addr:");
2975		iprintu(dbuf, addr, SIZE_LONG);
2976		iaddchar(' ');
2977		*dbuf->cinfo = 0;
2978	} else {
2979		printu(dbuf, addr, SIZE_LONG);
2980	}
2981}
2982
2983static void
2984prints(dis_buffer_t *dbuf, int val, int sz)
2985{
2986	extern int db_radix;
2987
2988	if (val == 0) {
2989		dbuf->casm[0] = '0';
2990		dbuf->casm[1] = 0;
2991	} else if (sz == SIZE_BYTE)
2992		prints_wb(dbuf, (char)val, sz, db_radix);
2993	else if (sz == SIZE_WORD)
2994		prints_wb(dbuf, (short)val, sz, db_radix);
2995	else
2996		prints_wb(dbuf, (long)val, sz, db_radix);
2997
2998	dbuf->casm = &dbuf->casm[strlen(dbuf->casm)];
2999}
3000
3001#if 0
3002static void
3003iprints(dis_buffer_t *dbuf, int val, int sz)
3004{
3005	extern int db_radix;
3006
3007	if (val == 0) {
3008		dbuf->cinfo[0] = '0';
3009		dbuf->cinfo[1] = 0;
3010	} else if (sz == SIZE_BYTE)
3011		iprints_wb(dbuf, (char)val, sz, db_radix);
3012	else if (sz == SIZE_WORD)
3013		iprints_wb(dbuf, (short)val, sz, db_radix);
3014	else
3015		iprints_wb(dbuf, (long)val, sz, db_radix);
3016
3017	dbuf->cinfo = &dbuf->cinfo[strlen(dbuf->cinfo)];
3018}
3019#endif
3020
3021static void
3022printu(dis_buffer_t *dbuf, u_int val, int sz)
3023{
3024	extern int db_radix;
3025
3026	if (val == 0) {
3027		dbuf->casm[0] = '0';
3028		dbuf->casm[1] = 0;
3029	} else if (sz == SIZE_BYTE)
3030		printu_wb(dbuf, (u_char)val, sz, db_radix);
3031	else if (sz == SIZE_WORD)
3032		printu_wb(dbuf, (u_short)val, sz, db_radix);
3033	else
3034		printu_wb(dbuf, (u_long)val, sz, db_radix);
3035	dbuf->casm = &dbuf->casm[strlen(dbuf->casm)];
3036}
3037
3038static void
3039iprintu(dis_buffer_t *dbuf, u_int val, int sz)
3040{
3041	extern int db_radix;
3042
3043	if (val == 0) {
3044		dbuf->cinfo[0] = '0';
3045		dbuf->cinfo[1] = 0;
3046	} else if (sz == SIZE_BYTE)
3047		iprintu_wb(dbuf, (u_char)val, sz, db_radix);
3048	else if (sz == SIZE_WORD)
3049		iprintu_wb(dbuf, (u_short)val, sz, db_radix);
3050	else
3051		iprintu_wb(dbuf, (u_long)val, sz, db_radix);
3052	dbuf->cinfo = &dbuf->cinfo[strlen(dbuf->cinfo)];
3053}
3054
3055static void
3056printu_wb(dis_buffer_t *dbuf, u_int val, int sz, int base)
3057{
3058	static char buf[sizeof(long) * NBBY / 3 + 2];
3059	char *p, ch;
3060
3061	if (base != 10) {
3062		addchar('0');
3063		if (base != 8) {
3064			base = 16;
3065			addchar('x');
3066		}
3067	}
3068
3069	p = buf;
3070	do {
3071		*++p = hexdigits[val % base];
3072	} while (val /= base);
3073
3074	while ((ch = *p--))
3075		addchar(ch);
3076
3077	*dbuf->casm = 0;
3078}
3079
3080static void
3081prints_wb(dis_buffer_t *dbuf, int val, int sz, int base)
3082{
3083	if (val < 0) {
3084		addchar('-');
3085		val = -val;
3086	}
3087	printu_wb(dbuf, val, sz, base);
3088}
3089
3090static void
3091iprintu_wb(dis_buffer_t *dbuf, u_int val, int sz, int base)
3092{
3093	static char buf[sizeof(long) * NBBY / 3 + 2];
3094	char *p, ch;
3095
3096	if (base != 10) {
3097		iaddchar('0');
3098		if (base != 8) {
3099			base = 16;
3100			iaddchar('x');
3101		}
3102	}
3103
3104	p = buf;
3105	do {
3106		*++p = hexdigits[val % base];
3107	} while (val /= base);
3108
3109	while ((ch = *p--))
3110		iaddchar(ch);
3111
3112	*dbuf->cinfo = 0;
3113}
3114
3115#if 0
3116static void
3117iprints_wb(dis_buffer_t *dbuf, int val, int sz, int base)
3118{
3119	if (val < 0) {
3120		iaddchar('-');
3121		val = -val;
3122	}
3123	iprintu_wb(dbuf, val, sz, base);
3124}
3125#endif
3126
3127static void
3128prints_bf(dis_buffer_t *dbuf, int val, int sb, int eb)
3129{
3130	if (ISBITSET(val,sb))
3131		val = (~0 & ~BITFIELD(~0, sb, eb)) | BITFIELD(val, sb, eb);
3132	else
3133		val = BITFIELD(val,sb,eb);
3134
3135	prints(dbuf, val, SIZE_LONG);
3136}
3137
3138static void
3139printu_bf(dis_buffer_t *dbuf, u_int val, int sb, int eb)
3140{
3141	printu(dbuf,BITFIELD(val,sb,eb),SIZE_LONG);
3142}
3143