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