2 * Copyright (c) 2000-2006 Marcel Moolenaar
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
30 #include <sys/param.h>
31 #include <sys/systm.h>
33 #include <ia64/disasm/disasm_int.h>
34 #include <ia64/disasm/disasm.h>
37 * Mnemonics (keep in sync with enum asm_op).
39 static const char *asm_mnemonics[] = {
41 "add", "addl", "addp4", "adds", "alloc", "and", "andcm",
42 "br", "break", "brl", "brp", "bsw",
43 "chk", "clrrrb", "cmp", "cmp4", "cmp8xchg16", "cmpxchg1", "cmpxchg2",
44 "cmpxchg4", "cmpxchg8", "cover", "czx1", "czx2",
47 "famax", "famin", "fand", "fandcm", "fc", "fchkf", "fclass", "fclrf",
48 "fcmp", "fcvt", "fetchadd4", "fetchadd8", "flushrs", "fma", "fmax",
49 "fmerge", "fmin", "fmix", "fms", "fnma", "for", "fpack", "fpamax",
50 "fpamin", "fpcmp", "fpcvt", "fpma", "fpmax", "fpmerge", "fpmin",
51 "fpms", "fpnma", "fprcpa", "fprsqrta", "frcpa", "frsqrta", "fselect",
52 "fsetc", "fswap", "fsxt", "fwb", "fxor",
55 "invala", "itc", "itr",
56 "ld1", "ld16", "ld2", "ld4", "ld8", "ldf", "ldf8", "ldfd", "ldfe",
57 "ldfp8", "ldfpd", "ldfps", "ldfs", "lfetch", "loadrs",
58 "mf", "mix1", "mix2", "mix4", "mov", "movl", "mux1", "mux2",
61 "pack2", "pack4", "padd1", "padd2", "padd4", "pavg1", "pavg2",
62 "pavgsub1", "pavgsub2", "pcmp1", "pcmp2", "pcmp4", "pmax1", "pmax2",
63 "pmin1", "pmin2", "pmpy2", "pmpyshr2", "popcnt", "probe", "psad1",
64 "pshl2", "pshl4", "pshladd2", "pshr2", "pshr4", "pshradd2", "psub1",
65 "psub2", "psub4", "ptc", "ptr",
67 "setf", "shl", "shladd", "shladdp4", "shr", "shrp", "srlz", "ssm",
68 "st1", "st16", "st2", "st4", "st8", "stf", "stf8", "stfd", "stfe",
69 "stfs", "sub", "sum", "sxt1", "sxt2", "sxt4", "sync",
70 "tak", "tbit", "tf", "thash", "tnat", "tpa", "ttag",
71 "unpack1", "unpack2", "unpack4",
73 "xchg1", "xchg2", "xchg4", "xchg8", "xma", "xor",
74 "zxt1", "zxt2", "zxt4"
78 * Completers (keep in sync with enum asm_cmpltr_type).
80 static const char *asm_completers[] = {
85 ".c.clr", ".c.clr.acq", ".c.nc", ".call", ".cexit", ".cloop", ".clr",
87 ".d", ".dc.dc", ".dc.nt", ".dpnt", ".dptk",
88 ".e", ".eq", ".excl", ".exit", ".exp",
89 ".f", ".fault", ".few", ".fill", ".fx", ".fxu",
90 ".g", ".ga", ".ge", ".gt",
93 ".l", ".le", ".loop", ".lr", ".lt", ".ltu",
95 ".nc", ".ne", ".neq", ".nl", ".nle", ".nlt", ".nm", ".nr", ".ns",
96 ".nt.dc", ".nt.nt", ".nt.tk", ".nt1", ".nt2", ".nta", ".nz",
97 ".or", ".or.andcm", ".ord",
99 ".r", ".raz", ".rel", ".ret", ".rw",
100 ".s", ".s0", ".s1", ".s2", ".s3", ".sa", ".se", ".sig", ".spill",
101 ".spnt", ".sptk", ".sss",
102 ".tk.dc", ".tk.nt", ".tk.tk", ".trunc",
103 ".u", ".unc", ".unord", ".uss", ".uus", ".uuu",
104 ".w", ".wexit", ".wtop",
110 asm_completer(const struct asm_cmpltr *c, char *buf)
112 strcpy(buf, asm_completers[c->c_type]);
116 asm_mnemonic(enum asm_op op, char *buf)
118 strcpy(buf, asm_mnemonics[(op < ASM_OP_INTERNAL_OPCODES) ? op : 0]);
122 asm_operand(const struct asm_oper *o, char *buf, uint64_t ip)
129 switch ((int)o->o_value) {
130 case AR_K0: n = "k0"; break;
131 case AR_K1: n = "k1"; break;
132 case AR_K2: n = "k2"; break;
133 case AR_K3: n = "k3"; break;
134 case AR_K4: n = "k4"; break;
135 case AR_K5: n = "k5"; break;
136 case AR_K6: n = "k6"; break;
137 case AR_K7: n = "k7"; break;
138 case AR_RSC: n = "rsc"; break;
139 case AR_BSP: n = "bsp"; break;
140 case AR_BSPSTORE: n = "bspstore"; break;
141 case AR_RNAT: n = "rnat"; break;
142 case AR_FCR: n = "fcr"; break;
143 case AR_EFLAG: n = "eflag"; break;
144 case AR_CSD: n = "csd"; break;
145 case AR_SSD: n = "ssd"; break;
146 case AR_CFLG: n = "cflg"; break;
147 case AR_FSR: n = "fsr"; break;
148 case AR_FIR: n = "fir"; break;
149 case AR_FDR: n = "fdr"; break;
150 case AR_CCV: n = "ccv"; break;
151 case AR_UNAT: n = "unat"; break;
152 case AR_FPSR: n = "fpsr"; break;
153 case AR_ITC: n = "itc"; break;
154 case AR_PFS: n = "pfs"; break;
155 case AR_LC: n = "lc"; break;
156 case AR_EC: n = "ec"; break;
158 sprintf(buf, "ar%d", (int)o->o_value);
161 sprintf(buf, "ar.%s", n);
165 sprintf(buf, "b%d", (int)o->o_value);
173 switch ((int)o->o_value) {
174 case CR_DCR: n = "dcr"; break;
175 case CR_ITM: n = "itm"; break;
176 case CR_IVA: n = "iva"; break;
177 case CR_PTA: n = "pta"; break;
178 case CR_IPSR: n = "ipsr"; break;
179 case CR_ISR: n = "isr"; break;
180 case CR_IIP: n = "iip"; break;
181 case CR_IFA: n = "ifa"; break;
182 case CR_ITIR: n = "itir"; break;
183 case CR_IIPA: n = "iipa"; break;
184 case CR_IFS: n = "ifs"; break;
185 case CR_IIM: n = "iim"; break;
186 case CR_IHA: n = "iha"; break;
187 case CR_LID: n = "lid"; break;
188 case CR_IVR: n = "ivr"; break;
189 case CR_TPR: n = "tpr"; break;
190 case CR_EOI: n = "eoi"; break;
191 case CR_IRR0: n = "irr0"; break;
192 case CR_IRR1: n = "irr1"; break;
193 case CR_IRR2: n = "irr2"; break;
194 case CR_IRR3: n = "irr3"; break;
195 case CR_ITV: n = "itv"; break;
196 case CR_PMV: n = "pmv"; break;
197 case CR_CMCV: n = "cmcv"; break;
198 case CR_LRR0: n = "lrr0"; break;
199 case CR_LRR1: n = "lrr1"; break;
201 sprintf(buf, "cr%d", (int)o->o_value);
204 sprintf(buf, "cr.%s", n);
210 sprintf(buf, "%lx", ip + o->o_value);
216 sprintf(buf, "f%d", (int)o->o_value);
224 sprintf(buf, "0x%lx", o->o_value);
250 case ASM_OPER_PR_ROT:
251 strcpy(buf, "pr.rot");
254 sprintf(buf, "p%d", (int)o->o_value);
260 strcpy(buf, "psr.l");
262 case ASM_OPER_PSR_UM:
263 strcpy(buf, "psr.um");
273 buf += sprintf(buf, "%s[", n);
274 switch ((int)o->o_value) {
275 case 1: strcpy(buf, "gp"); buf += 2; break;
276 case 12: strcpy(buf, "sp"); buf += 2; break;
277 case 13: strcpy(buf, "tp"); buf += 2; break;
278 default: buf += sprintf(buf, "r%d", (int)o->o_value); break;
285 asm_print_bundle(const struct asm_bundle *b, uint64_t ip)
287 asm_print_inst(b, 0, ip);
288 asm_print_inst(b, 1, ip);
289 asm_print_inst(b, 2, ip);
293 asm_print_inst(const struct asm_bundle *b, int slot, uint64_t ip)
296 const struct asm_inst *i;
300 tmpl = b->b_templ + slot;
301 if (*tmpl == ';' || (slot == 2 && b->b_templ[1] == ';'))
303 i = b->b_inst + slot;
304 if (*tmpl == 'L' || i->i_op == ASM_OP_NONE)
307 /* Address + slot. */
308 printf("%lx[%c] ", ip + slot, *tmpl);
311 if (i->i_oper[0].o_value != 0) {
312 asm_operand(i->i_oper+0, buf, ip);
313 w = printf("(%s)", buf);
319 /* Mnemonic & completers. */
320 asm_mnemonic(i->i_op, buf);
323 while (n < i->i_ncmpltrs) {
324 asm_completer(i->i_cmpltr + n, buf);
334 while (n < 7 && i->i_oper[n].o_type != ASM_OPER_NONE) {
336 if (n == i->i_srcidx)
341 asm_operand(i->i_oper + n, buf, ip);