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