View | Details | Raw Unified | Return to bug 532
Collapse All | Expand All

(-)a/opcodes/disassemble.c (+4 lines)
Lines 763-768 disassemble_free_target (struct disassemble_info *info) Link Here
763
#endif
763
#endif
764
#ifdef ARCH_powerpc
764
#ifdef ARCH_powerpc
765
    case bfd_arch_powerpc:
765
    case bfd_arch_powerpc:
766
      {
767
	extern void ppc_disassemble_free_target (struct disassemble_info *);
768
	ppc_disassemble_free_target (info);
769
      }
766
      break;
770
      break;
767
#endif
771
#endif
768
#ifdef ARCH_riscv
772
#ifdef ARCH_riscv
(-)a/opcodes/ppc-dis.c (+94 lines)
Lines 27-32 Link Here
27
#include "opintl.h"
27
#include "opintl.h"
28
#include "opcode/ppc.h"
28
#include "opcode/ppc.h"
29
#include "libiberty.h"
29
#include "libiberty.h"
30
#include "hashtab.h"
30
31
31
/* This file provides several disassembler functions, all of which use
32
/* This file provides several disassembler functions, all of which use
32
   the disassembler interface defined in dis-asm.h.  Several functions
33
   the disassembler interface defined in dis-asm.h.  Several functions
Lines 36-47 Link Here
36
static int print_insn_powerpc (bfd_vma, struct disassemble_info *, int,
37
static int print_insn_powerpc (bfd_vma, struct disassemble_info *, int,
37
			       ppc_cpu_t);
38
			       ppc_cpu_t);
38
39
40
struct opcode_counter
41
{
42
  const struct powerpc_opcode *opcode;
43
  size_t count;
44
};
45
46
static hashval_t
47
hash_opcode_counter (const void *opcnt)
48
{
49
  const struct opcode_counter *oc = (const struct opcode_counter *)opcnt;
50
  return htab_hash_pointer (oc->opcode);
51
}
52
53
static int
54
same_opcode_counter (const void *opcnt1, const void *opcnt2)
55
{
56
  const struct opcode_counter *oc1 = (const struct opcode_counter *)opcnt1;
57
  const struct opcode_counter *oc2 = (const struct opcode_counter *)opcnt2;
58
  return htab_eq_pointer (oc1->opcode, oc2->opcode);
59
}
60
39
struct dis_private
61
struct dis_private
40
{
62
{
41
  /* Stash the result of parsing disassembler_options here.  */
63
  /* Stash the result of parsing disassembler_options here.  */
42
  ppc_cpu_t dialect;
64
  ppc_cpu_t dialect;
65
66
  /* Counters for encountered opcodes.  */
67
  htab_t histogram;
43
};
68
};
44
69
70
static int
71
increment_opcode_counter (struct disassemble_info *info,
72
			  const struct powerpc_opcode *opcode)
73
{
74
  struct dis_private *priv = (struct dis_private *) (info->private_data);
75
76
  if (!priv->histogram)
77
    return 0;
78
79
  struct opcode_counter oc, *ocp;
80
  oc.opcode = opcode;
81
82
  void **ret = htab_find_slot (priv->histogram, &oc, INSERT);
83
  ocp = *ret;
84
  if (ocp == HTAB_EMPTY_ENTRY)
85
    {
86
      *ret = ocp = calloc (sizeof (oc), 1);
87
      ocp->opcode = opcode;
88
    }
89
90
  ocp->count++;
91
92
  return 1;
93
}
94
45
#define POWERPC_DIALECT(INFO) \
95
#define POWERPC_DIALECT(INFO) \
46
  (((struct dis_private *) ((INFO)->private_data))->dialect)
96
  (((struct dis_private *) ((INFO)->private_data))->dialect)
47
97
Lines 381-386 powerpc_init_dialect (struct disassemble_info *info) Link Here
381
	dialect |= PPC_OPCODE_64;
431
	dialect |= PPC_OPCODE_64;
382
      else if ((new_cpu = ppc_parse_cpu (dialect, &sticky, opt)) != 0)
432
      else if ((new_cpu = ppc_parse_cpu (dialect, &sticky, opt)) != 0)
383
	dialect = new_cpu;
433
	dialect = new_cpu;
434
      else if (disassembler_options_cmp (opt, "histogram") == 0)
435
	priv->histogram = htab_create (17,
436
				       hash_opcode_counter,
437
				       same_opcode_counter,
438
				       free);
384
      else
439
      else
385
	/* xgettext: c-format */
440
	/* xgettext: c-format */
386
	opcodes_error_handler (_("warning: ignoring unknown -M%s option"), opt);
441
	opcodes_error_handler (_("warning: ignoring unknown -M%s option"), opt);
Lines 864-869 print_insn_powerpc (bfd_vma memaddr, Link Here
864
      bfd_boolean skip_optional;
919
      bfd_boolean skip_optional;
865
      int blanks;
920
      int blanks;
866
921
922
      increment_opcode_counter (info, opcode);
923
867
      (*info->fprintf_func) (info->stream, "%s", opcode->name);
924
      (*info->fprintf_func) (info->stream, "%s", opcode->name);
868
      /* gdb fprintf_func doesn't return count printed.  */
925
      /* gdb fprintf_func doesn't return count printed.  */
869
      blanks = 8 - strlen (opcode->name);
926
      blanks = 8 - strlen (opcode->name);
Lines 1013-1015 the -M switch:\n")); Link Here
1013
    }
1070
    }
1014
  fprintf (stream, "\n");
1071
  fprintf (stream, "\n");
1015
}
1072
}
1073
1074
static int
1075
dump_opcode_histogram (void **ocp, void *info_)
1076
{
1077
  struct opcode_counter *oc = *ocp;
1078
  struct disassemble_info *info = info_;
1079
1080
  (*info->fprintf_func) (info->stream, "%8lu %s (%lx)\n",
1081
			 (unsigned long)oc->count,
1082
			 oc->opcode->name,
1083
			 (unsigned long)oc->opcode->opcode);
1084
1085
  return 1;
1086
}
1087
1088
void ppc_disassemble_free_target (struct disassemble_info *info);
1089
1090
void
1091
ppc_disassemble_free_target (struct disassemble_info *info)
1092
{
1093
  struct dis_private *priv = (struct dis_private *) (info->private_data);
1094
1095
  if (priv->histogram)
1096
    {
1097
      if (htab_elements (priv->histogram))
1098
	{
1099
	  (*info->fprintf_func) (info->stream, "\n\nOpcode histogram\n");
1100
	  htab_traverse (priv->histogram, dump_opcode_histogram, info);
1101
	}
1102
1103
      htab_delete (priv->histogram);
1104
      priv->histogram = NULL;
1105
    }
1106
1107
  free (priv);
1108
  info->private_data = NULL;
1109
}

Return to bug 532