]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - opcodes/sparc-dis.c
* config/tc-sparc.c (parse_keyword_arg, parse_const_expr_arg): New fns.
[thirdparty/binutils-gdb.git] / opcodes / sparc-dis.c
CommitLineData
3ac166b1 1/* Print SPARC instructions.
f069afb4 2 Copyright 1989, 1991, 1992, 1993, 1995 Free Software Foundation, Inc.
2fa0b342 3
3ac166b1 4This program is free software; you can redistribute it and/or modify
2fa0b342 5it under the terms of the GNU General Public License as published by
3ac166b1
JK
6the Free Software Foundation; either version 2 of the License, or
7(at your option) any later version.
2fa0b342 8
3ac166b1 9This program is distributed in the hope that it will be useful,
2fa0b342
DHW
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
3ac166b1 15along with this program; if not, write to the Free Software
f069afb4 16Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
2fa0b342 17
f069afb4 18#include "ansidecl.h"
4aa58a0a 19#include "opcode/sparc.h"
3ac166b1 20#include "dis-asm.h"
f069afb4 21#include "libiberty.h"
3ac166b1 22#include <string.h>
2fa0b342 23
f069afb4
DE
24/* For faster lookup, after insns are sorted they are hashed. */
25/* ??? I think there is room for even more improvement. */
26
27#define HASH_SIZE 256
28/* It is important that we only look at insn code bits as that is how the
29 opcode table is hashed. OPCODE_BITS is a table of valid bits for each
30 of the main types (0,1,2,3). */
31static int opcode_bits[4] = { 0x01c00000, 0x0, 0x01f80000, 0x01f80000 };
32#define HASH_INSN(INSN) \
33 ((((INSN) >> 24) & 0xc0) | (((INSN) & opcode_bits[((INSN) >> 30) & 3]) >> 19))
34struct opcode_hash {
35 struct opcode_hash *next;
36 struct sparc_opcode *opcode;
37};
38static struct opcode_hash *opcode_hash_table[HASH_SIZE];
39static void build_hash_table ();
40
41/* Sign-extend a value which is N bits long. */
42#define SEX(value, bits) \
43 ((((int)(value)) << ((8 * sizeof (int)) - bits)) \
44 >> ((8 * sizeof (int)) - bits) )
45
2fa0b342 46static char *reg_names[] =
f069afb4 47{ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
2fa0b342
DHW
48 "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
49 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
50 "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
51 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
52 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
53 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
54 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
f069afb4
DE
55#ifndef NO_V9
56 "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
57 "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
58 "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
59 "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
60/* psr, wim, tbr, fpsr, cpsr are v8 only. */
61#endif
62 "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr"
63};
2fa0b342
DHW
64
65#define freg_names (&reg_names[4 * 8])
66
f069afb4
DE
67#ifndef NO_V9
68/* These are ordered according to there register number in
69 rdpr and wrpr insns. */
70static char *v9_priv_reg_names[] =
71{
72 "tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl",
73 "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
74 "wstate", "fq"
75 /* "ver" - special cased */
76};
77#endif
78
79/* Macros used to extract instruction fields. Not all fields have
80 macros defined here, only those which are actually used. */
81
82#define X_RD(i) (((i) >> 25) & 0x1f)
83#define X_RS1(i) (((i) >> 14) & 0x1f)
84#define X_LDST_I(i) (((i) >> 13) & 1)
85#define X_ASI(i) (((i) >> 5) & 0xff)
86#define X_RS2(i) (((i) >> 0) & 0x1f)
87#define X_IMM13(i) (((i) >> 0) & 0x1fff)
88#define X_DISP22(i) (((i) >> 0) & 0x3fffff)
89#define X_IMM22(i) X_DISP22 (i)
90#define X_DISP30(i) (((i) >> 0) & 0x3fffffff)
3ac166b1 91
839df5c3 92#ifndef NO_V9
f069afb4
DE
93#define X_DISP16(i) (((((i) >> 20) & 3) << 14) | (((i) >> 0) & 0x3fff))
94#endif
95
96/* Here is the union which was used to extract instruction fields
97 before the shift and mask macros were written.
98
99 union sparc_insn
100 {
101 unsigned long int code;
102 struct
103 {
104 unsigned int anop:2;
105 #define op ldst.anop
106 unsigned int anrd:5;
107 #define rd ldst.anrd
108 unsigned int op3:6;
109 unsigned int anrs1:5;
110 #define rs1 ldst.anrs1
111 unsigned int i:1;
112 unsigned int anasi:8;
113 #define asi ldst.anasi
114 unsigned int anrs2:5;
115 #define rs2 ldst.anrs2
116 #define shcnt rs2
117 } ldst;
118 struct
119 {
120 unsigned int anop:2, anrd:5, op3:6, anrs1:5, i:1;
121 unsigned int IMM13:13;
122 #define imm13 IMM13.IMM13
123 } IMM13;
124 struct
125 {
126 unsigned int anop:2;
127 unsigned int a:1;
128 unsigned int cond:4;
129 unsigned int op2:3;
130 unsigned int DISP22:22;
131 #define disp22 branch.DISP22
132 #define imm22 disp22
133 } branch;
134 #ifndef NO_V9
135 struct
136 {
137 unsigned int anop:2;
138 unsigned int a:1;
139 unsigned int z:1;
140 unsigned int rcond:3;
141 unsigned int op2:3;
142 unsigned int DISP16HI:2;
143 unsigned int p:1;
144 unsigned int _rs1:5;
145 unsigned int DISP16LO:14;
146 } branch16;
147 #endif
148 struct
149 {
150 unsigned int anop:2;
151 unsigned int adisp30:30;
152 #define disp30 call.adisp30
153 } call;
154 };
155
156 */
2fa0b342
DHW
157
158/* Nonzero if INSN is the opcode for a delayed branch. */
159static int
160is_delayed_branch (insn)
f069afb4 161 unsigned long insn;
2fa0b342 162{
f069afb4 163 struct opcode_hash *op;
2fa0b342 164
f069afb4 165 for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
2fa0b342 166 {
f069afb4
DE
167 CONST struct sparc_opcode *opcode = op->opcode;
168 if ((opcode->match & insn) == opcode->match
169 && (opcode->lose & insn) == 0)
3ac166b1 170 return (opcode->flags & F_DELAYED);
2fa0b342
DHW
171 }
172 return 0;
173}
174
f069afb4
DE
175/* Nonzero of opcode table has been initialized. */
176static int opcodes_initialized = 0;
3ac166b1 177
f069afb4
DE
178/* extern void qsort (); */
179static int compare_opcodes ();
180
181/* Print one instruction from MEMADDR on INFO->STREAM.
2fa0b342 182
3ac166b1
JK
183 We suffix the instruction with a comment that gives the absolute
184 address involved, as well as its symbolic form, if the instruction
185 is preceded by a findable `sethi' and it either adds an immediate
186 displacement to that register, or it is an `add' or `or' instruction
187 on that register. */
f069afb4
DE
188
189static int
7ec65830 190print_insn (memaddr, info, sparc64_p)
2fa0b342 191 bfd_vma memaddr;
3ac166b1 192 disassemble_info *info;
7ec65830 193 int sparc64_p;
2fa0b342 194{
3ac166b1 195 FILE *stream = info->stream;
f069afb4
DE
196 bfd_byte buffer[4];
197 unsigned long insn;
2fa0b342 198 register unsigned int i;
f069afb4 199 register struct opcode_hash *op;
2fa0b342 200
f069afb4 201 if (!opcodes_initialized)
2fa0b342 202 {
2fa0b342
DHW
203 qsort ((char *) sparc_opcodes, NUMOPCODES,
204 sizeof (sparc_opcodes[0]), compare_opcodes);
f069afb4
DE
205 build_hash_table (sparc_opcodes, opcode_hash_table, NUMOPCODES);
206 opcodes_initialized = 1;
2fa0b342
DHW
207 }
208
3ac166b1
JK
209 {
210 int status =
f069afb4 211 (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
3ac166b1
JK
212 if (status != 0)
213 {
214 (*info->memory_error_func) (status, memaddr, info);
215 return -1;
216 }
217 }
2fa0b342 218
f069afb4
DE
219 insn = bfd_getb32 (buffer);
220
221 info->insn_info_valid = 1; /* We do return this info */
222 info->insn_type = dis_nonbranch; /* Assume non branch insn */
223 info->branch_delay_insns = 0; /* Assume no delay */
224 info->target = 0; /* Assume no target known */
225
226 for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
2fa0b342 227 {
f069afb4
DE
228 CONST struct sparc_opcode *opcode = op->opcode;
229
7ec65830
DE
230 /* If the current architecture isn't sparc64, skip sparc64 insns. */
231 if (!sparc64_p
232 && opcode->architecture == v9)
233 continue;
234
235 /* If the current architecture is sparc64, skip sparc32 only insns. */
236 if (sparc64_p
237 && (opcode->flags & F_NOTV9))
238 continue;
239
f069afb4
DE
240 if ((opcode->match & insn) == opcode->match
241 && (opcode->lose & insn) == 0)
2fa0b342
DHW
242 {
243 /* Nonzero means that we have found an instruction which has
244 the effect of adding or or'ing the imm13 field to rs1. */
245 int imm_added_to_rs1 = 0;
246
247 /* Nonzero means that we have found a plus sign in the args
248 field of the opcode table. */
249 int found_plus = 0;
250
f069afb4
DE
251 /* Nonzero means we have an annulled branch. */
252 int is_annulled = 0;
253
3ac166b1 254 /* Do we have an `add' or `or' instruction where rs1 is the same
2fa0b342 255 as rsd, and which has the i bit set? */
3ac166b1
JK
256 if ((opcode->match == 0x80102000 || opcode->match == 0x80002000)
257 /* (or) (add) */
f069afb4 258 && X_RS1 (insn) == X_RD (insn))
2fa0b342
DHW
259 imm_added_to_rs1 = 1;
260
f069afb4 261 if (X_RS1 (insn) != X_RD (insn)
c005c66c 262 && strchr (opcode->args, 'r') != 0)
2fa0b342
DHW
263 /* Can't do simple format if source and dest are different. */
264 continue;
265
3ac166b1 266 (*info->fprintf_func) (stream, opcode->name);
2fa0b342
DHW
267
268 {
f069afb4 269 register CONST char *s;
2fa0b342
DHW
270
271 if (opcode->args[0] != ',')
3ac166b1 272 (*info->fprintf_func) (stream, " ");
76d89cb1
MT
273 for (s = opcode->args; *s != '\0'; ++s)
274 {
275 while (*s == ',')
276 {
3ac166b1 277 (*info->fprintf_func) (stream, ",");
76d89cb1 278 ++s;
76d89cb1
MT
279 switch (*s) {
280 case 'a':
3ac166b1 281 (*info->fprintf_func) (stream, "a");
f069afb4 282 is_annulled = 1;
76d89cb1
MT
283 ++s;
284 continue;
839df5c3 285#ifndef NO_V9
76d89cb1 286 case 'N':
3ac166b1 287 (*info->fprintf_func) (stream, "pn");
76d89cb1
MT
288 ++s;
289 continue;
290
291 case 'T':
3ac166b1 292 (*info->fprintf_func) (stream, "pt");
76d89cb1
MT
293 ++s;
294 continue;
f069afb4 295#endif /* NO_V9 */
76d89cb1
MT
296
297 default:
298 break;
299 } /* switch on arg */
300 } /* while there are comma started args */
839df5c3 301
3ac166b1 302 (*info->fprintf_func) (stream, " ");
839df5c3 303
2fa0b342
DHW
304 switch (*s)
305 {
306 case '+':
307 found_plus = 1;
308
309 /* note fall-through */
310 default:
3ac166b1 311 (*info->fprintf_func) (stream, "%c", *s);
2fa0b342
DHW
312 break;
313
314 case '#':
3ac166b1 315 (*info->fprintf_func) (stream, "0");
2fa0b342
DHW
316 break;
317
3ac166b1 318#define reg(n) (*info->fprintf_func) (stream, "%%%s", reg_names[n])
2fa0b342
DHW
319 case '1':
320 case 'r':
f069afb4 321 reg (X_RS1 (insn));
2fa0b342
DHW
322 break;
323
324 case '2':
f069afb4 325 reg (X_RS2 (insn));
2fa0b342
DHW
326 break;
327
328 case 'd':
f069afb4 329 reg (X_RD (insn));
2fa0b342
DHW
330 break;
331#undef reg
332
f069afb4
DE
333#define freg(n) (*info->fprintf_func) (stream, "%%%s", freg_names[n])
334#define fregx(n) (*info->fprintf_func) (stream, "%%%s", freg_names[((n) & ~1) | (((n) & 1) << 5)])
2fa0b342 335 case 'e':
f069afb4
DE
336 freg (X_RS1 (insn));
337 break;
6f34472d
PB
338 case 'v': /* double/even */
339 case 'V': /* quad/multiple of 4 */
f069afb4 340 fregx (X_RS1 (insn));
2fa0b342
DHW
341 break;
342
343 case 'f':
f069afb4
DE
344 freg (X_RS2 (insn));
345 break;
6f34472d
PB
346 case 'B': /* double/even */
347 case 'R': /* quad/multiple of 4 */
f069afb4 348 fregx (X_RS2 (insn));
2fa0b342
DHW
349 break;
350
351 case 'g':
f069afb4
DE
352 freg (X_RD (insn));
353 break;
6f34472d
PB
354 case 'H': /* double/even */
355 case 'J': /* quad/multiple of 4 */
f069afb4 356 fregx (X_RD (insn));
2fa0b342
DHW
357 break;
358#undef freg
f069afb4 359#undef fregx
2fa0b342 360
3ac166b1 361#define creg(n) (*info->fprintf_func) (stream, "%%c%u", (unsigned int) (n))
2fa0b342 362 case 'b':
f069afb4 363 creg (X_RS1 (insn));
2fa0b342
DHW
364 break;
365
366 case 'c':
f069afb4 367 creg (X_RS2 (insn));
2fa0b342
DHW
368 break;
369
370 case 'D':
f069afb4 371 creg (X_RD (insn));
2fa0b342
DHW
372 break;
373#undef creg
374
375 case 'h':
3ac166b1 376 (*info->fprintf_func) (stream, "%%hi(%#x)",
f069afb4
DE
377 (0xFFFFFFFF
378 & ((int) X_IMM22 (insn) << 10)));
2fa0b342
DHW
379 break;
380
381 case 'i':
382 {
f069afb4 383 int imm = SEX (X_IMM13 (insn), 13);
2fa0b342
DHW
384
385 /* Check to see whether we have a 1+i, and take
386 note of that fact.
3ac166b1 387
2fa0b342
DHW
388 Note: because of the way we sort the table,
389 we will be matching 1+i rather than i+1,
390 so it is OK to assume that i is after +,
391 not before it. */
392 if (found_plus)
393 imm_added_to_rs1 = 1;
394
395 if (imm <= 9)
3ac166b1 396 (*info->fprintf_func) (stream, "%d", imm);
2fa0b342 397 else
3ac166b1 398 (*info->fprintf_func) (stream, "%#x", imm);
2fa0b342
DHW
399 }
400 break;
401
839df5c3 402#ifndef NO_V9
93fd00fb
JW
403 case 'I': /* 11 bit immediate. */
404 case 'j': /* 10 bit immediate. */
405 {
93fd00fb
JW
406 int imm;
407
408 if (*s == 'I')
f069afb4 409 imm = SEX (X_IMM13 (insn), 11);
93fd00fb 410 else
f069afb4 411 imm = SEX (X_IMM13 (insn), 10);
93fd00fb
JW
412
413 /* Check to see whether we have a 1+i, and take
414 note of that fact.
415
416 Note: because of the way we sort the table,
417 we will be matching 1+i rather than i+1,
418 so it is OK to assume that i is after +,
419 not before it. */
420 if (found_plus)
421 imm_added_to_rs1 = 1;
422
423 if (imm <= 9)
3ac166b1 424 (info->fprintf_func) (stream, "%d", imm);
93fd00fb 425 else
3ac166b1 426 (info->fprintf_func) (stream, "%#x", (unsigned) imm);
93fd00fb
JW
427 }
428 break;
429
839df5c3 430 case 'k':
f069afb4
DE
431 info->target = memaddr + (SEX (X_DISP16 (insn), 16)) * 4;
432 (*info->print_address_func) (info->target, info);
839df5c3
RP
433 break;
434
5f4d1571 435 case 'G':
f069afb4
DE
436 info->target = memaddr + (SEX (X_DISP22 (insn), 19)) * 4;
437 (*info->print_address_func) (info->target, info);
839df5c3
RP
438 break;
439
5f4d1571
MT
440 case '6':
441 case '7':
442 case '8':
443 case '9':
f069afb4 444 (*info->fprintf_func) (stream, "%%fcc%c", *s - '6' + '0');
5f4d1571
MT
445 break;
446
447 case 'z':
f069afb4 448 (*info->fprintf_func) (stream, "%%icc");
5f4d1571
MT
449 break;
450
451 case 'Z':
f069afb4 452 (*info->fprintf_func) (stream, "%%xcc");
5f4d1571 453 break;
93fd00fb
JW
454
455 case 'E':
3245e377 456 (*info->fprintf_func) (stream, "%%ccr");
93fd00fb
JW
457 break;
458
459 case 's':
3245e377 460 (*info->fprintf_func) (stream, "%%fprs");
93fd00fb 461 break;
f069afb4
DE
462
463 case 'o':
464 (*info->fprintf_func) (stream, "%%asi");
465 break;
466
467 case 'W':
468 (*info->fprintf_func) (stream, "%%tick");
469 break;
470
471 case 'P':
472 (*info->fprintf_func) (stream, "%%pc");
473 break;
474
475 case '?':
476 if (X_RS1 (insn) == 31)
477 (*info->fprintf_func) (stream, "%%ver");
478 else if ((unsigned) X_RS1 (insn) < 16)
479 (*info->fprintf_func) (stream, "%%%s",
480 v9_priv_reg_names[X_RS1 (insn)]);
481 else
482 (*info->fprintf_func) (stream, "%%reserved");
483 break;
484
485 case '!':
486 if ((unsigned) X_RD (insn) < 15)
487 (*info->fprintf_func) (stream, "%%%s",
488 v9_priv_reg_names[X_RD (insn)]);
489 else
490 (*info->fprintf_func) (stream, "%%reserved");
491 break;
492 break;
493#endif /* NO_V9 */
839df5c3 494
76d89cb1 495 case 'M':
f069afb4 496 (*info->fprintf_func) (stream, "%%asr%d", X_RS1 (insn));
839df5c3
RP
497 break;
498
76d89cb1 499 case 'm':
f069afb4 500 (*info->fprintf_func) (stream, "%%asr%d", X_RD (insn));
839df5c3
RP
501 break;
502
76d89cb1 503 case 'L':
f069afb4
DE
504 info->target = memaddr + X_DISP30 (insn) * 4;
505 (*info->print_address_func) (info->target, info);
506 break;
507
508 case 'n':
509 (*info->fprintf_func)
510 (stream, "%#x", (SEX (X_DISP22 (insn), 22)));
2fa0b342
DHW
511 break;
512
513 case 'l':
f069afb4
DE
514 info->target = memaddr + (SEX (X_DISP22 (insn), 22)) * 4;
515 (*info->print_address_func) (info->target, info);
2fa0b342
DHW
516 break;
517
518 case 'A':
7ec65830
DE
519 {
520 char *name = sparc_decode_asi (X_ASI (insn));
521
522 if (name)
523 (*info->fprintf_func) (stream, "%s", name);
524 else
525 (*info->fprintf_func) (stream, "(%d)", X_ASI (insn));
526 break;
527 }
2fa0b342
DHW
528
529 case 'C':
3245e377 530 (*info->fprintf_func) (stream, "%%csr");
2fa0b342
DHW
531 break;
532
533 case 'F':
3245e377 534 (*info->fprintf_func) (stream, "%%fsr");
2fa0b342
DHW
535 break;
536
537 case 'p':
3245e377 538 (*info->fprintf_func) (stream, "%%psr");
2fa0b342
DHW
539 break;
540
541 case 'q':
3245e377 542 (*info->fprintf_func) (stream, "%%fq");
2fa0b342
DHW
543 break;
544
545 case 'Q':
3245e377 546 (*info->fprintf_func) (stream, "%%cq");
2fa0b342
DHW
547 break;
548
549 case 't':
3245e377 550 (*info->fprintf_func) (stream, "%%tbr");
2fa0b342
DHW
551 break;
552
553 case 'w':
3245e377 554 (*info->fprintf_func) (stream, "%%wim");
2fa0b342
DHW
555 break;
556
f069afb4
DE
557 case 'x':
558 (*info->fprintf_func) (stream, "%d",
559 ((X_LDST_I (insn) << 8)
560 + X_ASI (insn)));
561 break;
562
2fa0b342 563 case 'y':
3245e377 564 (*info->fprintf_func) (stream, "%%y");
2fa0b342
DHW
565 break;
566 }
567 }
568 }
569
570 /* If we are adding or or'ing something to rs1, then
571 check to see whether the previous instruction was
572 a sethi to the same register as in the sethi.
573 If so, attempt to print the result of the add or
574 or (in this context add and or do the same thing)
575 and its symbolic value. */
576 if (imm_added_to_rs1)
577 {
f069afb4 578 unsigned long prev_insn;
3ac166b1 579 int errcode;
2fa0b342 580
3ac166b1
JK
581 errcode =
582 (*info->read_memory_func)
f069afb4
DE
583 (memaddr - 4, buffer, sizeof (buffer), info);
584 prev_insn = bfd_getb32 (buffer);
2fa0b342
DHW
585
586 if (errcode == 0)
587 {
588 /* If it is a delayed branch, we need to look at the
589 instruction before the delayed branch. This handles
590 sequences such as
591
592 sethi %o1, %hi(_foo), %o1
593 call _printf
594 or %o1, %lo(_foo), %o1
595 */
596
597 if (is_delayed_branch (prev_insn))
f069afb4
DE
598 {
599 errcode = (*info->read_memory_func)
600 (memaddr - 8, buffer, sizeof (buffer), info);
601 prev_insn = bfd_getb32 (buffer);
602 }
2fa0b342
DHW
603 }
604
605 /* If there was a problem reading memory, then assume
606 the previous instruction was not sethi. */
607 if (errcode == 0)
608 {
609 /* Is it sethi to the same register? */
f069afb4
DE
610 if ((prev_insn & 0xc1c00000) == 0x01000000
611 && X_RD (prev_insn) == X_RS1 (insn))
2fa0b342 612 {
3ac166b1 613 (*info->fprintf_func) (stream, "\t! ");
f069afb4
DE
614 info->target =
615 (0xFFFFFFFF & (int) X_IMM22 (prev_insn) << 10)
616 | SEX (X_IMM13 (insn), 13);
617 (*info->print_address_func) (info->target, info);
618 info->insn_type = dis_dref;
619 info->data_size = 4; /* FIXME!!! */
2fa0b342
DHW
620 }
621 }
622 }
623
f069afb4
DE
624 if (opcode->flags & (F_UNBR|F_CONDBR|F_JSR))
625 {
626 /* FIXME -- check is_annulled flag */
627 if (opcode->flags & F_UNBR)
628 info->insn_type = dis_branch;
629 if (opcode->flags & F_CONDBR)
630 info->insn_type = dis_condbranch;
631 if (opcode->flags & F_JSR)
632 info->insn_type = dis_jsr;
633 if (opcode->flags & F_DELAYED)
634 info->branch_delay_insns = 1;
635 }
636
637 return sizeof (buffer);
2fa0b342
DHW
638 }
639 }
640
f069afb4
DE
641 info->insn_type = dis_noninsn; /* Mark as non-valid instruction */
642 (*info->fprintf_func) (stream, "%#8x", insn);
643 return sizeof (buffer);
2fa0b342
DHW
644}
645
2fa0b342
DHW
646/* Compare opcodes A and B. */
647
648static int
649compare_opcodes (a, b)
650 char *a, *b;
651{
652 struct sparc_opcode *op0 = (struct sparc_opcode *) a;
653 struct sparc_opcode *op1 = (struct sparc_opcode *) b;
654 unsigned long int match0 = op0->match, match1 = op1->match;
655 unsigned long int lose0 = op0->lose, lose1 = op1->lose;
656 register unsigned int i;
657
658 /* If a bit is set in both match and lose, there is something
659 wrong with the opcode table. */
660 if (match0 & lose0)
661 {
662 fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
663 op0->name, match0, lose0);
664 op0->lose &= ~op0->match;
665 lose0 = op0->lose;
666 }
667
668 if (match1 & lose1)
669 {
670 fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
671 op1->name, match1, lose1);
672 op1->lose &= ~op1->match;
673 lose1 = op1->lose;
674 }
675
676 /* Because the bits that are variable in one opcode are constant in
677 another, it is important to order the opcodes in the right order. */
678 for (i = 0; i < 32; ++i)
679 {
680 unsigned long int x = 1 << i;
681 int x0 = (match0 & x) != 0;
682 int x1 = (match1 & x) != 0;
683
684 if (x0 != x1)
685 return x1 - x0;
686 }
687
688 for (i = 0; i < 32; ++i)
689 {
690 unsigned long int x = 1 << i;
691 int x0 = (lose0 & x) != 0;
692 int x1 = (lose1 & x) != 0;
693
694 if (x0 != x1)
695 return x1 - x0;
696 }
697
7ec65830
DE
698 /* Put non-sparc64 insns ahead of sparc64 ones. */
699 if ((op0->architecture == v9) != (op1->architecture == v9))
700 return (op0->architecture == v9) - (op1->architecture == v9);
701
2fa0b342
DHW
702 /* They are functionally equal. So as long as the opcode table is
703 valid, we can put whichever one first we want, on aesthetic grounds. */
3ac166b1
JK
704
705 /* Our first aesthetic ground is that aliases defer to real insns. */
706 {
707 int alias_diff = (op0->flags & F_ALIAS) - (op1->flags & F_ALIAS);
708 if (alias_diff != 0)
709 /* Put the one that isn't an alias first. */
710 return alias_diff;
711 }
712
713 /* Except for aliases, two "identical" instructions had
714 better have the same opcode. This is a sanity check on the table. */
715 i = strcmp (op0->name, op1->name);
716 if (i)
717 if (op0->flags & F_ALIAS) /* If they're both aliases, be arbitrary. */
718 return i;
719 else
720 fprintf (stderr,
721 "Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n",
722 op0->name, op1->name);
723
724 /* Fewer arguments are preferred. */
2fa0b342
DHW
725 {
726 int length_diff = strlen (op0->args) - strlen (op1->args);
727 if (length_diff != 0)
728 /* Put the one with fewer arguments first. */
729 return length_diff;
730 }
731
732 /* Put 1+i before i+1. */
733 {
c005c66c
JG
734 char *p0 = (char *) strchr(op0->args, '+');
735 char *p1 = (char *) strchr(op1->args, '+');
2fa0b342
DHW
736
737 if (p0 && p1)
738 {
739 /* There is a plus in both operands. Note that a plus
740 sign cannot be the first character in args,
741 so the following [-1]'s are valid. */
742 if (p0[-1] == 'i' && p1[1] == 'i')
743 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
744 return 1;
745 if (p0[1] == 'i' && p1[-1] == 'i')
746 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
747 return -1;
748 }
749 }
750
7ec65830
DE
751 /* Put 1,i before i,1. */
752 {
753 int i0 = strncmp (op0->args, "i,1", 3) == 0;
754 int i1 = strncmp (op1->args, "i,1", 3) == 0;
755
756 if (i0 ^ i1)
757 return i0 - i1;
758 }
759
2fa0b342
DHW
760 /* They are, as far as we can tell, identical.
761 Since qsort may have rearranged the table partially, there is
762 no way to tell which one was first in the opcode table as
763 written, so just say there are equal. */
764 return 0;
765}
f069afb4
DE
766
767/* Build a hash table from the opcode table. */
768
769static void
770build_hash_table (table, hash_table, num_opcodes)
771 struct sparc_opcode *table;
772 struct opcode_hash **hash_table;
773 int num_opcodes;
774{
1a67b3b6 775 register int i;
f069afb4 776 int hash_count[HASH_SIZE];
28661653 777 static struct opcode_hash *hash_buf = NULL;
f069afb4
DE
778
779 /* Start at the end of the table and work backwards so that each
780 chain is sorted. */
f069afb4
DE
781
782 memset (hash_table, 0, HASH_SIZE * sizeof (hash_table[0]));
783 memset (hash_count, 0, HASH_SIZE * sizeof (hash_count[0]));
28661653
DE
784 if (hash_buf != NULL)
785 free (hash_buf);
1a67b3b6 786 hash_buf = (struct opcode_hash *) xmalloc (sizeof (struct opcode_hash) * num_opcodes);
f069afb4
DE
787 for (i = num_opcodes - 1; i >= 0; --i)
788 {
1a67b3b6
DE
789 register int hash = HASH_INSN (sparc_opcodes[i].match);
790 register struct opcode_hash *h = &hash_buf[i];
f069afb4
DE
791 h->next = hash_table[hash];
792 h->opcode = &sparc_opcodes[i];
793 hash_table[hash] = h;
794 ++hash_count[hash];
795 }
796
797#if 0 /* for debugging */
798 {
799 int min_count = num_opcodes, max_count = 0;
800 int total;
801
802 for (i = 0; i < HASH_SIZE; ++i)
803 {
804 if (hash_count[i] < min_count)
805 min_count = hash_count[i];
806 if (hash_count[i] > max_count)
807 max_count = hash_count[i];
808 total += hash_count[i];
809 }
810
811 printf ("Opcode hash table stats: min %d, max %d, ave %f\n",
812 min_count, max_count, (double) total / HASH_SIZE);
813 }
814#endif
815}
816
817int
818print_insn_sparc (memaddr, info)
819 bfd_vma memaddr;
820 disassemble_info *info;
821{
7ec65830 822 return print_insn (memaddr, info, 0);
f069afb4
DE
823}
824
825int
826print_insn_sparc64 (memaddr, info)
827 bfd_vma memaddr;
828 disassemble_info *info;
829{
7ec65830 830 return print_insn (memaddr, info, 1);
f069afb4 831}