1 1.5 scole /* $NetBSD: disasm_format.c,v 1.5 2016/08/05 16:45:50 scole Exp $ */ 2 1.1 cherry 3 1.1 cherry /*- 4 1.5 scole * Copyright (c) 2000-2006 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.5 scole /* __FBSDID("$FreeBSD: releng/10.1/sys/ia64/disasm/disasm_format.c 159916 2006-06-24 19:21:11Z marcel $"); */ 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.5 scole "hint", 61 1.1 cherry "invala", "itc", "itr", 62 1.1 cherry "ld1", "ld16", "ld2", "ld4", "ld8", "ldf", "ldf8", "ldfd", "ldfe", 63 1.1 cherry "ldfp8", "ldfpd", "ldfps", "ldfs", "lfetch", "loadrs", 64 1.1 cherry "mf", "mix1", "mix2", "mix4", "mov", "movl", "mux1", "mux2", 65 1.1 cherry "nop", 66 1.1 cherry "or", 67 1.1 cherry "pack2", "pack4", "padd1", "padd2", "padd4", "pavg1", "pavg2", 68 1.1 cherry "pavgsub1", "pavgsub2", "pcmp1", "pcmp2", "pcmp4", "pmax1", "pmax2", 69 1.1 cherry "pmin1", "pmin2", "pmpy2", "pmpyshr2", "popcnt", "probe", "psad1", 70 1.1 cherry "pshl2", "pshl4", "pshladd2", "pshr2", "pshr4", "pshradd2", "psub1", 71 1.1 cherry "psub2", "psub4", "ptc", "ptr", 72 1.1 cherry "rfi", "rsm", "rum", 73 1.1 cherry "setf", "shl", "shladd", "shladdp4", "shr", "shrp", "srlz", "ssm", 74 1.1 cherry "st1", "st16", "st2", "st4", "st8", "stf", "stf8", "stfd", "stfe", 75 1.1 cherry "stfs", "sub", "sum", "sxt1", "sxt2", "sxt4", "sync", 76 1.5 scole "tak", "tbit", "tf", "thash", "tnat", "tpa", "ttag", 77 1.1 cherry "unpack1", "unpack2", "unpack4", 78 1.5 scole "vmsw", 79 1.1 cherry "xchg1", "xchg2", "xchg4", "xchg8", "xma", "xor", 80 1.1 cherry "zxt1", "zxt2", "zxt4" 81 1.1 cherry }; 82 1.1 cherry 83 1.1 cherry /* 84 1.1 cherry * Completers (keep in sync with enum asm_cmpltr_type). 85 1.1 cherry */ 86 1.1 cherry static const char *asm_completers[] = { 87 1.1 cherry "", 88 1.1 cherry ".0", ".1", 89 1.1 cherry ".a", ".acq", ".and", 90 1.1 cherry ".b", ".bias", 91 1.1 cherry ".c.clr", ".c.clr.acq", ".c.nc", ".call", ".cexit", ".cloop", ".clr", 92 1.1 cherry ".ctop", 93 1.1 cherry ".d", ".dc.dc", ".dc.nt", ".dpnt", ".dptk", 94 1.1 cherry ".e", ".eq", ".excl", ".exit", ".exp", 95 1.1 cherry ".f", ".fault", ".few", ".fill", ".fx", ".fxu", 96 1.1 cherry ".g", ".ga", ".ge", ".gt", 97 1.1 cherry ".h", ".hu", 98 1.1 cherry ".i", ".ia", ".imp", 99 1.1 cherry ".l", ".le", ".loop", ".lr", ".lt", ".ltu", 100 1.1 cherry ".m", ".many", 101 1.1 cherry ".nc", ".ne", ".neq", ".nl", ".nle", ".nlt", ".nm", ".nr", ".ns", 102 1.1 cherry ".nt.dc", ".nt.nt", ".nt.tk", ".nt1", ".nt2", ".nta", ".nz", 103 1.1 cherry ".or", ".or.andcm", ".ord", 104 1.1 cherry ".pr", 105 1.1 cherry ".r", ".raz", ".rel", ".ret", ".rw", 106 1.1 cherry ".s", ".s0", ".s1", ".s2", ".s3", ".sa", ".se", ".sig", ".spill", 107 1.1 cherry ".spnt", ".sptk", ".sss", 108 1.1 cherry ".tk.dc", ".tk.nt", ".tk.tk", ".trunc", 109 1.1 cherry ".u", ".unc", ".unord", ".uss", ".uus", ".uuu", 110 1.1 cherry ".w", ".wexit", ".wtop", 111 1.1 cherry ".x", ".xf", 112 1.1 cherry ".z" 113 1.1 cherry }; 114 1.1 cherry 115 1.1 cherry void 116 1.2 christos asm_completer(const struct asm_cmpltr *c, char *buf, size_t buflen) 117 1.1 cherry { 118 1.2 christos strlcpy(buf, asm_completers[c->c_type], buflen); 119 1.1 cherry } 120 1.1 cherry 121 1.1 cherry void 122 1.2 christos asm_mnemonic(enum asm_op op, char *buf, size_t buflen) 123 1.1 cherry { 124 1.2 christos strlcpy(buf, asm_mnemonics[(op < ASM_OP_INTERNAL_OPCODES) ? op : 0], 125 1.2 christos buflen); 126 1.1 cherry } 127 1.1 cherry 128 1.1 cherry void 129 1.2 christos asm_operand(const struct asm_oper *o, char *buf, size_t buflen, uint64_t ip) 130 1.1 cherry { 131 1.1 cherry const char *n; 132 1.2 christos size_t l; 133 1.1 cherry 134 1.1 cherry n = ""; 135 1.1 cherry switch (o->o_type) { 136 1.1 cherry case ASM_OPER_AREG: 137 1.1 cherry switch ((int)o->o_value) { 138 1.1 cherry case AR_K0: n = "k0"; break; 139 1.1 cherry case AR_K1: n = "k1"; break; 140 1.1 cherry case AR_K2: n = "k2"; break; 141 1.1 cherry case AR_K3: n = "k3"; break; 142 1.1 cherry case AR_K4: n = "k4"; break; 143 1.1 cherry case AR_K5: n = "k5"; break; 144 1.1 cherry case AR_K6: n = "k6"; break; 145 1.1 cherry case AR_K7: n = "k7"; break; 146 1.1 cherry case AR_RSC: n = "rsc"; break; 147 1.1 cherry case AR_BSP: n = "bsp"; break; 148 1.1 cherry case AR_BSPSTORE: n = "bspstore"; break; 149 1.1 cherry case AR_RNAT: n = "rnat"; break; 150 1.1 cherry case AR_FCR: n = "fcr"; break; 151 1.1 cherry case AR_EFLAG: n = "eflag"; break; 152 1.1 cherry case AR_CSD: n = "csd"; break; 153 1.1 cherry case AR_SSD: n = "ssd"; break; 154 1.1 cherry case AR_CFLG: n = "cflg"; break; 155 1.1 cherry case AR_FSR: n = "fsr"; break; 156 1.1 cherry case AR_FIR: n = "fir"; break; 157 1.1 cherry case AR_FDR: n = "fdr"; break; 158 1.1 cherry case AR_CCV: n = "ccv"; break; 159 1.1 cherry case AR_UNAT: n = "unat"; break; 160 1.1 cherry case AR_FPSR: n = "fpsr"; break; 161 1.1 cherry case AR_ITC: n = "itc"; break; 162 1.1 cherry case AR_PFS: n = "pfs"; break; 163 1.1 cherry case AR_LC: n = "lc"; break; 164 1.1 cherry case AR_EC: n = "ec"; break; 165 1.1 cherry default: 166 1.2 christos snprintf(buf, buflen, "ar%d", (int)o->o_value); 167 1.1 cherry return; 168 1.1 cherry } 169 1.2 christos snprintf(buf, buflen, "ar.%s", n); 170 1.1 cherry return; 171 1.1 cherry case ASM_OPER_BREG: 172 1.1 cherry if (o->o_value != 0) 173 1.2 christos snprintf(buf, buflen, "b%d", (int)o->o_value); 174 1.1 cherry else 175 1.2 christos strlcpy(buf, "rp", buflen); 176 1.1 cherry return; 177 1.1 cherry case ASM_OPER_CPUID: 178 1.1 cherry n = "cpuid"; 179 1.1 cherry break; 180 1.1 cherry case ASM_OPER_CREG: 181 1.1 cherry switch ((int)o->o_value) { 182 1.1 cherry case CR_DCR: n = "dcr"; break; 183 1.1 cherry case CR_ITM: n = "itm"; break; 184 1.1 cherry case CR_IVA: n = "iva"; break; 185 1.1 cherry case CR_PTA: n = "pta"; break; 186 1.1 cherry case CR_IPSR: n = "ipsr"; break; 187 1.1 cherry case CR_ISR: n = "isr"; break; 188 1.1 cherry case CR_IIP: n = "iip"; break; 189 1.1 cherry case CR_IFA: n = "ifa"; break; 190 1.1 cherry case CR_ITIR: n = "itir"; break; 191 1.1 cherry case CR_IIPA: n = "iipa"; break; 192 1.1 cherry case CR_IFS: n = "ifs"; break; 193 1.1 cherry case CR_IIM: n = "iim"; break; 194 1.1 cherry case CR_IHA: n = "iha"; break; 195 1.1 cherry case CR_LID: n = "lid"; break; 196 1.1 cherry case CR_IVR: n = "ivr"; break; 197 1.1 cherry case CR_TPR: n = "tpr"; break; 198 1.1 cherry case CR_EOI: n = "eoi"; break; 199 1.1 cherry case CR_IRR0: n = "irr0"; break; 200 1.1 cherry case CR_IRR1: n = "irr1"; break; 201 1.1 cherry case CR_IRR2: n = "irr2"; break; 202 1.1 cherry case CR_IRR3: n = "irr3"; break; 203 1.1 cherry case CR_ITV: n = "itv"; break; 204 1.1 cherry case CR_PMV: n = "pmv"; break; 205 1.1 cherry case CR_CMCV: n = "cmcv"; break; 206 1.1 cherry case CR_LRR0: n = "lrr0"; break; 207 1.1 cherry case CR_LRR1: n = "lrr1"; break; 208 1.1 cherry default: 209 1.2 christos snprintf(buf, buflen, "cr%d", (int)o->o_value); 210 1.1 cherry return; 211 1.1 cherry } 212 1.2 christos snprintf(buf, buflen, "cr.%s", n); 213 1.1 cherry return; 214 1.1 cherry case ASM_OPER_DBR: 215 1.1 cherry n = "dbr"; 216 1.1 cherry break; 217 1.1 cherry case ASM_OPER_DISP: 218 1.2 christos snprintf(buf, buflen, "%lx", ip + o->o_value); 219 1.1 cherry return; 220 1.1 cherry case ASM_OPER_DTR: 221 1.1 cherry n = "dtr"; 222 1.1 cherry break; 223 1.1 cherry case ASM_OPER_FREG: 224 1.2 christos snprintf(buf, buflen, "f%d", (int)o->o_value); 225 1.1 cherry return; 226 1.1 cherry case ASM_OPER_GREG: 227 1.1 cherry break; 228 1.1 cherry case ASM_OPER_IBR: 229 1.1 cherry n = "ibr"; 230 1.1 cherry break; 231 1.1 cherry case ASM_OPER_IMM: 232 1.2 christos snprintf(buf, buflen, "0x%lx", o->o_value); 233 1.1 cherry return; 234 1.1 cherry case ASM_OPER_IP: 235 1.2 christos strlcpy(buf, "ip", buflen); 236 1.1 cherry return; 237 1.1 cherry case ASM_OPER_ITR: 238 1.1 cherry n = "itr"; 239 1.1 cherry break; 240 1.1 cherry case ASM_OPER_MEM: 241 1.1 cherry n = ""; 242 1.1 cherry break; 243 1.1 cherry case ASM_OPER_MSR: 244 1.1 cherry n = "msr"; 245 1.1 cherry break; 246 1.1 cherry case ASM_OPER_PKR: 247 1.1 cherry n = "pkr"; 248 1.1 cherry break; 249 1.1 cherry case ASM_OPER_PMC: 250 1.1 cherry n = "pmc"; 251 1.1 cherry break; 252 1.1 cherry case ASM_OPER_PMD: 253 1.1 cherry n = "pmd"; 254 1.1 cherry break; 255 1.1 cherry case ASM_OPER_PR: 256 1.2 christos strlcpy(buf, "pr", buflen); 257 1.1 cherry return; 258 1.1 cherry case ASM_OPER_PR_ROT: 259 1.2 christos strlcpy(buf, "pr.rot", buflen); 260 1.1 cherry return; 261 1.1 cherry case ASM_OPER_PREG: 262 1.2 christos snprintf(buf, buflen, "p%d", (int)o->o_value); 263 1.1 cherry return; 264 1.1 cherry case ASM_OPER_PSR: 265 1.2 christos strlcpy(buf, "psr", buflen); 266 1.1 cherry return; 267 1.1 cherry case ASM_OPER_PSR_L: 268 1.2 christos strlcpy(buf, "psr.l", buflen); 269 1.1 cherry return; 270 1.1 cherry case ASM_OPER_PSR_UM: 271 1.2 christos strlcpy(buf, "psr.um", buflen); 272 1.1 cherry return; 273 1.1 cherry case ASM_OPER_RR: 274 1.1 cherry n = "rr"; 275 1.1 cherry break; 276 1.1 cherry case ASM_OPER_NONE: 277 1.1 cherry KASSERT(0); 278 1.1 cherry break; 279 1.1 cherry } 280 1.2 christos if (n[0] != '\0') { 281 1.2 christos l = snprintf(buf, buflen, "%s[", n); 282 1.3 christos if (l > buflen) 283 1.3 christos l = buflen; 284 1.2 christos buf += l; 285 1.2 christos buflen -= l; 286 1.2 christos } 287 1.1 cherry switch ((int)o->o_value) { 288 1.2 christos case 1: l = strlcpy(buf, "gp", buflen); break; 289 1.2 christos case 12: l = strlcpy(buf, "sp", buflen); break; 290 1.2 christos case 13: l = strlcpy(buf, "tp", buflen); break; 291 1.3 christos default: 292 1.4 martin l = snprintf(buf, buflen, "r%d", (int)o->o_value); 293 1.3 christos if (l > buflen) 294 1.3 christos l = buflen; 295 1.3 christos break; 296 1.1 cherry } 297 1.2 christos buf += l; 298 1.2 christos buflen -= l; 299 1.1 cherry if (n[0] != '\0') 300 1.2 christos strlcpy(buf, "]", buflen); 301 1.1 cherry } 302 1.1 cherry 303 1.1 cherry void 304 1.1 cherry asm_print_bundle(const struct asm_bundle *b, uint64_t ip) 305 1.1 cherry { 306 1.1 cherry asm_print_inst(b, 0, ip); 307 1.1 cherry asm_print_inst(b, 1, ip); 308 1.1 cherry asm_print_inst(b, 2, ip); 309 1.1 cherry } 310 1.1 cherry 311 1.1 cherry void 312 1.1 cherry asm_print_inst(const struct asm_bundle *b, int slot, uint64_t ip) 313 1.1 cherry { 314 1.1 cherry char buf[32]; 315 1.1 cherry const struct asm_inst *i; 316 1.1 cherry const char *tmpl; 317 1.1 cherry int n, w; 318 1.1 cherry 319 1.1 cherry tmpl = b->b_templ + slot; 320 1.1 cherry if (*tmpl == ';' || (slot == 2 && b->b_templ[1] == ';')) 321 1.1 cherry tmpl++; 322 1.1 cherry i = b->b_inst + slot; 323 1.1 cherry if (*tmpl == 'L' || i->i_op == ASM_OP_NONE) 324 1.1 cherry return; 325 1.1 cherry 326 1.1 cherry /* Address + slot. */ 327 1.1 cherry printf("%lx[%c] ", ip + slot, *tmpl); 328 1.1 cherry 329 1.1 cherry /* Predicate. */ 330 1.1 cherry if (i->i_oper[0].o_value != 0) { 331 1.2 christos asm_operand(i->i_oper+0, buf, sizeof(buf), ip); 332 1.1 cherry printf("(%s)", buf); 333 1.1 cherry w = strlen(buf); 334 1.1 cherry } else 335 1.1 cherry w = 0; 336 1.1 cherry while (w++ < 8) 337 1.1 cherry printf(" "); 338 1.1 cherry 339 1.1 cherry /* Mnemonic & completers. */ 340 1.2 christos asm_mnemonic(i->i_op, buf, sizeof(buf)); 341 1.2 christos printf("%s", buf); 342 1.1 cherry w = strlen(buf); 343 1.1 cherry n = 0; 344 1.1 cherry while (n < i->i_ncmpltrs) { 345 1.2 christos asm_completer(i->i_cmpltr + n, buf, sizeof(buf)); 346 1.1 cherry printf(buf); 347 1.1 cherry w += strlen(buf); 348 1.1 cherry n++; 349 1.1 cherry } 350 1.1 cherry while (w++ < 15) 351 1.1 cherry printf(" "); 352 1.1 cherry printf(" "); 353 1.1 cherry 354 1.1 cherry /* Operands. */ 355 1.1 cherry n = 1; 356 1.1 cherry while (n < 7 && i->i_oper[n].o_type != ASM_OPER_NONE) { 357 1.1 cherry if (n > 1) { 358 1.1 cherry if (n == i->i_srcidx) 359 1.1 cherry printf(" = "); 360 1.1 cherry else 361 1.1 cherry printf(", "); 362 1.1 cherry } 363 1.2 christos asm_operand(i->i_oper + n, buf, sizeof(buf), ip); 364 1.2 christos printf("%s", buf); 365 1.1 cherry n++; 366 1.1 cherry } 367 1.1 cherry printf("\n"); 368 1.1 cherry } 369 1.1 cherry 370 1.1 cherry #endif 371