diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2016-11-18 14:54:10 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2016-11-25 08:38:56 -0500 |
commit | acc9bfb5fae5c48ca875911d87d8d8a9d886bb66 (patch) | |
tree | 56cfb2d9ecabe8ab458089e412cde5b893dd90d0 | |
parent | 0781ea923445405a45464842e9ee0e30f76cb84b (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.c | 147 | ||||
-rw-r--r-- | tools/perf/util/annotate.c | 9 |
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 @@ | |||
1 | static 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, }, | 4 | struct 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 | |||
9 | static 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 | |||
26 | static 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 | |||
54 | out_free_call: | ||
55 | regfree(&arm->call_insn); | ||
56 | out_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 | ||
87 | static __maybe_unused int arch__associate_ins_ops(struct arch* arch, const char *name, struct ins_ops *ops) | 87 | static 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 | |||
110 | static struct arch architectures[] = { | 110 | static 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", |