[PATCH 05/12] perf annotate: Initial PowerPC support

From: Arnaldo Carvalho de Melo
Date: Fri Nov 25 2016 - 10:12:53 EST


From: Ravi Bangoria <ravi.bangoria@xxxxxxxxxxxxxxxxxx>

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@xxxxxxxxxxxxxxxxxx>
Signed-off-by: Naveen N. Rao <naveen.n.rao@xxxxxxxxxxxxxxxxxx>
Tested-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
Cc: Kim Phillips <kim.phillips@xxxxxxx>
Link: http://lkml.kernel.org/n/tip-tbjnp40ddoxxl474uvhwi6g4@xxxxxxxxxxxxxx
Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
---
tools/perf/arch/powerpc/annotate/instructions.c | 58 +++++++++++++++++++++++++
tools/perf/util/annotate.c | 5 +++
2 files changed, 63 insertions(+)
create mode 100644 tools/perf/arch/powerpc/annotate/instructions.c

diff --git a/tools/perf/arch/powerpc/annotate/instructions.c b/tools/perf/arch/powerpc/annotate/instructions.c
new file mode 100644
index 000000000000..3c4004db81b9
--- /dev/null
+++ b/tools/perf/arch/powerpc/annotate/instructions.c
@@ -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;
+}
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index bad44db7dd67..3e34ee0fde28 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -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)
--
2.7.4