0962f9f571e5841b3661e9a99f15f5ef4e72b430
1 /* Print SPARC instructions.
2 Copyright 1989, 1991, 1992, 1993, 1995 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19 #include "opcode/sparc.h"
21 #include "libiberty.h"
24 /* For faster lookup, after insns are sorted they are hashed. */
25 /* ??? I think there is room for even more improvement. */
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). */
31 static int opcode_bits
[4] = { 0x01c00000, 0x0, 0x01f80000, 0x01f80000 };
32 #define HASH_INSN(INSN) \
33 ((((INSN) >> 24) & 0xc0) | (((INSN) & opcode_bits[((INSN) >> 30) & 3]) >> 19))
35 struct opcode_hash
*next
;
36 struct sparc_opcode
*opcode
;
38 static struct opcode_hash
*opcode_hash_table
[HASH_SIZE
];
39 static void build_hash_table ();
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) )
46 static char *reg_names
[] =
47 { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
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",
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. */
62 "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr"
65 #define freg_names (®_names[4 * 8])
68 /* These are ordered according to there register number in
69 rdpr and wrpr insns. */
70 static char *v9_priv_reg_names
[] =
72 "tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl",
73 "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
75 /* "ver" - special cased */
79 /* Macros used to extract instruction fields. Not all fields have
80 macros defined here, only those which are actually used. */
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)
93 #define X_DISP16(i) (((((i) >> 20) & 3) << 14) | (((i) >> 0) & 0x3fff))
96 /* Here is the union which was used to extract instruction fields
97 before the shift and mask macros were written.
101 unsigned long int code;
109 unsigned int anrs1:5;
110 #define rs1 ldst.anrs1
112 unsigned int anasi:8;
113 #define asi ldst.anasi
114 unsigned int anrs2:5;
115 #define rs2 ldst.anrs2
120 unsigned int anop:2, anrd:5, op3:6, anrs1:5, i:1;
121 unsigned int IMM13:13;
122 #define imm13 IMM13.IMM13
130 unsigned int DISP22:22;
131 #define disp22 branch.DISP22
140 unsigned int rcond:3;
142 unsigned int DISP16HI:2;
145 unsigned int DISP16LO:14;
151 unsigned int adisp30:30;
152 #define disp30 call.adisp30
158 /* Nonzero if INSN is the opcode for a delayed branch. */
160 is_delayed_branch (insn
)
163 struct opcode_hash
*op
;
165 for (op
= opcode_hash_table
[HASH_INSN (insn
)]; op
; op
= op
->next
)
167 CONST
struct sparc_opcode
*opcode
= op
->opcode
;
168 if ((opcode
->match
& insn
) == opcode
->match
169 && (opcode
->lose
& insn
) == 0)
170 return (opcode
->flags
& F_DELAYED
);
175 /* Nonzero of opcode table has been initialized. */
176 static int opcodes_initialized
= 0;
178 /* extern void qsort (); */
179 static int compare_opcodes ();
181 /* Print one instruction from MEMADDR on INFO->STREAM.
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
190 print_insn (memaddr
, info
, sparc64_p
)
192 disassemble_info
*info
;
195 FILE *stream
= info
->stream
;
198 register unsigned int i
;
199 register struct opcode_hash
*op
;
201 if (!opcodes_initialized
)
203 qsort ((char *) sparc_opcodes
, NUMOPCODES
,
204 sizeof (sparc_opcodes
[0]), compare_opcodes
);
205 build_hash_table (sparc_opcodes
, opcode_hash_table
, NUMOPCODES
);
206 opcodes_initialized
= 1;
211 (*info
->read_memory_func
) (memaddr
, buffer
, sizeof (buffer
), info
);
214 (*info
->memory_error_func
) (status
, memaddr
, info
);
219 insn
= bfd_getb32 (buffer
);
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 */
226 for (op
= opcode_hash_table
[HASH_INSN (insn
)]; op
; op
= op
->next
)
228 CONST
struct sparc_opcode
*opcode
= op
->opcode
;
230 /* If the current architecture isn't sparc64, skip sparc64 insns. */
232 && opcode
->architecture
== v9
)
235 /* If the current architecture is sparc64, skip sparc32 only insns. */
237 && (opcode
->flags
& F_NOTV9
))
240 if ((opcode
->match
& insn
) == opcode
->match
241 && (opcode
->lose
& insn
) == 0)
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;
247 /* Nonzero means that we have found a plus sign in the args
248 field of the opcode table. */
251 /* Nonzero means we have an annulled branch. */
254 /* Do we have an `add' or `or' instruction where rs1 is the same
255 as rsd, and which has the i bit set? */
256 if ((opcode
->match
== 0x80102000 || opcode
->match
== 0x80002000)
258 && X_RS1 (insn
) == X_RD (insn
))
259 imm_added_to_rs1
= 1;
261 if (X_RS1 (insn
) != X_RD (insn
)
262 && strchr (opcode
->args
, 'r') != 0)
263 /* Can't do simple format if source and dest are different. */
266 (*info
->fprintf_func
) (stream
, opcode
->name
);
269 register CONST
char *s
;
271 if (opcode
->args
[0] != ',')
272 (*info
->fprintf_func
) (stream
, " ");
273 for (s
= opcode
->args
; *s
!= '\0'; ++s
)
277 (*info
->fprintf_func
) (stream
, ",");
281 (*info
->fprintf_func
) (stream
, "a");
287 (*info
->fprintf_func
) (stream
, "pn");
292 (*info
->fprintf_func
) (stream
, "pt");
299 } /* switch on arg */
300 } /* while there are comma started args */
302 (*info
->fprintf_func
) (stream
, " ");
309 /* note fall-through */
311 (*info
->fprintf_func
) (stream
, "%c", *s
);
315 (*info
->fprintf_func
) (stream
, "0");
318 #define reg(n) (*info->fprintf_func) (stream, "%%%s", reg_names[n])
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)])
338 case 'v': /* double/even */
339 case 'V': /* quad/multiple of 4 */
340 fregx (X_RS1 (insn
));
346 case 'B': /* double/even */
347 case 'R': /* quad/multiple of 4 */
348 fregx (X_RS2 (insn
));
354 case 'H': /* double/even */
355 case 'J': /* quad/multiple of 4 */
361 #define creg(n) (*info->fprintf_func) (stream, "%%c%u", (unsigned int) (n))
376 (*info
->fprintf_func
) (stream
, "%%hi(%#x)",
378 & ((int) X_IMM22 (insn
) << 10)));
383 int imm
= SEX (X_IMM13 (insn
), 13);
385 /* Check to see whether we have a 1+i, and take
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 +,
393 imm_added_to_rs1
= 1;
396 (*info
->fprintf_func
) (stream
, "%d", imm
);
398 (*info
->fprintf_func
) (stream
, "%#x", imm
);
403 case 'I': /* 11 bit immediate. */
404 case 'j': /* 10 bit immediate. */
409 imm
= SEX (X_IMM13 (insn
), 11);
411 imm
= SEX (X_IMM13 (insn
), 10);
413 /* Check to see whether we have a 1+i, and take
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 +,
421 imm_added_to_rs1
= 1;
424 (info
->fprintf_func
) (stream
, "%d", imm
);
426 (info
->fprintf_func
) (stream
, "%#x", (unsigned) imm
);
431 info
->target
= memaddr
+ (SEX (X_DISP16 (insn
), 16)) * 4;
432 (*info
->print_address_func
) (info
->target
, info
);
436 info
->target
= memaddr
+ (SEX (X_DISP22 (insn
), 19)) * 4;
437 (*info
->print_address_func
) (info
->target
, info
);
444 (*info
->fprintf_func
) (stream
, "%%fcc%c", *s
- '6' + '0');
448 (*info
->fprintf_func
) (stream
, "%%icc");
452 (*info
->fprintf_func
) (stream
, "%%xcc");
456 (*info
->fprintf_func
) (stream
, "%%ccr");
460 (*info
->fprintf_func
) (stream
, "%%fprs");
464 (*info
->fprintf_func
) (stream
, "%%asi");
468 (*info
->fprintf_func
) (stream
, "%%tick");
472 (*info
->fprintf_func
) (stream
, "%%pc");
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
)]);
482 (*info
->fprintf_func
) (stream
, "%%reserved");
486 if ((unsigned) X_RD (insn
) < 15)
487 (*info
->fprintf_func
) (stream
, "%%%s",
488 v9_priv_reg_names
[X_RD (insn
)]);
490 (*info
->fprintf_func
) (stream
, "%%reserved");
496 (*info
->fprintf_func
) (stream
, "%%asr%d", X_RS1 (insn
));
500 (*info
->fprintf_func
) (stream
, "%%asr%d", X_RD (insn
));
504 info
->target
= memaddr
+ X_DISP30 (insn
) * 4;
505 (*info
->print_address_func
) (info
->target
, info
);
509 (*info
->fprintf_func
)
510 (stream
, "%#x", (SEX (X_DISP22 (insn
), 22)));
514 info
->target
= memaddr
+ (SEX (X_DISP22 (insn
), 22)) * 4;
515 (*info
->print_address_func
) (info
->target
, info
);
520 char *name
= sparc_decode_asi (X_ASI (insn
));
523 (*info
->fprintf_func
) (stream
, "%s", name
);
525 (*info
->fprintf_func
) (stream
, "(%d)", X_ASI (insn
));
530 (*info
->fprintf_func
) (stream
, "%%csr");
534 (*info
->fprintf_func
) (stream
, "%%fsr");
538 (*info
->fprintf_func
) (stream
, "%%psr");
542 (*info
->fprintf_func
) (stream
, "%%fq");
546 (*info
->fprintf_func
) (stream
, "%%cq");
550 (*info
->fprintf_func
) (stream
, "%%tbr");
554 (*info
->fprintf_func
) (stream
, "%%wim");
558 (*info
->fprintf_func
) (stream
, "%d",
559 ((X_LDST_I (insn
) << 8)
564 (*info
->fprintf_func
) (stream
, "%%y");
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
)
578 unsigned long prev_insn
;
582 (*info
->read_memory_func
)
583 (memaddr
- 4, buffer
, sizeof (buffer
), info
);
584 prev_insn
= bfd_getb32 (buffer
);
588 /* If it is a delayed branch, we need to look at the
589 instruction before the delayed branch. This handles
592 sethi %o1, %hi(_foo), %o1
594 or %o1, %lo(_foo), %o1
597 if (is_delayed_branch (prev_insn
))
599 errcode
= (*info
->read_memory_func
)
600 (memaddr
- 8, buffer
, sizeof (buffer
), info
);
601 prev_insn
= bfd_getb32 (buffer
);
605 /* If there was a problem reading memory, then assume
606 the previous instruction was not sethi. */
609 /* Is it sethi to the same register? */
610 if ((prev_insn
& 0xc1c00000) == 0x01000000
611 && X_RD (prev_insn
) == X_RS1 (insn
))
613 (*info
->fprintf_func
) (stream
, "\t! ");
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!!! */
624 if (opcode
->flags
& (F_UNBR
|F_CONDBR
|F_JSR
))
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;
637 return sizeof (buffer
);
641 info
->insn_type
= dis_noninsn
; /* Mark as non-valid instruction */
642 (*info
->fprintf_func
) (stream
, "%#8x", insn
);
643 return sizeof (buffer
);
646 /* Compare opcodes A and B. */
649 compare_opcodes (a
, b
)
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
;
658 /* If a bit is set in both match and lose, there is something
659 wrong with the opcode table. */
662 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
663 op0
->name
, match0
, lose0
);
664 op0
->lose
&= ~op0
->match
;
670 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
671 op1
->name
, match1
, lose1
);
672 op1
->lose
&= ~op1
->match
;
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
)
680 unsigned long int x
= 1 << i
;
681 int x0
= (match0
& x
) != 0;
682 int x1
= (match1
& x
) != 0;
688 for (i
= 0; i
< 32; ++i
)
690 unsigned long int x
= 1 << i
;
691 int x0
= (lose0
& x
) != 0;
692 int x1
= (lose1
& x
) != 0;
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
);
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. */
705 /* Our first aesthetic ground is that aliases defer to real insns. */
707 int alias_diff
= (op0
->flags
& F_ALIAS
) - (op1
->flags
& F_ALIAS
);
709 /* Put the one that isn't an alias first. */
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
);
717 if (op0
->flags
& F_ALIAS
) /* If they're both aliases, be arbitrary. */
721 "Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n",
722 op0
->name
, op1
->name
);
724 /* Fewer arguments are preferred. */
726 int length_diff
= strlen (op0
->args
) - strlen (op1
->args
);
727 if (length_diff
!= 0)
728 /* Put the one with fewer arguments first. */
732 /* Put 1+i before i+1. */
734 char *p0
= (char *) strchr(op0
->args
, '+');
735 char *p1
= (char *) strchr(op1
->args
, '+');
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. */
745 if (p0
[1] == 'i' && p1
[-1] == 'i')
746 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
751 /* Put 1,i before i,1. */
753 int i0
= strncmp (op0
->args
, "i,1", 3) == 0;
754 int i1
= strncmp (op1
->args
, "i,1", 3) == 0;
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. */
767 /* Build a hash table from the opcode table. */
770 build_hash_table (table
, hash_table
, num_opcodes
)
771 struct sparc_opcode
*table
;
772 struct opcode_hash
**hash_table
;
776 int hash_count
[HASH_SIZE
];
777 static struct opcode_hash
*hash_buf
= NULL
;
779 /* Start at the end of the table and work backwards so that each
782 memset (hash_table
, 0, HASH_SIZE
* sizeof (hash_table
[0]));
783 memset (hash_count
, 0, HASH_SIZE
* sizeof (hash_count
[0]));
784 if (hash_buf
!= NULL
)
786 hash_buf
= (struct opcode_hash
*) xmalloc (sizeof (struct opcode_hash
) * num_opcodes
);
787 for (i
= num_opcodes
- 1; i
>= 0; --i
)
789 register int hash
= HASH_INSN (sparc_opcodes
[i
].match
);
790 register struct opcode_hash
*h
= &hash_buf
[i
];
791 h
->next
= hash_table
[hash
];
792 h
->opcode
= &sparc_opcodes
[i
];
793 hash_table
[hash
] = h
;
797 #if 0 /* for debugging */
799 int min_count
= num_opcodes
, max_count
= 0;
802 for (i
= 0; i
< HASH_SIZE
; ++i
)
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
];
811 printf ("Opcode hash table stats: min %d, max %d, ave %f\n",
812 min_count
, max_count
, (double) total
/ HASH_SIZE
);
818 print_insn_sparc (memaddr
, info
)
820 disassemble_info
*info
;
822 return print_insn (memaddr
, info
, 0);
826 print_insn_sparc64 (memaddr
, info
)
828 disassemble_info
*info
;
830 return print_insn (memaddr
, info
, 1);
This page took 0.048182 seconds and 4 git commands to generate.