aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2016-11-18 14:54:10 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-11-25 08:38:56 -0500
commitacc9bfb5fae5c48ca875911d87d8d8a9d886bb66 (patch)
tree56cfb2d9ecabe8ab458089e412cde5b893dd90d0
parent0781ea923445405a45464842e9ee0e30f76cb84b (diff)
perf annotate: Improve support for ARM
By using arch->init() to set up some regular expressions to associate ins_ops to ARM instructions, ditching that old table that has instructions not present on ARM. Take advantage of having an arch->init() to hide more arm specific stuff from the common code, like the objdump details. The regular expressions comes from a patch written by Kim Phillips. Reviewed-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Chris Riyder <chris.ryder@arm.com> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Kim Phillips <kim.phillips@arm.com> Cc: Markus Trippelsdorf <markus@trippelsdorf.de> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com> Cc: Pawel Moll <pawel.moll@arm.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Russell King <rmk+kernel@arm.linux.org.uk> Cc: Taeung Song <treeze.taeung@gmail.com> Cc: Wang Nan <wangnan0@huawei.com> Link: http://lkml.kernel.org/n/tip-77m7lufz9ajjimkrebtg5ead@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/arch/arm/annotate/instructions.c147
-rw-r--r--tools/perf/util/annotate.c9
2 files changed, 60 insertions, 96 deletions
diff --git a/tools/perf/arch/arm/annotate/instructions.c b/tools/perf/arch/arm/annotate/instructions.c
index d67b8aa26274..1ce0872b1726 100644
--- a/tools/perf/arch/arm/annotate/instructions.c
+++ b/tools/perf/arch/arm/annotate/instructions.c
@@ -1,90 +1,59 @@
1static struct ins arm__instructions[] = { 1#include <sys/types.h>
2 { .name = "add", .ops = &mov_ops, }, 2#include <regex.h>
3 { .name = "addl", .ops = &mov_ops, }, 3
4 { .name = "addq", .ops = &mov_ops, }, 4struct arm_annotate {
5 { .name = "addw", .ops = &mov_ops, }, 5 regex_t call_insn,
6 { .name = "and", .ops = &mov_ops, }, 6 jump_insn;
7 { .name = "b", .ops = &jump_ops, }, // might also be a call
8 { .name = "bcc", .ops = &jump_ops, },
9 { .name = "bcs", .ops = &jump_ops, },
10 { .name = "beq", .ops = &jump_ops, },
11 { .name = "bge", .ops = &jump_ops, },
12 { .name = "bgt", .ops = &jump_ops, },
13 { .name = "bhi", .ops = &jump_ops, },
14 { .name = "bl", .ops = &call_ops, },
15 { .name = "bls", .ops = &jump_ops, },
16 { .name = "blt", .ops = &jump_ops, },
17 { .name = "blx", .ops = &call_ops, },
18 { .name = "bne", .ops = &jump_ops, },
19 { .name = "bts", .ops = &mov_ops, },
20 { .name = "call", .ops = &call_ops, },
21 { .name = "callq", .ops = &call_ops, },
22 { .name = "cmp", .ops = &mov_ops, },
23 { .name = "cmpb", .ops = &mov_ops, },
24 { .name = "cmpl", .ops = &mov_ops, },
25 { .name = "cmpq", .ops = &mov_ops, },
26 { .name = "cmpw", .ops = &mov_ops, },
27 { .name = "cmpxch", .ops = &mov_ops, },
28 { .name = "dec", .ops = &dec_ops, },
29 { .name = "decl", .ops = &dec_ops, },
30 { .name = "imul", .ops = &mov_ops, },
31 { .name = "inc", .ops = &dec_ops, },
32 { .name = "incl", .ops = &dec_ops, },
33 { .name = "ja", .ops = &jump_ops, },
34 { .name = "jae", .ops = &jump_ops, },
35 { .name = "jb", .ops = &jump_ops, },
36 { .name = "jbe", .ops = &jump_ops, },
37 { .name = "jc", .ops = &jump_ops, },
38 { .name = "jcxz", .ops = &jump_ops, },
39 { .name = "je", .ops = &jump_ops, },
40 { .name = "jecxz", .ops = &jump_ops, },
41 { .name = "jg", .ops = &jump_ops, },
42 { .name = "jge", .ops = &jump_ops, },
43 { .name = "jl", .ops = &jump_ops, },
44 { .name = "jle", .ops = &jump_ops, },
45 { .name = "jmp", .ops = &jump_ops, },
46 { .name = "jmpq", .ops = &jump_ops, },
47 { .name = "jna", .ops = &jump_ops, },
48 { .name = "jnae", .ops = &jump_ops, },
49 { .name = "jnb", .ops = &jump_ops, },
50 { .name = "jnbe", .ops = &jump_ops, },
51 { .name = "jnc", .ops = &jump_ops, },
52 { .name = "jne", .ops = &jump_ops, },
53 { .name = "jng", .ops = &jump_ops, },
54 { .name = "jnge", .ops = &jump_ops, },
55 { .name = "jnl", .ops = &jump_ops, },
56 { .name = "jnle", .ops = &jump_ops, },
57 { .name = "jno", .ops = &jump_ops, },
58 { .name = "jnp", .ops = &jump_ops, },
59 { .name = "jns", .ops = &jump_ops, },
60 { .name = "jnz", .ops = &jump_ops, },
61 { .name = "jo", .ops = &jump_ops, },
62 { .name = "jp", .ops = &jump_ops, },
63 { .name = "jpe", .ops = &jump_ops, },
64 { .name = "jpo", .ops = &jump_ops, },
65 { .name = "jrcxz", .ops = &jump_ops, },
66 { .name = "js", .ops = &jump_ops, },
67 { .name = "jz", .ops = &jump_ops, },
68 { .name = "lea", .ops = &mov_ops, },
69 { .name = "lock", .ops = &lock_ops, },
70 { .name = "mov", .ops = &mov_ops, },
71 { .name = "movb", .ops = &mov_ops, },
72 { .name = "movdqa", .ops = &mov_ops, },
73 { .name = "movl", .ops = &mov_ops, },
74 { .name = "movq", .ops = &mov_ops, },
75 { .name = "movslq", .ops = &mov_ops, },
76 { .name = "movzbl", .ops = &mov_ops, },
77 { .name = "movzwl", .ops = &mov_ops, },
78 { .name = "nop", .ops = &nop_ops, },
79 { .name = "nopl", .ops = &nop_ops, },
80 { .name = "nopw", .ops = &nop_ops, },
81 { .name = "or", .ops = &mov_ops, },
82 { .name = "orl", .ops = &mov_ops, },
83 { .name = "test", .ops = &mov_ops, },
84 { .name = "testb", .ops = &mov_ops, },
85 { .name = "testl", .ops = &mov_ops, },
86 { .name = "xadd", .ops = &mov_ops, },
87 { .name = "xbeginl", .ops = &jump_ops, },
88 { .name = "xbeginq", .ops = &jump_ops, },
89 { .name = "retq", .ops = &ret_ops, },
90}; 7};
8
9static struct ins_ops *arm__associate_instruction_ops(struct arch *arch, const char *name)
10{
11 struct arm_annotate *arm = arch->priv;
12 struct ins_ops *ops;
13 regmatch_t match[2];
14
15 if (!regexec(&arm->call_insn, name, 2, match, 0))
16 ops = &call_ops;
17 else if (!regexec(&arm->jump_insn, name, 2, match, 0))
18 ops = &jump_ops;
19 else
20 return NULL;
21
22 arch__associate_ins_ops(arch, name, ops);
23 return ops;
24}
25
26static int arm__annotate_init(struct arch *arch)
27{
28 struct arm_annotate *arm;
29 int err;
30
31 if (arch->initialized)
32 return 0;
33
34 arm = zalloc(sizeof(*arm));
35 if (!arm)
36 return -1;
37
38#define ARM_CONDS "(cc|cs|eq|ge|gt|hi|le|ls|lt|mi|ne|pl|vc|vs)"
39 err = regcomp(&arm->call_insn, "^blx?" ARM_CONDS "?$", REG_EXTENDED);
40 if (err)
41 goto out_free_arm;
42 err = regcomp(&arm->jump_insn, "^bx?" ARM_CONDS "?$", REG_EXTENDED);
43 if (err)
44 goto out_free_call;
45#undef ARM_CONDS
46
47 arch->initialized = true;
48 arch->priv = arm;
49 arch->associate_instruction_ops = arm__associate_instruction_ops;
50 arch->objdump.comment_char = ';';
51 arch->objdump.skip_functions_char = '+';
52 return 0;
53
54out_free_call:
55 regfree(&arm->call_insn);
56out_free_arm:
57 free(arm);
58 return -1;
59}
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 1e96549650d7..bad44db7dd67 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -84,7 +84,7 @@ grow_from_non_allocated_table:
84 goto out_update_instructions; 84 goto out_update_instructions;
85} 85}
86 86
87static __maybe_unused int arch__associate_ins_ops(struct arch* arch, const char *name, struct ins_ops *ops) 87static int arch__associate_ins_ops(struct arch* arch, const char *name, struct ins_ops *ops)
88{ 88{
89 struct ins *ins; 89 struct ins *ins;
90 90
@@ -110,12 +110,7 @@ static __maybe_unused int arch__associate_ins_ops(struct arch* arch, const char
110static struct arch architectures[] = { 110static struct arch architectures[] = {
111 { 111 {
112 .name = "arm", 112 .name = "arm",
113 .instructions = arm__instructions, 113 .init = arm__annotate_init,
114 .nr_instructions = ARRAY_SIZE(arm__instructions),
115 .objdump = {
116 .comment_char = ';',
117 .skip_functions_char = '+',
118 },
119 }, 114 },
120 { 115 {
121 .name = "x86", 116 .name = "x86",