sparc-dis.c revision 1.1.1.8 1 1.1 christos /* Print SPARC instructions.
2 1.1.1.8 christos Copyright (C) 1989-2020 Free Software Foundation, Inc.
3 1.1 christos
4 1.1 christos This file is part of the GNU opcodes library.
5 1.1 christos
6 1.1 christos This library is free software; you can redistribute it and/or modify
7 1.1 christos it under the terms of the GNU General Public License as published by
8 1.1 christos the Free Software Foundation; either version 3, or (at your option)
9 1.1 christos any later version.
10 1.1 christos
11 1.1 christos It is distributed in the hope that it will be useful, but WITHOUT
12 1.1 christos ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 1.1 christos or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 1.1 christos License for more details.
15 1.1 christos
16 1.1 christos You should have received a copy of the GNU General Public License
17 1.1 christos along with this program; if not, write to the Free Software
18 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 1.1 christos MA 02110-1301, USA. */
20 1.1 christos
21 1.1 christos #include "sysdep.h"
22 1.1.1.2 christos #include <stdio.h>
23 1.1 christos #include "opcode/sparc.h"
24 1.1 christos #include "dis-asm.h"
25 1.1 christos #include "libiberty.h"
26 1.1 christos #include "opintl.h"
27 1.1 christos
28 1.1 christos /* Bitmask of v9 architectures. */
29 1.1 christos #define MASK_V9 ((1 << SPARC_OPCODE_ARCH_V9) \
30 1.1 christos | (1 << SPARC_OPCODE_ARCH_V9A) \
31 1.1.1.5 christos | (1 << SPARC_OPCODE_ARCH_V9B) \
32 1.1.1.5 christos | (1 << SPARC_OPCODE_ARCH_V9C) \
33 1.1.1.5 christos | (1 << SPARC_OPCODE_ARCH_V9D) \
34 1.1.1.5 christos | (1 << SPARC_OPCODE_ARCH_V9E) \
35 1.1.1.5 christos | (1 << SPARC_OPCODE_ARCH_V9V) \
36 1.1.1.7 christos | (1 << SPARC_OPCODE_ARCH_V9M) \
37 1.1.1.7 christos | (1 << SPARC_OPCODE_ARCH_M8))
38 1.1 christos /* 1 if INSN is for v9 only. */
39 1.1 christos #define V9_ONLY_P(insn) (! ((insn)->architecture & ~MASK_V9))
40 1.1 christos /* 1 if INSN is for v9. */
41 1.1 christos #define V9_P(insn) (((insn)->architecture & MASK_V9) != 0)
42 1.1 christos
43 1.1 christos /* The sorted opcode table. */
44 1.1 christos static const sparc_opcode **sorted_opcodes;
45 1.1 christos
46 1.1 christos /* For faster lookup, after insns are sorted they are hashed. */
47 1.1 christos /* ??? I think there is room for even more improvement. */
48 1.1 christos
49 1.1 christos #define HASH_SIZE 256
50 1.1 christos /* It is important that we only look at insn code bits as that is how the
51 1.1 christos opcode table is hashed. OPCODE_BITS is a table of valid bits for each
52 1.1 christos of the main types (0,1,2,3). */
53 1.1 christos static int opcode_bits[4] = { 0x01c00000, 0x0, 0x01f80000, 0x01f80000 };
54 1.1 christos #define HASH_INSN(INSN) \
55 1.1 christos ((((INSN) >> 24) & 0xc0) | (((INSN) & opcode_bits[((INSN) >> 30) & 3]) >> 19))
56 1.1 christos typedef struct sparc_opcode_hash
57 1.1 christos {
58 1.1 christos struct sparc_opcode_hash *next;
59 1.1 christos const sparc_opcode *opcode;
60 1.1 christos } sparc_opcode_hash;
61 1.1 christos
62 1.1 christos static sparc_opcode_hash *opcode_hash_table[HASH_SIZE];
63 1.1 christos
64 1.1 christos /* Sign-extend a value which is N bits long. */
65 1.1 christos #define SEX(value, bits) \
66 1.1.1.8 christos ((int) (((value & ((1u << (bits - 1) << 1) - 1)) \
67 1.1.1.8 christos ^ (1u << (bits - 1))) - (1u << (bits - 1))))
68 1.1 christos
69 1.1 christos static char *reg_names[] =
70 1.1 christos { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
71 1.1 christos "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
72 1.1 christos "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
73 1.1 christos "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
74 1.1 christos "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
75 1.1 christos "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
76 1.1 christos "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
77 1.1 christos "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
78 1.1 christos "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
79 1.1 christos "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
80 1.1 christos "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
81 1.1 christos "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
82 1.1 christos /* psr, wim, tbr, fpsr, cpsr are v8 only. */
83 1.1 christos "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr"
84 1.1 christos };
85 1.1 christos
86 1.1 christos #define freg_names (®_names[4 * 8])
87 1.1 christos
88 1.1 christos /* These are ordered according to there register number in
89 1.1 christos rdpr and wrpr insns. */
90 1.1 christos static char *v9_priv_reg_names[] =
91 1.1 christos {
92 1.1 christos "tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl",
93 1.1 christos "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
94 1.1 christos "wstate", "fq", "gl"
95 1.1.1.5 christos /* "ver" and "pmcdper" - special cased */
96 1.1 christos };
97 1.1 christos
98 1.1 christos /* These are ordered according to there register number in
99 1.1 christos rdhpr and wrhpr insns. */
100 1.1 christos static char *v9_hpriv_reg_names[] =
101 1.1 christos {
102 1.1 christos "hpstate", "htstate", "resv2", "hintp", "resv4", "htba", "hver",
103 1.1.1.5 christos "resv7", "resv8", "resv9", "resv10", "resv11", "resv12", "resv13",
104 1.1 christos "resv14", "resv15", "resv16", "resv17", "resv18", "resv19", "resv20",
105 1.1.1.5 christos "resv21", "resv22", "hmcdper", "hmcddfr", "resv25", "resv26", "hva_mask_nz",
106 1.1.1.4 christos "hstick_offset", "hstick_enable", "resv30", "hstick_cmpr"
107 1.1 christos };
108 1.1 christos
109 1.1 christos /* These are ordered according to there register number in
110 1.1 christos rd and wr insns (-16). */
111 1.1 christos static char *v9a_asr_reg_names[] =
112 1.1 christos {
113 1.1.1.5 christos "pcr", "pic", "dcr", "gsr", "softint_set", "softint_clear",
114 1.1.1.2 christos "softint", "tick_cmpr", "stick", "stick_cmpr", "cfr",
115 1.1.1.4 christos "pause", "mwait"
116 1.1 christos };
117 1.1 christos
118 1.1 christos /* Macros used to extract instruction fields. Not all fields have
119 1.1 christos macros defined here, only those which are actually used. */
120 1.1 christos
121 1.1 christos #define X_RD(i) (((i) >> 25) & 0x1f)
122 1.1 christos #define X_RS1(i) (((i) >> 14) & 0x1f)
123 1.1 christos #define X_LDST_I(i) (((i) >> 13) & 1)
124 1.1 christos #define X_ASI(i) (((i) >> 5) & 0xff)
125 1.1 christos #define X_RS2(i) (((i) >> 0) & 0x1f)
126 1.1.1.2 christos #define X_RS3(i) (((i) >> 9) & 0x1f)
127 1.1 christos #define X_IMM(i,n) (((i) >> 0) & ((1 << (n)) - 1))
128 1.1 christos #define X_SIMM(i,n) SEX (X_IMM ((i), (n)), (n))
129 1.1 christos #define X_DISP22(i) (((i) >> 0) & 0x3fffff)
130 1.1 christos #define X_IMM22(i) X_DISP22 (i)
131 1.1 christos #define X_DISP30(i) (((i) >> 0) & 0x3fffffff)
132 1.1.1.7 christos #define X_IMM2(i) (((i & 0x10) >> 3) | (i & 0x1))
133 1.1 christos
134 1.1 christos /* These are for v9. */
135 1.1 christos #define X_DISP16(i) (((((i) >> 20) & 3) << 14) | (((i) >> 0) & 0x3fff))
136 1.1.1.2 christos #define X_DISP10(i) (((((i) >> 19) & 3) << 8) | (((i) >> 5) & 0xff))
137 1.1 christos #define X_DISP19(i) (((i) >> 0) & 0x7ffff)
138 1.1 christos #define X_MEMBAR(i) ((i) & 0x7f)
139 1.1 christos
140 1.1 christos /* Here is the union which was used to extract instruction fields
141 1.1 christos before the shift and mask macros were written.
142 1.1 christos
143 1.1 christos union sparc_insn
144 1.1 christos {
145 1.1 christos unsigned long int code;
146 1.1 christos struct
147 1.1 christos {
148 1.1 christos unsigned int anop:2;
149 1.1 christos #define op ldst.anop
150 1.1 christos unsigned int anrd:5;
151 1.1 christos #define rd ldst.anrd
152 1.1 christos unsigned int op3:6;
153 1.1 christos unsigned int anrs1:5;
154 1.1 christos #define rs1 ldst.anrs1
155 1.1 christos unsigned int i:1;
156 1.1 christos unsigned int anasi:8;
157 1.1 christos #define asi ldst.anasi
158 1.1 christos unsigned int anrs2:5;
159 1.1 christos #define rs2 ldst.anrs2
160 1.1 christos #define shcnt rs2
161 1.1 christos } ldst;
162 1.1 christos struct
163 1.1 christos {
164 1.1 christos unsigned int anop:2, anrd:5, op3:6, anrs1:5, i:1;
165 1.1 christos unsigned int IMM13:13;
166 1.1 christos #define imm13 IMM13.IMM13
167 1.1 christos } IMM13;
168 1.1 christos struct
169 1.1 christos {
170 1.1 christos unsigned int anop:2;
171 1.1 christos unsigned int a:1;
172 1.1 christos unsigned int cond:4;
173 1.1 christos unsigned int op2:3;
174 1.1 christos unsigned int DISP22:22;
175 1.1 christos #define disp22 branch.DISP22
176 1.1 christos #define imm22 disp22
177 1.1 christos } branch;
178 1.1 christos struct
179 1.1 christos {
180 1.1 christos unsigned int anop:2;
181 1.1 christos unsigned int a:1;
182 1.1 christos unsigned int z:1;
183 1.1 christos unsigned int rcond:3;
184 1.1 christos unsigned int op2:3;
185 1.1 christos unsigned int DISP16HI:2;
186 1.1 christos unsigned int p:1;
187 1.1 christos unsigned int _rs1:5;
188 1.1 christos unsigned int DISP16LO:14;
189 1.1 christos } branch16;
190 1.1 christos struct
191 1.1 christos {
192 1.1 christos unsigned int anop:2;
193 1.1 christos unsigned int adisp30:30;
194 1.1 christos #define disp30 call.adisp30
195 1.1 christos } call;
196 1.1 christos }; */
197 1.1 christos
198 1.1 christos /* Nonzero if INSN is the opcode for a delayed branch. */
199 1.1 christos
200 1.1 christos static int
201 1.1 christos is_delayed_branch (unsigned long insn)
202 1.1 christos {
203 1.1 christos sparc_opcode_hash *op;
204 1.1 christos
205 1.1 christos for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
206 1.1 christos {
207 1.1 christos const sparc_opcode *opcode = op->opcode;
208 1.1 christos
209 1.1 christos if ((opcode->match & insn) == opcode->match
210 1.1 christos && (opcode->lose & insn) == 0)
211 1.1 christos return opcode->flags & F_DELAYED;
212 1.1 christos }
213 1.1 christos return 0;
214 1.1 christos }
215 1.1 christos
216 1.1 christos /* extern void qsort (); */
217 1.1 christos
218 1.1 christos /* Records current mask of SPARC_OPCODE_ARCH_FOO values, used to pass value
219 1.1 christos to compare_opcodes. */
220 1.1 christos static unsigned int current_arch_mask;
221 1.1 christos
222 1.1 christos /* Given BFD mach number, return a mask of SPARC_OPCODE_ARCH_FOO values. */
223 1.1 christos
224 1.1 christos static int
225 1.1 christos compute_arch_mask (unsigned long mach)
226 1.1 christos {
227 1.1 christos switch (mach)
228 1.1 christos {
229 1.1 christos case 0 :
230 1.1 christos case bfd_mach_sparc :
231 1.1.1.3 christos return (SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8)
232 1.1.1.3 christos | SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_LEON));
233 1.1 christos case bfd_mach_sparc_sparclet :
234 1.1 christos return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLET);
235 1.1 christos case bfd_mach_sparc_sparclite :
236 1.1 christos case bfd_mach_sparc_sparclite_le :
237 1.1 christos /* sparclites insns are recognized by default (because that's how
238 1.1 christos they've always been treated, for better or worse). Kludge this by
239 1.1 christos indicating generic v8 is also selected. */
240 1.1 christos return (SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLITE)
241 1.1 christos | SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8));
242 1.1 christos case bfd_mach_sparc_v8plus :
243 1.1 christos case bfd_mach_sparc_v9 :
244 1.1 christos return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9);
245 1.1 christos case bfd_mach_sparc_v8plusa :
246 1.1 christos case bfd_mach_sparc_v9a :
247 1.1 christos return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9A);
248 1.1 christos case bfd_mach_sparc_v8plusb :
249 1.1 christos case bfd_mach_sparc_v9b :
250 1.1 christos return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9B);
251 1.1.1.5 christos case bfd_mach_sparc_v8plusc :
252 1.1.1.5 christos case bfd_mach_sparc_v9c :
253 1.1.1.5 christos return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9C);
254 1.1.1.5 christos case bfd_mach_sparc_v8plusd :
255 1.1.1.5 christos case bfd_mach_sparc_v9d :
256 1.1.1.5 christos return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9D);
257 1.1.1.5 christos case bfd_mach_sparc_v8pluse :
258 1.1.1.5 christos case bfd_mach_sparc_v9e :
259 1.1.1.5 christos return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9E);
260 1.1.1.5 christos case bfd_mach_sparc_v8plusv :
261 1.1.1.5 christos case bfd_mach_sparc_v9v :
262 1.1.1.5 christos return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9V);
263 1.1.1.5 christos case bfd_mach_sparc_v8plusm :
264 1.1.1.5 christos case bfd_mach_sparc_v9m :
265 1.1.1.5 christos return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9M);
266 1.1.1.7 christos case bfd_mach_sparc_v8plusm8 :
267 1.1.1.7 christos case bfd_mach_sparc_v9m8 :
268 1.1.1.7 christos return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_M8);
269 1.1 christos }
270 1.1 christos abort ();
271 1.1 christos }
272 1.1 christos
273 1.1 christos /* Compare opcodes A and B. */
274 1.1 christos
275 1.1 christos static int
276 1.1 christos compare_opcodes (const void * a, const void * b)
277 1.1 christos {
278 1.1 christos sparc_opcode *op0 = * (sparc_opcode **) a;
279 1.1 christos sparc_opcode *op1 = * (sparc_opcode **) b;
280 1.1 christos unsigned long int match0 = op0->match, match1 = op1->match;
281 1.1 christos unsigned long int lose0 = op0->lose, lose1 = op1->lose;
282 1.1 christos register unsigned int i;
283 1.1 christos
284 1.1 christos /* If one (and only one) insn isn't supported by the current architecture,
285 1.1 christos prefer the one that is. If neither are supported, but they're both for
286 1.1 christos the same architecture, continue processing. Otherwise (both unsupported
287 1.1 christos and for different architectures), prefer lower numbered arch's (fudged
288 1.1 christos by comparing the bitmasks). */
289 1.1 christos if (op0->architecture & current_arch_mask)
290 1.1 christos {
291 1.1 christos if (! (op1->architecture & current_arch_mask))
292 1.1 christos return -1;
293 1.1 christos }
294 1.1 christos else
295 1.1 christos {
296 1.1 christos if (op1->architecture & current_arch_mask)
297 1.1 christos return 1;
298 1.1 christos else if (op0->architecture != op1->architecture)
299 1.1 christos return op0->architecture - op1->architecture;
300 1.1 christos }
301 1.1 christos
302 1.1 christos /* If a bit is set in both match and lose, there is something
303 1.1 christos wrong with the opcode table. */
304 1.1 christos if (match0 & lose0)
305 1.1 christos {
306 1.1.1.7 christos opcodes_error_handler
307 1.1.1.7 christos /* xgettext:c-format */
308 1.1.1.7 christos (_("internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"),
309 1.1 christos op0->name, match0, lose0);
310 1.1 christos op0->lose &= ~op0->match;
311 1.1 christos lose0 = op0->lose;
312 1.1 christos }
313 1.1 christos
314 1.1 christos if (match1 & lose1)
315 1.1 christos {
316 1.1.1.7 christos opcodes_error_handler
317 1.1.1.7 christos /* xgettext:c-format */
318 1.1.1.7 christos (_("internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"),
319 1.1 christos op1->name, match1, lose1);
320 1.1 christos op1->lose &= ~op1->match;
321 1.1 christos lose1 = op1->lose;
322 1.1 christos }
323 1.1 christos
324 1.1 christos /* Because the bits that are variable in one opcode are constant in
325 1.1 christos another, it is important to order the opcodes in the right order. */
326 1.1 christos for (i = 0; i < 32; ++i)
327 1.1 christos {
328 1.1.1.8 christos unsigned long int x = 1ul << i;
329 1.1 christos int x0 = (match0 & x) != 0;
330 1.1 christos int x1 = (match1 & x) != 0;
331 1.1 christos
332 1.1 christos if (x0 != x1)
333 1.1 christos return x1 - x0;
334 1.1 christos }
335 1.1 christos
336 1.1 christos for (i = 0; i < 32; ++i)
337 1.1 christos {
338 1.1.1.8 christos unsigned long int x = 1ul << i;
339 1.1 christos int x0 = (lose0 & x) != 0;
340 1.1 christos int x1 = (lose1 & x) != 0;
341 1.1 christos
342 1.1 christos if (x0 != x1)
343 1.1 christos return x1 - x0;
344 1.1 christos }
345 1.1 christos
346 1.1 christos /* They are functionally equal. So as long as the opcode table is
347 1.1 christos valid, we can put whichever one first we want, on aesthetic grounds. */
348 1.1 christos
349 1.1 christos /* Our first aesthetic ground is that aliases defer to real insns. */
350 1.1 christos {
351 1.1 christos int alias_diff = (op0->flags & F_ALIAS) - (op1->flags & F_ALIAS);
352 1.1 christos
353 1.1 christos if (alias_diff != 0)
354 1.1 christos /* Put the one that isn't an alias first. */
355 1.1 christos return alias_diff;
356 1.1 christos }
357 1.1 christos
358 1.1 christos /* Except for aliases, two "identical" instructions had
359 1.1 christos better have the same opcode. This is a sanity check on the table. */
360 1.1 christos i = strcmp (op0->name, op1->name);
361 1.1 christos if (i)
362 1.1 christos {
363 1.1.1.3 christos if (op0->flags & F_ALIAS)
364 1.1.1.3 christos {
365 1.1.1.3 christos if (op0->flags & F_PREFERRED)
366 1.1.1.3 christos return -1;
367 1.1.1.3 christos if (op1->flags & F_PREFERRED)
368 1.1.1.3 christos return 1;
369 1.1.1.3 christos
370 1.1.1.3 christos /* If they're both aliases, and neither is marked as preferred,
371 1.1.1.3 christos be arbitrary. */
372 1.1.1.3 christos return i;
373 1.1.1.3 christos }
374 1.1 christos else
375 1.1.1.7 christos opcodes_error_handler
376 1.1.1.7 christos /* xgettext:c-format */
377 1.1.1.7 christos (_("internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n"),
378 1.1.1.7 christos op0->name, op1->name);
379 1.1 christos }
380 1.1 christos
381 1.1 christos /* Fewer arguments are preferred. */
382 1.1 christos {
383 1.1 christos int length_diff = strlen (op0->args) - strlen (op1->args);
384 1.1 christos
385 1.1 christos if (length_diff != 0)
386 1.1 christos /* Put the one with fewer arguments first. */
387 1.1 christos return length_diff;
388 1.1 christos }
389 1.1 christos
390 1.1 christos /* Put 1+i before i+1. */
391 1.1 christos {
392 1.1 christos char *p0 = (char *) strchr (op0->args, '+');
393 1.1 christos char *p1 = (char *) strchr (op1->args, '+');
394 1.1 christos
395 1.1 christos if (p0 && p1)
396 1.1 christos {
397 1.1 christos /* There is a plus in both operands. Note that a plus
398 1.1 christos sign cannot be the first character in args,
399 1.1 christos so the following [-1]'s are valid. */
400 1.1 christos if (p0[-1] == 'i' && p1[1] == 'i')
401 1.1 christos /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
402 1.1 christos return 1;
403 1.1 christos if (p0[1] == 'i' && p1[-1] == 'i')
404 1.1 christos /* op0 is 1+i and op1 is i+1, so op0 goes first. */
405 1.1 christos return -1;
406 1.1 christos }
407 1.1 christos }
408 1.1 christos
409 1.1 christos /* Put 1,i before i,1. */
410 1.1 christos {
411 1.1 christos int i0 = strncmp (op0->args, "i,1", 3) == 0;
412 1.1 christos int i1 = strncmp (op1->args, "i,1", 3) == 0;
413 1.1 christos
414 1.1 christos if (i0 ^ i1)
415 1.1 christos return i0 - i1;
416 1.1 christos }
417 1.1 christos
418 1.1 christos /* They are, as far as we can tell, identical.
419 1.1 christos Since qsort may have rearranged the table partially, there is
420 1.1 christos no way to tell which one was first in the opcode table as
421 1.1 christos written, so just say there are equal. */
422 1.1 christos /* ??? This is no longer true now that we sort a vector of pointers,
423 1.1 christos not the table itself. */
424 1.1 christos return 0;
425 1.1 christos }
426 1.1 christos
427 1.1 christos /* Build a hash table from the opcode table.
428 1.1 christos OPCODE_TABLE is a sorted list of pointers into the opcode table. */
429 1.1 christos
430 1.1 christos static void
431 1.1 christos build_hash_table (const sparc_opcode **opcode_table,
432 1.1 christos sparc_opcode_hash **hash_table,
433 1.1 christos int num_opcodes)
434 1.1 christos {
435 1.1 christos int i;
436 1.1 christos int hash_count[HASH_SIZE];
437 1.1 christos static sparc_opcode_hash *hash_buf = NULL;
438 1.1 christos
439 1.1 christos /* Start at the end of the table and work backwards so that each
440 1.1 christos chain is sorted. */
441 1.1 christos
442 1.1 christos memset (hash_table, 0, HASH_SIZE * sizeof (hash_table[0]));
443 1.1 christos memset (hash_count, 0, HASH_SIZE * sizeof (hash_count[0]));
444 1.1.1.8 christos free (hash_buf);
445 1.1 christos hash_buf = xmalloc (sizeof (* hash_buf) * num_opcodes);
446 1.1 christos for (i = num_opcodes - 1; i >= 0; --i)
447 1.1 christos {
448 1.1 christos int hash = HASH_INSN (opcode_table[i]->match);
449 1.1 christos sparc_opcode_hash *h = &hash_buf[i];
450 1.1 christos
451 1.1 christos h->next = hash_table[hash];
452 1.1 christos h->opcode = opcode_table[i];
453 1.1 christos hash_table[hash] = h;
454 1.1 christos ++hash_count[hash];
455 1.1 christos }
456 1.1 christos
457 1.1 christos #if 0 /* for debugging */
458 1.1 christos {
459 1.1 christos int min_count = num_opcodes, max_count = 0;
460 1.1 christos int total;
461 1.1 christos
462 1.1 christos for (i = 0; i < HASH_SIZE; ++i)
463 1.1 christos {
464 1.1 christos if (hash_count[i] < min_count)
465 1.1 christos min_count = hash_count[i];
466 1.1 christos if (hash_count[i] > max_count)
467 1.1 christos max_count = hash_count[i];
468 1.1 christos total += hash_count[i];
469 1.1 christos }
470 1.1 christos
471 1.1 christos printf ("Opcode hash table stats: min %d, max %d, ave %f\n",
472 1.1 christos min_count, max_count, (double) total / HASH_SIZE);
473 1.1 christos }
474 1.1 christos #endif
475 1.1 christos }
476 1.1 christos
477 1.1 christos /* Print one instruction from MEMADDR on INFO->STREAM.
478 1.1 christos
479 1.1 christos We suffix the instruction with a comment that gives the absolute
480 1.1 christos address involved, as well as its symbolic form, if the instruction
481 1.1 christos is preceded by a findable `sethi' and it either adds an immediate
482 1.1 christos displacement to that register, or it is an `add' or `or' instruction
483 1.1 christos on that register. */
484 1.1 christos
485 1.1 christos int
486 1.1 christos print_insn_sparc (bfd_vma memaddr, disassemble_info *info)
487 1.1 christos {
488 1.1 christos FILE *stream = info->stream;
489 1.1 christos bfd_byte buffer[4];
490 1.1 christos unsigned long insn;
491 1.1 christos sparc_opcode_hash *op;
492 1.1 christos /* Nonzero of opcode table has been initialized. */
493 1.1 christos static int opcodes_initialized = 0;
494 1.1 christos /* bfd mach number of last call. */
495 1.1 christos static unsigned long current_mach = 0;
496 1.1 christos bfd_vma (*getword) (const void *);
497 1.1 christos
498 1.1 christos if (!opcodes_initialized
499 1.1 christos || info->mach != current_mach)
500 1.1 christos {
501 1.1 christos int i;
502 1.1 christos
503 1.1 christos current_arch_mask = compute_arch_mask (info->mach);
504 1.1 christos
505 1.1 christos if (!opcodes_initialized)
506 1.1 christos sorted_opcodes =
507 1.1 christos xmalloc (sparc_num_opcodes * sizeof (sparc_opcode *));
508 1.1 christos /* Reset the sorted table so we can resort it. */
509 1.1 christos for (i = 0; i < sparc_num_opcodes; ++i)
510 1.1 christos sorted_opcodes[i] = &sparc_opcodes[i];
511 1.1 christos qsort ((char *) sorted_opcodes, sparc_num_opcodes,
512 1.1 christos sizeof (sorted_opcodes[0]), compare_opcodes);
513 1.1 christos
514 1.1 christos build_hash_table (sorted_opcodes, opcode_hash_table, sparc_num_opcodes);
515 1.1 christos current_mach = info->mach;
516 1.1 christos opcodes_initialized = 1;
517 1.1 christos }
518 1.1 christos
519 1.1 christos {
520 1.1 christos int status =
521 1.1 christos (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
522 1.1 christos
523 1.1 christos if (status != 0)
524 1.1 christos {
525 1.1 christos (*info->memory_error_func) (status, memaddr, info);
526 1.1 christos return -1;
527 1.1 christos }
528 1.1 christos }
529 1.1 christos
530 1.1 christos /* On SPARClite variants such as DANlite (sparc86x), instructions
531 1.1 christos are always big-endian even when the machine is in little-endian mode. */
532 1.1 christos if (info->endian == BFD_ENDIAN_BIG || info->mach == bfd_mach_sparc_sparclite)
533 1.1 christos getword = bfd_getb32;
534 1.1 christos else
535 1.1 christos getword = bfd_getl32;
536 1.1 christos
537 1.1 christos insn = getword (buffer);
538 1.1 christos
539 1.1 christos info->insn_info_valid = 1; /* We do return this info. */
540 1.1 christos info->insn_type = dis_nonbranch; /* Assume non branch insn. */
541 1.1 christos info->branch_delay_insns = 0; /* Assume no delay. */
542 1.1 christos info->target = 0; /* Assume no target known. */
543 1.1 christos
544 1.1 christos for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
545 1.1 christos {
546 1.1 christos const sparc_opcode *opcode = op->opcode;
547 1.1 christos
548 1.1 christos /* If the insn isn't supported by the current architecture, skip it. */
549 1.1 christos if (! (opcode->architecture & current_arch_mask))
550 1.1 christos continue;
551 1.1 christos
552 1.1 christos if ((opcode->match & insn) == opcode->match
553 1.1 christos && (opcode->lose & insn) == 0)
554 1.1 christos {
555 1.1 christos /* Nonzero means that we have found an instruction which has
556 1.1 christos the effect of adding or or'ing the imm13 field to rs1. */
557 1.1 christos int imm_added_to_rs1 = 0;
558 1.1 christos int imm_ored_to_rs1 = 0;
559 1.1 christos
560 1.1 christos /* Nonzero means that we have found a plus sign in the args
561 1.1 christos field of the opcode table. */
562 1.1 christos int found_plus = 0;
563 1.1 christos
564 1.1 christos /* Nonzero means we have an annulled branch. */
565 1.1 christos int is_annulled = 0;
566 1.1 christos
567 1.1 christos /* Do we have an `add' or `or' instruction combining an
568 1.1 christos immediate with rs1? */
569 1.1 christos if (opcode->match == 0x80102000) /* or */
570 1.1 christos imm_ored_to_rs1 = 1;
571 1.1 christos if (opcode->match == 0x80002000) /* add */
572 1.1 christos imm_added_to_rs1 = 1;
573 1.1 christos
574 1.1 christos if (X_RS1 (insn) != X_RD (insn)
575 1.1 christos && strchr (opcode->args, 'r') != 0)
576 1.1 christos /* Can't do simple format if source and dest are different. */
577 1.1 christos continue;
578 1.1 christos if (X_RS2 (insn) != X_RD (insn)
579 1.1 christos && strchr (opcode->args, 'O') != 0)
580 1.1 christos /* Can't do simple format if source and dest are different. */
581 1.1 christos continue;
582 1.1 christos
583 1.1.1.2 christos (*info->fprintf_func) (stream, "%s", opcode->name);
584 1.1 christos
585 1.1 christos {
586 1.1 christos const char *s;
587 1.1 christos
588 1.1 christos if (opcode->args[0] != ',')
589 1.1 christos (*info->fprintf_func) (stream, " ");
590 1.1 christos
591 1.1 christos for (s = opcode->args; *s != '\0'; ++s)
592 1.1 christos {
593 1.1 christos while (*s == ',')
594 1.1 christos {
595 1.1 christos (*info->fprintf_func) (stream, ",");
596 1.1 christos ++s;
597 1.1 christos switch (*s)
598 1.1 christos {
599 1.1 christos case 'a':
600 1.1 christos (*info->fprintf_func) (stream, "a");
601 1.1 christos is_annulled = 1;
602 1.1 christos ++s;
603 1.1 christos continue;
604 1.1 christos case 'N':
605 1.1 christos (*info->fprintf_func) (stream, "pn");
606 1.1 christos ++s;
607 1.1 christos continue;
608 1.1 christos
609 1.1 christos case 'T':
610 1.1 christos (*info->fprintf_func) (stream, "pt");
611 1.1 christos ++s;
612 1.1 christos continue;
613 1.1 christos
614 1.1 christos default:
615 1.1 christos break;
616 1.1 christos }
617 1.1 christos }
618 1.1 christos
619 1.1 christos (*info->fprintf_func) (stream, " ");
620 1.1 christos
621 1.1 christos switch (*s)
622 1.1 christos {
623 1.1 christos case '+':
624 1.1 christos found_plus = 1;
625 1.1 christos /* Fall through. */
626 1.1 christos
627 1.1 christos default:
628 1.1 christos (*info->fprintf_func) (stream, "%c", *s);
629 1.1 christos break;
630 1.1 christos
631 1.1 christos case '#':
632 1.1 christos (*info->fprintf_func) (stream, "0");
633 1.1 christos break;
634 1.1 christos
635 1.1 christos #define reg(n) (*info->fprintf_func) (stream, "%%%s", reg_names[n])
636 1.1 christos case '1':
637 1.1 christos case 'r':
638 1.1 christos reg (X_RS1 (insn));
639 1.1 christos break;
640 1.1 christos
641 1.1 christos case '2':
642 1.1 christos case 'O':
643 1.1 christos reg (X_RS2 (insn));
644 1.1 christos break;
645 1.1 christos
646 1.1 christos case 'd':
647 1.1 christos reg (X_RD (insn));
648 1.1 christos break;
649 1.1 christos #undef reg
650 1.1 christos
651 1.1 christos #define freg(n) (*info->fprintf_func) (stream, "%%%s", freg_names[n])
652 1.1 christos #define fregx(n) (*info->fprintf_func) (stream, "%%%s", freg_names[((n) & ~1) | (((n) & 1) << 5)])
653 1.1 christos case 'e':
654 1.1 christos freg (X_RS1 (insn));
655 1.1 christos break;
656 1.1 christos case 'v': /* Double/even. */
657 1.1 christos case 'V': /* Quad/multiple of 4. */
658 1.1.1.7 christos case ';': /* Double/even multiple of 8 doubles. */
659 1.1 christos fregx (X_RS1 (insn));
660 1.1 christos break;
661 1.1 christos
662 1.1 christos case 'f':
663 1.1 christos freg (X_RS2 (insn));
664 1.1 christos break;
665 1.1 christos case 'B': /* Double/even. */
666 1.1 christos case 'R': /* Quad/multiple of 4. */
667 1.1.1.7 christos case ':': /* Double/even multiple of 8 doubles. */
668 1.1 christos fregx (X_RS2 (insn));
669 1.1 christos break;
670 1.1 christos
671 1.1.1.2 christos case '4':
672 1.1.1.2 christos freg (X_RS3 (insn));
673 1.1.1.2 christos break;
674 1.1.1.2 christos case '5': /* Double/even. */
675 1.1.1.2 christos fregx (X_RS3 (insn));
676 1.1.1.2 christos break;
677 1.1.1.2 christos
678 1.1 christos case 'g':
679 1.1 christos freg (X_RD (insn));
680 1.1 christos break;
681 1.1 christos case 'H': /* Double/even. */
682 1.1 christos case 'J': /* Quad/multiple of 4. */
683 1.1.1.4 christos case '}': /* Double/even. */
684 1.1 christos fregx (X_RD (insn));
685 1.1 christos break;
686 1.1.1.7 christos
687 1.1.1.7 christos case '^': /* Double/even multiple of 8 doubles. */
688 1.1.1.7 christos fregx (X_RD (insn) & ~0x6);
689 1.1.1.7 christos break;
690 1.1.1.7 christos
691 1.1.1.7 christos case '\'': /* Double/even in FPCMPSHL. */
692 1.1.1.7 christos fregx (X_RS2 (insn | 0x11));
693 1.1.1.7 christos break;
694 1.1.1.7 christos
695 1.1 christos #undef freg
696 1.1 christos #undef fregx
697 1.1 christos
698 1.1 christos #define creg(n) (*info->fprintf_func) (stream, "%%c%u", (unsigned int) (n))
699 1.1 christos case 'b':
700 1.1 christos creg (X_RS1 (insn));
701 1.1 christos break;
702 1.1 christos
703 1.1 christos case 'c':
704 1.1 christos creg (X_RS2 (insn));
705 1.1 christos break;
706 1.1 christos
707 1.1 christos case 'D':
708 1.1 christos creg (X_RD (insn));
709 1.1 christos break;
710 1.1 christos #undef creg
711 1.1 christos
712 1.1 christos case 'h':
713 1.1 christos (*info->fprintf_func) (stream, "%%hi(%#x)",
714 1.1.1.8 christos (unsigned) X_IMM22 (insn) << 10);
715 1.1 christos break;
716 1.1 christos
717 1.1 christos case 'i': /* 13 bit immediate. */
718 1.1 christos case 'I': /* 11 bit immediate. */
719 1.1 christos case 'j': /* 10 bit immediate. */
720 1.1 christos {
721 1.1 christos int imm;
722 1.1 christos
723 1.1 christos if (*s == 'i')
724 1.1 christos imm = X_SIMM (insn, 13);
725 1.1 christos else if (*s == 'I')
726 1.1 christos imm = X_SIMM (insn, 11);
727 1.1 christos else
728 1.1 christos imm = X_SIMM (insn, 10);
729 1.1 christos
730 1.1 christos /* Check to see whether we have a 1+i, and take
731 1.1 christos note of that fact.
732 1.1 christos
733 1.1 christos Note: because of the way we sort the table,
734 1.1 christos we will be matching 1+i rather than i+1,
735 1.1 christos so it is OK to assume that i is after +,
736 1.1 christos not before it. */
737 1.1 christos if (found_plus)
738 1.1 christos imm_added_to_rs1 = 1;
739 1.1 christos
740 1.1 christos if (imm <= 9)
741 1.1 christos (*info->fprintf_func) (stream, "%d", imm);
742 1.1 christos else
743 1.1 christos (*info->fprintf_func) (stream, "%#x", imm);
744 1.1 christos }
745 1.1 christos break;
746 1.1 christos
747 1.1.1.2 christos case ')': /* 5 bit unsigned immediate from RS3. */
748 1.1.1.2 christos (info->fprintf_func) (stream, "%#x", (unsigned int) X_RS3 (insn));
749 1.1.1.2 christos break;
750 1.1.1.2 christos
751 1.1 christos case 'X': /* 5 bit unsigned immediate. */
752 1.1 christos case 'Y': /* 6 bit unsigned immediate. */
753 1.1 christos {
754 1.1 christos int imm = X_IMM (insn, *s == 'X' ? 5 : 6);
755 1.1 christos
756 1.1 christos if (imm <= 9)
757 1.1 christos (info->fprintf_func) (stream, "%d", imm);
758 1.1 christos else
759 1.1 christos (info->fprintf_func) (stream, "%#x", (unsigned) imm);
760 1.1 christos }
761 1.1 christos break;
762 1.1 christos
763 1.1 christos case '3':
764 1.1 christos (info->fprintf_func) (stream, "%ld", X_IMM (insn, 3));
765 1.1 christos break;
766 1.1 christos
767 1.1 christos case 'K':
768 1.1 christos {
769 1.1 christos int mask = X_MEMBAR (insn);
770 1.1 christos int bit = 0x40, printed_one = 0;
771 1.1 christos const char *name;
772 1.1 christos
773 1.1 christos if (mask == 0)
774 1.1 christos (info->fprintf_func) (stream, "0");
775 1.1 christos else
776 1.1 christos while (bit)
777 1.1 christos {
778 1.1 christos if (mask & bit)
779 1.1 christos {
780 1.1 christos if (printed_one)
781 1.1 christos (info->fprintf_func) (stream, "|");
782 1.1 christos name = sparc_decode_membar (bit);
783 1.1 christos (info->fprintf_func) (stream, "%s", name);
784 1.1 christos printed_one = 1;
785 1.1 christos }
786 1.1 christos bit >>= 1;
787 1.1 christos }
788 1.1 christos break;
789 1.1 christos }
790 1.1 christos
791 1.1.1.2 christos case '=':
792 1.1.1.2 christos info->target = memaddr + SEX (X_DISP10 (insn), 10) * 4;
793 1.1.1.2 christos (*info->print_address_func) (info->target, info);
794 1.1.1.2 christos break;
795 1.1.1.2 christos
796 1.1 christos case 'k':
797 1.1 christos info->target = memaddr + SEX (X_DISP16 (insn), 16) * 4;
798 1.1 christos (*info->print_address_func) (info->target, info);
799 1.1 christos break;
800 1.1 christos
801 1.1 christos case 'G':
802 1.1 christos info->target = memaddr + SEX (X_DISP19 (insn), 19) * 4;
803 1.1 christos (*info->print_address_func) (info->target, info);
804 1.1 christos break;
805 1.1 christos
806 1.1 christos case '6':
807 1.1 christos case '7':
808 1.1 christos case '8':
809 1.1 christos case '9':
810 1.1 christos (*info->fprintf_func) (stream, "%%fcc%c", *s - '6' + '0');
811 1.1 christos break;
812 1.1 christos
813 1.1 christos case 'z':
814 1.1 christos (*info->fprintf_func) (stream, "%%icc");
815 1.1 christos break;
816 1.1 christos
817 1.1 christos case 'Z':
818 1.1 christos (*info->fprintf_func) (stream, "%%xcc");
819 1.1 christos break;
820 1.1 christos
821 1.1 christos case 'E':
822 1.1 christos (*info->fprintf_func) (stream, "%%ccr");
823 1.1 christos break;
824 1.1 christos
825 1.1 christos case 's':
826 1.1 christos (*info->fprintf_func) (stream, "%%fprs");
827 1.1 christos break;
828 1.1 christos
829 1.1.1.4 christos case '{':
830 1.1.1.4 christos (*info->fprintf_func) (stream, "%%mcdper");
831 1.1.1.4 christos break;
832 1.1.1.4 christos
833 1.1.1.7 christos case '&':
834 1.1.1.7 christos (*info->fprintf_func) (stream, "%%entropy");
835 1.1.1.7 christos break;
836 1.1.1.7 christos
837 1.1 christos case 'o':
838 1.1 christos (*info->fprintf_func) (stream, "%%asi");
839 1.1 christos break;
840 1.1 christos
841 1.1 christos case 'W':
842 1.1 christos (*info->fprintf_func) (stream, "%%tick");
843 1.1 christos break;
844 1.1 christos
845 1.1 christos case 'P':
846 1.1 christos (*info->fprintf_func) (stream, "%%pc");
847 1.1 christos break;
848 1.1 christos
849 1.1 christos case '?':
850 1.1 christos if (X_RS1 (insn) == 31)
851 1.1 christos (*info->fprintf_func) (stream, "%%ver");
852 1.1.1.5 christos else if (X_RS1 (insn) == 23)
853 1.1.1.5 christos (*info->fprintf_func) (stream, "%%pmcdper");
854 1.1 christos else if ((unsigned) X_RS1 (insn) < 17)
855 1.1 christos (*info->fprintf_func) (stream, "%%%s",
856 1.1 christos v9_priv_reg_names[X_RS1 (insn)]);
857 1.1 christos else
858 1.1 christos (*info->fprintf_func) (stream, "%%reserved");
859 1.1 christos break;
860 1.1 christos
861 1.1 christos case '!':
862 1.1.1.5 christos if (X_RD (insn) == 31)
863 1.1.1.5 christos (*info->fprintf_func) (stream, "%%ver");
864 1.1.1.5 christos else if (X_RD (insn) == 23)
865 1.1.1.5 christos (*info->fprintf_func) (stream, "%%pmcdper");
866 1.1.1.5 christos else if ((unsigned) X_RD (insn) < 17)
867 1.1 christos (*info->fprintf_func) (stream, "%%%s",
868 1.1 christos v9_priv_reg_names[X_RD (insn)]);
869 1.1 christos else
870 1.1 christos (*info->fprintf_func) (stream, "%%reserved");
871 1.1 christos break;
872 1.1 christos
873 1.1 christos case '$':
874 1.1 christos if ((unsigned) X_RS1 (insn) < 32)
875 1.1 christos (*info->fprintf_func) (stream, "%%%s",
876 1.1 christos v9_hpriv_reg_names[X_RS1 (insn)]);
877 1.1 christos else
878 1.1 christos (*info->fprintf_func) (stream, "%%reserved");
879 1.1 christos break;
880 1.1 christos
881 1.1 christos case '%':
882 1.1 christos if ((unsigned) X_RD (insn) < 32)
883 1.1 christos (*info->fprintf_func) (stream, "%%%s",
884 1.1 christos v9_hpriv_reg_names[X_RD (insn)]);
885 1.1 christos else
886 1.1 christos (*info->fprintf_func) (stream, "%%reserved");
887 1.1 christos break;
888 1.1 christos
889 1.1 christos case '/':
890 1.1.1.2 christos if (X_RS1 (insn) < 16 || X_RS1 (insn) > 28)
891 1.1 christos (*info->fprintf_func) (stream, "%%reserved");
892 1.1 christos else
893 1.1 christos (*info->fprintf_func) (stream, "%%%s",
894 1.1 christos v9a_asr_reg_names[X_RS1 (insn)-16]);
895 1.1 christos break;
896 1.1 christos
897 1.1 christos case '_':
898 1.1.1.2 christos if (X_RD (insn) < 16 || X_RD (insn) > 28)
899 1.1 christos (*info->fprintf_func) (stream, "%%reserved");
900 1.1 christos else
901 1.1 christos (*info->fprintf_func) (stream, "%%%s",
902 1.1 christos v9a_asr_reg_names[X_RD (insn)-16]);
903 1.1 christos break;
904 1.1 christos
905 1.1 christos case '*':
906 1.1 christos {
907 1.1 christos const char *name = sparc_decode_prefetch (X_RD (insn));
908 1.1 christos
909 1.1 christos if (name)
910 1.1 christos (*info->fprintf_func) (stream, "%s", name);
911 1.1 christos else
912 1.1 christos (*info->fprintf_func) (stream, "%ld", X_RD (insn));
913 1.1 christos break;
914 1.1 christos }
915 1.1 christos
916 1.1 christos case 'M':
917 1.1 christos (*info->fprintf_func) (stream, "%%asr%ld", X_RS1 (insn));
918 1.1 christos break;
919 1.1 christos
920 1.1 christos case 'm':
921 1.1 christos (*info->fprintf_func) (stream, "%%asr%ld", X_RD (insn));
922 1.1 christos break;
923 1.1 christos
924 1.1 christos case 'L':
925 1.1 christos info->target = memaddr + SEX (X_DISP30 (insn), 30) * 4;
926 1.1 christos (*info->print_address_func) (info->target, info);
927 1.1 christos break;
928 1.1 christos
929 1.1 christos case 'n':
930 1.1 christos (*info->fprintf_func)
931 1.1 christos (stream, "%#x", SEX (X_DISP22 (insn), 22));
932 1.1 christos break;
933 1.1 christos
934 1.1 christos case 'l':
935 1.1 christos info->target = memaddr + SEX (X_DISP22 (insn), 22) * 4;
936 1.1 christos (*info->print_address_func) (info->target, info);
937 1.1 christos break;
938 1.1 christos
939 1.1 christos case 'A':
940 1.1 christos {
941 1.1 christos const char *name = sparc_decode_asi (X_ASI (insn));
942 1.1 christos
943 1.1 christos if (name)
944 1.1 christos (*info->fprintf_func) (stream, "%s", name);
945 1.1 christos else
946 1.1 christos (*info->fprintf_func) (stream, "(%ld)", X_ASI (insn));
947 1.1 christos break;
948 1.1 christos }
949 1.1 christos
950 1.1 christos case 'C':
951 1.1 christos (*info->fprintf_func) (stream, "%%csr");
952 1.1 christos break;
953 1.1 christos
954 1.1 christos case 'F':
955 1.1 christos (*info->fprintf_func) (stream, "%%fsr");
956 1.1 christos break;
957 1.1 christos
958 1.1.1.2 christos case '(':
959 1.1.1.2 christos (*info->fprintf_func) (stream, "%%efsr");
960 1.1.1.2 christos break;
961 1.1.1.2 christos
962 1.1 christos case 'p':
963 1.1 christos (*info->fprintf_func) (stream, "%%psr");
964 1.1 christos break;
965 1.1 christos
966 1.1 christos case 'q':
967 1.1 christos (*info->fprintf_func) (stream, "%%fq");
968 1.1 christos break;
969 1.1 christos
970 1.1 christos case 'Q':
971 1.1 christos (*info->fprintf_func) (stream, "%%cq");
972 1.1 christos break;
973 1.1 christos
974 1.1 christos case 't':
975 1.1 christos (*info->fprintf_func) (stream, "%%tbr");
976 1.1 christos break;
977 1.1 christos
978 1.1 christos case 'w':
979 1.1 christos (*info->fprintf_func) (stream, "%%wim");
980 1.1 christos break;
981 1.1 christos
982 1.1 christos case 'x':
983 1.1 christos (*info->fprintf_func) (stream, "%ld",
984 1.1 christos ((X_LDST_I (insn) << 8)
985 1.1 christos + X_ASI (insn)));
986 1.1 christos break;
987 1.1 christos
988 1.1.1.7 christos case '|': /* 2-bit immediate */
989 1.1.1.7 christos (*info->fprintf_func) (stream, "%ld", X_IMM2 (insn));
990 1.1.1.7 christos break;
991 1.1.1.7 christos
992 1.1 christos case 'y':
993 1.1 christos (*info->fprintf_func) (stream, "%%y");
994 1.1 christos break;
995 1.1 christos
996 1.1 christos case 'u':
997 1.1 christos case 'U':
998 1.1 christos {
999 1.1 christos int val = *s == 'U' ? X_RS1 (insn) : X_RD (insn);
1000 1.1 christos const char *name = sparc_decode_sparclet_cpreg (val);
1001 1.1 christos
1002 1.1 christos if (name)
1003 1.1 christos (*info->fprintf_func) (stream, "%s", name);
1004 1.1 christos else
1005 1.1 christos (*info->fprintf_func) (stream, "%%cpreg(%d)", val);
1006 1.1 christos break;
1007 1.1 christos }
1008 1.1 christos }
1009 1.1 christos }
1010 1.1 christos }
1011 1.1 christos
1012 1.1 christos /* If we are adding or or'ing something to rs1, then
1013 1.1 christos check to see whether the previous instruction was
1014 1.1 christos a sethi to the same register as in the sethi.
1015 1.1 christos If so, attempt to print the result of the add or
1016 1.1 christos or (in this context add and or do the same thing)
1017 1.1 christos and its symbolic value. */
1018 1.1 christos if (imm_ored_to_rs1 || imm_added_to_rs1)
1019 1.1 christos {
1020 1.1 christos unsigned long prev_insn;
1021 1.1 christos int errcode;
1022 1.1 christos
1023 1.1 christos if (memaddr >= 4)
1024 1.1 christos errcode =
1025 1.1 christos (*info->read_memory_func)
1026 1.1 christos (memaddr - 4, buffer, sizeof (buffer), info);
1027 1.1 christos else
1028 1.1 christos errcode = 1;
1029 1.1 christos
1030 1.1 christos prev_insn = getword (buffer);
1031 1.1 christos
1032 1.1 christos if (errcode == 0)
1033 1.1 christos {
1034 1.1 christos /* If it is a delayed branch, we need to look at the
1035 1.1 christos instruction before the delayed branch. This handles
1036 1.1 christos sequences such as:
1037 1.1 christos
1038 1.1 christos sethi %o1, %hi(_foo), %o1
1039 1.1 christos call _printf
1040 1.1 christos or %o1, %lo(_foo), %o1 */
1041 1.1 christos
1042 1.1 christos if (is_delayed_branch (prev_insn))
1043 1.1 christos {
1044 1.1 christos if (memaddr >= 8)
1045 1.1 christos errcode = (*info->read_memory_func)
1046 1.1 christos (memaddr - 8, buffer, sizeof (buffer), info);
1047 1.1 christos else
1048 1.1 christos errcode = 1;
1049 1.1 christos
1050 1.1 christos prev_insn = getword (buffer);
1051 1.1 christos }
1052 1.1 christos }
1053 1.1 christos
1054 1.1 christos /* If there was a problem reading memory, then assume
1055 1.1 christos the previous instruction was not sethi. */
1056 1.1 christos if (errcode == 0)
1057 1.1 christos {
1058 1.1 christos /* Is it sethi to the same register? */
1059 1.1 christos if ((prev_insn & 0xc1c00000) == 0x01000000
1060 1.1 christos && X_RD (prev_insn) == X_RS1 (insn))
1061 1.1 christos {
1062 1.1 christos (*info->fprintf_func) (stream, "\t! ");
1063 1.1.1.8 christos info->target = (unsigned) X_IMM22 (prev_insn) << 10;
1064 1.1 christos if (imm_added_to_rs1)
1065 1.1 christos info->target += X_SIMM (insn, 13);
1066 1.1 christos else
1067 1.1 christos info->target |= X_SIMM (insn, 13);
1068 1.1 christos (*info->print_address_func) (info->target, info);
1069 1.1 christos info->insn_type = dis_dref;
1070 1.1 christos info->data_size = 4; /* FIXME!!! */
1071 1.1 christos }
1072 1.1 christos }
1073 1.1 christos }
1074 1.1 christos
1075 1.1 christos if (opcode->flags & (F_UNBR|F_CONDBR|F_JSR))
1076 1.1 christos {
1077 1.1 christos /* FIXME -- check is_annulled flag. */
1078 1.1 christos (void) is_annulled;
1079 1.1 christos if (opcode->flags & F_UNBR)
1080 1.1 christos info->insn_type = dis_branch;
1081 1.1 christos if (opcode->flags & F_CONDBR)
1082 1.1 christos info->insn_type = dis_condbranch;
1083 1.1 christos if (opcode->flags & F_JSR)
1084 1.1 christos info->insn_type = dis_jsr;
1085 1.1 christos if (opcode->flags & F_DELAYED)
1086 1.1 christos info->branch_delay_insns = 1;
1087 1.1 christos }
1088 1.1 christos
1089 1.1 christos return sizeof (buffer);
1090 1.1 christos }
1091 1.1 christos }
1092 1.1 christos
1093 1.1 christos info->insn_type = dis_noninsn; /* Mark as non-valid instruction. */
1094 1.1 christos (*info->fprintf_func) (stream, _("unknown"));
1095 1.1 christos return sizeof (buffer);
1096 1.1 christos }
1097