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