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