source: trunk/src/binutils/opcodes/sparc-dis.c@ 842

Last change on this file since 842 was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 26.6 KB
Line 
1/* Print SPARC instructions.
2 Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2002, 2003 Free Software Foundation, Inc.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18
19#include <stdio.h>
20
21#include "sysdep.h"
22#include "opcode/sparc.h"
23#include "dis-asm.h"
24#include "libiberty.h"
25#include "opintl.h"
26
27/* Bitmask of v9 architectures. */
28#define MASK_V9 ((1 << SPARC_OPCODE_ARCH_V9) \
29 | (1 << SPARC_OPCODE_ARCH_V9A) \
30 | (1 << SPARC_OPCODE_ARCH_V9B))
31/* 1 if INSN is for v9 only. */
32#define V9_ONLY_P(insn) (! ((insn)->architecture & ~MASK_V9))
33/* 1 if INSN is for v9. */
34#define V9_P(insn) (((insn)->architecture & MASK_V9) != 0)
35
36/* The sorted opcode table. */
37static const struct sparc_opcode **sorted_opcodes;
38
39/* For faster lookup, after insns are sorted they are hashed. */
40/* ??? I think there is room for even more improvement. */
41
42#define HASH_SIZE 256
43/* It is important that we only look at insn code bits as that is how the
44 opcode table is hashed. OPCODE_BITS is a table of valid bits for each
45 of the main types (0,1,2,3). */
46static int opcode_bits[4] = { 0x01c00000, 0x0, 0x01f80000, 0x01f80000 };
47#define HASH_INSN(INSN) \
48 ((((INSN) >> 24) & 0xc0) | (((INSN) & opcode_bits[((INSN) >> 30) & 3]) >> 19))
49struct opcode_hash
50{
51 struct opcode_hash *next;
52 const struct sparc_opcode *opcode;
53};
54static struct opcode_hash *opcode_hash_table[HASH_SIZE];
55
56static void build_hash_table
57 PARAMS ((const struct sparc_opcode **, struct opcode_hash **, int));
58static int is_delayed_branch PARAMS ((unsigned long));
59static int compare_opcodes PARAMS ((const PTR, const PTR));
60static int compute_arch_mask PARAMS ((unsigned long));
61
62/* Sign-extend a value which is N bits long. */
63#define SEX(value, bits) \
64 ((((int)(value)) << ((8 * sizeof (int)) - bits)) \
65 >> ((8 * sizeof (int)) - bits) )
66
67static char *reg_names[] =
68{ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
69 "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
70 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
71 "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
72 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
73 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
74 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
75 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
76 "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
77 "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
78 "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
79 "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
80/* psr, wim, tbr, fpsr, cpsr are v8 only. */
81 "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr"
82};
83
84#define freg_names (&reg_names[4 * 8])
85
86/* These are ordered according to there register number in
87 rdpr and wrpr insns. */
88static char *v9_priv_reg_names[] =
89{
90 "tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl",
91 "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
92 "wstate", "fq"
93 /* "ver" - special cased */
94};
95
96/* These are ordered according to there register number in
97 rd and wr insns (-16). */
98static char *v9a_asr_reg_names[] =
99{
100 "pcr", "pic", "dcr", "gsr", "set_softint", "clear_softint",
101 "softint", "tick_cmpr", "sys_tick", "sys_tick_cmpr"
102};
103
104/* Macros used to extract instruction fields. Not all fields have
105 macros defined here, only those which are actually used. */
106
107#define X_RD(i) (((i) >> 25) & 0x1f)
108#define X_RS1(i) (((i) >> 14) & 0x1f)
109#define X_LDST_I(i) (((i) >> 13) & 1)
110#define X_ASI(i) (((i) >> 5) & 0xff)
111#define X_RS2(i) (((i) >> 0) & 0x1f)
112#define X_IMM(i,n) (((i) >> 0) & ((1 << (n)) - 1))
113#define X_SIMM(i,n) SEX (X_IMM ((i), (n)), (n))
114#define X_DISP22(i) (((i) >> 0) & 0x3fffff)
115#define X_IMM22(i) X_DISP22 (i)
116#define X_DISP30(i) (((i) >> 0) & 0x3fffffff)
117
118/* These are for v9. */
119#define X_DISP16(i) (((((i) >> 20) & 3) << 14) | (((i) >> 0) & 0x3fff))
120#define X_DISP19(i) (((i) >> 0) & 0x7ffff)
121#define X_MEMBAR(i) ((i) & 0x7f)
122
123/* Here is the union which was used to extract instruction fields
124 before the shift and mask macros were written.
125
126 union sparc_insn
127 {
128 unsigned long int code;
129 struct
130 {
131 unsigned int anop:2;
132 #define op ldst.anop
133 unsigned int anrd:5;
134 #define rd ldst.anrd
135 unsigned int op3:6;
136 unsigned int anrs1:5;
137 #define rs1 ldst.anrs1
138 unsigned int i:1;
139 unsigned int anasi:8;
140 #define asi ldst.anasi
141 unsigned int anrs2:5;
142 #define rs2 ldst.anrs2
143 #define shcnt rs2
144 } ldst;
145 struct
146 {
147 unsigned int anop:2, anrd:5, op3:6, anrs1:5, i:1;
148 unsigned int IMM13:13;
149 #define imm13 IMM13.IMM13
150 } IMM13;
151 struct
152 {
153 unsigned int anop:2;
154 unsigned int a:1;
155 unsigned int cond:4;
156 unsigned int op2:3;
157 unsigned int DISP22:22;
158 #define disp22 branch.DISP22
159 #define imm22 disp22
160 } branch;
161 struct
162 {
163 unsigned int anop:2;
164 unsigned int a:1;
165 unsigned int z:1;
166 unsigned int rcond:3;
167 unsigned int op2:3;
168 unsigned int DISP16HI:2;
169 unsigned int p:1;
170 unsigned int _rs1:5;
171 unsigned int DISP16LO:14;
172 } branch16;
173 struct
174 {
175 unsigned int anop:2;
176 unsigned int adisp30:30;
177 #define disp30 call.adisp30
178 } call;
179 };
180
181 */
182
183/* Nonzero if INSN is the opcode for a delayed branch. */