1 /* Print SPARC instructions.
2 Copyright (C) 1989, 91-93, 1995, 1996 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 /* Bitmask of v9 architectures. */
25 #define MASK_V9 ((1 << SPARC_OPCODE_ARCH_V9) \
26 | (1 << SPARC_OPCODE_ARCH_V9A))
27 /* 1 if INSN is for v9 only. */
28 #define V9_ONLY_P(insn) (! ((insn)->architecture & ~MASK_V9))
29 /* 1 if INSN is for v9. */
30 #define V9_P(insn) (((insn)->architecture & MASK_V9) != 0)
32 /* For faster lookup, after insns are sorted they are hashed. */
33 /* ??? I think there is room for even more improvement. */
36 /* It is important that we only look at insn code bits as that is how the
37 opcode table is hashed. OPCODE_BITS is a table of valid bits for each
38 of the main types (0,1,2,3). */
39 static int opcode_bits
[4] = { 0x01c00000, 0x0, 0x01f80000, 0x01f80000 };
40 #define HASH_INSN(INSN) \
41 ((((INSN) >> 24) & 0xc0) | (((INSN) & opcode_bits[((INSN) >> 30) & 3]) >> 19))
43 struct opcode_hash
*next
;
44 struct sparc_opcode
*opcode
;
46 static struct opcode_hash
*opcode_hash_table
[HASH_SIZE
];
47 static void build_hash_table ();
49 /* Sign-extend a value which is N bits long. */
50 #define SEX(value, bits) \
51 ((((int)(value)) << ((8 * sizeof (int)) - bits)) \
52 >> ((8 * sizeof (int)) - bits) )
54 static char *reg_names
[] =
55 { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
56 "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
57 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
58 "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
59 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
60 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
61 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
62 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
63 "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
64 "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
65 "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
66 "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
67 /* psr, wim, tbr, fpsr, cpsr are v8 only. */
68 "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr"
71 #define freg_names (®_names[4 * 8])
73 /* These are ordered according to there register number in
74 rdpr and wrpr insns. */
75 static char *v9_priv_reg_names
[] =
77 "tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl",
78 "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
80 /* "ver" - special cased */
83 /* Macros used to extract instruction fields. Not all fields have
84 macros defined here, only those which are actually used. */
86 #define X_RD(i) (((i) >> 25) & 0x1f)
87 #define X_RS1(i) (((i) >> 14) & 0x1f)
88 #define X_LDST_I(i) (((i) >> 13) & 1)
89 #define X_ASI(i) (((i) >> 5) & 0xff)
90 #define X_RS2(i) (((i) >> 0) & 0x1f)
91 #define X_IMM13(i) (((i) >> 0) & 0x1fff)
92 #define X_DISP22(i) (((i) >> 0) & 0x3fffff)
93 #define X_IMM22(i) X_DISP22 (i)
94 #define X_DISP30(i) (((i) >> 0) & 0x3fffffff)
96 /* These are for v9. */
97 #define X_DISP16(i) (((((i) >> 20) & 3) << 14) | (((i) >> 0) & 0x3fff))
98 #define X_DISP19(i) (((i) >> 0) & 0x7ffff)
99 #define X_MEMBAR(i) ((i) & 0x7f)
101 /* Here is the union which was used to extract instruction fields
102 before the shift and mask macros were written.
106 unsigned long int code;
114 unsigned int anrs1:5;
115 #define rs1 ldst.anrs1
117 unsigned int anasi:8;
118 #define asi ldst.anasi
119 unsigned int anrs2:5;
120 #define rs2 ldst.anrs2
125 unsigned int anop:2, anrd:5, op3:6, anrs1:5, i:1;
126 unsigned int IMM13:13;
127 #define imm13 IMM13.IMM13
135 unsigned int DISP22:22;
136 #define disp22 branch.DISP22
144 unsigned int rcond:3;
146 unsigned int DISP16HI:2;
149 unsigned int DISP16LO:14;
154 unsigned int adisp30:30;
155 #define disp30 call.adisp30
161 /* Nonzero if INSN is the opcode for a delayed branch. */
163 is_delayed_branch (insn
)
166 struct opcode_hash
*op
;
168 for (op
= opcode_hash_table
[HASH_INSN (insn
)]; op
; op
= op
->next
)
170 CONST
struct sparc_opcode
*opcode
= op
->opcode
;
171 if ((opcode
->match
& insn
) == opcode
->match
172 && (opcode
->lose
& insn
) == 0)
173 return (opcode
->flags
& F_DELAYED
);
178 /* Nonzero of opcode table has been initialized. */
179 static int opcodes_initialized
= 0;
181 /* extern void qsort (); */
182 static int compare_opcodes ();
184 /* Print one instruction from MEMADDR on INFO->STREAM.
186 We suffix the instruction with a comment that gives the absolute
187 address involved, as well as its symbolic form, if the instruction
188 is preceded by a findable `sethi' and it either adds an immediate
189 displacement to that register, or it is an `add' or `or' instruction
193 print_insn_sparc (memaddr
, info
)
195 disassemble_info
*info
;
197 FILE *stream
= info
->stream
;
200 register unsigned int i
;
201 register struct opcode_hash
*op
;
202 int sparc_v9_p
= bfd_mach_sparc_v9_p (info
->mach
);
204 if (!opcodes_initialized
)
206 qsort ((char *) sparc_opcodes
, sparc_num_opcodes
,
207 sizeof (sparc_opcodes
[0]), compare_opcodes
);
208 build_hash_table (sparc_opcodes
, opcode_hash_table
, sparc_num_opcodes
);
209 opcodes_initialized
= 1;
214 (*info
->read_memory_func
) (memaddr
, buffer
, sizeof (buffer
), info
);
217 (*info
->memory_error_func
) (status
, memaddr
, info
);
222 insn
= bfd_getb32 (buffer
);
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 */
229 for (op
= opcode_hash_table
[HASH_INSN (insn
)]; op
; op
= op
->next
)
231 CONST
struct sparc_opcode
*opcode
= op
->opcode
;
233 /* ??? These architecture tests need to be more selective. */
235 /* If the current architecture isn't sparc64, skip sparc64 insns. */
237 && V9_ONLY_P (opcode
))
240 /* If the current architecture is sparc64, skip sparc32 only insns. */
245 if ((opcode
->match
& insn
) == opcode
->match
246 && (opcode
->lose
& insn
) == 0)
248 /* Nonzero means that we have found an instruction which has
249 the effect of adding or or'ing the imm13 field to rs1. */
250 int imm_added_to_rs1
= 0;
252 /* Nonzero means that we have found a plus sign in the args
253 field of the opcode table. */
256 /* Nonzero means we have an annulled branch. */
259 /* Do we have an `add' or `or' instruction where rs1 is the same
260 as rsd, and which has the i bit set? */
261 if ((opcode
->match
== 0x80102000 || opcode
->match
== 0x80002000)
263 && X_RS1 (insn
) == X_RD (insn
))
264 imm_added_to_rs1
= 1;
266 if (X_RS1 (insn
) != X_RD (insn
)
267 && strchr (opcode
->args
, 'r') != 0)
268 /* Can't do simple format if source and dest are different. */
271 (*info
->fprintf_func
) (stream
, opcode
->name
);
274 register CONST
char *s
;
276 if (opcode
->args
[0] != ',')
277 (*info
->fprintf_func
) (stream
, " ");
278 for (s
= opcode
->args
; *s
!= '\0'; ++s
)
282 (*info
->fprintf_func
) (stream
, ",");
286 (*info
->fprintf_func
) (stream
, "a");
291 (*info
->fprintf_func
) (stream
, "pn");
296 (*info
->fprintf_func
) (stream
, "pt");
302 } /* switch on arg */
303 } /* while there are comma started args */
305 (*info
->fprintf_func
) (stream
, " ");
312 /* note fall-through */
314 (*info
->fprintf_func
) (stream
, "%c", *s
);
318 (*info
->fprintf_func
) (stream
, "0");
321 #define reg(n) (*info->fprintf_func) (stream, "%%%s", reg_names[n])
336 #define freg(n) (*info->fprintf_func) (stream, "%%%s", freg_names[n])
337 #define fregx(n) (*info->fprintf_func) (stream, "%%%s", freg_names[((n) & ~1) | (((n) & 1) << 5)])
341 case 'v': /* double/even */
342 case 'V': /* quad/multiple of 4 */
343 fregx (X_RS1 (insn
));
349 case 'B': /* double/even */
350 case 'R': /* quad/multiple of 4 */
351 fregx (X_RS2 (insn
));
357 case 'H': /* double/even */
358 case 'J': /* quad/multiple of 4 */
364 #define creg(n) (*info->fprintf_func) (stream, "%%c%u", (unsigned int) (n))
379 (*info
->fprintf_func
) (stream
, "%%hi(%#x)",
381 & ((int) X_IMM22 (insn
) << 10)));
386 int imm
= SEX (X_IMM13 (insn
), 13);
388 /* Check to see whether we have a 1+i, and take
391 Note: because of the way we sort the table,
392 we will be matching 1+i rather than i+1,
393 so it is OK to assume that i is after +,
396 imm_added_to_rs1
= 1;
399 (*info
->fprintf_func
) (stream
, "%d", imm
);
401 (*info
->fprintf_func
) (stream
, "%#x", imm
);
405 case 'I': /* 11 bit immediate. */
406 case 'j': /* 10 bit immediate. */
411 imm
= SEX (X_IMM13 (insn
), 11);
413 imm
= SEX (X_IMM13 (insn
), 10);
415 /* Check to see whether we have a 1+i, and take
418 Note: because of the way we sort the table,
419 we will be matching 1+i rather than i+1,
420 so it is OK to assume that i is after +,
423 imm_added_to_rs1
= 1;
426 (info
->fprintf_func
) (stream
, "%d", imm
);
428 (info
->fprintf_func
) (stream
, "%#x", (unsigned) imm
);
434 int mask
= X_MEMBAR (insn
);
435 int bit
= 0x40, printed_one
= 0;
439 (info
->fprintf_func
) (stream
, "0");
446 (info
->fprintf_func
) (stream
, "|");
447 name
= sparc_decode_membar (bit
);
448 (info
->fprintf_func
) (stream
, "%s", name
);
457 info
->target
= memaddr
+ SEX (X_DISP16 (insn
), 16) * 4;
458 (*info
->print_address_func
) (info
->target
, info
);
462 info
->target
= memaddr
+ SEX (X_DISP19 (insn
), 19) * 4;
463 (*info
->print_address_func
) (info
->target
, info
);
470 (*info
->fprintf_func
) (stream
, "%%fcc%c", *s
- '6' + '0');
474 (*info
->fprintf_func
) (stream
, "%%icc");
478 (*info
->fprintf_func
) (stream
, "%%xcc");
482 (*info
->fprintf_func
) (stream
, "%%ccr");
486 (*info
->fprintf_func
) (stream
, "%%fprs");
490 (*info
->fprintf_func
) (stream
, "%%asi");
494 (*info
->fprintf_func
) (stream
, "%%tick");
498 (*info
->fprintf_func
) (stream
, "%%pc");
502 if (X_RS1 (insn
) == 31)
503 (*info
->fprintf_func
) (stream
, "%%ver");
504 else if ((unsigned) X_RS1 (insn
) < 16)
505 (*info
->fprintf_func
) (stream
, "%%%s",
506 v9_priv_reg_names
[X_RS1 (insn
)]);
508 (*info
->fprintf_func
) (stream
, "%%reserved");
512 if ((unsigned) X_RD (insn
) < 15)
513 (*info
->fprintf_func
) (stream
, "%%%s",
514 v9_priv_reg_names
[X_RD (insn
)]);
516 (*info
->fprintf_func
) (stream
, "%%reserved");
521 char *name
= sparc_decode_prefetch (X_RD (insn
));
524 (*info
->fprintf_func
) (stream
, "%s", name
);
526 (*info
->fprintf_func
) (stream
, "%d", X_RD (insn
));
531 (*info
->fprintf_func
) (stream
, "%%asr%d", X_RS1 (insn
));
535 (*info
->fprintf_func
) (stream
, "%%asr%d", X_RD (insn
));
539 info
->target
= memaddr
+ SEX (X_DISP30 (insn
), 30) * 4;
540 (*info
->print_address_func
) (info
->target
, info
);
544 (*info
->fprintf_func
)
545 (stream
, "%#x", SEX (X_DISP22 (insn
), 22));
549 info
->target
= memaddr
+ SEX (X_DISP22 (insn
), 22) * 4;
550 (*info
->print_address_func
) (info
->target
, info
);
555 char *name
= sparc_decode_asi (X_ASI (insn
));
558 (*info
->fprintf_func
) (stream
, "%s", name
);
560 (*info
->fprintf_func
) (stream
, "(%d)", X_ASI (insn
));
565 (*info
->fprintf_func
) (stream
, "%%csr");
569 (*info
->fprintf_func
) (stream
, "%%fsr");
573 (*info
->fprintf_func
) (stream
, "%%psr");
577 (*info
->fprintf_func
) (stream
, "%%fq");
581 (*info
->fprintf_func
) (stream
, "%%cq");
585 (*info
->fprintf_func
) (stream
, "%%tbr");
589 (*info
->fprintf_func
) (stream
, "%%wim");
593 (*info
->fprintf_func
) (stream
, "%d",
594 ((X_LDST_I (insn
) << 8)
599 (*info
->fprintf_func
) (stream
, "%%y");
605 int val
= *s
== 'U' ? X_RS1 (insn
) : X_RD (insn
);
606 char *name
= sparc_decode_sparclet_cpreg (val
);
609 (*info
->fprintf_func
) (stream
, "%s", name
);
611 (*info
->fprintf_func
) (stream
, "%%cpreg(%d)", val
);
618 /* If we are adding or or'ing something to rs1, then
619 check to see whether the previous instruction was
620 a sethi to the same register as in the sethi.
621 If so, attempt to print the result of the add or
622 or (in this context add and or do the same thing)
623 and its symbolic value. */
624 if (imm_added_to_rs1
)
626 unsigned long prev_insn
;
630 (*info
->read_memory_func
)
631 (memaddr
- 4, buffer
, sizeof (buffer
), info
);
632 prev_insn
= bfd_getb32 (buffer
);
636 /* If it is a delayed branch, we need to look at the
637 instruction before the delayed branch. This handles
640 sethi %o1, %hi(_foo), %o1
642 or %o1, %lo(_foo), %o1
645 if (is_delayed_branch (prev_insn
))
647 errcode
= (*info
->read_memory_func
)
648 (memaddr
- 8, buffer
, sizeof (buffer
), info
);
649 prev_insn
= bfd_getb32 (buffer
);
653 /* If there was a problem reading memory, then assume
654 the previous instruction was not sethi. */
657 /* Is it sethi to the same register? */
658 if ((prev_insn
& 0xc1c00000) == 0x01000000
659 && X_RD (prev_insn
) == X_RS1 (insn
))
661 (*info
->fprintf_func
) (stream
, "\t! ");
663 (0xFFFFFFFF & (int) X_IMM22 (prev_insn
) << 10)
664 | SEX (X_IMM13 (insn
), 13);
665 (*info
->print_address_func
) (info
->target
, info
);
666 info
->insn_type
= dis_dref
;
667 info
->data_size
= 4; /* FIXME!!! */
672 if (opcode
->flags
& (F_UNBR
|F_CONDBR
|F_JSR
))
674 /* FIXME -- check is_annulled flag */
675 if (opcode
->flags
& F_UNBR
)
676 info
->insn_type
= dis_branch
;
677 if (opcode
->flags
& F_CONDBR
)
678 info
->insn_type
= dis_condbranch
;
679 if (opcode
->flags
& F_JSR
)
680 info
->insn_type
= dis_jsr
;
681 if (opcode
->flags
& F_DELAYED
)
682 info
->branch_delay_insns
= 1;
685 return sizeof (buffer
);
689 info
->insn_type
= dis_noninsn
; /* Mark as non-valid instruction */
690 (*info
->fprintf_func
) (stream
, "unknown");
691 return sizeof (buffer
);
694 /* Compare opcodes A and B. */
697 compare_opcodes (a
, b
)
700 struct sparc_opcode
*op0
= (struct sparc_opcode
*) a
;
701 struct sparc_opcode
*op1
= (struct sparc_opcode
*) b
;
702 unsigned long int match0
= op0
->match
, match1
= op1
->match
;
703 unsigned long int lose0
= op0
->lose
, lose1
= op1
->lose
;
704 register unsigned int i
;
706 /* If a bit is set in both match and lose, there is something
707 wrong with the opcode table. */
710 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
711 op0
->name
, match0
, lose0
);
712 op0
->lose
&= ~op0
->match
;
718 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
719 op1
->name
, match1
, lose1
);
720 op1
->lose
&= ~op1
->match
;
724 /* Because the bits that are variable in one opcode are constant in
725 another, it is important to order the opcodes in the right order. */
726 for (i
= 0; i
< 32; ++i
)
728 unsigned long int x
= 1 << i
;
729 int x0
= (match0
& x
) != 0;
730 int x1
= (match1
& x
) != 0;
736 for (i
= 0; i
< 32; ++i
)
738 unsigned long int x
= 1 << i
;
739 int x0
= (lose0
& x
) != 0;
740 int x1
= (lose1
& x
) != 0;
746 /* Put non-sparc64 insns ahead of sparc64 ones. */
747 if (V9_ONLY_P (op0
) != V9_ONLY_P (op1
))
748 return V9_ONLY_P (op0
) - V9_ONLY_P (op1
);
750 /* They are functionally equal. So as long as the opcode table is
751 valid, we can put whichever one first we want, on aesthetic grounds. */
753 /* Our first aesthetic ground is that aliases defer to real insns. */
755 int alias_diff
= (op0
->flags
& F_ALIAS
) - (op1
->flags
& F_ALIAS
);
757 /* Put the one that isn't an alias first. */
761 /* Except for aliases, two "identical" instructions had
762 better have the same opcode. This is a sanity check on the table. */
763 i
= strcmp (op0
->name
, op1
->name
);
765 if (op0
->flags
& F_ALIAS
) /* If they're both aliases, be arbitrary. */
769 "Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n",
770 op0
->name
, op1
->name
);
772 /* Fewer arguments are preferred. */
774 int length_diff
= strlen (op0
->args
) - strlen (op1
->args
);
775 if (length_diff
!= 0)
776 /* Put the one with fewer arguments first. */
780 /* Put 1+i before i+1. */
782 char *p0
= (char *) strchr(op0
->args
, '+');
783 char *p1
= (char *) strchr(op1
->args
, '+');
787 /* There is a plus in both operands. Note that a plus
788 sign cannot be the first character in args,
789 so the following [-1]'s are valid. */
790 if (p0
[-1] == 'i' && p1
[1] == 'i')
791 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
793 if (p0
[1] == 'i' && p1
[-1] == 'i')
794 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
799 /* Put 1,i before i,1. */
801 int i0
= strncmp (op0
->args
, "i,1", 3) == 0;
802 int i1
= strncmp (op1
->args
, "i,1", 3) == 0;
808 /* They are, as far as we can tell, identical.
809 Since qsort may have rearranged the table partially, there is
810 no way to tell which one was first in the opcode table as
811 written, so just say there are equal. */
815 /* Build a hash table from the opcode table. */
818 build_hash_table (table
, hash_table
, num_opcodes
)
819 struct sparc_opcode
*table
;
820 struct opcode_hash
**hash_table
;
824 int hash_count
[HASH_SIZE
];
825 static struct opcode_hash
*hash_buf
= NULL
;
827 /* Start at the end of the table and work backwards so that each
830 memset (hash_table
, 0, HASH_SIZE
* sizeof (hash_table
[0]));
831 memset (hash_count
, 0, HASH_SIZE
* sizeof (hash_count
[0]));
832 if (hash_buf
!= NULL
)
834 hash_buf
= (struct opcode_hash
*) xmalloc (sizeof (struct opcode_hash
) * num_opcodes
);
835 for (i
= num_opcodes
- 1; i
>= 0; --i
)
837 register int hash
= HASH_INSN (sparc_opcodes
[i
].match
);
838 register struct opcode_hash
*h
= &hash_buf
[i
];
839 h
->next
= hash_table
[hash
];
840 h
->opcode
= &sparc_opcodes
[i
];
841 hash_table
[hash
] = h
;
845 #if 0 /* for debugging */
847 int min_count
= num_opcodes
, max_count
= 0;
850 for (i
= 0; i
< HASH_SIZE
; ++i
)
852 if (hash_count
[i
] < min_count
)
853 min_count
= hash_count
[i
];
854 if (hash_count
[i
] > max_count
)
855 max_count
= hash_count
[i
];
856 total
+= hash_count
[i
];
859 printf ("Opcode hash table stats: min %d, max %d, ave %f\n",
860 min_count
, max_count
, (double) total
/ HASH_SIZE
);
This page took 0.050483 seconds and 5 git commands to generate.