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