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