perf annotate: Initial PowerPC support
authorRavi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
Wed, 23 Nov 2016 16:03:46 +0000 (21:33 +0530)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Fri, 25 Nov 2016 13:38:56 +0000 (10:38 -0300)
Support the PowerPC architecture using the ins_ops association
method.

Committer notes:

Testing it with a perf.data file collected on a PowerPC machine and
cross-annotated on a x86_64 workstation, using the associated vmlinux
file:

$ perf report -i perf.data.f22vm.powerdev --vmlinux vmlinux.powerpc
  .ktime_get  vmlinux.powerpc
        │      clrldi r9,r28,63
   8.57 │   ┌──bne    e0                   <- TUI cursor positioned here
        │54:│  lwsync
   2.86 │   │  std    r2,40(r1)
        │   │  ld     r9,144(r31)
        │   │  ld     r3,136(r31)
        │   │  ld     r30,184(r31)
        │   │  ld     r10,0(r9)
        │   │  mtctr  r10
        │   │  ld     r2,8(r9)
   8.57 │   │→ bctrl
        │   │  ld     r2,40(r1)
        │   │  ld     r10,160(r31)
        │   │  ld     r5,152(r31)
        │   │  lwz    r7,168(r31)
        │   │  ld     r9,176(r31)
   8.57 │   │  lwz    r6,172(r31)
        │   │  lwsync
   2.86 │   │  lwz    r8,128(r31)
        │   │  cmpw   cr7,r8,r28
   2.86 │   │↑ bne    48
        │   │  subf   r10,r10,r3
        │   │  mr     r3,r29
        │   │  and    r10,r10,r5
   2.86 │   │  mulld  r10,r10,r7
        │   │  add    r9,r10,r9
        │   │  srd    r9,r9,r6
        │   │  add    r9,r9,r30
        │   │  std    r9,0(r29)
        │   │  addi   r1,r1,144
        │   │  ld     r0,16(r1)
        │   │  ld     r28,-32(r1)
        │   │  ld     r29,-24(r1)
        │   │  ld     r30,-16(r1)
        │   │  mtlr   r0
        │   │  ld     r31,-8(r1)
        │   │← blr
   5.71 │e0:└─→mr     r1,r1
  11.43 │      mr     r2,r2
  11.43 │      lwz    r28,128(r31)
  Press 'h' for help on key bindings

  $ perf report -i perf.data.f22vm.powerdev --header-only
  # ========
  # captured on: Thu Nov 24 12:40:38 2016
  # hostname : pdev-f22-qemu
  # os release : 4.4.10-200.fc22.ppc64
  # perf version : 4.9.rc1.g6298ce
  # arch : ppc64
  # nrcpus online : 48
  # nrcpus avail : 48
  # cpudesc : POWER7 (architected), altivec supported
  # cpuid : 74,513
  # total memory : 4158976 kB
  # cmdline : /home/ravi/Workspace/linux/tools/perf/perf record -a
  # event : name = cycles:ppp, , size = 112, { sample_period, sample_freq } = 4000, sample_type = IP|TID|TIME|CPU|PERIOD, disabled = 1, inherit = 1, mmap = 1, comm = 1, freq = 1, task = 1, precise_ip = 3, sample_id_all = 1, exclude_guest = 1, mmap2 = 1, comm_exec = 1
  # HEADER_CPU_TOPOLOGY info available, use -I to display
  # HEADER_NUMA_TOPOLOGY info available, use -I to display
  # pmu mappings: cpu = 4, software = 1, tracepoint = 2, breakpoint = 5
  # missing features: HEADER_TRACING_DATA HEADER_BRANCH_STACK HEADER_GROUP_DESC HEADER_AUXTRACE HEADER_STAT HEADER_CACHE
  # ========
  #
  $

Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Kim Phillips <kim.phillips@arm.com>
Link: http://lkml.kernel.org/n/tip-tbjnp40ddoxxl474uvhwi6g4@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/arch/powerpc/annotate/instructions.c [new file with mode: 0644]
tools/perf/util/annotate.c

diff --git a/tools/perf/arch/powerpc/annotate/instructions.c b/tools/perf/arch/powerpc/annotate/instructions.c
new file mode 100644 (file)
index 0000000..3c4004d
--- /dev/null
@@ -0,0 +1,58 @@
+static struct ins_ops *powerpc__associate_instruction_ops(struct arch *arch, const char *name)
+{
+       int i;
+       struct ins_ops *ops;
+
+       /*
+        * - Interested only if instruction starts with 'b'.
+        * - Few start with 'b', but aren't branch instructions.
+        */
+       if (name[0] != 'b'             ||
+           !strncmp(name, "bcd", 3)   ||
+           !strncmp(name, "brinc", 5) ||
+           !strncmp(name, "bper", 4))
+               return NULL;
+
+       ops = &jump_ops;
+
+       i = strlen(name) - 1;
+       if (i < 0)
+               return NULL;
+
+       /* ignore optional hints at the end of the instructions */
+       if (name[i] == '+' || name[i] == '-')
+               i--;
+
+       if (name[i] == 'l' || (name[i] == 'a' && name[i-1] == 'l')) {
+               /*
+                * if the instruction ends up with 'l' or 'la', then
+                * those are considered 'calls' since they update LR.
+                * ... except for 'bnl' which is branch if not less than
+                * and the absolute form of the same.
+                */
+               if (strcmp(name, "bnl") && strcmp(name, "bnl+") &&
+                   strcmp(name, "bnl-") && strcmp(name, "bnla") &&
+                   strcmp(name, "bnla+") && strcmp(name, "bnla-"))
+                       ops = &call_ops;
+       }
+       if (name[i] == 'r' && name[i-1] == 'l')
+               /*
+                * instructions ending with 'lr' are considered to be
+                * return instructions
+                */
+               ops = &ret_ops;
+
+       arch__associate_ins_ops(arch, name, ops);
+       return ops;
+}
+
+static int powerpc__annotate_init(struct arch *arch)
+{
+       if (!arch->initialized) {
+               arch->initialized = true;
+               arch->associate_instruction_ops = powerpc__associate_instruction_ops;
+               arch->objdump.comment_char      = '#';
+       }
+
+       return 0;
+}
index bad44db7dd6731880e73d4ecf848f2d8493cbdac..3e34ee0fde2830132ed171dc2fddac691aa62e20 100644 (file)
@@ -106,6 +106,7 @@ static int arch__associate_ins_ops(struct arch* arch, const char *name, struct i
 
 #include "arch/arm/annotate/instructions.c"
 #include "arch/x86/annotate/instructions.c"
+#include "arch/powerpc/annotate/instructions.c"
 
 static struct arch architectures[] = {
        {
@@ -120,6 +121,10 @@ static struct arch architectures[] = {
                        .comment_char = '#',
                },
        },
+       {
+               .name = "powerpc",
+               .init = powerpc__annotate_init,
+       },
 };
 
 static void ins__delete(struct ins_operands *ops)