disasm_format.c revision 1.1 1 1.1 cherry /* $NetBSD: disasm_format.c,v 1.1 2006/04/07 14:21:18 cherry 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.1 cherry asm_completer(const struct asm_cmpltr *c, char *buf)
115 1.1 cherry {
116 1.1 cherry strcpy(buf, asm_completers[c->c_type]);
117 1.1 cherry }
118 1.1 cherry
119 1.1 cherry void
120 1.1 cherry asm_mnemonic(enum asm_op op, char *buf)
121 1.1 cherry {
122 1.1 cherry strcpy(buf, asm_mnemonics[(op < ASM_OP_INTERNAL_OPCODES) ? op : 0]);
123 1.1 cherry }
124 1.1 cherry
125 1.1 cherry void
126 1.1 cherry asm_operand(const struct asm_oper *o, char *buf, uint64_t ip)
127 1.1 cherry {
128 1.1 cherry const char *n;
129 1.1 cherry
130 1.1 cherry n = "";
131 1.1 cherry switch (o->o_type) {
132 1.1 cherry case ASM_OPER_AREG:
133 1.1 cherry switch ((int)o->o_value) {
134 1.1 cherry case AR_K0: n = "k0"; break;
135 1.1 cherry case AR_K1: n = "k1"; break;
136 1.1 cherry case AR_K2: n = "k2"; break;
137 1.1 cherry case AR_K3: n = "k3"; break;
138 1.1 cherry case AR_K4: n = "k4"; break;
139 1.1 cherry case AR_K5: n = "k5"; break;
140 1.1 cherry case AR_K6: n = "k6"; break;
141 1.1 cherry case AR_K7: n = "k7"; break;
142 1.1 cherry case AR_RSC: n = "rsc"; break;
143 1.1 cherry case AR_BSP: n = "bsp"; break;
144 1.1 cherry case AR_BSPSTORE: n = "bspstore"; break;
145 1.1 cherry case AR_RNAT: n = "rnat"; break;
146 1.1 cherry case AR_FCR: n = "fcr"; break;
147 1.1 cherry case AR_EFLAG: n = "eflag"; break;
148 1.1 cherry case AR_CSD: n = "csd"; break;
149 1.1 cherry case AR_SSD: n = "ssd"; break;
150 1.1 cherry case AR_CFLG: n = "cflg"; break;
151 1.1 cherry case AR_FSR: n = "fsr"; break;
152 1.1 cherry case AR_FIR: n = "fir"; break;
153 1.1 cherry case AR_FDR: n = "fdr"; break;
154 1.1 cherry case AR_CCV: n = "ccv"; break;
155 1.1 cherry case AR_UNAT: n = "unat"; break;
156 1.1 cherry case AR_FPSR: n = "fpsr"; break;
157 1.1 cherry case AR_ITC: n = "itc"; break;
158 1.1 cherry case AR_PFS: n = "pfs"; break;
159 1.1 cherry case AR_LC: n = "lc"; break;
160 1.1 cherry case AR_EC: n = "ec"; break;
161 1.1 cherry default:
162 1.1 cherry sprintf(buf, "ar%d", (int)o->o_value);
163 1.1 cherry return;
164 1.1 cherry }
165 1.1 cherry sprintf(buf, "ar.%s", n);
166 1.1 cherry return;
167 1.1 cherry case ASM_OPER_BREG:
168 1.1 cherry if (o->o_value != 0)
169 1.1 cherry sprintf(buf, "b%d", (int)o->o_value);
170 1.1 cherry else
171 1.1 cherry strcpy(buf, "rp");
172 1.1 cherry return;
173 1.1 cherry case ASM_OPER_CPUID:
174 1.1 cherry n = "cpuid";
175 1.1 cherry break;
176 1.1 cherry case ASM_OPER_CREG:
177 1.1 cherry switch ((int)o->o_value) {
178 1.1 cherry case CR_DCR: n = "dcr"; break;
179 1.1 cherry case CR_ITM: n = "itm"; break;
180 1.1 cherry case CR_IVA: n = "iva"; break;
181 1.1 cherry case CR_PTA: n = "pta"; break;
182 1.1 cherry case CR_IPSR: n = "ipsr"; break;
183 1.1 cherry case CR_ISR: n = "isr"; break;
184 1.1 cherry case CR_IIP: n = "iip"; break;
185 1.1 cherry case CR_IFA: n = "ifa"; break;
186 1.1 cherry case CR_ITIR: n = "itir"; break;
187 1.1 cherry case CR_IIPA: n = "iipa"; break;
188 1.1 cherry case CR_IFS: n = "ifs"; break;
189 1.1 cherry case CR_IIM: n = "iim"; break;
190 1.1 cherry case CR_IHA: n = "iha"; break;
191 1.1 cherry case CR_LID: n = "lid"; break;
192 1.1 cherry case CR_IVR: n = "ivr"; break;
193 1.1 cherry case CR_TPR: n = "tpr"; break;
194 1.1 cherry case CR_EOI: n = "eoi"; break;
195 1.1 cherry case CR_IRR0: n = "irr0"; break;
196 1.1 cherry case CR_IRR1: n = "irr1"; break;
197 1.1 cherry case CR_IRR2: n = "irr2"; break;
198 1.1 cherry case CR_IRR3: n = "irr3"; break;
199 1.1 cherry case CR_ITV: n = "itv"; break;
200 1.1 cherry case CR_PMV: n = "pmv"; break;
201 1.1 cherry case CR_CMCV: n = "cmcv"; break;
202 1.1 cherry case CR_LRR0: n = "lrr0"; break;
203 1.1 cherry case CR_LRR1: n = "lrr1"; break;
204 1.1 cherry default:
205 1.1 cherry sprintf(buf, "cr%d", (int)o->o_value);
206 1.1 cherry return;
207 1.1 cherry }
208 1.1 cherry sprintf(buf, "cr.%s", n);
209 1.1 cherry return;
210 1.1 cherry case ASM_OPER_DBR:
211 1.1 cherry n = "dbr";
212 1.1 cherry break;
213 1.1 cherry case ASM_OPER_DISP:
214 1.1 cherry sprintf(buf, "%lx", ip + o->o_value);
215 1.1 cherry return;
216 1.1 cherry case ASM_OPER_DTR:
217 1.1 cherry n = "dtr";
218 1.1 cherry break;
219 1.1 cherry case ASM_OPER_FREG:
220 1.1 cherry sprintf(buf, "f%d", (int)o->o_value);
221 1.1 cherry return;
222 1.1 cherry case ASM_OPER_GREG:
223 1.1 cherry break;
224 1.1 cherry case ASM_OPER_IBR:
225 1.1 cherry n = "ibr";
226 1.1 cherry break;
227 1.1 cherry case ASM_OPER_IMM:
228 1.1 cherry sprintf(buf, "0x%lx", o->o_value);
229 1.1 cherry return;
230 1.1 cherry case ASM_OPER_IP:
231 1.1 cherry strcpy(buf, "ip");
232 1.1 cherry return;
233 1.1 cherry case ASM_OPER_ITR:
234 1.1 cherry n = "itr";
235 1.1 cherry break;
236 1.1 cherry case ASM_OPER_MEM:
237 1.1 cherry n = "";
238 1.1 cherry break;
239 1.1 cherry case ASM_OPER_MSR:
240 1.1 cherry n = "msr";
241 1.1 cherry break;
242 1.1 cherry case ASM_OPER_PKR:
243 1.1 cherry n = "pkr";
244 1.1 cherry break;
245 1.1 cherry case ASM_OPER_PMC:
246 1.1 cherry n = "pmc";
247 1.1 cherry break;
248 1.1 cherry case ASM_OPER_PMD:
249 1.1 cherry n = "pmd";
250 1.1 cherry break;
251 1.1 cherry case ASM_OPER_PR:
252 1.1 cherry strcpy(buf, "pr");
253 1.1 cherry return;
254 1.1 cherry case ASM_OPER_PR_ROT:
255 1.1 cherry strcpy(buf, "pr.rot");
256 1.1 cherry return;
257 1.1 cherry case ASM_OPER_PREG:
258 1.1 cherry sprintf(buf, "p%d", (int)o->o_value);
259 1.1 cherry return;
260 1.1 cherry case ASM_OPER_PSR:
261 1.1 cherry strcpy(buf, "psr");
262 1.1 cherry return;
263 1.1 cherry case ASM_OPER_PSR_L:
264 1.1 cherry strcpy(buf, "psr.l");
265 1.1 cherry return;
266 1.1 cherry case ASM_OPER_PSR_UM:
267 1.1 cherry strcpy(buf, "psr.um");
268 1.1 cherry return;
269 1.1 cherry case ASM_OPER_RR:
270 1.1 cherry n = "rr";
271 1.1 cherry break;
272 1.1 cherry case ASM_OPER_NONE:
273 1.1 cherry KASSERT(0);
274 1.1 cherry break;
275 1.1 cherry }
276 1.1 cherry if (n[0] != '\0')
277 1.1 cherry buf += sprintf(buf, "%s[", n);
278 1.1 cherry switch ((int)o->o_value) {
279 1.1 cherry case 1: strcpy(buf, "gp"); buf += 2; break;
280 1.1 cherry case 12: strcpy(buf, "sp"); buf += 2; break;
281 1.1 cherry case 13: strcpy(buf, "tp"); buf += 2; break;
282 1.1 cherry default: buf += sprintf(buf, "r%d", (int)o->o_value); break;
283 1.1 cherry }
284 1.1 cherry if (n[0] != '\0')
285 1.1 cherry strcpy(buf, "]");
286 1.1 cherry }
287 1.1 cherry
288 1.1 cherry void
289 1.1 cherry asm_print_bundle(const struct asm_bundle *b, uint64_t ip)
290 1.1 cherry {
291 1.1 cherry asm_print_inst(b, 0, ip);
292 1.1 cherry asm_print_inst(b, 1, ip);
293 1.1 cherry asm_print_inst(b, 2, ip);
294 1.1 cherry }
295 1.1 cherry
296 1.1 cherry void
297 1.1 cherry asm_print_inst(const struct asm_bundle *b, int slot, uint64_t ip)
298 1.1 cherry {
299 1.1 cherry char buf[32];
300 1.1 cherry const struct asm_inst *i;
301 1.1 cherry const char *tmpl;
302 1.1 cherry int n, w;
303 1.1 cherry
304 1.1 cherry tmpl = b->b_templ + slot;
305 1.1 cherry if (*tmpl == ';' || (slot == 2 && b->b_templ[1] == ';'))
306 1.1 cherry tmpl++;
307 1.1 cherry i = b->b_inst + slot;
308 1.1 cherry if (*tmpl == 'L' || i->i_op == ASM_OP_NONE)
309 1.1 cherry return;
310 1.1 cherry
311 1.1 cherry /* Address + slot. */
312 1.1 cherry printf("%lx[%c] ", ip + slot, *tmpl);
313 1.1 cherry
314 1.1 cherry /* Predicate. */
315 1.1 cherry if (i->i_oper[0].o_value != 0) {
316 1.1 cherry asm_operand(i->i_oper+0, buf, ip);
317 1.1 cherry printf("(%s)", buf);
318 1.1 cherry w = strlen(buf);
319 1.1 cherry } else
320 1.1 cherry w = 0;
321 1.1 cherry while (w++ < 8)
322 1.1 cherry printf(" ");
323 1.1 cherry
324 1.1 cherry /* Mnemonic & completers. */
325 1.1 cherry asm_mnemonic(i->i_op, buf);
326 1.1 cherry printf(buf);
327 1.1 cherry w = strlen(buf);
328 1.1 cherry n = 0;
329 1.1 cherry while (n < i->i_ncmpltrs) {
330 1.1 cherry asm_completer(i->i_cmpltr + n, buf);
331 1.1 cherry printf(buf);
332 1.1 cherry w += strlen(buf);
333 1.1 cherry n++;
334 1.1 cherry }
335 1.1 cherry while (w++ < 15)
336 1.1 cherry printf(" ");
337 1.1 cherry printf(" ");
338 1.1 cherry
339 1.1 cherry /* Operands. */
340 1.1 cherry n = 1;
341 1.1 cherry while (n < 7 && i->i_oper[n].o_type != ASM_OPER_NONE) {
342 1.1 cherry if (n > 1) {
343 1.1 cherry if (n == i->i_srcidx)
344 1.1 cherry printf(" = ");
345 1.1 cherry else
346 1.1 cherry printf(", ");
347 1.1 cherry }
348 1.1 cherry asm_operand(i->i_oper + n, buf, ip);
349 1.1 cherry printf(buf);
350 1.1 cherry n++;
351 1.1 cherry }
352 1.1 cherry printf("\n");
353 1.1 cherry }
354 1.1 cherry
355 1.1 cherry #endif
356