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