Home | History | Annotate | Line # | Download | only in disasm
disasm_format.c revision 1.3
      1  1.3  christos /*	$NetBSD: disasm_format.c,v 1.3 2014/03/27 18:22:56 christos Exp $	*/
      2  1.1    cherry 
      3  1.1    cherry /*-
      4  1.1    cherry  * Copyright (c) 2000-2003 Marcel Moolenaar
      5  1.1    cherry  * All rights reserved.
      6  1.1    cherry  *
      7  1.1    cherry  * Redistribution and use in source and binary forms, with or without
      8  1.1    cherry  * modification, are permitted provided that the following conditions
      9  1.1    cherry  * are met:
     10  1.1    cherry  *
     11  1.1    cherry  * 1. Redistributions of source code must retain the above copyright
     12  1.1    cherry  *    notice, this list of conditions and the following disclaimer.
     13  1.1    cherry  * 2. Redistributions in binary form must reproduce the above copyright
     14  1.1    cherry  *    notice, this list of conditions and the following disclaimer in the
     15  1.1    cherry  *    documentation and/or other materials provided with the distribution.
     16  1.1    cherry  *
     17  1.1    cherry  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18  1.1    cherry  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19  1.1    cherry  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20  1.1    cherry  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21  1.1    cherry  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22  1.1    cherry  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23  1.1    cherry  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24  1.1    cherry  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  1.1    cherry  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26  1.1    cherry  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  1.1    cherry  */
     28  1.1    cherry 
     29  1.1    cherry #include "opt_ddb.h"
     30  1.1    cherry 
     31  1.1    cherry #include <sys/cdefs.h>
     32  1.1    cherry /* __FBSDID("$FreeBSD: src/sys/ia64/disasm/disasm_format.c,v 1.2 2005/01/06 22:18:22 imp Exp $"); */
     33  1.1    cherry 
     34  1.1    cherry #include <sys/param.h>
     35  1.1    cherry #include <sys/systm.h>
     36  1.1    cherry 
     37  1.1    cherry #ifdef DDB
     38  1.1    cherry 
     39  1.1    cherry #include <ia64/disasm/disasm_int.h>
     40  1.1    cherry #include <ia64/disasm/disasm.h>
     41  1.1    cherry 
     42  1.1    cherry /*
     43  1.1    cherry  * Mnemonics (keep in sync with enum asm_op).
     44  1.1    cherry  */
     45  1.1    cherry static const char *asm_mnemonics[] = {
     46  1.1    cherry 	"",
     47  1.1    cherry 	"add", "addl", "addp4", "adds", "alloc", "and", "andcm",
     48  1.1    cherry 	"br", "break", "brl", "brp", "bsw",
     49  1.1    cherry 	"chk", "clrrrb", "cmp", "cmp4", "cmp8xchg16", "cmpxchg1", "cmpxchg2",
     50  1.1    cherry 	"cmpxchg4", "cmpxchg8", "cover", "czx1", "czx2",
     51  1.1    cherry 	"dep",
     52  1.1    cherry 	"epc", "extr",
     53  1.1    cherry 	"famax", "famin", "fand", "fandcm", "fc", "fchkf", "fclass", "fclrf",
     54  1.1    cherry 	"fcmp", "fcvt", "fetchadd4", "fetchadd8", "flushrs", "fma", "fmax",
     55  1.1    cherry 	"fmerge", "fmin", "fmix", "fms", "fnma", "for", "fpack", "fpamax",
     56  1.1    cherry 	"fpamin", "fpcmp", "fpcvt", "fpma", "fpmax", "fpmerge", "fpmin",
     57  1.1    cherry 	"fpms", "fpnma", "fprcpa", "fprsqrta", "frcpa", "frsqrta", "fselect",
     58  1.1    cherry 	"fsetc", "fswap", "fsxt", "fwb", "fxor",
     59  1.1    cherry 	"getf",
     60  1.1    cherry 	"invala", "itc", "itr",
     61  1.1    cherry 	"ld1", "ld16", "ld2", "ld4", "ld8", "ldf", "ldf8", "ldfd", "ldfe",
     62  1.1    cherry 	"ldfp8", "ldfpd", "ldfps", "ldfs", "lfetch", "loadrs",
     63  1.1    cherry 	"mf", "mix1", "mix2", "mix4", "mov", "movl", "mux1", "mux2",
     64  1.1    cherry 	"nop",
     65  1.1    cherry 	"or",
     66  1.1    cherry 	"pack2", "pack4", "padd1", "padd2", "padd4", "pavg1", "pavg2",
     67  1.1    cherry 	"pavgsub1", "pavgsub2", "pcmp1", "pcmp2", "pcmp4", "pmax1", "pmax2",
     68  1.1    cherry 	"pmin1", "pmin2", "pmpy2", "pmpyshr2", "popcnt", "probe", "psad1",
     69  1.1    cherry 	"pshl2", "pshl4", "pshladd2", "pshr2", "pshr4", "pshradd2", "psub1",
     70  1.1    cherry 	"psub2", "psub4", "ptc", "ptr",
     71  1.1    cherry 	"rfi", "rsm", "rum",
     72  1.1    cherry 	"setf", "shl", "shladd", "shladdp4", "shr", "shrp", "srlz", "ssm",
     73  1.1    cherry 	"st1", "st16", "st2", "st4", "st8", "stf", "stf8", "stfd", "stfe",
     74  1.1    cherry 	"stfs", "sub", "sum", "sxt1", "sxt2", "sxt4", "sync",
     75  1.1    cherry 	"tak", "tbit", "thash", "tnat", "tpa", "ttag",
     76  1.1    cherry 	"unpack1", "unpack2", "unpack4",
     77  1.1    cherry 	"xchg1", "xchg2", "xchg4", "xchg8", "xma", "xor",
     78  1.1    cherry 	"zxt1", "zxt2", "zxt4"
     79  1.1    cherry };
     80  1.1    cherry 
     81  1.1    cherry /*
     82  1.1    cherry  * Completers (keep in sync with enum asm_cmpltr_type).
     83  1.1    cherry  */
     84  1.1    cherry static const char *asm_completers[] = {
     85  1.1    cherry 	"",
     86  1.1    cherry 	".0", ".1",
     87  1.1    cherry 	".a", ".acq", ".and",
     88  1.1    cherry 	".b", ".bias",
     89  1.1    cherry 	".c.clr", ".c.clr.acq", ".c.nc", ".call", ".cexit", ".cloop", ".clr",
     90  1.1    cherry 	".ctop",
     91  1.1    cherry 	".d", ".dc.dc", ".dc.nt", ".dpnt", ".dptk",
     92  1.1    cherry 	".e", ".eq", ".excl", ".exit", ".exp",
     93  1.1    cherry 	".f", ".fault", ".few", ".fill", ".fx", ".fxu",
     94  1.1    cherry 	".g", ".ga", ".ge", ".gt",
     95  1.1    cherry 	".h", ".hu",
     96  1.1    cherry 	".i", ".ia", ".imp",
     97  1.1    cherry 	".l", ".le", ".loop", ".lr", ".lt", ".ltu",
     98  1.1    cherry 	".m", ".many",
     99  1.1    cherry 	".nc", ".ne", ".neq", ".nl", ".nle", ".nlt", ".nm", ".nr", ".ns",
    100  1.1    cherry 	".nt.dc", ".nt.nt", ".nt.tk", ".nt1", ".nt2", ".nta", ".nz",
    101  1.1    cherry 	".or", ".or.andcm", ".ord",
    102  1.1    cherry 	".pr",
    103  1.1    cherry 	".r", ".raz", ".rel", ".ret", ".rw",
    104  1.1    cherry 	".s", ".s0", ".s1", ".s2", ".s3", ".sa", ".se", ".sig", ".spill",
    105  1.1    cherry 	".spnt", ".sptk", ".sss",
    106  1.1    cherry 	".tk.dc", ".tk.nt", ".tk.tk", ".trunc",
    107  1.1    cherry 	".u", ".unc", ".unord", ".uss", ".uus", ".uuu",
    108  1.1    cherry 	".w", ".wexit", ".wtop",
    109  1.1    cherry 	".x", ".xf",
    110  1.1    cherry 	".z"
    111  1.1    cherry };
    112  1.1    cherry 
    113  1.1    cherry void
    114  1.2  christos asm_completer(const struct asm_cmpltr *c, char *buf, size_t buflen)
    115  1.1    cherry {
    116  1.2  christos 	strlcpy(buf, asm_completers[c->c_type], buflen);
    117  1.1    cherry }
    118  1.1    cherry 
    119  1.1    cherry void
    120  1.2  christos asm_mnemonic(enum asm_op op, char *buf, size_t buflen)
    121  1.1    cherry {
    122  1.2  christos 	strlcpy(buf, asm_mnemonics[(op < ASM_OP_INTERNAL_OPCODES) ? op : 0],
    123  1.2  christos 	    buflen);
    124  1.1    cherry }
    125  1.1    cherry 
    126  1.1    cherry void
    127  1.2  christos asm_operand(const struct asm_oper *o, char *buf, size_t buflen, uint64_t ip)
    128  1.1    cherry {
    129  1.1    cherry 	const char *n;
    130  1.2  christos 	size_t l;
    131  1.1    cherry 
    132  1.1    cherry 	n = "";
    133  1.1    cherry 	switch (o->o_type) {
    134  1.1    cherry 	case ASM_OPER_AREG:
    135  1.1    cherry 		switch ((int)o->o_value) {
    136  1.1    cherry 		case AR_K0: n = "k0"; break;
    137  1.1    cherry 		case AR_K1: n = "k1"; break;
    138  1.1    cherry 		case AR_K2: n = "k2"; break;
    139  1.1    cherry 		case AR_K3: n = "k3"; break;
    140  1.1    cherry 		case AR_K4: n = "k4"; break;
    141  1.1    cherry 		case AR_K5: n = "k5"; break;
    142  1.1    cherry 		case AR_K6: n = "k6"; break;
    143  1.1    cherry 		case AR_K7: n = "k7"; break;
    144  1.1    cherry 		case AR_RSC: n = "rsc"; break;
    145  1.1    cherry 		case AR_BSP: n = "bsp"; break;
    146  1.1    cherry 		case AR_BSPSTORE: n = "bspstore"; break;
    147  1.1    cherry 		case AR_RNAT: n = "rnat"; break;
    148  1.1    cherry 		case AR_FCR: n = "fcr"; break;
    149  1.1    cherry 		case AR_EFLAG: n = "eflag"; break;
    150  1.1    cherry 		case AR_CSD: n = "csd"; break;
    151  1.1    cherry 		case AR_SSD: n = "ssd"; break;
    152  1.1    cherry 		case AR_CFLG: n = "cflg"; break;
    153  1.1    cherry 		case AR_FSR: n = "fsr"; break;
    154  1.1    cherry 		case AR_FIR: n = "fir"; break;
    155  1.1    cherry 		case AR_FDR: n = "fdr"; break;
    156  1.1    cherry 		case AR_CCV: n = "ccv"; break;
    157  1.1    cherry 		case AR_UNAT: n = "unat"; break;
    158  1.1    cherry 		case AR_FPSR: n = "fpsr"; break;
    159  1.1    cherry 		case AR_ITC: n = "itc"; break;
    160  1.1    cherry 		case AR_PFS: n = "pfs"; break;
    161  1.1    cherry 		case AR_LC: n = "lc"; break;
    162  1.1    cherry 		case AR_EC: n = "ec"; break;
    163  1.1    cherry 		default:
    164  1.2  christos 			snprintf(buf, buflen, "ar%d", (int)o->o_value);
    165  1.1    cherry 			return;
    166  1.1    cherry 		}
    167  1.2  christos 		snprintf(buf, buflen, "ar.%s", n);
    168  1.1    cherry 		return;
    169  1.1    cherry 	case ASM_OPER_BREG:
    170  1.1    cherry 		if (o->o_value != 0)
    171  1.2  christos 			snprintf(buf, buflen, "b%d", (int)o->o_value);
    172  1.1    cherry 		else
    173  1.2  christos 			strlcpy(buf, "rp", buflen);
    174  1.1    cherry 		return;
    175  1.1    cherry 	case ASM_OPER_CPUID:
    176  1.1    cherry 		n = "cpuid";
    177  1.1    cherry 		break;
    178  1.1    cherry 	case ASM_OPER_CREG:
    179  1.1    cherry 		switch ((int)o->o_value) {
    180  1.1    cherry 		case CR_DCR: n = "dcr"; break;
    181  1.1    cherry 		case CR_ITM: n = "itm"; break;
    182  1.1    cherry 		case CR_IVA: n = "iva"; break;
    183  1.1    cherry 		case CR_PTA: n = "pta"; break;
    184  1.1    cherry 		case CR_IPSR: n = "ipsr"; break;
    185  1.1    cherry 		case CR_ISR: n = "isr"; break;
    186  1.1    cherry 		case CR_IIP: n = "iip"; break;
    187  1.1    cherry 		case CR_IFA: n = "ifa"; break;
    188  1.1    cherry 		case CR_ITIR: n = "itir"; break;
    189  1.1    cherry 		case CR_IIPA: n = "iipa"; break;
    190  1.1    cherry 		case CR_IFS: n = "ifs"; break;
    191  1.1    cherry 		case CR_IIM: n = "iim"; break;
    192  1.1    cherry 		case CR_IHA: n = "iha"; break;
    193  1.1    cherry 		case CR_LID: n = "lid"; break;
    194  1.1    cherry 		case CR_IVR: n = "ivr"; break;
    195  1.1    cherry 		case CR_TPR: n = "tpr"; break;
    196  1.1    cherry 		case CR_EOI: n = "eoi"; break;
    197  1.1    cherry 		case CR_IRR0: n = "irr0"; break;
    198  1.1    cherry 		case CR_IRR1: n = "irr1"; break;
    199  1.1    cherry 		case CR_IRR2: n = "irr2"; break;
    200  1.1    cherry 		case CR_IRR3: n = "irr3"; break;
    201  1.1    cherry 		case CR_ITV: n = "itv"; break;
    202  1.1    cherry 		case CR_PMV: n = "pmv"; break;
    203  1.1    cherry 		case CR_CMCV: n = "cmcv"; break;
    204  1.1    cherry 		case CR_LRR0: n = "lrr0"; break;
    205  1.1    cherry 		case CR_LRR1: n = "lrr1"; break;
    206  1.1    cherry 		default:
    207  1.2  christos 			snprintf(buf, buflen, "cr%d", (int)o->o_value);
    208  1.1    cherry 			return;
    209  1.1    cherry 		}
    210  1.2  christos 		snprintf(buf, buflen, "cr.%s", n);
    211  1.1    cherry 		return;
    212  1.1    cherry 	case ASM_OPER_DBR:
    213  1.1    cherry 		n = "dbr";
    214  1.1    cherry 		break;
    215  1.1    cherry 	case ASM_OPER_DISP:
    216  1.2  christos 		snprintf(buf, buflen, "%lx", ip + o->o_value);
    217  1.1    cherry 		return;
    218  1.1    cherry 	case ASM_OPER_DTR:
    219  1.1    cherry 		n = "dtr";
    220  1.1    cherry 		break;
    221  1.1    cherry 	case ASM_OPER_FREG:
    222  1.2  christos 		snprintf(buf, buflen, "f%d", (int)o->o_value);
    223  1.1    cherry 		return;
    224  1.1    cherry 	case ASM_OPER_GREG:
    225  1.1    cherry 		break;
    226  1.1    cherry 	case ASM_OPER_IBR:
    227  1.1    cherry 		n = "ibr";
    228  1.1    cherry 		break;
    229  1.1    cherry 	case ASM_OPER_IMM:
    230  1.2  christos 		snprintf(buf, buflen, "0x%lx", o->o_value);
    231  1.1    cherry 		return;
    232  1.1    cherry 	case ASM_OPER_IP:
    233  1.2  christos 		strlcpy(buf, "ip", buflen);
    234  1.1    cherry 		return;
    235  1.1    cherry 	case ASM_OPER_ITR:
    236  1.1    cherry 		n = "itr";
    237  1.1    cherry 		break;
    238  1.1    cherry 	case ASM_OPER_MEM:
    239  1.1    cherry 		n = "";
    240  1.1    cherry 		break;
    241  1.1    cherry 	case ASM_OPER_MSR:
    242  1.1    cherry 		n = "msr";
    243  1.1    cherry 		break;
    244  1.1    cherry 	case ASM_OPER_PKR:
    245  1.1    cherry 		n = "pkr";
    246  1.1    cherry 		break;
    247  1.1    cherry 	case ASM_OPER_PMC:
    248  1.1    cherry 		n = "pmc";
    249  1.1    cherry 		break;
    250  1.1    cherry 	case ASM_OPER_PMD:
    251  1.1    cherry 		n = "pmd";
    252  1.1    cherry 		break;
    253  1.1    cherry 	case ASM_OPER_PR:
    254  1.2  christos 		strlcpy(buf, "pr", buflen);
    255  1.1    cherry                 return;
    256  1.1    cherry 	case ASM_OPER_PR_ROT:
    257  1.2  christos 		strlcpy(buf, "pr.rot", buflen);
    258  1.1    cherry 		return;
    259  1.1    cherry 	case ASM_OPER_PREG:
    260  1.2  christos 		snprintf(buf, buflen, "p%d", (int)o->o_value);
    261  1.1    cherry 		return;
    262  1.1    cherry 	case ASM_OPER_PSR:
    263  1.2  christos 		strlcpy(buf, "psr", buflen);
    264  1.1    cherry 		return;
    265  1.1    cherry 	case ASM_OPER_PSR_L:
    266  1.2  christos 		strlcpy(buf, "psr.l", buflen);
    267  1.1    cherry 		return;
    268  1.1    cherry 	case ASM_OPER_PSR_UM:
    269  1.2  christos 		strlcpy(buf, "psr.um", buflen);
    270  1.1    cherry 		return;
    271  1.1    cherry 	case ASM_OPER_RR:
    272  1.1    cherry 		n = "rr";
    273  1.1    cherry 		break;
    274  1.1    cherry 	case ASM_OPER_NONE:
    275  1.1    cherry 		KASSERT(0);
    276  1.1    cherry 		break;
    277  1.1    cherry 	}
    278  1.2  christos 	if (n[0] != '\0') {
    279  1.2  christos 		l = snprintf(buf, buflen, "%s[", n);
    280  1.3  christos 		if (l > buflen)
    281  1.3  christos 			l = buflen;
    282  1.2  christos 		buf += l;
    283  1.2  christos 		buflen -= l;
    284  1.2  christos 	}
    285  1.1    cherry 	switch ((int)o->o_value) {
    286  1.2  christos 	case 1:	l = strlcpy(buf, "gp", buflen); break;
    287  1.2  christos 	case 12: l = strlcpy(buf, "sp", buflen); break;
    288  1.2  christos 	case 13: l = strlcpy(buf, "tp", buflen); break;
    289  1.3  christos 	default:
    290  1.3  christos 	    l += snprintf(buf, buflen, "r%d", (int)o->o_value);
    291  1.3  christos 	    if (l > buflen)
    292  1.3  christos 		l = buflen;
    293  1.3  christos 	    break;
    294  1.1    cherry 	}
    295  1.2  christos 	buf += l;
    296  1.2  christos 	buflen -= l;
    297  1.1    cherry 	if (n[0] != '\0')
    298  1.2  christos 		strlcpy(buf, "]", buflen);
    299  1.1    cherry }
    300  1.1    cherry 
    301  1.1    cherry void
    302  1.1    cherry asm_print_bundle(const struct asm_bundle *b, uint64_t ip)
    303  1.1    cherry {
    304  1.1    cherry 	asm_print_inst(b, 0, ip);
    305  1.1    cherry 	asm_print_inst(b, 1, ip);
    306  1.1    cherry 	asm_print_inst(b, 2, ip);
    307  1.1    cherry }
    308  1.1    cherry 
    309  1.1    cherry void
    310  1.1    cherry asm_print_inst(const struct asm_bundle *b, int slot, uint64_t ip)
    311  1.1    cherry {
    312  1.1    cherry 	char buf[32];
    313  1.1    cherry 	const struct asm_inst *i;
    314  1.1    cherry 	const char *tmpl;
    315  1.1    cherry 	int n, w;
    316  1.1    cherry 
    317  1.1    cherry 	tmpl = b->b_templ + slot;
    318  1.1    cherry 	if (*tmpl == ';' || (slot == 2 && b->b_templ[1] == ';'))
    319  1.1    cherry 		tmpl++;
    320  1.1    cherry 	i = b->b_inst + slot;
    321  1.1    cherry 	if (*tmpl == 'L' || i->i_op == ASM_OP_NONE)
    322  1.1    cherry 		return;
    323  1.1    cherry 
    324  1.1    cherry 	/* Address + slot. */
    325  1.1    cherry 	printf("%lx[%c] ", ip + slot, *tmpl);
    326  1.1    cherry 
    327  1.1    cherry 	/* Predicate. */
    328  1.1    cherry 	if (i->i_oper[0].o_value != 0) {
    329  1.2  christos 		asm_operand(i->i_oper+0, buf, sizeof(buf), ip);
    330  1.1    cherry 		printf("(%s)", buf);
    331  1.1    cherry 		w = strlen(buf);
    332  1.1    cherry 	} else
    333  1.1    cherry 		w = 0;
    334  1.1    cherry 	while (w++ < 8)
    335  1.1    cherry 		printf(" ");
    336  1.1    cherry 
    337  1.1    cherry 	/* Mnemonic & completers. */
    338  1.2  christos 	asm_mnemonic(i->i_op, buf, sizeof(buf));
    339  1.2  christos 	printf("%s", buf);
    340  1.1    cherry 	w = strlen(buf);
    341  1.1    cherry 	n = 0;
    342  1.1    cherry 	while (n < i->i_ncmpltrs) {
    343  1.2  christos 		asm_completer(i->i_cmpltr + n, buf, sizeof(buf));
    344  1.1    cherry 		printf(buf);
    345  1.1    cherry 		w += strlen(buf);
    346  1.1    cherry 		n++;
    347  1.1    cherry 	}
    348  1.1    cherry 	while (w++ < 15)
    349  1.1    cherry 		printf(" ");
    350  1.1    cherry 	printf(" ");
    351  1.1    cherry 
    352  1.1    cherry 	/* Operands. */
    353  1.1    cherry 	n = 1;
    354  1.1    cherry 	while (n < 7 && i->i_oper[n].o_type != ASM_OPER_NONE) {
    355  1.1    cherry 		if (n > 1) {
    356  1.1    cherry 			if (n == i->i_srcidx)
    357  1.1    cherry 				printf(" = ");
    358  1.1    cherry 			else
    359  1.1    cherry 				printf(", ");
    360  1.1    cherry 		}
    361  1.2  christos 		asm_operand(i->i_oper + n, buf, sizeof(buf), ip);
    362  1.2  christos 		printf("%s", buf);
    363  1.1    cherry 		n++;
    364  1.1    cherry 	}
    365  1.1    cherry 	printf("\n");
    366  1.1    cherry }
    367  1.1    cherry 
    368  1.1    cherry #endif
    369