#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: db_disasm.c,v 1.47 2023/09/26 14:33:55 tsutsui Exp $");
#include <sys/param.h>
#ifdef _KERNEL
#include <sys/systm.h>
#endif
#include <machine/db_machdep.h>
#include <ddb/db_interface.h>
#include <ddb/db_output.h>
#include <ddb/db_sym.h>
#include <m68k/m68k/db_disasm.h>
static void get_modregstr(dis_buffer_t *, int, int, int, int);
static void get_modregstr_moto(dis_buffer_t *, int, int, int, int);
static void get_modregstr_mit(dis_buffer_t *, int, int, int, int);
#if 0
static u_long get_areg_val(int reg);
#endif
static void get_immed(dis_buffer_t *, int);
static void get_fpustdGEN(dis_buffer_t *, u_short, const char *);
static void addstr(dis_buffer_t *, const char *s);
static void prints(dis_buffer_t *, int, int);
static void printu(dis_buffer_t *, u_int, int);
static void prints_wb(dis_buffer_t *, int, int, int);
static void printu_wb(dis_buffer_t *, u_int, int, int);
static void prints_bf(dis_buffer_t *, int, int, int);
static void printu_bf(dis_buffer_t *, u_int, int, int);
static void iaddstr(dis_buffer_t *, const char *s);
#if 0
static void iprints(dis_buffer_t *, int, int);
#endif
static void iprintu(dis_buffer_t *, u_int, int);
#if 0
static void iprints_wb(dis_buffer_t *, int, int, int);
#endif
static void iprintu_wb(dis_buffer_t *, u_int, int, int);
static void make_cond(dis_buffer_t *, int , const char *);
static void print_fcond(dis_buffer_t *, char);
static void print_mcond(dis_buffer_t *, char);
static void print_disp(dis_buffer_t *, int, int, int);
static void print_addr(dis_buffer_t *, u_long);
static void print_reglist(dis_buffer_t *, int, u_short);
static void print_freglist(dis_buffer_t *, int, u_short, int);
static void print_fcode(dis_buffer_t *, u_short);
static void opcode_bitmanip(dis_buffer_t *, u_short);
static void opcode_move(dis_buffer_t *, u_short);
static void opcode_misc(dis_buffer_t *, u_short);
static void opcode_branch(dis_buffer_t *, u_short);
static void opcode_coproc(dis_buffer_t *, u_short);
static void opcode_0101(dis_buffer_t *, u_short);
static void opcode_1000(dis_buffer_t *, u_short);
static void opcode_addsub(dis_buffer_t *, u_short);
static void opcode_1010(dis_buffer_t *, u_short);
static void opcode_1011(dis_buffer_t *, u_short);
static void opcode_1100(dis_buffer_t *, u_short);
static void opcode_1110(dis_buffer_t *, u_short);
static void opcode_fpu(dis_buffer_t *, u_short);
static void opcode_mmu(dis_buffer_t *, u_short);
static void opcode_mmu040(dis_buffer_t *, u_short);
static void opcode_move16(dis_buffer_t *, u_short);
static void opcode_movec(dis_buffer_t *, u_short);
static void opcode_divmul(dis_buffer_t *, u_short);
static void opcode_movem(dis_buffer_t *, u_short);
static void opcode_fmove_ext(dis_buffer_t *, u_short, u_short);
static void opcode_pmove(dis_buffer_t *, u_short, u_short);
static void opcode_pflush(dis_buffer_t *, u_short, u_short);
#define addchar(ch) (*dbuf->casm++ = ch)
#define iaddchar(ch) (*dbuf->cinfo++ = ch)
typedef void dis_func_t(dis_buffer_t *, u_short);
static dis_func_t *const opcode_map[16] = {
opcode_bitmanip, opcode_move, opcode_move, opcode_move,
opcode_misc, opcode_0101, opcode_branch, opcode_move,
opcode_1000, opcode_addsub, opcode_1010, opcode_1011,
opcode_1100, opcode_addsub, opcode_1110, opcode_coproc
};
static const char *const cc_table[16] = {
"t", "f", "hi", "ls",
"cc", "cs", "ne", "eq",
"vc", "vs", "pl", "mi",
"ge", "lt", "gt", "le"
};
static const char *const fpcc_table[32] = {
"f", "eq", "ogt", "oge", "olt", "ole", "ogl", "or",
"un", "ueq", "ugt", "uge", "ult", "ule", "ne", "t",
"sf", "seq", "gt", "ge", "lt", "le", "gl", "gle",
"ngle", "ngl", "nle", "nlt", "nge", "ngt", "sne", "st" };
static const char *const mmcc_table[16] = {
"bs", "bc", "ls", "lc", "ss", "sc", "as", "sc",
"ws", "wc", "is", "ic", "gs", "gc", "cs", "cc" };
static const char *const aregs[8] = {"a0","a1","a2","a3","a4","a5","a6","sp"};
static const char *const dregs[8] = {"d0","d1","d2","d3","d4","d5","d6","d7"};
static const char *const fpregs[8] = {
"fp0","fp1","fp2","fp3","fp4","fp5","fp6","fp7" };
static const char *const fpcregs[3] = { "fpiar", "fpsr", "fpcr" };
#ifndef _KERNEL
static const char hexdigits[] = "0123456789abcdef";
#endif
static char asm_buffer[256];
static char info_buffer[256];
db_addr_t
db_disasm(db_addr_t loc, bool moto_syntax)
{
u_short opc;
dis_func_t *func;
dis_buffer_t dbuf;
dbuf.casm = dbuf.dasm = asm_buffer;
dbuf.cinfo = dbuf.info = info_buffer;
dbuf.used = 0;
dbuf.val = (short *)loc;
dbuf.mit = moto_syntax ? 0 : 1;
dbuf.dasm[0] = 0;
dbuf.info[0] = 0;
opc = *dbuf.val;
dbuf.used++;
func = opcode_map[OPCODE_MAP(opc)];
func(&dbuf, opc);
db_printf("%s",asm_buffer);
if (info_buffer[0])
db_printf("\t[%s]\n",info_buffer);
else
db_printf("\n");
return loc + sizeof(short) * dbuf.used;
}
static void
opcode_bitmanip(dis_buffer_t *dbuf, u_short opc)
{
const char *tmp;
u_short ext;
int sz;
tmp = NULL;
switch (opc) {
case ANDITOCCR_INST:
tmp = "andib\t";
break;
case ANDIROSR_INST:
tmp = "andiw\t";
break;
case EORITOCCR_INST:
tmp = "eorib\t";
break;
case EORITOSR_INST:
tmp = "eoriw\t";
break;
case ORITOCCR_INST:
tmp = "orib\t";
break;
case ORITOSR_INST:
tmp = "oriw\t";
break;
}
if (tmp) {
addstr(dbuf, tmp);
if (ISBITSET(opc,6)) {
get_immed(dbuf, SIZE_WORD);
addstr(dbuf, ",sr");
} else {
get_immed(dbuf, SIZE_BYTE);
addstr(dbuf, ",ccr");
}
return;
}
if (IS_INST(RTM,opc)) {
addstr(dbuf, "rtm\t");
if (ISBITSET(opc,3))
PRINT_AREG(dbuf, BITFIELD(opc,2,0));
else
PRINT_DREG(dbuf, BITFIELD(opc,2,0));
return;
}
if (IS_INST(MOVEP,opc)) {
addstr(dbuf, "movp");
if (ISBITSET(opc,6))
addchar('l');
else
addchar('w');
addchar('\t');
if (ISBITSET(opc,7)) {
PRINT_DREG(dbuf, BITFIELD(opc, 11, 9));
addchar(',');
}
PRINT_AREG(dbuf, BITFIELD(opc, 2, 0));
addchar('@');
addchar('(');
print_disp(dbuf, *(dbuf->val + 1), SIZE_WORD,
BITFIELD(opc, 2, 0));
dbuf->used++;
addchar(')');
if (!ISBITSET(opc,7)) {
addchar(',');
PRINT_DREG(dbuf, BITFIELD(opc, 11, 9));
}
return;
}
switch (opc & BCHGD_MASK) {
case BCHGD_INST:
tmp = "bchg\t";
break;
case BCLRD_INST:
tmp = "bclr\t";
break;
case BSETD_INST:
tmp = "bset\t";
break;
case BTSTD_INST:
tmp = "btst\t";
break;
}
if (tmp) {
addstr(dbuf, tmp);
PRINT_DREG(dbuf, BITFIELD(opc,11,9));
addchar(',');
get_modregstr(dbuf,5,GETMOD_BEFORE,0,0);
return;
}
switch (opc & BCHGS_MASK) {
case BCHGS_INST:
tmp = "bchg\t";
break;
case BCLRS_INST:
tmp = "bclr\t";
break;
case BSETS_INST:
tmp = "bset\t";
break;
case BTSTS_INST:
tmp = "btst\t";
break;
}
if (tmp) {
addstr(dbuf, tmp);
get_immed(dbuf, SIZE_BYTE);
addchar(',');
get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 1);
return;
}
if (IS_INST(CAS2,opc)) {
u_short ext2;
ext = *(dbuf->val + 1);
ext2 = *(dbuf->val + 2);
dbuf->used += 2;
if (ISBITSET(opc,9))
addstr(dbuf, "cas2l\t");
else
addstr(dbuf, "cas2w\t");
PRINT_DREG(dbuf, BITFIELD(ext,2,0));
addchar(':');
PRINT_DREG(dbuf, BITFIELD(ext2,2,0));
addchar(',');
PRINT_DREG(dbuf, BITFIELD(ext,8,6));
addchar(':');
PRINT_DREG(dbuf, BITFIELD(ext2,8,6));
addchar(',');
if (ISBITSET(ext,15))
PRINT_AREG(dbuf, BITFIELD(ext,14,12));
else
PRINT_DREG(dbuf, BITFIELD(ext,14,12));
addchar('@');
addchar(':');
if (ISBITSET(ext2,15))
PRINT_AREG(dbuf, BITFIELD(ext2,14,12));
else
PRINT_DREG(dbuf, BITFIELD(ext2,14,12));
addchar('@');
return;
}
switch (opc & CAS_MASK) {
case CAS_INST:
ext = *(dbuf->val + 1);
dbuf->used++;
addstr(dbuf,"cas");
sz = BITFIELD(opc,10,9);
if (sz == 0) {
sz = SIZE_BYTE;
addchar('b');
} else if (sz == 1) {
sz = SIZE_WORD;
addchar('w');
} else {
sz = SIZE_LONG;
addchar('l');
}
addchar('\t');
PRINT_DREG(dbuf, BITFIELD(ext, 2, 0));
addchar(',');
PRINT_DREG(dbuf, BITFIELD(ext, 8, 6));
addchar(',');
get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 1);
return;
case CHK2_INST:
ext = *(dbuf->val + 1);
dbuf->used++;
if (ISBITSET(ext,11))
addstr(dbuf,"chk2");
else
addstr(dbuf,"cmp2");
sz = BITFIELD(opc,10,9);
if (sz == 0) {
sz = SIZE_BYTE;
addchar('b');
} else if (sz == 1) {
sz = SIZE_WORD;
addchar('w');
} else {
sz = SIZE_LONG;
addchar('l');
}
addchar('\t');
get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 1);
addchar(',');
if(ISBITSET(ext,15))
PRINT_AREG(dbuf, BITFIELD(ext, 14, 12));
else
PRINT_DREG(dbuf, BITFIELD(ext, 14, 12));
return;
}
switch (ADDI_MASK & opc) {
case MOVES_INST:
addstr(dbuf, "movs");
sz = BITFIELD(opc,7,6);
if (sz == 0) {
addchar('b');
sz = SIZE_BYTE;
} else if (sz == 1) {
addchar('w');
sz = SIZE_WORD;
} else {
addchar ('l');
sz = SIZE_LONG;
}
addchar('\t');
ext = *(dbuf->val + 1);
dbuf->used++;
if (ISBITSET(ext,11)) {
if (ISBITSET(ext,15))
PRINT_AREG(dbuf,BITFIELD(ext,14,12));
else
PRINT_DREG(dbuf,BITFIELD(ext,14,12));
addchar(',');
get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 1);
} else {
get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 1);
addchar(',');
if (ISBITSET(ext,15))
PRINT_AREG(dbuf,BITFIELD(ext,14,12));
else
PRINT_DREG(dbuf,BITFIELD(ext,14,12));
}
return;
case ADDI_INST:
tmp = "addi";
break;
case ANDI_INST:
tmp = "andi";
break;
case CMPI_INST:
tmp = "cmpi";
break;
case EORI_INST:
tmp = "eori";
break;
case ORI_INST:
tmp = "ori";
break;
case SUBI_INST:
tmp = "subi";
break;
}
if (tmp) {
addstr(dbuf, tmp);
sz = BITFIELD(opc,7,6);
switch (sz) {
case 0:
addchar('b');
addchar('\t');
sz = SIZE_BYTE;
break;
case 1:
addchar('w');
addchar('\t');
sz = SIZE_WORD;
break;
case 2:
addchar ('l');
addchar('\t');
get_immed(dbuf,SIZE_LONG);
addchar(',');
get_modregstr(dbuf,5,GETMOD_BEFORE,SIZE_LONG,2);
return;
}
get_immed(dbuf,sz);
addchar(',');
get_modregstr(dbuf,5,GETMOD_BEFORE,sz,1);
return;
}
}
static void
opcode_move(dis_buffer_t *dbuf, u_short opc)
{
int sz, lused;
sz = 0;
switch (OPCODE_MAP(opc)) {
case 0x1:
sz = SIZE_BYTE;
break;
case 0x3:
sz = SIZE_WORD;
break;
case 0x2:
sz = SIZE_LONG;
break;
case 0x7:
addstr(dbuf, "movq\t#");
prints_bf(dbuf, opc, 7, 0);
addchar(',');
PRINT_DREG(dbuf,BITFIELD(opc,11,9));
return;
}
addstr(dbuf, "mov");
if (BITFIELD(opc,8,6) == AR_DIR)
addchar('a');
if (sz == SIZE_BYTE)
addchar('b');
else if (sz == SIZE_WORD)
addchar('w');
else
addchar('l');
addchar('\t');
lused = dbuf->used;
get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 0);
addchar(',');
get_modregstr(dbuf, 11, GETMOD_AFTER, sz, dbuf->used - lused);
}
static void
opcode_misc(dis_buffer_t *dbuf, u_short opc)
{
const char *tmp;
int sz;
tmp = NULL;
switch (opc) {
case BGND_INST:
tmp = "bgnd";
break;
case ILLEGAL_INST:
tmp = "illegal";
break;
case MOVEFRC_INST:
case MOVETOC_INST:
opcode_movec(dbuf, opc);
return;
case NOP_INST:
tmp = "nop";
break;
case RESET_INST:
tmp = "reset";
break;
case RTD_INST:
addstr(dbuf, "rtd\t");
get_immed(dbuf, SIZE_WORD);
return;
case RTE_INST:
tmp = "rte";
break;
case RTR_INST:
tmp = "rtr";
break;
case RTS_INST:
tmp = "rts";
break;
case STOP_INST:
addstr(dbuf, "stop\t");
get_immed(dbuf, SIZE_WORD);
return;
case TRAPV_INST:
tmp = "trapv";
break;
default:
break;
}
if (tmp) {
addstr(dbuf, tmp);
return;
}
switch (opc & BKPT_MASK) {
case BKPT_INST:
addstr(dbuf, "bkpt\t#");
printu_bf(dbuf, opc, 2, 0);
return;
case EXTBW_INST:
addstr(dbuf, "extw\t");
get_modregstr(dbuf,2,DR_DIR,0,0);
return;
case EXTWL_INST:
addstr(dbuf, "extl\t");
get_modregstr(dbuf,2,DR_DIR,0,0);
return;
case EXTBL_INST:
addstr(dbuf, "extbl\t");
get_modregstr(dbuf,2,DR_DIR,0,0);
return;
case LINKW_INST:
case LINKL_INST:
if ((LINKW_MASK & opc) == LINKW_INST) {
addstr(dbuf, "linkw\t");
get_modregstr(dbuf, 2, AR_DIR, 0, 1);
} else {
addstr(dbuf, "linkl\t");
get_modregstr(dbuf, 2, AR_DIR, 0, 2);
}
addchar(',');
if ((LINKW_MASK & opc) == LINKW_INST)
get_immed(dbuf, SIZE_WORD);
else
get_immed(dbuf,SIZE_LONG);
return;
case MOVETOUSP_INST:
case MOVEFRUSP_INST:
addstr(dbuf, "movl\t");
if (!ISBITSET(opc,3)) {
get_modregstr(dbuf, 2, AR_DIR, 0, 0);
addchar(',');
}
addstr(dbuf, "usp");
if (ISBITSET(opc,3)) {
addchar(',');
get_modregstr(dbuf, 2, AR_DIR, 0, 0);
}
return;
case SWAP_INST:
addstr(dbuf, "swap\t");
get_modregstr(dbuf, 2, DR_DIR, 0, 0);
return;
case UNLK_INST:
addstr(dbuf, "unlk\t");
get_modregstr(dbuf, 2, AR_DIR, 0, 0);
return;
}
if ((opc & TRAP_MASK) == TRAP_INST) {
addstr(dbuf, "trap\t#");
printu_bf(dbuf, opc, 3, 0);
return;
}
sz = 0;
switch (DIVSL_MASK & opc) {
case DIVSL_INST:
case MULSL_INST:
opcode_divmul(dbuf, opc);
return;
case JMP_INST:
tmp = "jmp\t";
break;
case JSR_INST:
tmp = "jsr\t";
break;
case MOVEFRCCR_INST:
tmp = "mov\tccr,";
break;
case MOVEFRSR_INST:
tmp = "mov\tsr,";
break;
case NBCD_INST:
tmp = "nbcd\t";
break;
case PEA_INST:
tmp = "pea\t";
break;
case TAS_INST:
tmp = "tas\t";
break;
case MOVETOCCR_INST:
case MOVETOSR_INST:
tmp = "mov\t";
sz = SIZE_WORD;
break;
}
if (tmp) {
addstr(dbuf, tmp);
get_modregstr(dbuf,5, GETMOD_BEFORE, sz, 0);
if(IS_INST(MOVETOSR,opc))
addstr(dbuf, ",sr");
else if(IS_INST(MOVETOCCR,opc))
addstr(dbuf, ",ccr");
return;
}
if ((opc & MOVEM_MASK) == MOVEM_INST) {
opcode_movem(dbuf, opc);
return;
}
switch (opc & CLR_MASK) {
case CLR_INST:
tmp = "clr";
break;
case NEG_INST:
tmp = "neg";
break;
case NEGX_INST:
tmp = "negx";
break;
case NOT_INST:
tmp = "not";
break;
case TST_INST:
tmp = "tst";
break;
}
if (tmp) {
int msz;
addstr(dbuf, tmp);
msz = BITFIELD(opc,7,6);
if (msz == 0) {
tmp = "b\t";
sz = SIZE_BYTE;
} else if (msz == 1) {
tmp = "w\t";
sz = SIZE_WORD;
} else {
tmp = "l\t";
sz = SIZE_LONG;
}
addstr(dbuf, tmp);
get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 0);
return;
}
if ((opc & LEA_MASK) == LEA_INST) {
addstr(dbuf, "lea\t");
get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_LONG, 0);
addchar(',');
get_modregstr(dbuf, 11, AR_DIR, 0, 0);
return;
} else if ((opc & CHK_MASK) == CHK_INST) {
if (BITFIELD(opc,8,7) == 0x3) {
addstr(dbuf, "chkw\t");
get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_WORD, 0);
} else {
addstr(dbuf, "chkl\t");
get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_LONG, 0);
}
addchar(',');
get_modregstr(dbuf, 11, DR_DIR, 0, 0);
return;
}
}
static void
opcode_0101(dis_buffer_t *dbuf, u_short opc)
{
int data;
if (IS_INST(TRAPcc, opc) && BITFIELD(opc,2,0) > 1) {
int opmode;
opmode = BITFIELD(opc,2,0);
make_cond(dbuf,11,"trap");
if (opmode == 0x2) {
addchar('w');
addchar('\t');
get_immed(dbuf, SIZE_WORD);
} else if (opmode == 0x3) {
addchar('l');
addchar('\t');
get_immed(dbuf, SIZE_LONG);
}
return;
} else if (IS_INST(DBcc, opc)) {
make_cond(dbuf,11,"db");
addchar('\t');
PRINT_DREG(dbuf, BITFIELD(opc,2,0));
addchar(',');
print_disp(dbuf, *(dbuf->val + 1), SIZE_WORD, -1);
dbuf->used++;
return;
} else if (IS_INST(Scc,opc)) {
make_cond(dbuf,11,"s");
addchar('\t');
get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_BYTE, 0);
return;
} else if (IS_INST(ADDQ, opc) || IS_INST(SUBQ, opc)) {
int size = BITFIELD(opc,7,6);
if (IS_INST(SUBQ, opc))
addstr(dbuf, "subq");
else
addstr(dbuf, "addq");
if (size == 0x1)
addchar('w');
else if (size == 0x2)
addchar('l');
else
addchar('b');
addchar('\t');
addchar('#');
data = BITFIELD(opc,11,9);
if (data == 0)
data = 8;
printu(dbuf, data, SIZE_BYTE);
addchar(',');
get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 0);
return;
}
}
static void
opcode_branch(dis_buffer_t *dbuf, u_short opc)
{
int disp;
if (IS_INST(BRA,opc))
addstr(dbuf, "bra");
else if (IS_INST(BSR,opc))
addstr(dbuf, "bsr");
else
make_cond(dbuf,11,"b");
disp = BITFIELD(opc,7,0);
if (disp == 0) {
disp = *(dbuf->val + 1);
dbuf->used++;
addchar('w');
} else if (disp == 0xff) {
disp = *(long *)(dbuf->val + 1);
dbuf->used += 2;
addchar('l');
} else {
if (ISBITSET(disp,7))
disp -= 256;
addchar('b');
}
addchar('\t');
print_addr(dbuf, disp + (u_long)dbuf->val + 2);
}
static void
opcode_addsub(dis_buffer_t *dbuf, u_short opc)
{
int sz, ch, amode;
sz = BITFIELD(opc,7,6);
amode = 0;
if (sz == 0) {
ch = 'b';
sz = SIZE_BYTE;
} else if (sz == 1) {
ch = 'w';
sz = SIZE_WORD;
} else if (sz == 2) {
ch = 'l';
sz = SIZE_LONG;
} else {
amode = 1;
if (!ISBITSET(opc,8)) {
sz = SIZE_WORD;
ch = 'w';
} else {
sz = SIZE_LONG;
ch = 'l';
}
}
if (!amode && (IS_INST(ADDX,opc) || IS_INST(SUBX,opc))) {
if (IS_INST(ADDX,opc))
addstr(dbuf,"addx");
else
addstr(dbuf,"subx");
addchar(ch);
addchar('\t');
if (ISBITSET(opc,3)) {
PRINT_AREG(dbuf,BITFIELD(opc,2,0));
addchar('@');
addchar('-');
addchar(',');
PRINT_AREG(dbuf,BITFIELD(opc,11,9));
addchar('@');
addchar('-');
} else {
PRINT_DREG(dbuf,BITFIELD(opc,2,0));
addchar(',');
PRINT_DREG(dbuf,BITFIELD(opc,11,9));
}
} else {
if (IS_INST(ADD,opc))
addstr(dbuf, "add");
else
addstr(dbuf, "sub");
if (amode)
addchar('a');
addchar(ch);
addchar('\t');
if (ISBITSET(opc,8) && amode == 0) {
PRINT_DREG(dbuf,BITFIELD(opc,11,9));
addchar(',');
get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 0);
} else {
get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 0);
addchar(',');
if (amode)
PRINT_AREG(dbuf,BITFIELD(opc,11,9));
else
PRINT_DREG(dbuf,BITFIELD(opc,11,9));
}
}
return;
}
static void
opcode_1110(dis_buffer_t *dbuf, u_short opc)
{
const char *tmp;
u_short ext;
int type, sz;
tmp = NULL;
switch (opc & BFCHG_MASK) {
case BFCHG_INST:
tmp = "bfchg";
break;
case BFCLR_INST:
tmp = "bfclr";
break;
case BFEXTS_INST:
tmp = "bfexts";
break;
case BFEXTU_INST:
tmp = "bfextu";
break;
case BFFFO_INST:
tmp = "bfffo";
break;
case BFINS_INST:
tmp = "bfins";
break;
case BFSET_INST:
tmp = "bfset";
break;
case BFTST_INST:
tmp = "bftst";
break;
}
if (tmp) {
short bf;
addstr(dbuf, tmp);
addchar('\t');
ext = *(dbuf->val + 1);
dbuf->used++;
if (IS_INST(BFINS,opc)) {
PRINT_DREG(dbuf, BITFIELD(ext,14,12));
addchar(',');
}
get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 1);
addchar('{');
bf = BITFIELD(ext,10,6);
if (ISBITSET(ext, 11))
PRINT_DREG(dbuf, bf);
else
printu_wb(dbuf, bf, SIZE_BYTE, 10);
addchar(':');
bf = BITFIELD(ext, 4, 0);
if (ISBITSET(ext, 5))
PRINT_DREG(dbuf, bf);
else {
if (bf == 0)
bf = 32;
printu_wb(dbuf, bf, SIZE_BYTE, 10);
}
addchar('}');
if (ISBITSET(opc,8) && !IS_INST(BFINS,opc)) {
addchar(',');
PRINT_DREG(dbuf, BITFIELD(ext,14,12));
} else
*dbuf->casm = 0;
return;
}
sz = BITFIELD(opc,7,6);
if (sz == 0x3)
type = BITFIELD(opc, 10, 9);
else
type = BITFIELD(opc, 4, 3);
switch (type) {
case AS_TYPE:
addchar('a');
addchar('s');
break;
case LS_TYPE:
addchar('l');
addchar('s');
break;
case RO_TYPE:
addchar('r');
addchar('o');
break;
case ROX_TYPE:
addchar('r');
addchar('o');
addchar('x');
break;
}
if (ISBITSET(opc,8))
addchar('l');
else
addchar('r');
switch (sz) {
case 0:
sz = SIZE_BYTE;
addchar('b');
break;
case 3:
case 1:
sz = SIZE_WORD;
addchar('w');
break;
case 2:
sz = SIZE_LONG;
addchar('l');
break;
}
addchar('\t');
if(BITFIELD(opc,7,6) == 0x3) {
get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 0);
return;
} else if (ISBITSET(opc,5))
PRINT_DREG(dbuf, BITFIELD(opc,11,9));
else {
addchar('#');
sz = BITFIELD(opc,11,9);
if (sz == 0)
sz = 8;
printu_wb(dbuf, sz, SIZE_BYTE, 10);
}
addchar(',');
PRINT_DREG(dbuf, BITFIELD(opc,2,0));
return;
}
static void
opcode_1011(dis_buffer_t *dbuf, u_short opc)
{
int sz;
if (IS_INST(CMPA,opc)) {
addstr(dbuf, "cmpa");
if (ISBITSET(opc, 8)) {
addchar('l');
sz = SIZE_LONG;
} else {
addchar('w');
sz = SIZE_WORD;
}
addchar('\t');
} else {
if (IS_INST(CMP, opc))
addstr(dbuf, "cmp");
else
addstr(dbuf, "eor");
sz = BITFIELD(opc,7,6);
switch (sz) {
case 0:
addchar('b');
sz = SIZE_BYTE;
break;
case 1:
addchar('w');
sz = SIZE_WORD;
break;
case 2:
addchar('l');
sz = SIZE_LONG;
break;
}
addchar('\t');
if (IS_INST(EOR,opc)) {
PRINT_DREG(dbuf, BITFIELD(opc,11,9));
addchar(',');
}
}
get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 0);
if (IS_INST(CMPA,opc)) {
addchar(',');
PRINT_AREG(dbuf, BITFIELD(opc,11,9));
} else if (IS_INST(CMP,opc)) {
addchar(',');
PRINT_DREG(dbuf, BITFIELD(opc,11,9));
}
return;
}
static void
opcode_1000(dis_buffer_t *dbuf, u_short opc)
{
int sz;
if (IS_INST(UNPKA,opc)) {
addstr(dbuf, "unpk\t");
PRINT_AREG(dbuf,BITFIELD(opc,2,0));
addstr(dbuf, "@-,");
PRINT_AREG(dbuf,BITFIELD(opc,11,9));
addstr(dbuf, "@-,");
get_immed(dbuf,SIZE_WORD);
} else if (IS_INST(UNPKD,opc)) {
addstr(dbuf, "unpk\t");
PRINT_DREG(dbuf,BITFIELD(opc,2,0));
addchar(',');
PRINT_DREG(dbuf,BITFIELD(opc,11,9));
addchar(',');
get_immed(dbuf,SIZE_WORD);
} else if (IS_INST(SBCDA,opc)) {
addstr(dbuf, "sbcd\t");
PRINT_AREG(dbuf,BITFIELD(opc,2,0));
addstr(dbuf, "@-,");
PRINT_AREG(dbuf,BITFIELD(opc,11,9));
addstr(dbuf, "@-");
} else if (IS_INST(SBCDD,opc)) {
addstr(dbuf, "sbcd\t");
PRINT_DREG(dbuf,BITFIELD(opc,2,0));
addchar(',');
PRINT_DREG(dbuf,BITFIELD(opc,11,9));
} else if (IS_INST(DIVSW,opc) || IS_INST(DIVUW,opc)) {
if (IS_INST(DIVSW,opc))
addstr(dbuf, "divsw\t");
else
addstr(dbuf, "divuw\t");
get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_WORD, 0);
addchar(',');
PRINT_DREG(dbuf, BITFIELD(opc,11,9));
} else {
addstr(dbuf, "or");
sz = BITFIELD(opc,7,6);
switch (sz) {
case 0:
addchar('b');
sz = SIZE_BYTE;
break;
case 1:
addchar('w');
sz = SIZE_WORD;
break;
case 2:
addchar('l');
sz = SIZE_LONG;
break;
}
addchar('\t');
if (ISBITSET(opc,8)) {
PRINT_DREG(dbuf, BITFIELD(opc,11,9));
addchar(',');
}
get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 0);
if (!ISBITSET(opc,8)) {
addchar(',');
PRINT_DREG(dbuf, BITFIELD(opc,11,9));
}
}
}
static void
opcode_1100(dis_buffer_t *dbuf, u_short opc)
{
int sz;
if (IS_INST(ABCDA,opc)) {
addstr(dbuf, "abcd\t");
PRINT_AREG(dbuf,BITFIELD(opc,2,0));
addstr(dbuf, "@-,");
PRINT_AREG(dbuf,BITFIELD(opc,11,9));
addstr(dbuf, "@-");
} else if (IS_INST(ABCDD,opc)) {
addstr(dbuf, "abcd\t");
PRINT_DREG(dbuf,BITFIELD(opc,2,0));
addchar(',');
PRINT_DREG(dbuf,BITFIELD(opc,11,9));
} else if (IS_INST(MULSW,opc) || IS_INST(MULUW,opc)) {
if (IS_INST(MULSW,opc))
addstr(dbuf, "mulsw\t");
else
addstr(dbuf, "muluw\t");
get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_WORD, 0);
addchar(',');
PRINT_DREG(dbuf, BITFIELD(opc,11,9));
} else if (IS_INST(EXG,opc)) {
addstr(dbuf, "exg\t");
if (ISBITSET(opc,7)) {
PRINT_DREG(dbuf,BITFIELD(opc,11,9));
addchar(',');
PRINT_AREG(dbuf,BITFIELD(opc,2,0));
} else if (ISBITSET(opc,3)) {
PRINT_AREG(dbuf,BITFIELD(opc,11,9));
addchar(',');
PRINT_AREG(dbuf,BITFIELD(opc,2,0));
} else {
PRINT_DREG(dbuf,BITFIELD(opc,11,9));
addchar(',');
PRINT_DREG(dbuf,BITFIELD(opc,2,0));
}
} else {
addstr(dbuf, "and");
sz = BITFIELD(opc,7,6);
switch (sz) {
case 0:
addchar('b');
sz = SIZE_BYTE;
break;
case 1:
addchar('w');
sz = SIZE_WORD;
break;
case 2:
addchar('l');
sz = SIZE_LONG;
break;
}
addchar('\t');
if (ISBITSET(opc,8)) {
PRINT_DREG(dbuf, BITFIELD(opc,11,9));
addchar(',');
}
get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 0);
if (!ISBITSET(opc,8)) {
addchar(',');
PRINT_DREG(dbuf, BITFIELD(opc,11,9));
}
}
}
static void
opcode_coproc(dis_buffer_t *dbuf, u_short opc)
{
switch (BITFIELD(*dbuf->val,11,9)) {
case 1:
opcode_fpu(dbuf, opc);
return;
case 0:
opcode_mmu(dbuf, opc);
return;
case 2:
opcode_mmu040(dbuf, opc);
return;
case 3:
opcode_move16(dbuf, opc);
return;
}
switch (BITFIELD(opc,8,6)) {
case 0:
dbuf->used++;
break;
case 3:
dbuf->used++;
case 2:
dbuf->used++;
break;
case 1:
dbuf->used++;
case 4:
case 5:
default:
;
}
addstr(dbuf, "UNKNOWN COPROC OPCODE");
return;
}
static void
opcode_1010(dis_buffer_t *dbuf, u_short opc)
{
addstr(dbuf, "RSVD");
dbuf->used++;
}
static void
opcode_fpu(dis_buffer_t *dbuf, u_short opc)
{
u_short ext;
int type, opmode;
type = BITFIELD(opc,8,6);
switch (type) {
case 0:
ext = *(dbuf->val + 1);
dbuf->used++;
opmode = BITFIELD(ext,5,0);
if (BITFIELD(opc,5,0) == 0 && BITFIELD(ext,15,10) == 0x17) {
addstr(dbuf,"fmovcrx #");
printu(dbuf,BITFIELD(ext,6,0),SIZE_BYTE);
return;
}
if (ISBITSET(ext,15) || ISBITSET(ext,13)) {
opcode_fmove_ext(dbuf, opc, ext);
return;
}
switch(opmode) {
case FMOVE:
get_fpustdGEN(dbuf,ext,"fmov");
return;
case FABS:
get_fpustdGEN(dbuf,ext,"fabs");
return;
case FACOS:
get_fpustdGEN(dbuf,ext,"facos");
return;
case FADD:
get_fpustdGEN(dbuf,ext,"fadd");
return;
case FASIN:
get_fpustdGEN(dbuf,ext,"fasin");
return;
case FATAN:
get_fpustdGEN(dbuf,ext,"fatan");
return;
case FATANH:
get_fpustdGEN(dbuf,ext,"fatanh");
return;
case FCMP:
get_fpustdGEN(dbuf,ext,"fcmp");
return;
case FCOS:
get_fpustdGEN(dbuf,ext,"fcos");
return;
case FCOSH:
get_fpustdGEN(dbuf,ext,"fcosh");
return;
case FDIV:
get_fpustdGEN(dbuf,ext,"fdiv");
return;
case FETOX:
get_fpustdGEN(dbuf,ext,"fetox");
return;
case FGETEXP:
get_fpustdGEN(dbuf,ext,"fgetexp");
return;
case FGETMAN:
get_fpustdGEN(dbuf,ext,"fgetman");
return;
case FINT:
get_fpustdGEN(dbuf,ext,"fint");
return;
case FINTRZ:
get_fpustdGEN(dbuf,ext,"fintrz");
return;
case FLOG10:
get_fpustdGEN(dbuf,ext,"flog10");
return;
case FLOG2:
get_fpustdGEN(dbuf,ext,"flog2");
return;
case FLOGN:
get_fpustdGEN(dbuf,ext,"flogn");
return;
case FLOGNP1:
get_fpustdGEN(dbuf,ext,"flognp1");
return;
case FMOD:
get_fpustdGEN(dbuf,ext,"fmod");
return;
case FMUL:
get_fpustdGEN(dbuf,ext,"fmul");
return;
case FNEG:
get_fpustdGEN(dbuf,ext,"fneg");
return;
case FREM:
get_fpustdGEN(dbuf,ext,"frem");
return;
case FSCALE:
get_fpustdGEN(dbuf,ext,"fscale");
return;
case FSGLDIV:
get_fpustdGEN(dbuf,ext,"fsgldiv");
return;
case FSGLMUL:
get_fpustdGEN(dbuf,ext,"fsglmul");
return;
case FSIN:
get_fpustdGEN(dbuf,ext,"fsin");
return;
case FSINH:
get_fpustdGEN(dbuf,ext,"fsinh");
return;
case FSQRT:
get_fpustdGEN(dbuf,ext,"fsqrt");
return;
case FSUB:
get_fpustdGEN(dbuf,ext,"fsub");
return;
case FTAN:
get_fpustdGEN(dbuf,ext,"ftan");
return;
case FTANH:
get_fpustdGEN(dbuf,ext,"ftanh");
return;
case FTENTOX:
get_fpustdGEN(dbuf,ext,"ftentox");
return;
case FTST:
get_fpustdGEN(dbuf,ext,"ftst");
return;
case FTWOTOX:
get_fpustdGEN(dbuf,ext,"ftwotox");
return;
}
case 2:
if (BITFIELD(opc,5,0) == 0 && *(dbuf->val + 1) == 0) {
dbuf->used++;
addstr (dbuf, "fnop");
return;
}
case 3:
addstr(dbuf, "fb");
print_fcond(dbuf, BITFIELD(opc,5,0));
if (type == 2) {
addchar('w');
addchar('\t');
print_disp(dbuf,*(dbuf->val + 1), SIZE_WORD, -1);
dbuf->used++;
} else {
addchar('l');
addchar('\t');
print_disp(dbuf,*(long *)(dbuf->val + 1), SIZE_LONG,
-1);
dbuf->used += 2;
}
return;
case 1:
ext = *(dbuf->val + 1);
dbuf->used++;
if (BITFIELD(opc,5,3) == 0x1) {
addstr(dbuf,"fdb");
print_fcond(dbuf,BITFIELD(ext,5,0));
addchar('\t');
PRINT_DREG(dbuf, BITFIELD(opc,2,0));
addchar(',');
print_disp(dbuf, *(dbuf->val + 2), SIZE_WORD, -1);
dbuf->used++;
} else if (BITFIELD(opc,5,3) == 0x7 &&
BITFIELD(opc,2,0) > 1) {
addstr(dbuf,"ftrap");
print_fcond(dbuf,BITFIELD(ext,5,0));
if (BITFIELD(opc,2,0) == 0x2) {
addchar('w');
addchar('\t');
dbuf->val++;
get_immed(dbuf, SIZE_WORD);
dbuf->val--;
} else if (BITFIELD(opc,2,0) == 0x3) {
addchar('l');
addchar('\t');
dbuf->val++;
get_immed(dbuf, SIZE_LONG);
dbuf->val--;
}
} else {
addstr(dbuf,"fs");
print_fcond(dbuf,BITFIELD(ext,5,0));
addchar('\t');
get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_BYTE, 1);
}
return;
case 4:
addstr(dbuf,"fsave\t");
get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 0);
return;
case 5:
addstr(dbuf,"frestor\t");
get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 0);
return;
}
}
static void
opcode_fmove_ext(dis_buffer_t *dbuf, u_short opc, u_short ext)
{
int sz;
sz = 0;
if (BITFIELD(ext,15,13) == 3) {
addstr(dbuf, "fmov");
switch (BITFIELD(ext,12,10)) {
case 0:
addchar('l');
sz = SIZE_LONG;
break;
case 1:
addchar('s');
sz = SIZE_SINGLE;
break;
case 2:
addchar('x');
sz = SIZE_EXTENDED;
break;
case 7:
case 3:
addchar('p');
sz = SIZE_PACKED;
break;
case 4:
addchar('w');
sz = SIZE_WORD;
break;
case 5:
addchar('d');
sz = SIZE_DOUBLE;
break;
case 6:
addchar('b');
sz = SIZE_BYTE;
break;
}
addchar('\t');
PRINT_FPREG(dbuf, BITFIELD(ext,9,7));
addchar(',');
get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 1);
if (sz == SIZE_PACKED) {
addchar('{');
if (ISBITSET(ext,12)) {
PRINT_DREG(dbuf,BITFIELD(ext,6,4));
} else {
addchar('#');
prints_bf(dbuf, ext, 6, 4);
}
addchar('}');
}
return;
}
addstr(dbuf,"fmovm");
if (!ISBITSET(ext,14)) {
addchar('l');
addchar('\t');
if (ISBITSET(ext,13)) {
print_freglist(dbuf, AR_DEC, BITFIELD(ext,12,10), 1);
addchar(',');
}
get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_LONG, 1);
if (!ISBITSET(ext,13)) {
addchar(',');
print_freglist(dbuf, AR_DEC, BITFIELD(ext,12,10), 1);
}
return;
}
addchar('x');
addchar('\t');
if (ISBITSET(ext,11)) {
if (ISBITSET(ext,13)) {
PRINT_DREG(dbuf,BITFIELD(ext,6,4));
addchar(',');
}
get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_EXTENDED, 1);
if (!ISBITSET(ext,13)) {
addchar(',');
PRINT_DREG(dbuf,BITFIELD(ext,6,4));
}
} else {
if (ISBITSET(ext,13)) {
print_freglist(dbuf, BITFIELD(opc,5,3),
BITFIELD(ext,7,0), 0);
addchar(',');
}
get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_EXTENDED, 1);
if (!ISBITSET(ext,13)) {
addchar(',');
print_freglist(dbuf, BITFIELD(opc,5,3),
BITFIELD(ext,7,0), 0);
}
}
}
static void
opcode_mmu(dis_buffer_t *dbuf, u_short opc)
{
u_short ext;
int type;
type = BITFIELD(opc,8,6);
switch (type) {
case 0:
ext = *(dbuf->val + 1);
dbuf->used++;
switch(BITFIELD(ext,15,13)) {
case 5:
case 1:
opcode_pflush(dbuf, opc, ext);
return;
case 0:
case 3:
case 2:
opcode_pmove(dbuf, opc, ext);
return;
case 4:
addstr(dbuf, "ptest");
if (ISBITSET(ext,9))
addchar('r');
else
addchar('w');
addchar('\t');
print_fcode(dbuf, BITFIELD(ext, 5, 0));
addchar(',');
get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 1);
addchar(',');
addchar('#');
printu_bf(dbuf, ext, 12, 10);
if (ISBITSET(ext, 8)) {
addchar(',');
PRINT_AREG(dbuf, BITFIELD(ext, 7, 5));
}
}
return;
case 2:
case 3:
addstr(dbuf, "pb");
print_mcond(dbuf, BITFIELD(opc,5,0));
if (type == 2) {
addchar('w');
addchar('\t');
print_disp(dbuf,*(dbuf->val + 1), SIZE_WORD, -1);
dbuf->used++;
} else {
addchar('l');
addchar('\t');
print_disp(dbuf,*(long *)(dbuf->val + 1), SIZE_LONG,
-1);
dbuf->used += 2;
}
return;
case 1:
ext = *(dbuf->val + 1);
dbuf->used++;
if (BITFIELD(opc,5,3) == 0x1) {
addstr(dbuf,"pdb");
print_fcond(dbuf,BITFIELD(ext,5,0));
addchar('\t');
PRINT_DREG(dbuf, BITFIELD(opc,2,0));
addchar(',');
print_disp(dbuf, *(dbuf->val + 2), SIZE_WORD, -1);
dbuf->used++;
} else if (BITFIELD(opc,5,3) == 0x7 &&
BITFIELD(opc,2,0) > 1) {
addstr(dbuf,"ptrap");
print_fcond(dbuf,BITFIELD(ext,5,0));
if (BITFIELD(opc,2,0) == 0x2) {
addchar('w');
addchar('\t');
dbuf->val++;
get_immed(dbuf, SIZE_WORD);
dbuf->val--;
} else if (BITFIELD(opc,2,0) == 0x3) {
addchar('l');
addchar('\t');
dbuf->val++;
get_immed(dbuf, SIZE_LONG);
dbuf->val--;
}
} else {
addstr(dbuf,"ps");
print_fcond(dbuf,BITFIELD(ext,5,0));
addchar('\t');
get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_BYTE, 1);
}
return;
case 4:
addstr(dbuf,"psave\t");
get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 0);
return;
case 5:
addstr(dbuf,"prestore\t");
get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 0);
return;
}
}
static void
opcode_pflush(dis_buffer_t *dbuf, u_short opc, u_short ext)
{
u_short mode, mask, fc;
mode = BITFIELD(ext,12,10);
mask = BITFIELD(ext,8,5);
fc = BITFIELD(ext, 5, 0);
if (ext == 0xa000) {
addstr(dbuf,"pflushr\t");
get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_LONG, 1);
return;
}
if (mode == 0) {
addstr(dbuf,"pload");
if (ISBITSET(ext,9))
addchar('r');
else
addchar('w');
addchar(' ');
print_fcode(dbuf, fc);
}
addstr(dbuf,"pflush");
switch (mode) {
case 1:
addchar('a');
*dbuf->casm = 0;
break;
case 7:
case 5:
addchar('s');
case 6:
case 4:
addchar('\t');
print_fcode(dbuf, fc);
addchar(',');
addchar('#');
printu(dbuf, mask, SIZE_BYTE);
if (!ISBITSET(mode,1))
break;
addchar(',');
get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_LONG, 1);
}
}
static void
opcode_pmove(dis_buffer_t *dbuf, u_short opc, u_short ext)
{
const char *reg;
int rtom, sz, preg;
reg = "???";
sz = 0;
rtom = ISBITSET(ext, 9);
preg = BITFIELD(ext, 12, 10);
addstr(dbuf,"pmov");
if (ISBITSET(ext,8)) {
addchar('f');
addchar('d');
}
switch (BITFIELD(ext, 15, 13)) {
case 0:
switch (preg) {
case 2:
reg = "tt0";
break;
case 3:
reg = "tt1";
break;
}
sz = SIZE_LONG;
break;
case 2:
switch (preg) {
case 0:
reg = "tc";
sz = SIZE_LONG;
break;
case 1:
reg = "drp";
sz = SIZE_QUAD;
break;
case 2:
reg = "srp";
sz = SIZE_QUAD;
break;
case 3:
reg = "crp";
sz = SIZE_QUAD;
break;
case 4:
reg = "cal";
sz = SIZE_BYTE;
break;
case 5:
reg = "val";
sz = SIZE_BYTE;
break;
case 6:
reg = "scc";
sz = SIZE_BYTE;
break;
case 7:
reg = "ac";
sz = SIZE_WORD;
}
break;
case 3:
switch (preg) {
case 0:
reg = "mmusr";
break;
case 1:
reg = "pcsr";
break;
case 4:
reg = "bad";
break;
case 5:
reg = "bac";
break;
}
sz = SIZE_WORD;
break;
}
switch (sz) {
case SIZE_BYTE:
addchar ('b');
break;
case SIZE_WORD:
addchar ('w');
break;
case SIZE_LONG:
addchar ('l');
break;
case SIZE_QUAD:
addchar ('d');
break;
}
addchar('\t');
if (!rtom) {
get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 1);
addchar(',');
}
addstr(dbuf, reg);
if (BITFIELD(ext, 15, 13) == 3 && preg > 1)
printu_bf(dbuf, ext, 4, 2);
if (rtom) {
addchar(',');
get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 1);
}
return;
}
static void
print_fcode(dis_buffer_t *dbuf, u_short fc)
{
if (ISBITSET(fc, 4))
printu_bf(dbuf, fc, 3, 0);
else if (ISBITSET(fc, 3))
PRINT_DREG(dbuf, BITFIELD(fc, 2, 0));
else if (fc == 1)
addstr(dbuf, "sfc");
else
addstr(dbuf, "dfc");
}
static void
opcode_mmu040(dis_buffer_t *dbuf, u_short opc)
{
if (ISBITSET(opc, 6)) {
addstr(dbuf, "ptest");
if (ISBITSET(opc, 5))
addchar('r');
else
addchar('w');
addchar('\t');
PRINT_AREG(dbuf, BITFIELD(opc,2,0));
addchar('@');
} else {
addstr(dbuf, "pflush");
switch (BITFIELD(opc, 4, 3)) {
case 3:
addchar('a');
break;
case 2:
addchar('a');
addchar('n');
break;
case 0:
addchar('n');
case 1:
addchar('\t');
PRINT_AREG(dbuf, BITFIELD(opc,2,0));
addchar('@');
break;
}
}
*dbuf->casm = 0;
}
static void
opcode_divmul(dis_buffer_t *dbuf, u_short opc)
{
u_short ext;
int iq, hr;
ext = *(dbuf->val + 1);
dbuf->used++;
iq = BITFIELD(ext,14,12);
hr = BITFIELD(ext,2,0);
if (IS_INST(DIVSL,opc))
addstr(dbuf, "div");
else
addstr(dbuf, "mul");
if (ISBITSET(ext,11))
addchar('s');
else
addchar('u');
addchar('l');
if (IS_INST(DIVSL,opc) && !ISBITSET(ext,10) && iq != hr)
addchar('l');
addchar('\t');
get_modregstr(dbuf,5,GETMOD_BEFORE,SIZE_LONG,1);
addchar(',');
if (ISBITSET(ext,10) ||
(iq != hr && IS_INST(DIVSL,opc))) {
PRINT_DREG(dbuf, hr);
if (dbuf->mit)
addchar(',');
else
addchar(':');
}
PRINT_DREG(dbuf, iq);
}
static void
print_reglist(dis_buffer_t *dbuf, int mod, u_short rl)
{
static const char *const regs[16] = {
"d0","d1","d2","d3","d4","d5","d6","d7",
"a0","a1","a2","a3","a4","a5","a6","a7" };
int bit, list;
if (mod == AR_DEC) {
list = rl;
rl = 0;
for (bit = 0; bit < 16; bit++)
if (list & (1 << bit))
rl |= (0x8000 >> bit);
}
for (bit = 0, list = 0; bit < 16; bit++) {
if (ISBITSET(rl,bit) && bit != 8) {
if (list == 0) {
list = 1;
addstr(dbuf, regs[bit]);
} else if (list == 1) {
list++;
addchar('-');
}
} else {
if (list) {
if (list > 1)
addstr(dbuf, regs[bit-1]);
addchar('/');
list = 0;
}
if (ISBITSET(rl,bit)) {
addstr(dbuf, regs[bit]);
list = 1;
}
}
}
if (list > 1)
addstr(dbuf, regs[15]);
if (dbuf->casm[-1] == '/' || dbuf->casm[-1] == '-')
dbuf->casm--;
*dbuf->casm = 0;
}
static void
print_freglist(dis_buffer_t *dbuf, int mod, u_short rl, int cntl)
{
const char *const * regs;
int bit, list, upper;
regs = cntl ? fpcregs : fpregs;
upper = cntl ? 3 : 8;
if (!cntl && mod != AR_DEC) {
list = rl;
rl = 0;
for (bit = 0; bit < upper; bit++)
if (list & (1 << bit))
rl |= (0x80 >> bit);
}
for (bit = 0, list = 0; bit < upper; bit++) {
if (ISBITSET(rl,bit)) {
if (list == 0) {
addstr(dbuf, regs[bit]);
if (cntl)
addchar('/');
else
list = 1;
} else if (list == 1) {
list++;
addchar('-');
}
} else {
if (list) {
if (list > 1)
addstr(dbuf, regs[bit-1]);
addchar('/');
list = 0;
}
}
}
if (list > 1)
addstr(dbuf, regs[upper-1]);
if (dbuf->casm[-1] == '/' || dbuf->casm[-1] == '-')
dbuf->casm--;
*dbuf->casm = 0;
}
static void
opcode_movem(dis_buffer_t *dbuf, u_short opc)
{
u_short rl;
rl = *(dbuf->val + 1);
dbuf->used++;
if (ISBITSET(opc,6))
addstr(dbuf, "movml\t");
else
addstr(dbuf, "movmw\t");
if (ISBITSET(opc,10)) {
get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 1);
addchar(',');
print_reglist(dbuf, BITFIELD(opc,5,3), rl);
} else {
print_reglist(dbuf, BITFIELD(opc,5,3), rl);
addchar(',');
get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 1);
}
}
static void
opcode_movec(dis_buffer_t *dbuf, u_short opc)
{
const char *tmp;
u_short ext;
ext = *(dbuf->val + 1);
dbuf->used++;
addstr(dbuf, "movc\t");
if (ISBITSET(opc,0)) {
dbuf->val++;
if (ISBITSET(ext,15))
get_modregstr(dbuf,14,AR_DIR,0,0);
else
get_modregstr(dbuf,14,DR_DIR,0,0);
dbuf->val--;
addchar(',');
}
switch (BITFIELD(ext,11,0)) {
case 0x000:
tmp = "sfc";
break;
case 0x001:
tmp = "dfc";
break;
case 0x800:
tmp = "usp";
break;
case 0x801:
tmp = "vbr";
break;
case 0x802:
tmp = "caar";
break;
case 0x002:
tmp = "cacr";
break;
case 0x803:
tmp = "msp";
break;
case 0x804:
tmp = "isp";
break;
case 0x003:
tmp = "tc";
break;
case 0x004:
tmp = "itt0";
break;
case 0x005:
tmp = "itt1";
break;
case 0x006:
tmp = "dtt0";
break;
case 0x007:
tmp = "dtt1";
break;
case 0x805:
tmp = "mmusr";
break;
case 0x806:
tmp = "urp";
break;
case 0x807:
tmp = "srp";
break;
case 0x008:
tmp = "buscr";
break;
case 0x808:
tmp = "pcr";
break;
default:
tmp = "INVALID";
break;
}
addstr(dbuf, tmp);
if (!ISBITSET(opc,0)) {
dbuf->val++;
addchar(',');
if (ISBITSET(ext,15))
get_modregstr(dbuf,14,AR_DIR,0,0);
else
get_modregstr(dbuf,14,DR_DIR,0,0);
dbuf->val--;
}
}
static void
opcode_move16(dis_buffer_t *dbuf, u_short opc)
{
u_short ext;
addstr(dbuf, "move16\t");
if (ISBITSET(opc, 5)) {
PRINT_AREG(dbuf, BITFIELD(opc,2,0));
addstr(dbuf, "@+,");
ext = *(dbuf->val + 1);
PRINT_AREG(dbuf, BITFIELD(ext,14,12));
addstr(dbuf, "@+");
dbuf->used++;
} else {
switch (BITFIELD(opc,4,3)) {
case 0:
PRINT_AREG(dbuf, BITFIELD(opc,2,0));
addstr(dbuf, "@+,");
get_immed(dbuf, SIZE_LONG);
break;
case 1:
get_immed(dbuf, SIZE_LONG);
addchar(',');
PRINT_AREG(dbuf, BITFIELD(opc,2,0));
addstr(dbuf, "@+");
break;
case 2:
PRINT_AREG(dbuf, BITFIELD(opc,2,0));
addstr(dbuf, "@,");
get_immed(dbuf, SIZE_LONG);
break;
case 3:
get_immed(dbuf, SIZE_LONG);
addchar(',');
PRINT_AREG(dbuf, BITFIELD(opc,2,0));
addchar('@');
break;
}
}
}
static void
addstr(dis_buffer_t *dbuf, const char *s)
{
while ((*dbuf->casm++ = *s++))
;
dbuf->casm--;
}
static void
iaddstr(dis_buffer_t *dbuf, const char *s)
{
while ((*dbuf->cinfo++ = *s++))
;
dbuf->cinfo--;
}
static void
get_modregstr_moto(dis_buffer_t *dbuf, int bit, int mod, int sz, int dd)
{
u_char scale, idx;
const short *nval;
u_short ext;
int disp, odisp, bd, od, reg;
odisp = 0;
if (mod != GETMOD_BEFORE && mod != GETMOD_AFTER)
reg = BITFIELD(*dbuf->val, bit, bit-2);
else if (mod == GETMOD_BEFORE) {
mod = BITFIELD(*dbuf->val, bit, bit-2);
reg = BITFIELD(*dbuf->val, bit-3, bit-5);
} else {
reg = BITFIELD(*dbuf->val, bit, bit-2);
mod = BITFIELD(*dbuf->val, bit-3, bit-5);
}
switch (mod) {
case DR_DIR:
case AR_DIR:
if (mod == DR_DIR)
PRINT_DREG(dbuf, reg);
else
PRINT_AREG(dbuf, reg);
break;
case AR_DIS:
print_disp(dbuf, *(dbuf->val + 1 + dd), SIZE_WORD,reg);
dbuf->used++;
case AR_IND:
case AR_INC:
case AR_DEC:
if (mod == AR_DEC)
addchar('-');
addchar('(');
PRINT_AREG(dbuf, reg);
addchar(')');
if (mod == AR_INC)
addchar('+');
break;
case MOD_SPECIAL:
if (reg == 0) {
print_addr(dbuf, *(dbuf->val + 1 + dd));
dbuf->used++;
addchar('.');
addchar('w');
break;
} else if (reg == 1) {
print_addr(dbuf, *(u_long *)(dbuf->val + 1 + dd));
dbuf->used += 2;
addchar('.');
addchar('l');
break;
} else if (reg == 2) {
dbuf->used++;
print_disp(dbuf, *(dbuf->val + 1 + dd), SIZE_WORD,
-1);
addstr(dbuf,"(pc)");
break;
} else if (reg == 4) {
if (sz == SIZE_BYTE) {
addchar('#');
prints(dbuf,
*((char *)dbuf->val + 3+ (dd * 2)), sz);
dbuf->used++;
} else if (sz == SIZE_WORD) {
addchar('#');
prints(dbuf, *(dbuf->val + 1 + dd), sz);
dbuf->used++;
} else if (sz == SIZE_LONG) {
addchar('#');
prints(dbuf, *(long *)(dbuf->val + 1 + dd),
sz);
dbuf->used += 2;
} else if (sz == SIZE_QUAD) {
dbuf->used += 4;
addstr(dbuf,"#<quad>");
} else if (sz == SIZE_SINGLE) {
dbuf->used += 2;
addstr(dbuf,"#<single>");
} else if (sz == SIZE_DOUBLE) {
dbuf->used += 4;
addstr(dbuf,"#<double>");
} else if (sz == SIZE_PACKED) {
dbuf->used += 6;
addstr(dbuf,"#<packed>");
} else if (sz == SIZE_EXTENDED) {
dbuf->used += 6;
addstr(dbuf,"#<extended>");
}
break;
}
case AR_IDX:
ext = *(dbuf->val + 1 + dd);
dbuf->used++;
nval = dbuf->val + 2 + dd;
scale = BITFIELD(ext,10,9);
idx = BITFIELD(ext,14,12);
if (ISBITSET(ext,8)) {
bd = BITFIELD(ext,5,4);
od = BITFIELD(ext,1,0);
if (bd == 1)
disp = 0;
else if (bd == 2) {
dbuf->used++;
disp = *nval++;
} else {
dbuf->used += 2;
disp = *(const long *)nval;
nval += 2;
}
if (od == 1)
odisp = 0;
else if (od == 2) {
dbuf->used++;
odisp = *nval++;
} else if (od == 3) {
dbuf->used += 2;
odisp = *(const long *)nval;
nval += 2;
}
} else {
od = 0;
bd = 0;
disp = (char)BITFIELD(ext,7,0);
}
addchar('(');
if (od)
addchar('[');
prints(dbuf, disp,
bd == 2 ? SIZE_WORD :
bd == 3 ? SIZE_LONG :
SIZE_BYTE);
addchar(',');
if (bd && ISBITSET(ext,7)) {
addchar('z');
if (mod != MOD_SPECIAL)
PRINT_AREG(dbuf,reg);
else {
addchar('p');
addchar('c');
}
} else if (mod == AR_IDX)
PRINT_AREG(dbuf, reg);
else {
addchar('p');
addchar('c');
}
if (od && ISBITSET(ext,2))
addchar(']');
addchar(',');
if (bd && ISBITSET(ext,6))
addchar('0');
else {
if (0x8000 & ext)
PRINT_AREG(dbuf, idx);
else
PRINT_DREG(dbuf, idx);
addchar('.');
addchar(0x800 & ext ? 'l' : 'w');
if (scale) {
addchar('*');
addchar('0' + (1 << scale));
}
}
if (od) {
if (!ISBITSET(ext,2))
addchar(']');
addchar(',');
prints(dbuf, odisp,
od == 2 ? SIZE_WORD :
od == 3 ? SIZE_LONG :
SIZE_BYTE);
}
addchar(')');
break;
}
*dbuf->casm = 0;
}
static void
get_modregstr_mit(dis_buffer_t *dbuf, int bit, int mod, int sz, int dd)
{
u_char scale, idx;
const short *nval;
u_short ext;
int disp, odisp, bd, od, reg;
disp = odisp = 0;
if (mod != GETMOD_BEFORE && mod != GETMOD_AFTER)
reg = BITFIELD(*dbuf->val, bit, bit-2);
else if (mod == GETMOD_BEFORE) {
mod = BITFIELD(*dbuf->val, bit, bit-2);
reg = BITFIELD(*dbuf->val, bit-3, bit-5);
} else {
reg = BITFIELD(*dbuf->val, bit, bit-2);
mod = BITFIELD(*dbuf->val, bit-3, bit-5);
}
switch (mod) {
case DR_DIR:
case AR_DIR:
if (mod == DR_DIR)
PRINT_DREG(dbuf, reg);
else
PRINT_AREG(dbuf, reg);
break;
case AR_DIS:
dbuf->used++;
disp = *(dbuf->val + 1 + dd);
case AR_IND:
case AR_INC:
case AR_DEC:
PRINT_AREG(dbuf, reg);
addchar('@' );
if (mod == AR_DEC)
addchar('-');
else if (mod == AR_INC)
addchar('+');
else if (mod == AR_DIS) {
addchar('(');
print_disp(dbuf, disp, SIZE_WORD, reg);
addchar(')');
}
break;
case MOD_SPECIAL:
if (reg == 0) {
print_addr(dbuf, *(dbuf->val + 1 + dd));
dbuf->used++;
break;
} else if (reg == 1) {
print_addr(dbuf, *(u_long *)(dbuf->val + 1 + dd));
dbuf->used += 2;
break;
} else if (reg == 2) {
addstr(dbuf,"pc@(");
print_disp(dbuf, *(dbuf->val + 1 + dd), SIZE_WORD, -1);
dbuf->used++;
addchar(')');
break;
} else if (reg == 4) {
if (sz == SIZE_BYTE) {
addchar('#');
prints(dbuf,
*((char *)dbuf->val + 3 + (dd * 2)), sz);
dbuf->used++;
} else if (sz == SIZE_WORD) {
addchar('#');
prints(dbuf, *(dbuf->val + 1 + dd), sz);
dbuf->used++;
} else if (sz == SIZE_LONG) {
addchar('#');
prints(dbuf, *(long *)(dbuf->val + 1 + dd),
sz);
dbuf->used += 2;
} else if (sz == SIZE_QUAD) {
dbuf->used += 4;
addstr(dbuf,"#<quad>");
} else if (sz == SIZE_SINGLE) {
dbuf->used += 2;
addstr(dbuf,"#<single>");
} else if (sz == SIZE_DOUBLE) {
dbuf->used += 4;
addstr(dbuf,"#<double>");
} else if (sz == SIZE_PACKED) {
dbuf->used += 6;
addstr(dbuf,"#<packed>");
} else if (sz == SIZE_EXTENDED) {
dbuf->used += 6;
addstr(dbuf,"#<extended>");
}
break;
}
case AR_IDX:
dbuf->used++;
ext = *(dbuf->val + 1 + dd);
nval = dbuf->val + 2 + dd;
scale = BITFIELD(ext,10,9);
idx = BITFIELD(ext,14,12);
if (ISBITSET(ext,8)) {
bd = BITFIELD(ext,5,4);
od = BITFIELD(ext,1,0);
if (bd == 1)
disp = 0;
else if (bd == 2) {
dbuf->used++;
disp = *nval++;
} else {
dbuf->used += 2;
disp = *(const long *)nval;
nval += 2;
}
if (od == 1)
odisp = 0;
else if (od == 2) {
dbuf->used++;
odisp = *nval++;
} else if (od == 3) {
dbuf->used += 2;
odisp = *(const long *)nval;
nval += 2;
}
} else {
od = 0;
bd = 0;
disp = (char)BITFIELD(ext,7,0);
}
if (mod == AR_IDX && (!bd || !ISBITSET(ext,7)))
PRINT_AREG(dbuf, reg);
else if (mod == MOD_SPECIAL && ISBITSET(ext,7)) {
addchar('z');
addchar('p');
addchar('c');
} else if (mod == MOD_SPECIAL) {
addchar('p');
addchar('c');
}
addchar('@');
addchar('(');
if (bd && bd != 1) {
prints(dbuf, disp,
bd == 2 ? SIZE_WORD :
bd == 3 ? SIZE_LONG :
SIZE_BYTE);
if (od && !ISBITSET(ext,6) && !ISBITSET(ext,2))
addchar(',');
else if (od && ISBITSET(ext,2)) {
addchar(')');
addchar('@');
addchar('(');
} else if (!od)
addchar(',');
} else if (!bd) {
prints(dbuf, disp,
bd == 2 ? SIZE_WORD :
bd == 3 ? SIZE_LONG :
SIZE_BYTE);
addchar(',');
}
if (od && ISBITSET(ext,2)) {
if (od != 1) {
prints(dbuf, odisp,
od == 2 ? SIZE_WORD :
od == 3 ? SIZE_LONG :
SIZE_BYTE);
addchar(',');
}
}
if (!bd || !ISBITSET(ext,6)) {
if (ISBITSET(ext,15))
PRINT_AREG(dbuf,idx);
else
PRINT_DREG(dbuf,idx);
addchar(':');
addchar(ISBITSET(ext,11) ? 'l' : 'w');
if (scale) {
addchar(':');
addchar('0' + (1 << scale));
}
}
if (od && !ISBITSET(ext,2)) {
if (od != 1) {
addchar(')');
addchar('@');
addchar('(');
prints(dbuf, odisp,
od == 2 ? SIZE_WORD :
od == 3 ? SIZE_LONG :
SIZE_BYTE);
}
}
addchar(')');
break;
}
*dbuf->casm = 0;
}
static void
get_modregstr(dis_buffer_t *dbuf, int bit, int mod, int sz, int dispdisp)
{
if (dbuf->mit)
get_modregstr_mit(dbuf,bit,mod,sz,dispdisp);
else
get_modregstr_moto(dbuf,bit,mod,sz,dispdisp);
}
static void
make_cond(dis_buffer_t *dbuf, int bit, const char *base)
{
int cc;
const char *ccs;
cc = BITFIELD(*dbuf->val,bit,bit-3);
ccs = cc_table[cc&15];
addstr(dbuf, base);
addstr(dbuf, ccs);
}
static void
print_fcond(dis_buffer_t *dbuf, char cp)
{
addstr(dbuf,fpcc_table[cp&31]);
}
static void
print_mcond(dis_buffer_t *dbuf, char cp)
{
addstr(dbuf,mmcc_table[cp&15]);
}
static void
get_immed(dis_buffer_t *dbuf,int sz)
{
addchar('#');
switch (sz) {
case SIZE_BYTE:
prints(dbuf, BITFIELD(*(dbuf->val + 1),7,0), SIZE_BYTE);
dbuf->used++;
break;
case SIZE_WORD:
prints(dbuf, *(dbuf->val + 1), SIZE_WORD);
dbuf->used++;
break;
case SIZE_LONG:
prints(dbuf, *(long *)(dbuf->val + 1), SIZE_LONG);
dbuf->used += 2;
break;
}
return;
}
static void
get_fpustdGEN(dis_buffer_t *dbuf, u_short ext, const char *name)
{
int sz;
sz = 0;
addchar(*name++);
if (ISBITSET(ext,7)) {
if(ISBITSET(ext,2))
addchar('d');
else
addchar('s');
}
addstr(dbuf,name);
if (ISBITSET(ext,14)) {
switch (BITFIELD(ext,12,10)) {
case 0:
addchar('l');
sz = SIZE_LONG;
break;
case 1:
addchar('s');
sz = SIZE_SINGLE;
break;
case 2:
addchar('x');
sz = SIZE_EXTENDED;
break;
case 3:
addchar('p');
sz = SIZE_PACKED;
break;
case 4:
addchar('w');
sz = SIZE_WORD;
break;
case 5:
addchar('d');
sz = SIZE_DOUBLE;
break;
case 6:
addchar('b');
sz = SIZE_BYTE;
break;
}
addchar('\t');
get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 1);
if (BITFIELD(ext,6,3) == 6) {
addchar(',');
PRINT_FPREG(dbuf, BITFIELD(ext,2,0));
addchar(':');
PRINT_FPREG(dbuf, BITFIELD(ext,9,7));
} else if (BITFIELD(ext,5,0) != FTST) {
addchar(',');
PRINT_FPREG(dbuf, BITFIELD(ext,9,7));
}
} else {
addchar('x');
addchar('\t');
PRINT_FPREG(dbuf, BITFIELD(ext,12,10));
if (BITFIELD(ext,6,3) == 6) {
addchar(',');
PRINT_FPREG(dbuf, BITFIELD(ext,2,0));
addchar(':');
PRINT_FPREG(dbuf, BITFIELD(ext,9,7));
} else if (BITFIELD(ext,5,0) != FTST) {
addchar(',');
PRINT_FPREG(dbuf, BITFIELD(ext,9,7));
}
}
}
#if 0
static u_long
get_areg_val(int reg)
{
return 0;
}
#endif
static void
print_disp(dis_buffer_t *dbuf, int disp, int sz, int rel)
{
db_expr_t diff;
db_sym_t sym;
const char *symname;
u_long nv;
prints(dbuf, disp, sz);
if (rel == -1)
nv = disp + (u_int)dbuf->val + 2;
else
return;
diff = INT_MAX;
symname = NULL;
sym = db_search_symbol(nv, DB_STGY_PROC, &diff);
db_symbol_values(sym, &symname, 0);
if (symname) {
iaddstr(dbuf, "disp:");
iaddstr(dbuf, symname);
iaddchar('+');
iprintu(dbuf, diff, SIZE_LONG);
iaddchar(' ');
*dbuf->cinfo = 0;
}
}
static void
print_addr(dis_buffer_t *dbuf, u_long addr)
{
db_expr_t diff;
db_sym_t sym;
const char *symname;
diff = INT_MAX;
symname = NULL;
sym = db_search_symbol(addr, DB_STGY_ANY, &diff);
db_symbol_values(sym, &symname, 0);
if (symname) {
if (diff == 0)
addstr(dbuf,symname);
else {
addchar('<');
addstr(dbuf,symname);
addchar('+');
printu(dbuf, diff, SIZE_LONG);
addchar('>');
*dbuf->casm = 0;
}
iaddstr(dbuf,"addr:");
iprintu(dbuf, addr, SIZE_LONG);
iaddchar(' ');
*dbuf->cinfo = 0;
} else {
printu(dbuf, addr, SIZE_LONG);
}
}
static void
prints(dis_buffer_t *dbuf, int val, int sz)
{
extern int db_radix;
if (val == 0) {
dbuf->casm[0] = '0';
dbuf->casm[1] = 0;
} else if (sz == SIZE_BYTE)
prints_wb(dbuf, (char)val, sz, db_radix);
else if (sz == SIZE_WORD)
prints_wb(dbuf, (short)val, sz, db_radix);
else
prints_wb(dbuf, (long)val, sz, db_radix);
dbuf->casm = &dbuf->casm[strlen(dbuf->casm)];
}
#if 0
static void
iprints(dis_buffer_t *dbuf, int val, int sz)
{
extern int db_radix;
if (val == 0) {
dbuf->cinfo[0] = '0';
dbuf->cinfo[1] = 0;
} else if (sz == SIZE_BYTE)
iprints_wb(dbuf, (char)val, sz, db_radix);
else if (sz == SIZE_WORD)
iprints_wb(dbuf, (short)val, sz, db_radix);
else
iprints_wb(dbuf, (long)val, sz, db_radix);
dbuf->cinfo = &dbuf->cinfo[strlen(dbuf->cinfo)];
}
#endif
static void
printu(dis_buffer_t *dbuf, u_int val, int sz)
{
extern int db_radix;
if (val == 0) {
dbuf->casm[0] = '0';
dbuf->casm[1] = 0;
} else if (sz == SIZE_BYTE)
printu_wb(dbuf, (u_char)val, sz, db_radix);
else if (sz == SIZE_WORD)
printu_wb(dbuf, (u_short)val, sz, db_radix);
else
printu_wb(dbuf, (u_long)val, sz, db_radix);
dbuf->casm = &dbuf->casm[strlen(dbuf->casm)];
}
static void
iprintu(dis_buffer_t *dbuf, u_int val, int sz)
{
extern int db_radix;
if (val == 0) {
dbuf->cinfo[0] = '0';
dbuf->cinfo[1] = 0;
} else if (sz == SIZE_BYTE)
iprintu_wb(dbuf, (u_char)val, sz, db_radix);
else if (sz == SIZE_WORD)
iprintu_wb(dbuf, (u_short)val, sz, db_radix);
else
iprintu_wb(dbuf, (u_long)val, sz, db_radix);
dbuf->cinfo = &dbuf->cinfo[strlen(dbuf->cinfo)];
}
static void
printu_wb(dis_buffer_t *dbuf, u_int val, int sz, int base)
{
static char buf[sizeof(long) * NBBY / 3 + 2];
char *p, ch;
if (base != 10) {
addchar('0');
if (base != 8) {
base = 16;
addchar('x');
}
}
p = buf;
do {
*++p = hexdigits[val % base];
} while (val /= base);
while ((ch = *p--))
addchar(ch);
*dbuf->casm = 0;
}
static void
prints_wb(dis_buffer_t *dbuf, int val, int sz, int base)
{
if (val < 0) {
addchar('-');
val = -val;
}
printu_wb(dbuf, val, sz, base);
}
static void
iprintu_wb(dis_buffer_t *dbuf, u_int val, int sz, int base)
{
static char buf[sizeof(long) * NBBY / 3 + 2];
char *p, ch;
if (base != 10) {
iaddchar('0');
if (base != 8) {
base = 16;
iaddchar('x');
}
}
p = buf;
do {
*++p = hexdigits[val % base];
} while (val /= base);
while ((ch = *p--))
iaddchar(ch);
*dbuf->cinfo = 0;
}
#if 0
static void
iprints_wb(dis_buffer_t *dbuf, int val, int sz, int base)
{
if (val < 0) {
iaddchar('-');
val = -val;
}
iprintu_wb(dbuf, val, sz, base);
}
#endif
static void
prints_bf(dis_buffer_t *dbuf, int val, int sb, int eb)
{
if (ISBITSET(val,sb))
val = (~0 & ~BITFIELD(~0, sb, eb)) | BITFIELD(val, sb, eb);
else
val = BITFIELD(val,sb,eb);
prints(dbuf, val, SIZE_LONG);
}
static void
printu_bf(dis_buffer_t *dbuf, u_int val, int sb, int eb)
{
printu(dbuf,BITFIELD(val,sb,eb),SIZE_LONG);
}