disasm_format.c revision 1.5 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