sparc-dis.c revision 1.1 1 1.1 christos /* Print SPARC instructions.
2 1.1 christos Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 1.1 christos 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010
4 1.1 christos Free Software Foundation, Inc.
5 1.1 christos
6 1.1 christos This file is part of the GNU opcodes library.
7 1.1 christos
8 1.1 christos This library is free software; you can redistribute it and/or modify
9 1.1 christos it under the terms of the GNU General Public License as published by
10 1.1 christos the Free Software Foundation; either version 3, or (at your option)
11 1.1 christos any later version.
12 1.1 christos
13 1.1 christos It is distributed in the hope that it will be useful, but WITHOUT
14 1.1 christos ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 1.1 christos or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 1.1 christos License for more details.
17 1.1 christos
18 1.1 christos You should have received a copy of the GNU General Public License
19 1.1 christos along with this program; if not, write to the Free Software
20 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 1.1 christos MA 02110-1301, USA. */
22 1.1 christos
23 1.1 christos #include <stdio.h>
24 1.1 christos
25 1.1 christos #include "sysdep.h"
26 1.1 christos #include "opcode/sparc.h"
27 1.1 christos #include "dis-asm.h"
28 1.1 christos #include "libiberty.h"
29 1.1 christos #include "opintl.h"
30 1.1 christos
31 1.1 christos /* Bitmask of v9 architectures. */
32 1.1 christos #define MASK_V9 ((1 << SPARC_OPCODE_ARCH_V9) \
33 1.1 christos | (1 << SPARC_OPCODE_ARCH_V9A) \
34 1.1 christos | (1 << SPARC_OPCODE_ARCH_V9B))
35 1.1 christos /* 1 if INSN is for v9 only. */
36 1.1 christos #define V9_ONLY_P(insn) (! ((insn)->architecture & ~MASK_V9))
37 1.1 christos /* 1 if INSN is for v9. */
38 1.1 christos #define V9_P(insn) (((insn)->architecture & MASK_V9) != 0)
39 1.1 christos
40 1.1 christos /* The sorted opcode table. */
41 1.1 christos static const sparc_opcode **sorted_opcodes;
42 1.1 christos
43 1.1 christos /* For faster lookup, after insns are sorted they are hashed. */
44 1.1 christos /* ??? I think there is room for even more improvement. */
45 1.1 christos
46 1.1 christos #define HASH_SIZE 256
47 1.1 christos /* It is important that we only look at insn code bits as that is how the
48 1.1 christos opcode table is hashed. OPCODE_BITS is a table of valid bits for each
49 1.1 christos of the main types (0,1,2,3). */
50 1.1 christos static int opcode_bits[4] = { 0x01c00000, 0x0, 0x01f80000, 0x01f80000 };
51 1.1 christos #define HASH_INSN(INSN) \
52 1.1 christos ((((INSN) >> 24) & 0xc0) | (((INSN) & opcode_bits[((INSN) >> 30) & 3]) >> 19))
53 1.1 christos typedef struct sparc_opcode_hash
54 1.1 christos {
55 1.1 christos struct sparc_opcode_hash *next;
56 1.1 christos const sparc_opcode *opcode;
57 1.1 christos } sparc_opcode_hash;
58 1.1 christos
59 1.1 christos static sparc_opcode_hash *opcode_hash_table[HASH_SIZE];
60 1.1 christos
61 1.1 christos /* Sign-extend a value which is N bits long. */
62 1.1 christos #define SEX(value, bits) \
63 1.1 christos ((((int)(value)) << ((8 * sizeof (int)) - bits)) \
64 1.1 christos >> ((8 * sizeof (int)) - bits) )
65 1.1 christos
66 1.1 christos static char *reg_names[] =
67 1.1 christos { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
68 1.1 christos "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
69 1.1 christos "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
70 1.1 christos "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
71 1.1 christos "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
72 1.1 christos "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
73 1.1 christos "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
74 1.1 christos "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
75 1.1 christos "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
76 1.1 christos "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
77 1.1 christos "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
78 1.1 christos "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
79 1.1 christos /* psr, wim, tbr, fpsr, cpsr are v8 only. */
80 1.1 christos "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr"
81 1.1 christos };
82 1.1 christos
83 1.1 christos #define freg_names (®_names[4 * 8])
84 1.1 christos
85 1.1 christos /* These are ordered according to there register number in
86 1.1 christos rdpr and wrpr insns. */
87 1.1 christos static char *v9_priv_reg_names[] =
88 1.1 christos {
89 1.1 christos "tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl",
90 1.1 christos "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
91 1.1 christos "wstate", "fq", "gl"
92 1.1 christos /* "ver" - special cased */
93 1.1 christos };
94 1.1 christos
95 1.1 christos /* These are ordered according to there register number in
96 1.1 christos rdhpr and wrhpr insns. */
97 1.1 christos static char *v9_hpriv_reg_names[] =
98 1.1 christos {
99 1.1 christos "hpstate", "htstate", "resv2", "hintp", "resv4", "htba", "hver",
100 1.1 christos "resv7", "resv8", "resv9", "resv10", "resv11", "resv12", "resv13",
101 1.1 christos "resv14", "resv15", "resv16", "resv17", "resv18", "resv19", "resv20",
102 1.1 christos "resv21", "resv22", "resv23", "resv24", "resv25", "resv26", "resv27",
103 1.1 christos "resv28", "resv29", "resv30", "hstick_cmpr"
104 1.1 christos };
105 1.1 christos
106 1.1 christos /* These are ordered according to there register number in
107 1.1 christos rd and wr insns (-16). */
108 1.1 christos static char *v9a_asr_reg_names[] =
109 1.1 christos {
110 1.1 christos "pcr", "pic", "dcr", "gsr", "set_softint", "clear_softint",
111 1.1 christos "softint", "tick_cmpr", "stick", "stick_cmpr"
112 1.1 christos };
113 1.1 christos
114 1.1 christos /* Macros used to extract instruction fields. Not all fields have
115 1.1 christos macros defined here, only those which are actually used. */
116 1.1 christos
117 1.1 christos #define X_RD(i) (((i) >> 25) & 0x1f)
118 1.1 christos #define X_RS1(i) (((i) >> 14) & 0x1f)
119 1.1 christos #define X_LDST_I(i) (((i) >> 13) & 1)
120 1.1 christos #define X_ASI(i) (((i) >> 5) & 0xff)
121 1.1 christos #define X_RS2(i) (((i) >> 0) & 0x1f)
122 1.1 christos #define X_IMM(i,n) (((i) >> 0) & ((1 << (n)) - 1))
123 1.1 christos #define X_SIMM(i,n) SEX (X_IMM ((i), (n)), (n))
124 1.1 christos #define X_DISP22(i) (((i) >> 0) & 0x3fffff)
125 1.1 christos #define X_IMM22(i) X_DISP22 (i)
126 1.1 christos #define X_DISP30(i) (((i) >> 0) & 0x3fffffff)
127 1.1 christos
128 1.1 christos /* These are for v9. */
129 1.1 christos #define X_DISP16(i) (((((i) >> 20) & 3) << 14) | (((i) >> 0) & 0x3fff))
130 1.1 christos #define X_DISP19(i) (((i) >> 0) & 0x7ffff)
131 1.1 christos #define X_MEMBAR(i) ((i) & 0x7f)
132 1.1 christos
133 1.1 christos /* Here is the union which was used to extract instruction fields
134 1.1 christos before the shift and mask macros were written.
135 1.1 christos
136 1.1 christos union sparc_insn
137 1.1 christos {
138 1.1 christos unsigned long int code;
139 1.1 christos struct
140 1.1 christos {
141 1.1 christos unsigned int anop:2;
142 1.1 christos #define op ldst.anop
143 1.1 christos unsigned int anrd:5;
144 1.1 christos #define rd ldst.anrd
145 1.1 christos unsigned int op3:6;
146 1.1 christos unsigned int anrs1:5;
147 1.1 christos #define rs1 ldst.anrs1
148 1.1 christos unsigned int i:1;
149 1.1 christos unsigned int anasi:8;
150 1.1 christos #define asi ldst.anasi
151 1.1 christos unsigned int anrs2:5;
152 1.1 christos #define rs2 ldst.anrs2
153 1.1 christos #define shcnt rs2
154 1.1 christos } ldst;
155 1.1 christos struct
156 1.1 christos {
157 1.1 christos unsigned int anop:2, anrd:5, op3:6, anrs1:5, i:1;
158 1.1 christos unsigned int IMM13:13;
159 1.1 christos #define imm13 IMM13.IMM13
160 1.1 christos } IMM13;
161 1.1 christos struct
162 1.1 christos {
163 1.1 christos unsigned int anop:2;
164 1.1 christos unsigned int a:1;
165 1.1 christos unsigned int cond:4;
166 1.1 christos unsigned int op2:3;
167 1.1 christos unsigned int DISP22:22;
168 1.1 christos #define disp22 branch.DISP22
169 1.1 christos #define imm22 disp22
170 1.1 christos } branch;
171 1.1 christos struct
172 1.1 christos {
173 1.1 christos unsigned int anop:2;
174 1.1 christos unsigned int a:1;
175 1.1 christos unsigned int z:1;
176 1.1 christos unsigned int rcond:3;
177 1.1 christos unsigned int op2:3;
178 1.1 christos unsigned int DISP16HI:2;
179 1.1 christos unsigned int p:1;
180 1.1 christos unsigned int _rs1:5;
181 1.1 christos unsigned int DISP16LO:14;
182 1.1 christos } branch16;
183 1.1 christos struct
184 1.1 christos {
185 1.1 christos unsigned int anop:2;
186 1.1 christos unsigned int adisp30:30;
187 1.1 christos #define disp30 call.adisp30
188 1.1 christos } call;
189 1.1 christos }; */
190 1.1 christos
191 1.1 christos /* Nonzero if INSN is the opcode for a delayed branch. */
192 1.1 christos
193 1.1 christos static int
194 1.1 christos is_delayed_branch (unsigned long insn)
195 1.1 christos {
196 1.1 christos sparc_opcode_hash *op;
197 1.1 christos
198 1.1 christos for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
199 1.1 christos {
200 1.1 christos const sparc_opcode *opcode = op->opcode;
201 1.1 christos
202 1.1 christos if ((opcode->match & insn) == opcode->match
203 1.1 christos && (opcode->lose & insn) == 0)
204 1.1 christos return opcode->flags & F_DELAYED;
205 1.1 christos }
206 1.1 christos return 0;
207 1.1 christos }
208 1.1 christos
209 1.1 christos /* extern void qsort (); */
210 1.1 christos
211 1.1 christos /* Records current mask of SPARC_OPCODE_ARCH_FOO values, used to pass value
212 1.1 christos to compare_opcodes. */
213 1.1 christos static unsigned int current_arch_mask;
214 1.1 christos
215 1.1 christos /* Given BFD mach number, return a mask of SPARC_OPCODE_ARCH_FOO values. */
216 1.1 christos
217 1.1 christos static int
218 1.1 christos compute_arch_mask (unsigned long mach)
219 1.1 christos {
220 1.1 christos switch (mach)
221 1.1 christos {
222 1.1 christos case 0 :
223 1.1 christos case bfd_mach_sparc :
224 1.1 christos return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8);
225 1.1 christos case bfd_mach_sparc_sparclet :
226 1.1 christos return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLET);
227 1.1 christos case bfd_mach_sparc_sparclite :
228 1.1 christos case bfd_mach_sparc_sparclite_le :
229 1.1 christos /* sparclites insns are recognized by default (because that's how
230 1.1 christos they've always been treated, for better or worse). Kludge this by
231 1.1 christos indicating generic v8 is also selected. */
232 1.1 christos return (SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLITE)
233 1.1 christos | SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8));
234 1.1 christos case bfd_mach_sparc_v8plus :
235 1.1 christos case bfd_mach_sparc_v9 :
236 1.1 christos return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9);
237 1.1 christos case bfd_mach_sparc_v8plusa :
238 1.1 christos case bfd_mach_sparc_v9a :
239 1.1 christos return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9A);
240 1.1 christos case bfd_mach_sparc_v8plusb :
241 1.1 christos case bfd_mach_sparc_v9b :
242 1.1 christos return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9B);
243 1.1 christos }
244 1.1 christos abort ();
245 1.1 christos }
246 1.1 christos
247 1.1 christos /* Compare opcodes A and B. */
248 1.1 christos
249 1.1 christos static int
250 1.1 christos compare_opcodes (const void * a, const void * b)
251 1.1 christos {
252 1.1 christos sparc_opcode *op0 = * (sparc_opcode **) a;
253 1.1 christos sparc_opcode *op1 = * (sparc_opcode **) b;
254 1.1 christos unsigned long int match0 = op0->match, match1 = op1->match;
255 1.1 christos unsigned long int lose0 = op0->lose, lose1 = op1->lose;
256 1.1 christos register unsigned int i;
257 1.1 christos
258 1.1 christos /* If one (and only one) insn isn't supported by the current architecture,
259 1.1 christos prefer the one that is. If neither are supported, but they're both for
260 1.1 christos the same architecture, continue processing. Otherwise (both unsupported
261 1.1 christos and for different architectures), prefer lower numbered arch's (fudged
262 1.1 christos by comparing the bitmasks). */
263 1.1 christos if (op0->architecture & current_arch_mask)
264 1.1 christos {
265 1.1 christos if (! (op1->architecture & current_arch_mask))
266 1.1 christos return -1;
267 1.1 christos }
268 1.1 christos else
269 1.1 christos {
270 1.1 christos if (op1->architecture & current_arch_mask)
271 1.1 christos return 1;
272 1.1 christos else if (op0->architecture != op1->architecture)
273 1.1 christos return op0->architecture - op1->architecture;
274 1.1 christos }
275 1.1 christos
276 1.1 christos /* If a bit is set in both match and lose, there is something
277 1.1 christos wrong with the opcode table. */
278 1.1 christos if (match0 & lose0)
279 1.1 christos {
280 1.1 christos fprintf
281 1.1 christos (stderr,
282 1.1 christos /* xgettext:c-format */
283 1.1 christos _("Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"),
284 1.1 christos op0->name, match0, lose0);
285 1.1 christos op0->lose &= ~op0->match;
286 1.1 christos lose0 = op0->lose;
287 1.1 christos }
288 1.1 christos
289 1.1 christos if (match1 & lose1)
290 1.1 christos {
291 1.1 christos fprintf
292 1.1 christos (stderr,
293 1.1 christos /* xgettext:c-format */
294 1.1 christos _("Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"),
295 1.1 christos op1->name, match1, lose1);
296 1.1 christos op1->lose &= ~op1->match;
297 1.1 christos lose1 = op1->lose;
298 1.1 christos }
299 1.1 christos
300 1.1 christos /* Because the bits that are variable in one opcode are constant in
301 1.1 christos another, it is important to order the opcodes in the right order. */
302 1.1 christos for (i = 0; i < 32; ++i)
303 1.1 christos {
304 1.1 christos unsigned long int x = 1 << i;
305 1.1 christos int x0 = (match0 & x) != 0;
306 1.1 christos int x1 = (match1 & x) != 0;
307 1.1 christos
308 1.1 christos if (x0 != x1)
309 1.1 christos return x1 - x0;
310 1.1 christos }
311 1.1 christos
312 1.1 christos for (i = 0; i < 32; ++i)
313 1.1 christos {
314 1.1 christos unsigned long int x = 1 << i;
315 1.1 christos int x0 = (lose0 & x) != 0;
316 1.1 christos int x1 = (lose1 & x) != 0;
317 1.1 christos
318 1.1 christos if (x0 != x1)
319 1.1 christos return x1 - x0;
320 1.1 christos }
321 1.1 christos
322 1.1 christos /* They are functionally equal. So as long as the opcode table is
323 1.1 christos valid, we can put whichever one first we want, on aesthetic grounds. */
324 1.1 christos
325 1.1 christos /* Our first aesthetic ground is that aliases defer to real insns. */
326 1.1 christos {
327 1.1 christos int alias_diff = (op0->flags & F_ALIAS) - (op1->flags & F_ALIAS);
328 1.1 christos
329 1.1 christos if (alias_diff != 0)
330 1.1 christos /* Put the one that isn't an alias first. */
331 1.1 christos return alias_diff;
332 1.1 christos }
333 1.1 christos
334 1.1 christos /* Except for aliases, two "identical" instructions had
335 1.1 christos better have the same opcode. This is a sanity check on the table. */
336 1.1 christos i = strcmp (op0->name, op1->name);
337 1.1 christos if (i)
338 1.1 christos {
339 1.1 christos if (op0->flags & F_ALIAS) /* If they're both aliases, be arbitrary. */
340 1.1 christos return i;
341 1.1 christos else
342 1.1 christos fprintf (stderr,
343 1.1 christos /* xgettext:c-format */
344 1.1 christos _("Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n"),
345 1.1 christos op0->name, op1->name);
346 1.1 christos }
347 1.1 christos
348 1.1 christos /* Fewer arguments are preferred. */
349 1.1 christos {
350 1.1 christos int length_diff = strlen (op0->args) - strlen (op1->args);
351 1.1 christos
352 1.1 christos if (length_diff != 0)
353 1.1 christos /* Put the one with fewer arguments first. */
354 1.1 christos return length_diff;
355 1.1 christos }
356 1.1 christos
357 1.1 christos /* Put 1+i before i+1. */
358 1.1 christos {
359 1.1 christos char *p0 = (char *) strchr (op0->args, '+');
360 1.1 christos char *p1 = (char *) strchr (op1->args, '+');
361 1.1 christos
362 1.1 christos if (p0 && p1)
363 1.1 christos {
364 1.1 christos /* There is a plus in both operands. Note that a plus
365 1.1 christos sign cannot be the first character in args,
366 1.1 christos so the following [-1]'s are valid. */
367 1.1 christos if (p0[-1] == 'i' && p1[1] == 'i')
368 1.1 christos /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
369 1.1 christos return 1;
370 1.1 christos if (p0[1] == 'i' && p1[-1] == 'i')
371 1.1 christos /* op0 is 1+i and op1 is i+1, so op0 goes first. */
372 1.1 christos return -1;
373 1.1 christos }
374 1.1 christos }
375 1.1 christos
376 1.1 christos /* Put 1,i before i,1. */
377 1.1 christos {
378 1.1 christos int i0 = strncmp (op0->args, "i,1", 3) == 0;
379 1.1 christos int i1 = strncmp (op1->args, "i,1", 3) == 0;
380 1.1 christos
381 1.1 christos if (i0 ^ i1)
382 1.1 christos return i0 - i1;
383 1.1 christos }
384 1.1 christos
385 1.1 christos /* They are, as far as we can tell, identical.
386 1.1 christos Since qsort may have rearranged the table partially, there is
387 1.1 christos no way to tell which one was first in the opcode table as
388 1.1 christos written, so just say there are equal. */
389 1.1 christos /* ??? This is no longer true now that we sort a vector of pointers,
390 1.1 christos not the table itself. */
391 1.1 christos return 0;
392 1.1 christos }
393 1.1 christos
394 1.1 christos /* Build a hash table from the opcode table.
395 1.1 christos OPCODE_TABLE is a sorted list of pointers into the opcode table. */
396 1.1 christos
397 1.1 christos static void
398 1.1 christos build_hash_table (const sparc_opcode **opcode_table,
399 1.1 christos sparc_opcode_hash **hash_table,
400 1.1 christos int num_opcodes)
401 1.1 christos {
402 1.1 christos int i;
403 1.1 christos int hash_count[HASH_SIZE];
404 1.1 christos static sparc_opcode_hash *hash_buf = NULL;
405 1.1 christos
406 1.1 christos /* Start at the end of the table and work backwards so that each
407 1.1 christos chain is sorted. */
408 1.1 christos
409 1.1 christos memset (hash_table, 0, HASH_SIZE * sizeof (hash_table[0]));
410 1.1 christos memset (hash_count, 0, HASH_SIZE * sizeof (hash_count[0]));
411 1.1 christos if (hash_buf != NULL)
412 1.1 christos free (hash_buf);
413 1.1 christos hash_buf = xmalloc (sizeof (* hash_buf) * num_opcodes);
414 1.1 christos for (i = num_opcodes - 1; i >= 0; --i)
415 1.1 christos {
416 1.1 christos int hash = HASH_INSN (opcode_table[i]->match);
417 1.1 christos sparc_opcode_hash *h = &hash_buf[i];
418 1.1 christos
419 1.1 christos h->next = hash_table[hash];
420 1.1 christos h->opcode = opcode_table[i];
421 1.1 christos hash_table[hash] = h;
422 1.1 christos ++hash_count[hash];
423 1.1 christos }
424 1.1 christos
425 1.1 christos #if 0 /* for debugging */
426 1.1 christos {
427 1.1 christos int min_count = num_opcodes, max_count = 0;
428 1.1 christos int total;
429 1.1 christos
430 1.1 christos for (i = 0; i < HASH_SIZE; ++i)
431 1.1 christos {
432 1.1 christos if (hash_count[i] < min_count)
433 1.1 christos min_count = hash_count[i];
434 1.1 christos if (hash_count[i] > max_count)
435 1.1 christos max_count = hash_count[i];
436 1.1 christos total += hash_count[i];
437 1.1 christos }
438 1.1 christos
439 1.1 christos printf ("Opcode hash table stats: min %d, max %d, ave %f\n",
440 1.1 christos min_count, max_count, (double) total / HASH_SIZE);
441 1.1 christos }
442 1.1 christos #endif
443 1.1 christos }
444 1.1 christos
445 1.1 christos /* Print one instruction from MEMADDR on INFO->STREAM.
446 1.1 christos
447 1.1 christos We suffix the instruction with a comment that gives the absolute
448 1.1 christos address involved, as well as its symbolic form, if the instruction
449 1.1 christos is preceded by a findable `sethi' and it either adds an immediate
450 1.1 christos displacement to that register, or it is an `add' or `or' instruction
451 1.1 christos on that register. */
452 1.1 christos
453 1.1 christos int
454 1.1 christos print_insn_sparc (bfd_vma memaddr, disassemble_info *info)
455 1.1 christos {
456 1.1 christos FILE *stream = info->stream;
457 1.1 christos bfd_byte buffer[4];
458 1.1 christos unsigned long insn;
459 1.1 christos sparc_opcode_hash *op;
460 1.1 christos /* Nonzero of opcode table has been initialized. */
461 1.1 christos static int opcodes_initialized = 0;
462 1.1 christos /* bfd mach number of last call. */
463 1.1 christos static unsigned long current_mach = 0;
464 1.1 christos bfd_vma (*getword) (const void *);
465 1.1 christos
466 1.1 christos if (!opcodes_initialized
467 1.1 christos || info->mach != current_mach)
468 1.1 christos {
469 1.1 christos int i;
470 1.1 christos
471 1.1 christos current_arch_mask = compute_arch_mask (info->mach);
472 1.1 christos
473 1.1 christos if (!opcodes_initialized)
474 1.1 christos sorted_opcodes =
475 1.1 christos xmalloc (sparc_num_opcodes * sizeof (sparc_opcode *));
476 1.1 christos /* Reset the sorted table so we can resort it. */
477 1.1 christos for (i = 0; i < sparc_num_opcodes; ++i)
478 1.1 christos sorted_opcodes[i] = &sparc_opcodes[i];
479 1.1 christos qsort ((char *) sorted_opcodes, sparc_num_opcodes,
480 1.1 christos sizeof (sorted_opcodes[0]), compare_opcodes);
481 1.1 christos
482 1.1 christos build_hash_table (sorted_opcodes, opcode_hash_table, sparc_num_opcodes);
483 1.1 christos current_mach = info->mach;
484 1.1 christos opcodes_initialized = 1;
485 1.1 christos }
486 1.1 christos
487 1.1 christos {
488 1.1 christos int status =
489 1.1 christos (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
490 1.1 christos
491 1.1 christos if (status != 0)
492 1.1 christos {
493 1.1 christos (*info->memory_error_func) (status, memaddr, info);
494 1.1 christos return -1;
495 1.1 christos }
496 1.1 christos }
497 1.1 christos
498 1.1 christos /* On SPARClite variants such as DANlite (sparc86x), instructions
499 1.1 christos are always big-endian even when the machine is in little-endian mode. */
500 1.1 christos if (info->endian == BFD_ENDIAN_BIG || info->mach == bfd_mach_sparc_sparclite)
501 1.1 christos getword = bfd_getb32;
502 1.1 christos else
503 1.1 christos getword = bfd_getl32;
504 1.1 christos
505 1.1 christos insn = getword (buffer);
506 1.1 christos
507 1.1 christos info->insn_info_valid = 1; /* We do return this info. */
508 1.1 christos info->insn_type = dis_nonbranch; /* Assume non branch insn. */
509 1.1 christos info->branch_delay_insns = 0; /* Assume no delay. */
510 1.1 christos info->target = 0; /* Assume no target known. */
511 1.1 christos
512 1.1 christos for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
513 1.1 christos {
514 1.1 christos const sparc_opcode *opcode = op->opcode;
515 1.1 christos
516 1.1 christos /* If the insn isn't supported by the current architecture, skip it. */
517 1.1 christos if (! (opcode->architecture & current_arch_mask))
518 1.1 christos continue;
519 1.1 christos
520 1.1 christos if ((opcode->match & insn) == opcode->match
521 1.1 christos && (opcode->lose & insn) == 0)
522 1.1 christos {
523 1.1 christos /* Nonzero means that we have found an instruction which has
524 1.1 christos the effect of adding or or'ing the imm13 field to rs1. */
525 1.1 christos int imm_added_to_rs1 = 0;
526 1.1 christos int imm_ored_to_rs1 = 0;
527 1.1 christos
528 1.1 christos /* Nonzero means that we have found a plus sign in the args
529 1.1 christos field of the opcode table. */
530 1.1 christos int found_plus = 0;
531 1.1 christos
532 1.1 christos /* Nonzero means we have an annulled branch. */
533 1.1 christos int is_annulled = 0;
534 1.1 christos
535 1.1 christos /* Do we have an `add' or `or' instruction combining an
536 1.1 christos immediate with rs1? */
537 1.1 christos if (opcode->match == 0x80102000) /* or */
538 1.1 christos imm_ored_to_rs1 = 1;
539 1.1 christos if (opcode->match == 0x80002000) /* add */
540 1.1 christos imm_added_to_rs1 = 1;
541 1.1 christos
542 1.1 christos if (X_RS1 (insn) != X_RD (insn)
543 1.1 christos && strchr (opcode->args, 'r') != 0)
544 1.1 christos /* Can't do simple format if source and dest are different. */
545 1.1 christos continue;
546 1.1 christos if (X_RS2 (insn) != X_RD (insn)
547 1.1 christos && strchr (opcode->args, 'O') != 0)
548 1.1 christos /* Can't do simple format if source and dest are different. */
549 1.1 christos continue;
550 1.1 christos
551 1.1 christos (*info->fprintf_func) (stream, opcode->name);
552 1.1 christos
553 1.1 christos {
554 1.1 christos const char *s;
555 1.1 christos
556 1.1 christos if (opcode->args[0] != ',')
557 1.1 christos (*info->fprintf_func) (stream, " ");
558 1.1 christos
559 1.1 christos for (s = opcode->args; *s != '\0'; ++s)
560 1.1 christos {
561 1.1 christos while (*s == ',')
562 1.1 christos {
563 1.1 christos (*info->fprintf_func) (stream, ",");
564 1.1 christos ++s;
565 1.1 christos switch (*s)
566 1.1 christos {
567 1.1 christos case 'a':
568 1.1 christos (*info->fprintf_func) (stream, "a");
569 1.1 christos is_annulled = 1;
570 1.1 christos ++s;
571 1.1 christos continue;
572 1.1 christos case 'N':
573 1.1 christos (*info->fprintf_func) (stream, "pn");
574 1.1 christos ++s;
575 1.1 christos continue;
576 1.1 christos
577 1.1 christos case 'T':
578 1.1 christos (*info->fprintf_func) (stream, "pt");
579 1.1 christos ++s;
580 1.1 christos continue;
581 1.1 christos
582 1.1 christos default:
583 1.1 christos break;
584 1.1 christos }
585 1.1 christos }
586 1.1 christos
587 1.1 christos (*info->fprintf_func) (stream, " ");
588 1.1 christos
589 1.1 christos switch (*s)
590 1.1 christos {
591 1.1 christos case '+':
592 1.1 christos found_plus = 1;
593 1.1 christos /* Fall through. */
594 1.1 christos
595 1.1 christos default:
596 1.1 christos (*info->fprintf_func) (stream, "%c", *s);
597 1.1 christos break;
598 1.1 christos
599 1.1 christos case '#':
600 1.1 christos (*info->fprintf_func) (stream, "0");
601 1.1 christos break;
602 1.1 christos
603 1.1 christos #define reg(n) (*info->fprintf_func) (stream, "%%%s", reg_names[n])
604 1.1 christos case '1':
605 1.1 christos case 'r':
606 1.1 christos reg (X_RS1 (insn));
607 1.1 christos break;
608 1.1 christos
609 1.1 christos case '2':
610 1.1 christos case 'O':
611 1.1 christos reg (X_RS2 (insn));
612 1.1 christos break;
613 1.1 christos
614 1.1 christos case 'd':
615 1.1 christos reg (X_RD (insn));
616 1.1 christos break;
617 1.1 christos #undef reg
618 1.1 christos
619 1.1 christos #define freg(n) (*info->fprintf_func) (stream, "%%%s", freg_names[n])
620 1.1 christos #define fregx(n) (*info->fprintf_func) (stream, "%%%s", freg_names[((n) & ~1) | (((n) & 1) << 5)])
621 1.1 christos case 'e':
622 1.1 christos freg (X_RS1 (insn));
623 1.1 christos break;
624 1.1 christos case 'v': /* Double/even. */
625 1.1 christos case 'V': /* Quad/multiple of 4. */
626 1.1 christos fregx (X_RS1 (insn));
627 1.1 christos break;
628 1.1 christos
629 1.1 christos case 'f':
630 1.1 christos freg (X_RS2 (insn));
631 1.1 christos break;
632 1.1 christos case 'B': /* Double/even. */
633 1.1 christos case 'R': /* Quad/multiple of 4. */
634 1.1 christos fregx (X_RS2 (insn));
635 1.1 christos break;
636 1.1 christos
637 1.1 christos case 'g':
638 1.1 christos freg (X_RD (insn));
639 1.1 christos break;
640 1.1 christos case 'H': /* Double/even. */
641 1.1 christos case 'J': /* Quad/multiple of 4. */
642 1.1 christos fregx (X_RD (insn));
643 1.1 christos break;
644 1.1 christos #undef freg
645 1.1 christos #undef fregx
646 1.1 christos
647 1.1 christos #define creg(n) (*info->fprintf_func) (stream, "%%c%u", (unsigned int) (n))
648 1.1 christos case 'b':
649 1.1 christos creg (X_RS1 (insn));
650 1.1 christos break;
651 1.1 christos
652 1.1 christos case 'c':
653 1.1 christos creg (X_RS2 (insn));
654 1.1 christos break;
655 1.1 christos
656 1.1 christos case 'D':
657 1.1 christos creg (X_RD (insn));
658 1.1 christos break;
659 1.1 christos #undef creg
660 1.1 christos
661 1.1 christos case 'h':
662 1.1 christos (*info->fprintf_func) (stream, "%%hi(%#x)",
663 1.1 christos ((unsigned) 0xFFFFFFFF
664 1.1 christos & ((int) X_IMM22 (insn) << 10)));
665 1.1 christos break;
666 1.1 christos
667 1.1 christos case 'i': /* 13 bit immediate. */
668 1.1 christos case 'I': /* 11 bit immediate. */
669 1.1 christos case 'j': /* 10 bit immediate. */
670 1.1 christos {
671 1.1 christos int imm;
672 1.1 christos
673 1.1 christos if (*s == 'i')
674 1.1 christos imm = X_SIMM (insn, 13);
675 1.1 christos else if (*s == 'I')
676 1.1 christos imm = X_SIMM (insn, 11);
677 1.1 christos else
678 1.1 christos imm = X_SIMM (insn, 10);
679 1.1 christos
680 1.1 christos /* Check to see whether we have a 1+i, and take
681 1.1 christos note of that fact.
682 1.1 christos
683 1.1 christos Note: because of the way we sort the table,
684 1.1 christos we will be matching 1+i rather than i+1,
685 1.1 christos so it is OK to assume that i is after +,
686 1.1 christos not before it. */
687 1.1 christos if (found_plus)
688 1.1 christos imm_added_to_rs1 = 1;
689 1.1 christos
690 1.1 christos if (imm <= 9)
691 1.1 christos (*info->fprintf_func) (stream, "%d", imm);
692 1.1 christos else
693 1.1 christos (*info->fprintf_func) (stream, "%#x", imm);
694 1.1 christos }
695 1.1 christos break;
696 1.1 christos
697 1.1 christos case 'X': /* 5 bit unsigned immediate. */
698 1.1 christos case 'Y': /* 6 bit unsigned immediate. */
699 1.1 christos {
700 1.1 christos int imm = X_IMM (insn, *s == 'X' ? 5 : 6);
701 1.1 christos
702 1.1 christos if (imm <= 9)
703 1.1 christos (info->fprintf_func) (stream, "%d", imm);
704 1.1 christos else
705 1.1 christos (info->fprintf_func) (stream, "%#x", (unsigned) imm);
706 1.1 christos }
707 1.1 christos break;
708 1.1 christos
709 1.1 christos case '3':
710 1.1 christos (info->fprintf_func) (stream, "%ld", X_IMM (insn, 3));
711 1.1 christos break;
712 1.1 christos
713 1.1 christos case 'K':
714 1.1 christos {
715 1.1 christos int mask = X_MEMBAR (insn);
716 1.1 christos int bit = 0x40, printed_one = 0;
717 1.1 christos const char *name;
718 1.1 christos
719 1.1 christos if (mask == 0)
720 1.1 christos (info->fprintf_func) (stream, "0");
721 1.1 christos else
722 1.1 christos while (bit)
723 1.1 christos {
724 1.1 christos if (mask & bit)
725 1.1 christos {
726 1.1 christos if (printed_one)
727 1.1 christos (info->fprintf_func) (stream, "|");
728 1.1 christos name = sparc_decode_membar (bit);
729 1.1 christos (info->fprintf_func) (stream, "%s", name);
730 1.1 christos printed_one = 1;
731 1.1 christos }
732 1.1 christos bit >>= 1;
733 1.1 christos }
734 1.1 christos break;
735 1.1 christos }
736 1.1 christos
737 1.1 christos case 'k':
738 1.1 christos info->target = memaddr + SEX (X_DISP16 (insn), 16) * 4;
739 1.1 christos (*info->print_address_func) (info->target, info);
740 1.1 christos break;
741 1.1 christos
742 1.1 christos case 'G':
743 1.1 christos info->target = memaddr + SEX (X_DISP19 (insn), 19) * 4;
744 1.1 christos (*info->print_address_func) (info->target, info);
745 1.1 christos break;
746 1.1 christos
747 1.1 christos case '6':
748 1.1 christos case '7':
749 1.1 christos case '8':
750 1.1 christos case '9':
751 1.1 christos (*info->fprintf_func) (stream, "%%fcc%c", *s - '6' + '0');
752 1.1 christos break;
753 1.1 christos
754 1.1 christos case 'z':
755 1.1 christos (*info->fprintf_func) (stream, "%%icc");
756 1.1 christos break;
757 1.1 christos
758 1.1 christos case 'Z':
759 1.1 christos (*info->fprintf_func) (stream, "%%xcc");
760 1.1 christos break;
761 1.1 christos
762 1.1 christos case 'E':
763 1.1 christos (*info->fprintf_func) (stream, "%%ccr");
764 1.1 christos break;
765 1.1 christos
766 1.1 christos case 's':
767 1.1 christos (*info->fprintf_func) (stream, "%%fprs");
768 1.1 christos break;
769 1.1 christos
770 1.1 christos case 'o':
771 1.1 christos (*info->fprintf_func) (stream, "%%asi");
772 1.1 christos break;
773 1.1 christos
774 1.1 christos case 'W':
775 1.1 christos (*info->fprintf_func) (stream, "%%tick");
776 1.1 christos break;
777 1.1 christos
778 1.1 christos case 'P':
779 1.1 christos (*info->fprintf_func) (stream, "%%pc");
780 1.1 christos break;
781 1.1 christos
782 1.1 christos case '?':
783 1.1 christos if (X_RS1 (insn) == 31)
784 1.1 christos (*info->fprintf_func) (stream, "%%ver");
785 1.1 christos else if ((unsigned) X_RS1 (insn) < 17)
786 1.1 christos (*info->fprintf_func) (stream, "%%%s",
787 1.1 christos v9_priv_reg_names[X_RS1 (insn)]);
788 1.1 christos else
789 1.1 christos (*info->fprintf_func) (stream, "%%reserved");
790 1.1 christos break;
791 1.1 christos
792 1.1 christos case '!':
793 1.1 christos if ((unsigned) X_RD (insn) < 17)
794 1.1 christos (*info->fprintf_func) (stream, "%%%s",
795 1.1 christos v9_priv_reg_names[X_RD (insn)]);
796 1.1 christos else
797 1.1 christos (*info->fprintf_func) (stream, "%%reserved");
798 1.1 christos break;
799 1.1 christos
800 1.1 christos case '$':
801 1.1 christos if ((unsigned) X_RS1 (insn) < 32)
802 1.1 christos (*info->fprintf_func) (stream, "%%%s",
803 1.1 christos v9_hpriv_reg_names[X_RS1 (insn)]);
804 1.1 christos else
805 1.1 christos (*info->fprintf_func) (stream, "%%reserved");
806 1.1 christos break;
807 1.1 christos
808 1.1 christos case '%':
809 1.1 christos if ((unsigned) X_RD (insn) < 32)
810 1.1 christos (*info->fprintf_func) (stream, "%%%s",
811 1.1 christos v9_hpriv_reg_names[X_RD (insn)]);
812 1.1 christos else
813 1.1 christos (*info->fprintf_func) (stream, "%%reserved");
814 1.1 christos break;
815 1.1 christos
816 1.1 christos case '/':
817 1.1 christos if (X_RS1 (insn) < 16 || X_RS1 (insn) > 25)
818 1.1 christos (*info->fprintf_func) (stream, "%%reserved");
819 1.1 christos else
820 1.1 christos (*info->fprintf_func) (stream, "%%%s",
821 1.1 christos v9a_asr_reg_names[X_RS1 (insn)-16]);
822 1.1 christos break;
823 1.1 christos
824 1.1 christos case '_':
825 1.1 christos if (X_RD (insn) < 16 || X_RD (insn) > 25)
826 1.1 christos (*info->fprintf_func) (stream, "%%reserved");
827 1.1 christos else
828 1.1 christos (*info->fprintf_func) (stream, "%%%s",
829 1.1 christos v9a_asr_reg_names[X_RD (insn)-16]);
830 1.1 christos break;
831 1.1 christos
832 1.1 christos case '*':
833 1.1 christos {
834 1.1 christos const char *name = sparc_decode_prefetch (X_RD (insn));
835 1.1 christos
836 1.1 christos if (name)
837 1.1 christos (*info->fprintf_func) (stream, "%s", name);
838 1.1 christos else
839 1.1 christos (*info->fprintf_func) (stream, "%ld", X_RD (insn));
840 1.1 christos break;
841 1.1 christos }
842 1.1 christos
843 1.1 christos case 'M':
844 1.1 christos (*info->fprintf_func) (stream, "%%asr%ld", X_RS1 (insn));
845 1.1 christos break;
846 1.1 christos
847 1.1 christos case 'm':
848 1.1 christos (*info->fprintf_func) (stream, "%%asr%ld", X_RD (insn));
849 1.1 christos break;
850 1.1 christos
851 1.1 christos case 'L':
852 1.1 christos info->target = memaddr + SEX (X_DISP30 (insn), 30) * 4;
853 1.1 christos (*info->print_address_func) (info->target, info);
854 1.1 christos break;
855 1.1 christos
856 1.1 christos case 'n':
857 1.1 christos (*info->fprintf_func)
858 1.1 christos (stream, "%#x", SEX (X_DISP22 (insn), 22));
859 1.1 christos break;
860 1.1 christos
861 1.1 christos case 'l':
862 1.1 christos info->target = memaddr + SEX (X_DISP22 (insn), 22) * 4;
863 1.1 christos (*info->print_address_func) (info->target, info);
864 1.1 christos break;
865 1.1 christos
866 1.1 christos case 'A':
867 1.1 christos {
868 1.1 christos const char *name = sparc_decode_asi (X_ASI (insn));
869 1.1 christos
870 1.1 christos if (name)
871 1.1 christos (*info->fprintf_func) (stream, "%s", name);
872 1.1 christos else
873 1.1 christos (*info->fprintf_func) (stream, "(%ld)", X_ASI (insn));
874 1.1 christos break;
875 1.1 christos }
876 1.1 christos
877 1.1 christos case 'C':
878 1.1 christos (*info->fprintf_func) (stream, "%%csr");
879 1.1 christos break;
880 1.1 christos
881 1.1 christos case 'F':
882 1.1 christos (*info->fprintf_func) (stream, "%%fsr");
883 1.1 christos break;
884 1.1 christos
885 1.1 christos case 'p':
886 1.1 christos (*info->fprintf_func) (stream, "%%psr");
887 1.1 christos break;
888 1.1 christos
889 1.1 christos case 'q':
890 1.1 christos (*info->fprintf_func) (stream, "%%fq");
891 1.1 christos break;
892 1.1 christos
893 1.1 christos case 'Q':
894 1.1 christos (*info->fprintf_func) (stream, "%%cq");
895 1.1 christos break;
896 1.1 christos
897 1.1 christos case 't':
898 1.1 christos (*info->fprintf_func) (stream, "%%tbr");
899 1.1 christos break;
900 1.1 christos
901 1.1 christos case 'w':
902 1.1 christos (*info->fprintf_func) (stream, "%%wim");
903 1.1 christos break;
904 1.1 christos
905 1.1 christos case 'x':
906 1.1 christos (*info->fprintf_func) (stream, "%ld",
907 1.1 christos ((X_LDST_I (insn) << 8)
908 1.1 christos + X_ASI (insn)));
909 1.1 christos break;
910 1.1 christos
911 1.1 christos case 'y':
912 1.1 christos (*info->fprintf_func) (stream, "%%y");
913 1.1 christos break;
914 1.1 christos
915 1.1 christos case 'u':
916 1.1 christos case 'U':
917 1.1 christos {
918 1.1 christos int val = *s == 'U' ? X_RS1 (insn) : X_RD (insn);
919 1.1 christos const char *name = sparc_decode_sparclet_cpreg (val);
920 1.1 christos
921 1.1 christos if (name)
922 1.1 christos (*info->fprintf_func) (stream, "%s", name);
923 1.1 christos else
924 1.1 christos (*info->fprintf_func) (stream, "%%cpreg(%d)", val);
925 1.1 christos break;
926 1.1 christos }
927 1.1 christos }
928 1.1 christos }
929 1.1 christos }
930 1.1 christos
931 1.1 christos /* If we are adding or or'ing something to rs1, then
932 1.1 christos check to see whether the previous instruction was
933 1.1 christos a sethi to the same register as in the sethi.
934 1.1 christos If so, attempt to print the result of the add or
935 1.1 christos or (in this context add and or do the same thing)
936 1.1 christos and its symbolic value. */
937 1.1 christos if (imm_ored_to_rs1 || imm_added_to_rs1)
938 1.1 christos {
939 1.1 christos unsigned long prev_insn;
940 1.1 christos int errcode;
941 1.1 christos
942 1.1 christos if (memaddr >= 4)
943 1.1 christos errcode =
944 1.1 christos (*info->read_memory_func)
945 1.1 christos (memaddr - 4, buffer, sizeof (buffer), info);
946 1.1 christos else
947 1.1 christos errcode = 1;
948 1.1 christos
949 1.1 christos prev_insn = getword (buffer);
950 1.1 christos
951 1.1 christos if (errcode == 0)
952 1.1 christos {
953 1.1 christos /* If it is a delayed branch, we need to look at the
954 1.1 christos instruction before the delayed branch. This handles
955 1.1 christos sequences such as:
956 1.1 christos
957 1.1 christos sethi %o1, %hi(_foo), %o1
958 1.1 christos call _printf
959 1.1 christos or %o1, %lo(_foo), %o1 */
960 1.1 christos
961 1.1 christos if (is_delayed_branch (prev_insn))
962 1.1 christos {
963 1.1 christos if (memaddr >= 8)
964 1.1 christos errcode = (*info->read_memory_func)
965 1.1 christos (memaddr - 8, buffer, sizeof (buffer), info);
966 1.1 christos else
967 1.1 christos errcode = 1;
968 1.1 christos
969 1.1 christos prev_insn = getword (buffer);
970 1.1 christos }
971 1.1 christos }
972 1.1 christos
973 1.1 christos /* If there was a problem reading memory, then assume
974 1.1 christos the previous instruction was not sethi. */
975 1.1 christos if (errcode == 0)
976 1.1 christos {
977 1.1 christos /* Is it sethi to the same register? */
978 1.1 christos if ((prev_insn & 0xc1c00000) == 0x01000000
979 1.1 christos && X_RD (prev_insn) == X_RS1 (insn))
980 1.1 christos {
981 1.1 christos (*info->fprintf_func) (stream, "\t! ");
982 1.1 christos info->target =
983 1.1 christos ((unsigned) 0xFFFFFFFF
984 1.1 christos & ((int) X_IMM22 (prev_insn) << 10));
985 1.1 christos if (imm_added_to_rs1)
986 1.1 christos info->target += X_SIMM (insn, 13);
987 1.1 christos else
988 1.1 christos info->target |= X_SIMM (insn, 13);
989 1.1 christos (*info->print_address_func) (info->target, info);
990 1.1 christos info->insn_type = dis_dref;
991 1.1 christos info->data_size = 4; /* FIXME!!! */
992 1.1 christos }
993 1.1 christos }
994 1.1 christos }
995 1.1 christos
996 1.1 christos if (opcode->flags & (F_UNBR|F_CONDBR|F_JSR))
997 1.1 christos {
998 1.1 christos /* FIXME -- check is_annulled flag. */
999 1.1 christos (void) is_annulled;
1000 1.1 christos if (opcode->flags & F_UNBR)
1001 1.1 christos info->insn_type = dis_branch;
1002 1.1 christos if (opcode->flags & F_CONDBR)
1003 1.1 christos info->insn_type = dis_condbranch;
1004 1.1 christos if (opcode->flags & F_JSR)
1005 1.1 christos info->insn_type = dis_jsr;
1006 1.1 christos if (opcode->flags & F_DELAYED)
1007 1.1 christos info->branch_delay_insns = 1;
1008 1.1 christos }
1009 1.1 christos
1010 1.1 christos return sizeof (buffer);
1011 1.1 christos }
1012 1.1 christos }
1013 1.1 christos
1014 1.1 christos info->insn_type = dis_noninsn; /* Mark as non-valid instruction. */
1015 1.1 christos (*info->fprintf_func) (stream, _("unknown"));
1016 1.1 christos return sizeof (buffer);
1017 1.1 christos }
1018