* sparc-dis.c (HASH_SIZE, HASH_INSN): Define.
[deliverable/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/* Nonzero of the current architecture is sparc64.
179 This is kept in a global because compare_opcodes uses it. */
180static int sparc64_p;
181
182/* extern void qsort (); */
183static int compare_opcodes ();
184
185/* Print one instruction from MEMADDR on INFO->STREAM.
2fa0b342 186
3ac166b1
JK
187 We suffix the instruction with a comment that gives the absolute
188 address involved, as well as its symbolic form, if the instruction
189 is preceded by a findable `sethi' and it either adds an immediate
190 displacement to that register, or it is an `add' or `or' instruction
191 on that register. */
f069afb4
DE
192
193static int
194print_insn (memaddr, info)
2fa0b342 195 bfd_vma memaddr;
3ac166b1 196 disassemble_info *info;
2fa0b342 197{
3ac166b1 198 FILE *stream = info->stream;
f069afb4
DE
199 bfd_byte buffer[4];
200 unsigned long insn;
2fa0b342 201 register unsigned int i;
f069afb4 202 register struct opcode_hash *op;
2fa0b342 203
f069afb4 204 if (!opcodes_initialized)
2fa0b342 205 {
2fa0b342
DHW
206 qsort ((char *) sparc_opcodes, NUMOPCODES,
207 sizeof (sparc_opcodes[0]), compare_opcodes);
f069afb4
DE
208 build_hash_table (sparc_opcodes, opcode_hash_table, NUMOPCODES);
209 opcodes_initialized = 1;
2fa0b342
DHW
210 }
211
3ac166b1
JK
212 {
213 int status =
f069afb4 214 (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
3ac166b1
JK
215 if (status != 0)
216 {
217 (*info->memory_error_func) (status, memaddr, info);
218 return -1;
219 }
220 }
2fa0b342 221
f069afb4
DE
222 insn = bfd_getb32 (buffer);
223
224 info->insn_info_valid = 1; /* We do return this info */
225 info->insn_type = dis_nonbranch; /* Assume non branch insn */
226 info->branch_delay_insns = 0; /* Assume no delay */
227 info->target = 0; /* Assume no target known */
228
229 for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
2fa0b342 230 {
f069afb4
DE
231 CONST struct sparc_opcode *opcode = op->opcode;
232
233 if ((opcode->match & insn) == opcode->match
234 && (opcode->lose & insn) == 0)
2fa0b342
DHW
235 {
236 /* Nonzero means that we have found an instruction which has
237 the effect of adding or or'ing the imm13 field to rs1. */
238 int imm_added_to_rs1 = 0;
239
240 /* Nonzero means that we have found a plus sign in the args
241 field of the opcode table. */
242 int found_plus = 0;
243
f069afb4
DE
244 /* Nonzero means we have an annulled branch. */
245 int is_annulled = 0;
246
3ac166b1 247 /* Do we have an `add' or `or' instruction where rs1 is the same
2fa0b342 248 as rsd, and which has the i bit set? */
3ac166b1
JK
249 if ((opcode->match == 0x80102000 || opcode->match == 0x80002000)
250 /* (or) (add) */
f069afb4 251 && X_RS1 (insn) == X_RD (insn))
2fa0b342
DHW
252 imm_added_to_rs1 = 1;
253
f069afb4 254 if (X_RS1 (insn) != X_RD (insn)
c005c66c 255 && strchr (opcode->args, 'r') != 0)
2fa0b342
DHW
256 /* Can't do simple format if source and dest are different. */
257 continue;
258
3ac166b1 259 (*info->fprintf_func) (stream, opcode->name);
2fa0b342
DHW
260
261 {
f069afb4 262 register CONST char *s;
2fa0b342
DHW
263
264 if (opcode->args[0] != ',')
3ac166b1 265 (*info->fprintf_func) (stream, " ");
76d89cb1
MT
266 for (s = opcode->args; *s != '\0'; ++s)
267 {
268 while (*s == ',')
269 {
3ac166b1 270 (*info->fprintf_func) (stream, ",");
76d89cb1 271 ++s;
76d89cb1
MT
272 switch (*s) {
273 case 'a':
3ac166b1 274 (*info->fprintf_func) (stream, "a");
f069afb4 275 is_annulled = 1;
76d89cb1
MT
276 ++s;
277 continue;
839df5c3 278#ifndef NO_V9
76d89cb1 279 case 'N':
3ac166b1 280 (*info->fprintf_func) (stream, "pn");
76d89cb1
MT
281 ++s;
282 continue;
283
284 case 'T':
3ac166b1 285 (*info->fprintf_func) (stream, "pt");
76d89cb1
MT
286 ++s;
287 continue;
f069afb4 288#endif /* NO_V9 */
76d89cb1
MT
289
290 default:
291 break;
292 } /* switch on arg */
293 } /* while there are comma started args */
839df5c3 294
3ac166b1 295 (*info->fprintf_func) (stream, " ");
839df5c3 296
2fa0b342
DHW
297 switch (*s)
298 {
299 case '+':
300 found_plus = 1;
301
302 /* note fall-through */
303 default:
3ac166b1 304 (*info->fprintf_func) (stream, "%c", *s);
2fa0b342
DHW
305 break;
306
307 case '#':
3ac166b1 308 (*info->fprintf_func) (stream, "0");
2fa0b342
DHW
309 break;
310
3ac166b1 311#define reg(n) (*info->fprintf_func) (stream, "%%%s", reg_names[n])
2fa0b342
DHW
312 case '1':
313 case 'r':
f069afb4 314 reg (X_RS1 (insn));
2fa0b342
DHW
315 break;
316
317 case '2':
f069afb4 318 reg (X_RS2 (insn));
2fa0b342
DHW
319 break;
320
321 case 'd':
f069afb4 322 reg (X_RD (insn));
2fa0b342
DHW
323 break;
324#undef reg
325
f069afb4
DE
326#define freg(n) (*info->fprintf_func) (stream, "%%%s", freg_names[n])
327#define fregx(n) (*info->fprintf_func) (stream, "%%%s", freg_names[((n) & ~1) | (((n) & 1) << 5)])
2fa0b342 328 case 'e':
f069afb4
DE
329 freg (X_RS1 (insn));
330 break;
6f34472d
PB
331 case 'v': /* double/even */
332 case 'V': /* quad/multiple of 4 */
f069afb4 333 fregx (X_RS1 (insn));
2fa0b342
DHW
334 break;
335
336 case 'f':
f069afb4
DE
337 freg (X_RS2 (insn));
338 break;
6f34472d
PB
339 case 'B': /* double/even */
340 case 'R': /* quad/multiple of 4 */
f069afb4 341 fregx (X_RS2 (insn));
2fa0b342
DHW
342 break;
343
344 case 'g':
f069afb4
DE
345 freg (X_RD (insn));
346 break;
6f34472d
PB
347 case 'H': /* double/even */
348 case 'J': /* quad/multiple of 4 */
f069afb4 349 fregx (X_RD (insn));
2fa0b342
DHW
350 break;
351#undef freg
f069afb4 352#undef fregx
2fa0b342 353
3ac166b1 354#define creg(n) (*info->fprintf_func) (stream, "%%c%u", (unsigned int) (n))
2fa0b342 355 case 'b':
f069afb4 356 creg (X_RS1 (insn));
2fa0b342
DHW
357 break;
358
359 case 'c':
f069afb4 360 creg (X_RS2 (insn));
2fa0b342
DHW
361 break;
362
363 case 'D':
f069afb4 364 creg (X_RD (insn));
2fa0b342
DHW
365 break;
366#undef creg
367
368 case 'h':
3ac166b1 369 (*info->fprintf_func) (stream, "%%hi(%#x)",
f069afb4
DE
370 (0xFFFFFFFF
371 & ((int) X_IMM22 (insn) << 10)));
2fa0b342
DHW
372 break;
373
374 case 'i':
375 {
f069afb4 376 int imm = SEX (X_IMM13 (insn), 13);
2fa0b342
DHW
377
378 /* Check to see whether we have a 1+i, and take
379 note of that fact.
3ac166b1 380
2fa0b342
DHW
381 Note: because of the way we sort the table,
382 we will be matching 1+i rather than i+1,
383 so it is OK to assume that i is after +,
384 not before it. */
385 if (found_plus)
386 imm_added_to_rs1 = 1;
387
388 if (imm <= 9)
3ac166b1 389 (*info->fprintf_func) (stream, "%d", imm);
2fa0b342 390 else
3ac166b1 391 (*info->fprintf_func) (stream, "%#x", imm);
2fa0b342
DHW
392 }
393 break;
394
839df5c3 395#ifndef NO_V9
93fd00fb
JW
396 case 'I': /* 11 bit immediate. */
397 case 'j': /* 10 bit immediate. */
398 {
93fd00fb
JW
399 int imm;
400
401 if (*s == 'I')
f069afb4 402 imm = SEX (X_IMM13 (insn), 11);
93fd00fb 403 else
f069afb4 404 imm = SEX (X_IMM13 (insn), 10);
93fd00fb
JW
405
406 /* Check to see whether we have a 1+i, and take
407 note of that fact.
408
409 Note: because of the way we sort the table,
410 we will be matching 1+i rather than i+1,
411 so it is OK to assume that i is after +,
412 not before it. */
413 if (found_plus)
414 imm_added_to_rs1 = 1;
415
416 if (imm <= 9)
3ac166b1 417 (info->fprintf_func) (stream, "%d", imm);
93fd00fb 418 else
3ac166b1 419 (info->fprintf_func) (stream, "%#x", (unsigned) imm);
93fd00fb
JW
420 }
421 break;
422
839df5c3 423 case 'k':
f069afb4
DE
424 info->target = memaddr + (SEX (X_DISP16 (insn), 16)) * 4;
425 (*info->print_address_func) (info->target, info);
839df5c3
RP
426 break;
427
5f4d1571 428 case 'G':
f069afb4
DE
429 info->target = memaddr + (SEX (X_DISP22 (insn), 19)) * 4;
430 (*info->print_address_func) (info->target, info);
839df5c3
RP
431 break;
432
5f4d1571
MT
433 case '6':
434 case '7':
435 case '8':
436 case '9':
f069afb4 437 (*info->fprintf_func) (stream, "%%fcc%c", *s - '6' + '0');
5f4d1571
MT
438 break;
439
440 case 'z':
f069afb4 441 (*info->fprintf_func) (stream, "%%icc");
5f4d1571
MT
442 break;
443
444 case 'Z':
f069afb4 445 (*info->fprintf_func) (stream, "%%xcc");
5f4d1571 446 break;
93fd00fb
JW
447
448 case 'E':
3245e377 449 (*info->fprintf_func) (stream, "%%ccr");
93fd00fb
JW
450 break;
451
452 case 's':
3245e377 453 (*info->fprintf_func) (stream, "%%fprs");
93fd00fb 454 break;
f069afb4
DE
455
456 case 'o':
457 (*info->fprintf_func) (stream, "%%asi");
458 break;
459
460 case 'W':
461 (*info->fprintf_func) (stream, "%%tick");
462 break;
463
464 case 'P':
465 (*info->fprintf_func) (stream, "%%pc");
466 break;
467
468 case '?':
469 if (X_RS1 (insn) == 31)
470 (*info->fprintf_func) (stream, "%%ver");
471 else if ((unsigned) X_RS1 (insn) < 16)
472 (*info->fprintf_func) (stream, "%%%s",
473 v9_priv_reg_names[X_RS1 (insn)]);
474 else
475 (*info->fprintf_func) (stream, "%%reserved");
476 break;
477
478 case '!':
479 if ((unsigned) X_RD (insn) < 15)
480 (*info->fprintf_func) (stream, "%%%s",
481 v9_priv_reg_names[X_RD (insn)]);
482 else
483 (*info->fprintf_func) (stream, "%%reserved");
484 break;
485 break;
486#endif /* NO_V9 */
839df5c3 487
76d89cb1 488 case 'M':
f069afb4 489 (*info->fprintf_func) (stream, "%%asr%d", X_RS1 (insn));
839df5c3
RP
490 break;
491
76d89cb1 492 case 'm':
f069afb4 493 (*info->fprintf_func) (stream, "%%asr%d", X_RD (insn));
839df5c3
RP
494 break;
495
76d89cb1 496 case 'L':
f069afb4
DE
497 info->target = memaddr + X_DISP30 (insn) * 4;
498 (*info->print_address_func) (info->target, info);
499 break;
500
501 case 'n':
502 (*info->fprintf_func)
503 (stream, "%#x", (SEX (X_DISP22 (insn), 22)));
2fa0b342
DHW
504 break;
505
506 case 'l':
f069afb4
DE
507 info->target = memaddr + (SEX (X_DISP22 (insn), 22)) * 4;
508 (*info->print_address_func) (info->target, info);
2fa0b342
DHW
509 break;
510
511 case 'A':
f069afb4 512 (*info->fprintf_func) (stream, "(%d)", X_ASI (insn));
2fa0b342
DHW
513 break;
514
515 case 'C':
3245e377 516 (*info->fprintf_func) (stream, "%%csr");
2fa0b342
DHW
517 break;
518
519 case 'F':
3245e377 520 (*info->fprintf_func) (stream, "%%fsr");
2fa0b342
DHW
521 break;
522
523 case 'p':
3245e377 524 (*info->fprintf_func) (stream, "%%psr");
2fa0b342
DHW
525 break;
526
527 case 'q':
3245e377 528 (*info->fprintf_func) (stream, "%%fq");
2fa0b342
DHW
529 break;
530
531 case 'Q':
3245e377 532 (*info->fprintf_func) (stream, "%%cq");
2fa0b342
DHW
533 break;
534
535 case 't':
3245e377 536 (*info->fprintf_func) (stream, "%%tbr");
2fa0b342
DHW
537 break;
538
539 case 'w':
3245e377 540 (*info->fprintf_func) (stream, "%%wim");
2fa0b342
DHW
541 break;
542
f069afb4
DE
543 case 'x':
544 (*info->fprintf_func) (stream, "%d",
545 ((X_LDST_I (insn) << 8)
546 + X_ASI (insn)));
547 break;
548
2fa0b342 549 case 'y':
3245e377 550 (*info->fprintf_func) (stream, "%%y");
2fa0b342
DHW
551 break;
552 }
553 }
554 }
555
556 /* If we are adding or or'ing something to rs1, then
557 check to see whether the previous instruction was
558 a sethi to the same register as in the sethi.
559 If so, attempt to print the result of the add or
560 or (in this context add and or do the same thing)
561 and its symbolic value. */
562 if (imm_added_to_rs1)
563 {
f069afb4 564 unsigned long prev_insn;
3ac166b1 565 int errcode;
2fa0b342 566
3ac166b1
JK
567 errcode =
568 (*info->read_memory_func)
f069afb4
DE
569 (memaddr - 4, buffer, sizeof (buffer), info);
570 prev_insn = bfd_getb32 (buffer);
2fa0b342
DHW
571
572 if (errcode == 0)
573 {
574 /* If it is a delayed branch, we need to look at the
575 instruction before the delayed branch. This handles
576 sequences such as
577
578 sethi %o1, %hi(_foo), %o1
579 call _printf
580 or %o1, %lo(_foo), %o1
581 */
582
583 if (is_delayed_branch (prev_insn))
f069afb4
DE
584 {
585 errcode = (*info->read_memory_func)
586 (memaddr - 8, buffer, sizeof (buffer), info);
587 prev_insn = bfd_getb32 (buffer);
588 }
2fa0b342
DHW
589 }
590
591 /* If there was a problem reading memory, then assume
592 the previous instruction was not sethi. */
593 if (errcode == 0)
594 {
595 /* Is it sethi to the same register? */
f069afb4
DE
596 if ((prev_insn & 0xc1c00000) == 0x01000000
597 && X_RD (prev_insn) == X_RS1 (insn))
2fa0b342 598 {
3ac166b1 599 (*info->fprintf_func) (stream, "\t! ");
f069afb4
DE
600 info->target =
601 (0xFFFFFFFF & (int) X_IMM22 (prev_insn) << 10)
602 | SEX (X_IMM13 (insn), 13);
603 (*info->print_address_func) (info->target, info);
604 info->insn_type = dis_dref;
605 info->data_size = 4; /* FIXME!!! */
2fa0b342
DHW
606 }
607 }
608 }
609
f069afb4
DE
610 if (opcode->flags & (F_UNBR|F_CONDBR|F_JSR))
611 {
612 /* FIXME -- check is_annulled flag */
613 if (opcode->flags & F_UNBR)
614 info->insn_type = dis_branch;
615 if (opcode->flags & F_CONDBR)
616 info->insn_type = dis_condbranch;
617 if (opcode->flags & F_JSR)
618 info->insn_type = dis_jsr;
619 if (opcode->flags & F_DELAYED)
620 info->branch_delay_insns = 1;
621 }
622
623 return sizeof (buffer);
2fa0b342
DHW
624 }
625 }
626
f069afb4
DE
627 info->insn_type = dis_noninsn; /* Mark as non-valid instruction */
628 (*info->fprintf_func) (stream, "%#8x", insn);
629 return sizeof (buffer);
2fa0b342
DHW
630}
631
2fa0b342
DHW
632/* Compare opcodes A and B. */
633
634static int
635compare_opcodes (a, b)
636 char *a, *b;
637{
638 struct sparc_opcode *op0 = (struct sparc_opcode *) a;
639 struct sparc_opcode *op1 = (struct sparc_opcode *) b;
640 unsigned long int match0 = op0->match, match1 = op1->match;
641 unsigned long int lose0 = op0->lose, lose1 = op1->lose;
642 register unsigned int i;
643
644 /* If a bit is set in both match and lose, there is something
645 wrong with the opcode table. */
646 if (match0 & lose0)
647 {
648 fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
649 op0->name, match0, lose0);
650 op0->lose &= ~op0->match;
651 lose0 = op0->lose;
652 }
653
654 if (match1 & lose1)
655 {
656 fprintf (stderr, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
657 op1->name, match1, lose1);
658 op1->lose &= ~op1->match;
659 lose1 = op1->lose;
660 }
661
f069afb4
DE
662 /* If the current architecture isn't sparc64, move v9 insns to the end.
663 Only do this when one isn't v9 and one is. If both are v9 we still
664 need to properly sort them.
665 This must be done before checking match and lose. */
666 if (!sparc64_p
667 && (op0->architecture == v9) != (op1->architecture == v9))
668 return (op0->architecture == v9) - (op1->architecture == v9);
669
670 /* If the current architecture is sparc64, move non-v9 insns to the end.
671 This must be done before checking match and lose. */
672 if (sparc64_p
673 && (op0->flags & F_NOTV9) != (op1->flags & F_NOTV9))
674 return (op0->flags & F_NOTV9) - (op1->flags & F_NOTV9);
675
2fa0b342
DHW
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
698 /* They are functionally equal. So as long as the opcode table is
699 valid, we can put whichever one first we want, on aesthetic grounds. */
3ac166b1
JK
700
701 /* Our first aesthetic ground is that aliases defer to real insns. */
702 {
703 int alias_diff = (op0->flags & F_ALIAS) - (op1->flags & F_ALIAS);
704 if (alias_diff != 0)
705 /* Put the one that isn't an alias first. */
706 return alias_diff;
707 }
708
709 /* Except for aliases, two "identical" instructions had
710 better have the same opcode. This is a sanity check on the table. */
711 i = strcmp (op0->name, op1->name);
712 if (i)
713 if (op0->flags & F_ALIAS) /* If they're both aliases, be arbitrary. */
714 return i;
715 else
716 fprintf (stderr,
717 "Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n",
718 op0->name, op1->name);
719
720 /* Fewer arguments are preferred. */
2fa0b342
DHW
721 {
722 int length_diff = strlen (op0->args) - strlen (op1->args);
723 if (length_diff != 0)
724 /* Put the one with fewer arguments first. */
725 return length_diff;
726 }
727
728 /* Put 1+i before i+1. */
729 {
c005c66c
JG
730 char *p0 = (char *) strchr(op0->args, '+');
731 char *p1 = (char *) strchr(op1->args, '+');
2fa0b342
DHW
732
733 if (p0 && p1)
734 {
735 /* There is a plus in both operands. Note that a plus
736 sign cannot be the first character in args,
737 so the following [-1]'s are valid. */
738 if (p0[-1] == 'i' && p1[1] == 'i')
739 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
740 return 1;
741 if (p0[1] == 'i' && p1[-1] == 'i')
742 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
743 return -1;
744 }
745 }
746
747 /* They are, as far as we can tell, identical.
748 Since qsort may have rearranged the table partially, there is
749 no way to tell which one was first in the opcode table as
750 written, so just say there are equal. */
751 return 0;
752}
f069afb4
DE
753
754/* Build a hash table from the opcode table. */
755
756static void
757build_hash_table (table, hash_table, num_opcodes)
758 struct sparc_opcode *table;
759 struct opcode_hash **hash_table;
760 int num_opcodes;
761{
762 int i;
763 int hash_count[HASH_SIZE];
764
765 /* Start at the end of the table and work backwards so that each
766 chain is sorted. */
767 /* ??? Do we really need to sort them now? */
768
769 memset (hash_table, 0, HASH_SIZE * sizeof (hash_table[0]));
770 memset (hash_count, 0, HASH_SIZE * sizeof (hash_count[0]));
771 for (i = num_opcodes - 1; i >= 0; --i)
772 {
773 int hash = HASH_INSN (sparc_opcodes[i].match);
774 struct opcode_hash *h = (struct opcode_hash *) xmalloc (sizeof (struct opcode_hash));
775 h->next = hash_table[hash];
776 h->opcode = &sparc_opcodes[i];
777 hash_table[hash] = h;
778 ++hash_count[hash];
779 }
780
781#if 0 /* for debugging */
782 {
783 int min_count = num_opcodes, max_count = 0;
784 int total;
785
786 for (i = 0; i < HASH_SIZE; ++i)
787 {
788 if (hash_count[i] < min_count)
789 min_count = hash_count[i];
790 if (hash_count[i] > max_count)
791 max_count = hash_count[i];
792 total += hash_count[i];
793 }
794
795 printf ("Opcode hash table stats: min %d, max %d, ave %f\n",
796 min_count, max_count, (double) total / HASH_SIZE);
797 }
798#endif
799}
800
801int
802print_insn_sparc (memaddr, info)
803 bfd_vma memaddr;
804 disassemble_info *info;
805{
806 /* It's not clear that we'll ever switch cpus in a running program.
807 It could theoretically happen in gdb so we handle it.
808 ??? There is currently a memory leak but it's not worth the trouble. */
809 if (sparc64_p)
810 opcodes_initialized = 0;
811 sparc64_p = 0;
812 return print_insn (memaddr, info);
813}
814
815int
816print_insn_sparc64 (memaddr, info)
817 bfd_vma memaddr;
818 disassemble_info *info;
819{
820 /* It's not clear that we'll ever switch cpus in a running program.
821 It could theoretically happen in gdb so we handle it.
822 ??? There is currently a memory leak but it's not worth the trouble. */
823 if (!sparc64_p)
824 opcodes_initialized = 0;
825 sparc64_p = 1;
826 return print_insn (memaddr, info);
827}
This page took 0.182972 seconds and 4 git commands to generate.