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