2016-10-10 13:59:20

by Ravi Bangoria

[permalink] [raw]
Subject: [PATCH] perf annotate: Cleanup arch specific stuff

Move arch specific stuff from util/annotate.c to their respective
files in util/annotate directory.

No functionality changes.

Signed-off-by: Ravi Bangoria <[email protected]>
---
tools/perf/util/Build | 1 +
tools/perf/util/annotate.c | 259 +++----------------------------------
tools/perf/util/annotate.h | 23 ++++
tools/perf/util/annotate/Build | 3 +
tools/perf/util/annotate/arm.c | 50 +++++++
tools/perf/util/annotate/powerpc.c | 63 +++++++++
tools/perf/util/annotate/x86.c | 107 +++++++++++++++
7 files changed, 264 insertions(+), 242 deletions(-)
create mode 100644 tools/perf/util/annotate/Build
create mode 100644 tools/perf/util/annotate/arm.c
create mode 100644 tools/perf/util/annotate/powerpc.c
create mode 100644 tools/perf/util/annotate/x86.c

diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index eb60e61..1ee1170 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -1,4 +1,5 @@
libperf-y += alias.o
+libperf-y += annotate/
libperf-y += annotate.o
libperf-y += block-range.o
libperf-y += build-id.o
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 83d5ac8..a168d1e 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -28,7 +28,6 @@ const char *disassembler_style;
const char *objdump_path;
static regex_t file_lineno;
static char *norm_arch;
-static regex_t arm_call_insn, arm_jump_insn;

static struct ins *ins__find(const char *name);
static int disasm_line__parse(char *line, char **namep, char **rawp);
@@ -110,7 +109,7 @@ static int call__scnprintf(struct ins *ins, char *bf, size_t size,
return scnprintf(bf, size, "%-6.6s *%" PRIx64, ins->name, ops->target.addr);
}

-static struct ins_ops call_ops = {
+struct ins_ops call_ops = {
.parse = call__parse,
.scnprintf = call__scnprintf,
};
@@ -149,7 +148,7 @@ static int jump__scnprintf(struct ins *ins, char *bf, size_t size,
return scnprintf(bf, size, "%-6.6s %" PRIx64, ins->name, ops->target.offset);
}

-static struct ins_ops jump_ops = {
+struct ins_ops jump_ops = {
.parse = jump__parse,
.scnprintf = jump__scnprintf,
};
@@ -242,7 +241,7 @@ static void lock__delete(struct ins_operands *ops)
zfree(&ops->target.name);
}

-static struct ins_ops lock_ops = {
+struct ins_ops lock_ops = {
.free = lock__delete,
.parse = lock__parse,
.scnprintf = lock__scnprintf,
@@ -306,7 +305,7 @@ static int mov__scnprintf(struct ins *ins, char *bf, size_t size,
ops->target.name ?: ops->target.raw);
}

-static struct ins_ops mov_ops = {
+struct ins_ops mov_ops = {
.parse = mov__parse,
.scnprintf = mov__scnprintf,
};
@@ -347,7 +346,7 @@ static int dec__scnprintf(struct ins *ins, char *bf, size_t size,
ops->target.name ?: ops->target.raw);
}

-static struct ins_ops dec_ops = {
+struct ins_ops dec_ops = {
.parse = dec__parse,
.scnprintf = dec__scnprintf,
};
@@ -358,11 +357,11 @@ static int nop__scnprintf(struct ins *ins __maybe_unused, char *bf, size_t size,
return scnprintf(bf, size, "%-6.6s", "nop");
}

-static struct ins_ops nop_ops = {
+struct ins_ops nop_ops = {
.scnprintf = nop__scnprintf,
};

-static struct ins_ops ret_ops = {
+struct ins_ops ret_ops = {
.scnprintf = ins__raw_scnprintf,
};

@@ -371,107 +370,8 @@ bool ins__is_ret(const struct ins *ins)
return ins->ops == &ret_ops;
}

-static struct ins instructions_x86[] = {
- { .name = "add", .ops = &mov_ops, },
- { .name = "addl", .ops = &mov_ops, },
- { .name = "addq", .ops = &mov_ops, },
- { .name = "addw", .ops = &mov_ops, },
- { .name = "and", .ops = &mov_ops, },
- { .name = "bts", .ops = &mov_ops, },
- { .name = "call", .ops = &call_ops, },
- { .name = "callq", .ops = &call_ops, },
- { .name = "cmp", .ops = &mov_ops, },
- { .name = "cmpb", .ops = &mov_ops, },
- { .name = "cmpl", .ops = &mov_ops, },
- { .name = "cmpq", .ops = &mov_ops, },
- { .name = "cmpw", .ops = &mov_ops, },
- { .name = "cmpxch", .ops = &mov_ops, },
- { .name = "dec", .ops = &dec_ops, },
- { .name = "decl", .ops = &dec_ops, },
- { .name = "imul", .ops = &mov_ops, },
- { .name = "inc", .ops = &dec_ops, },
- { .name = "incl", .ops = &dec_ops, },
- { .name = "ja", .ops = &jump_ops, },
- { .name = "jae", .ops = &jump_ops, },
- { .name = "jb", .ops = &jump_ops, },
- { .name = "jbe", .ops = &jump_ops, },
- { .name = "jc", .ops = &jump_ops, },
- { .name = "jcxz", .ops = &jump_ops, },
- { .name = "je", .ops = &jump_ops, },
- { .name = "jecxz", .ops = &jump_ops, },
- { .name = "jg", .ops = &jump_ops, },
- { .name = "jge", .ops = &jump_ops, },
- { .name = "jl", .ops = &jump_ops, },
- { .name = "jle", .ops = &jump_ops, },
- { .name = "jmp", .ops = &jump_ops, },
- { .name = "jmpq", .ops = &jump_ops, },
- { .name = "jna", .ops = &jump_ops, },
- { .name = "jnae", .ops = &jump_ops, },
- { .name = "jnb", .ops = &jump_ops, },
- { .name = "jnbe", .ops = &jump_ops, },
- { .name = "jnc", .ops = &jump_ops, },
- { .name = "jne", .ops = &jump_ops, },
- { .name = "jng", .ops = &jump_ops, },
- { .name = "jnge", .ops = &jump_ops, },
- { .name = "jnl", .ops = &jump_ops, },
- { .name = "jnle", .ops = &jump_ops, },
- { .name = "jno", .ops = &jump_ops, },
- { .name = "jnp", .ops = &jump_ops, },
- { .name = "jns", .ops = &jump_ops, },
- { .name = "jnz", .ops = &jump_ops, },
- { .name = "jo", .ops = &jump_ops, },
- { .name = "jp", .ops = &jump_ops, },
- { .name = "jpe", .ops = &jump_ops, },
- { .name = "jpo", .ops = &jump_ops, },
- { .name = "jrcxz", .ops = &jump_ops, },
- { .name = "js", .ops = &jump_ops, },
- { .name = "jz", .ops = &jump_ops, },
- { .name = "lea", .ops = &mov_ops, },
- { .name = "lock", .ops = &lock_ops, },
- { .name = "mov", .ops = &mov_ops, },
- { .name = "movb", .ops = &mov_ops, },
- { .name = "movdqa", .ops = &mov_ops, },
- { .name = "movl", .ops = &mov_ops, },
- { .name = "movq", .ops = &mov_ops, },
- { .name = "movslq", .ops = &mov_ops, },
- { .name = "movzbl", .ops = &mov_ops, },
- { .name = "movzwl", .ops = &mov_ops, },
- { .name = "nop", .ops = &nop_ops, },
- { .name = "nopl", .ops = &nop_ops, },
- { .name = "nopw", .ops = &nop_ops, },
- { .name = "or", .ops = &mov_ops, },
- { .name = "orl", .ops = &mov_ops, },
- { .name = "test", .ops = &mov_ops, },
- { .name = "testb", .ops = &mov_ops, },
- { .name = "testl", .ops = &mov_ops, },
- { .name = "xadd", .ops = &mov_ops, },
- { .name = "xbeginl", .ops = &jump_ops, },
- { .name = "xbeginq", .ops = &jump_ops, },
- { .name = "retq", .ops = &ret_ops, },
-};
-
-struct instructions_arch {
- struct ins *ins;
- struct list_head list;
-};
-
-static int ins__key_cmp(const void *name, const void *insp)
-{
- const struct ins *ins = insp;
-
- return strcmp(name, ins->name);
-}
-
-static int ins__cmp(const void *a, const void *b)
-{
- const struct ins *ia = a;
- const struct ins *ib = b;
-
- return strcmp(ia->name, ib->name);
-}
-
-static struct ins *list_add__ins_arch(struct instructions_arch *head,
- const char *name, struct ins_ops *ops)
+struct ins *list_add__ins_arch(struct instructions_arch *head,
+ const char *name, struct ins_ops *ops)
{
struct instructions_arch *ins_arch;
struct ins *ins;
@@ -501,8 +401,8 @@ static struct ins *list_add__ins_arch(struct instructions_arch *head,
return NULL;
}

-static struct ins *list_search__ins_arch(struct instructions_arch *head,
- const char *name)
+struct ins *list_search__ins_arch(struct instructions_arch *head,
+ const char *name)
{
struct instructions_arch *pos;

@@ -513,106 +413,6 @@ static struct ins *list_search__ins_arch(struct instructions_arch *head,
return NULL;
}

-static struct ins *ins__find_powerpc(const char *name)
-{
- int i;
- struct ins *ins;
- struct ins_ops *ops;
- static struct instructions_arch head = {
- .list = LIST_HEAD_INIT(head.list),
- };
-
- /*
- * - 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;
-
- /*
- * Return if we already have object of 'struct ins' for this instruction
- */
- ins = list_search__ins_arch(&head, name);
- if (ins)
- return ins;
-
- 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;
-
- /*
- * Add instruction to list so next time no need to
- * allocate memory for it.
- */
- return list_add__ins_arch(&head, name, ops);
-}
-
-static struct ins *ins__find_arm(const char *name)
-{
- struct ins *ins;
- struct ins_ops *ops = &mov_ops;
- regmatch_t match[2];
- int ret;
- static struct instructions_arch head = {
- .list = LIST_HEAD_INIT(head.list),
- };
-
- /*
- * Return if we already have object of 'struct ins' for this instruction
- */
- ins = list_search__ins_arch(&head, name);
- if (ins)
- return ins;
-
- ret = regexec(&arm_call_insn, name, 2, match, 0);
- if (!ret) {
- ops = &call_ops;
- } else {
- ret = regexec(&arm_jump_insn, name, 2, match, 0);
- if (!ret)
- ops = &jump_ops;
- }
-
- /*
- * Add instruction to list so next time no need to
- * allocate memory for it.
- */
- return list_add__ins_arch(&head, name, ops);
-}
-
-static void ins__sort(struct ins *instructions, int nmemb)
-{
- qsort(instructions, nmemb, sizeof(struct ins), ins__cmp);
-}
-
static const char *annotate__norm_arch(char *arch)
{
struct utsname uts;
@@ -625,43 +425,18 @@ static const char *annotate__norm_arch(char *arch)
return normalize_arch(arch);
}

-#define ARM_CONDS "(cc|cs|eq|ge|gt|hi|le|ls|lt|mi|ne|pl|vc|vs)"
-
static struct ins *ins__find(const char *name)
{
- static bool sorted;
- struct ins *instructions;
- int nmemb, ret;
-
- if (!sorted) {
- ins__sort(instructions_x86, ARRAY_SIZE(instructions_x86));
- if (!strcmp(norm_arch, "arm")) {
- ret = regcomp(&arm_call_insn,
- "^blx?" ARM_CONDS "?$", REG_EXTENDED);
- ret |= regcomp(&arm_jump_insn,
- "^bx?" ARM_CONDS "?$", REG_EXTENDED);
- if (ret) {
- pr_err("regcomp failed\n");
- return NULL;
- }
- }
- sorted = true;
- }
-
- if (!strcmp(norm_arch, "x86")) {
- instructions = instructions_x86;
- nmemb = ARRAY_SIZE(instructions_x86);
- } else if (!strcmp(norm_arch, "arm")) {
+ if (!strcmp(norm_arch, "x86"))
+ return ins__find_x86(name);
+ else if (!strcmp(norm_arch, "arm"))
return ins__find_arm(name);
- } else if (!strcmp(norm_arch, "powerpc")) {
+ else if (!strcmp(norm_arch, "powerpc"))
return ins__find_powerpc(name);
- } else {
+ else
pr_err("perf annotate not supported by %s arch\n", norm_arch);
- return NULL;
- }

- return bsearch(name, instructions, nmemb, sizeof(struct ins),
- ins__key_cmp);
+ return NULL;
}

int symbol__alloc_hist(struct symbol *sym)
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index 7ba3579..91b705a 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -42,11 +42,30 @@ struct ins_ops {
struct ins_operands *ops);
};

+/* Defined in annotate.c */
+extern struct ins_ops mov_ops;
+extern struct ins_ops call_ops;
+extern struct ins_ops dec_ops;
+extern struct ins_ops jump_ops;
+extern struct ins_ops lock_ops;
+extern struct ins_ops nop_ops;
+extern struct ins_ops ret_ops;
+
struct ins {
const char *name;
struct ins_ops *ops;
};

+struct instructions_arch {
+ struct ins *ins;
+ struct list_head list;
+};
+
+struct ins *list_add__ins_arch(struct instructions_arch *head,
+ const char *name, struct ins_ops *ops);
+struct ins *list_search__ins_arch(struct instructions_arch *head,
+ const char *name);
+
bool ins__is_jump(const struct ins *ins);
bool ins__is_call(const struct ins *ins);
bool ins__is_ret(const struct ins *ins);
@@ -210,4 +229,8 @@ static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused,

extern const char *disassembler_style;

+struct ins *ins__find_x86(const char *name);
+struct ins *ins__find_arm(const char *name);
+struct ins *ins__find_powerpc(const char *name);
+
#endif /* __PERF_ANNOTATE_H */
diff --git a/tools/perf/util/annotate/Build b/tools/perf/util/annotate/Build
new file mode 100644
index 0000000..ed87f1c
--- /dev/null
+++ b/tools/perf/util/annotate/Build
@@ -0,0 +1,3 @@
+libperf-y += x86.o
+libperf-y += arm.o
+libperf-y += powerpc.o
diff --git a/tools/perf/util/annotate/arm.c b/tools/perf/util/annotate/arm.c
new file mode 100644
index 0000000..6bfc866
--- /dev/null
+++ b/tools/perf/util/annotate/arm.c
@@ -0,0 +1,50 @@
+#include "../annotate.h"
+
+static regex_t arm_call_insn, arm_jump_insn;
+
+#define ARM_CONDS "(cc|cs|eq|ge|gt|hi|le|ls|lt|mi|ne|pl|vc|vs)"
+
+static __attribute__((constructor)) void init_regex(void)
+{
+ int ret;
+
+ ret = regcomp(&arm_call_insn, "^blx?" ARM_CONDS "?$", REG_EXTENDED);
+ ret |= regcomp(&arm_jump_insn, "^bx?" ARM_CONDS "?$", REG_EXTENDED);
+
+ if (ret)
+ pr_err("regcomp failed\n");
+}
+
+struct ins *ins__find_arm(const char *name)
+{
+ struct ins *ins;
+ struct ins_ops *ops = &mov_ops;
+ regmatch_t match[2];
+ int ret;
+ static struct instructions_arch head = {
+ .list = LIST_HEAD_INIT(head.list),
+ };
+
+ /*
+ * Return if we already have object of 'struct ins' for this instruction
+ */
+ ins = list_search__ins_arch(&head, name);
+ if (ins)
+ return ins;
+
+ ret = regexec(&arm_call_insn, name, 2, match, 0);
+ if (!ret) {
+ ops = &call_ops;
+ } else {
+ ret = regexec(&arm_jump_insn, name, 2, match, 0);
+ if (!ret)
+ ops = &jump_ops;
+ }
+
+ /*
+ * Add instruction to list so next time no need to
+ * allocate memory for it.
+ */
+ return list_add__ins_arch(&head, name, ops);
+
+}
diff --git a/tools/perf/util/annotate/powerpc.c b/tools/perf/util/annotate/powerpc.c
new file mode 100644
index 0000000..6088ce2
--- /dev/null
+++ b/tools/perf/util/annotate/powerpc.c
@@ -0,0 +1,63 @@
+#include "../annotate.h"
+
+struct ins *ins__find_powerpc(const char *name)
+{
+ int i;
+ struct ins *ins;
+ struct ins_ops *ops;
+ static struct instructions_arch head = {
+ .list = LIST_HEAD_INIT(head.list),
+ };
+
+ /*
+ * - 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;
+
+ /*
+ * Return if we already have object of 'struct ins' for this instruction
+ */
+ ins = list_search__ins_arch(&head, name);
+ if (ins)
+ return ins;
+
+ 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;
+
+ /*
+ * Add instruction to list so next time no need to
+ * allocate memory for it.
+ */
+ return list_add__ins_arch(&head, name, ops);
+}
diff --git a/tools/perf/util/annotate/x86.c b/tools/perf/util/annotate/x86.c
new file mode 100644
index 0000000..b519197
--- /dev/null
+++ b/tools/perf/util/annotate/x86.c
@@ -0,0 +1,107 @@
+#include "../annotate.h"
+
+static struct ins instructions[] = {
+ { .name = "add", .ops = &mov_ops, },
+ { .name = "addl", .ops = &mov_ops, },
+ { .name = "addq", .ops = &mov_ops, },
+ { .name = "addw", .ops = &mov_ops, },
+ { .name = "and", .ops = &mov_ops, },
+ { .name = "bts", .ops = &mov_ops, },
+ { .name = "call", .ops = &call_ops, },
+ { .name = "callq", .ops = &call_ops, },
+ { .name = "cmp", .ops = &mov_ops, },
+ { .name = "cmpb", .ops = &mov_ops, },
+ { .name = "cmpl", .ops = &mov_ops, },
+ { .name = "cmpq", .ops = &mov_ops, },
+ { .name = "cmpw", .ops = &mov_ops, },
+ { .name = "cmpxch", .ops = &mov_ops, },
+ { .name = "dec", .ops = &dec_ops, },
+ { .name = "decl", .ops = &dec_ops, },
+ { .name = "imul", .ops = &mov_ops, },
+ { .name = "inc", .ops = &dec_ops, },
+ { .name = "incl", .ops = &dec_ops, },
+ { .name = "ja", .ops = &jump_ops, },
+ { .name = "jae", .ops = &jump_ops, },
+ { .name = "jb", .ops = &jump_ops, },
+ { .name = "jbe", .ops = &jump_ops, },
+ { .name = "jc", .ops = &jump_ops, },
+ { .name = "jcxz", .ops = &jump_ops, },
+ { .name = "je", .ops = &jump_ops, },
+ { .name = "jecxz", .ops = &jump_ops, },
+ { .name = "jg", .ops = &jump_ops, },
+ { .name = "jge", .ops = &jump_ops, },
+ { .name = "jl", .ops = &jump_ops, },
+ { .name = "jle", .ops = &jump_ops, },
+ { .name = "jmp", .ops = &jump_ops, },
+ { .name = "jmpq", .ops = &jump_ops, },
+ { .name = "jna", .ops = &jump_ops, },
+ { .name = "jnae", .ops = &jump_ops, },
+ { .name = "jnb", .ops = &jump_ops, },
+ { .name = "jnbe", .ops = &jump_ops, },
+ { .name = "jnc", .ops = &jump_ops, },
+ { .name = "jne", .ops = &jump_ops, },
+ { .name = "jng", .ops = &jump_ops, },
+ { .name = "jnge", .ops = &jump_ops, },
+ { .name = "jnl", .ops = &jump_ops, },
+ { .name = "jnle", .ops = &jump_ops, },
+ { .name = "jno", .ops = &jump_ops, },
+ { .name = "jnp", .ops = &jump_ops, },
+ { .name = "jns", .ops = &jump_ops, },
+ { .name = "jnz", .ops = &jump_ops, },
+ { .name = "jo", .ops = &jump_ops, },
+ { .name = "jp", .ops = &jump_ops, },
+ { .name = "jpe", .ops = &jump_ops, },
+ { .name = "jpo", .ops = &jump_ops, },
+ { .name = "jrcxz", .ops = &jump_ops, },
+ { .name = "js", .ops = &jump_ops, },
+ { .name = "jz", .ops = &jump_ops, },
+ { .name = "lea", .ops = &mov_ops, },
+ { .name = "lock", .ops = &lock_ops, },
+ { .name = "mov", .ops = &mov_ops, },
+ { .name = "movb", .ops = &mov_ops, },
+ { .name = "movdqa", .ops = &mov_ops, },
+ { .name = "movl", .ops = &mov_ops, },
+ { .name = "movq", .ops = &mov_ops, },
+ { .name = "movslq", .ops = &mov_ops, },
+ { .name = "movzbl", .ops = &mov_ops, },
+ { .name = "movzwl", .ops = &mov_ops, },
+ { .name = "nop", .ops = &nop_ops, },
+ { .name = "nopl", .ops = &nop_ops, },
+ { .name = "nopw", .ops = &nop_ops, },
+ { .name = "or", .ops = &mov_ops, },
+ { .name = "orl", .ops = &mov_ops, },
+ { .name = "test", .ops = &mov_ops, },
+ { .name = "testb", .ops = &mov_ops, },
+ { .name = "testl", .ops = &mov_ops, },
+ { .name = "xadd", .ops = &mov_ops, },
+ { .name = "xbeginl", .ops = &jump_ops, },
+ { .name = "xbeginq", .ops = &jump_ops, },
+ { .name = "retq", .ops = &ret_ops, },
+};
+
+static int ins__cmp(const void *a, const void *b)
+{
+ const struct ins *ia = a;
+ const struct ins *ib = b;
+
+ return strcmp(ia->name, ib->name);
+}
+
+static __attribute__((constructor)) void ins__sort(void)
+{
+ qsort(instructions, ARRAY_SIZE(instructions), sizeof(struct ins),
+ ins__cmp);
+}
+
+static int ins__key_cmp(const void *name, const void *insp)
+{
+ const struct ins *ins = insp;
+
+ return strcmp(name, ins->name);
+}
+
+struct ins *ins__find_x86(const char *name)
+{
+ return bsearch(name, instructions, ARRAY_SIZE(instructions),
+ sizeof(struct ins), ins__key_cmp);
+}
--
2.5.5


2016-10-10 16:24:23

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: [PATCH] perf annotate: Cleanup arch specific stuff

Em Mon, Oct 10, 2016 at 07:29:02PM +0530, Ravi Bangoria escreveu:
> Move arch specific stuff from util/annotate.c to their respective
> files in util/annotate directory.
>
> No functionality changes.
>
> Signed-off-by: Ravi Bangoria <[email protected]>
> ---
> tools/perf/util/Build | 1 +
> tools/perf/util/annotate.c | 259 +++----------------------------------
> tools/perf/util/annotate.h | 23 ++++
> tools/perf/util/annotate/Build | 3 +
> tools/perf/util/annotate/arm.c | 50 +++++++
> tools/perf/util/annotate/powerpc.c | 63 +++++++++
> tools/perf/util/annotate/x86.c | 107 +++++++++++++++

We already have a per arch area: tools/perf/arch/

- Arnaldo

> 7 files changed, 264 insertions(+), 242 deletions(-)
> create mode 100644 tools/perf/util/annotate/Build
> create mode 100644 tools/perf/util/annotate/arm.c
> create mode 100644 tools/perf/util/annotate/powerpc.c
> create mode 100644 tools/perf/util/annotate/x86.c
>
> diff --git a/tools/perf/util/Build b/tools/perf/util/Build
> index eb60e61..1ee1170 100644
> --- a/tools/perf/util/Build
> +++ b/tools/perf/util/Build
> @@ -1,4 +1,5 @@
> libperf-y += alias.o
> +libperf-y += annotate/
> libperf-y += annotate.o
> libperf-y += block-range.o
> libperf-y += build-id.o
> diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
> index 83d5ac8..a168d1e 100644
> --- a/tools/perf/util/annotate.c
> +++ b/tools/perf/util/annotate.c
> @@ -28,7 +28,6 @@ const char *disassembler_style;
> const char *objdump_path;
> static regex_t file_lineno;
> static char *norm_arch;
> -static regex_t arm_call_insn, arm_jump_insn;
>
> static struct ins *ins__find(const char *name);
> static int disasm_line__parse(char *line, char **namep, char **rawp);
> @@ -110,7 +109,7 @@ static int call__scnprintf(struct ins *ins, char *bf, size_t size,
> return scnprintf(bf, size, "%-6.6s *%" PRIx64, ins->name, ops->target.addr);
> }
>
> -static struct ins_ops call_ops = {
> +struct ins_ops call_ops = {
> .parse = call__parse,
> .scnprintf = call__scnprintf,
> };
> @@ -149,7 +148,7 @@ static int jump__scnprintf(struct ins *ins, char *bf, size_t size,
> return scnprintf(bf, size, "%-6.6s %" PRIx64, ins->name, ops->target.offset);
> }
>
> -static struct ins_ops jump_ops = {
> +struct ins_ops jump_ops = {
> .parse = jump__parse,
> .scnprintf = jump__scnprintf,
> };
> @@ -242,7 +241,7 @@ static void lock__delete(struct ins_operands *ops)
> zfree(&ops->target.name);
> }
>
> -static struct ins_ops lock_ops = {
> +struct ins_ops lock_ops = {
> .free = lock__delete,
> .parse = lock__parse,
> .scnprintf = lock__scnprintf,
> @@ -306,7 +305,7 @@ static int mov__scnprintf(struct ins *ins, char *bf, size_t size,
> ops->target.name ?: ops->target.raw);
> }
>
> -static struct ins_ops mov_ops = {
> +struct ins_ops mov_ops = {
> .parse = mov__parse,
> .scnprintf = mov__scnprintf,
> };
> @@ -347,7 +346,7 @@ static int dec__scnprintf(struct ins *ins, char *bf, size_t size,
> ops->target.name ?: ops->target.raw);
> }
>
> -static struct ins_ops dec_ops = {
> +struct ins_ops dec_ops = {
> .parse = dec__parse,
> .scnprintf = dec__scnprintf,
> };
> @@ -358,11 +357,11 @@ static int nop__scnprintf(struct ins *ins __maybe_unused, char *bf, size_t size,
> return scnprintf(bf, size, "%-6.6s", "nop");
> }
>
> -static struct ins_ops nop_ops = {
> +struct ins_ops nop_ops = {
> .scnprintf = nop__scnprintf,
> };
>
> -static struct ins_ops ret_ops = {
> +struct ins_ops ret_ops = {
> .scnprintf = ins__raw_scnprintf,
> };
>
> @@ -371,107 +370,8 @@ bool ins__is_ret(const struct ins *ins)
> return ins->ops == &ret_ops;
> }
>
> -static struct ins instructions_x86[] = {
> - { .name = "add", .ops = &mov_ops, },
> - { .name = "addl", .ops = &mov_ops, },
> - { .name = "addq", .ops = &mov_ops, },
> - { .name = "addw", .ops = &mov_ops, },
> - { .name = "and", .ops = &mov_ops, },
> - { .name = "bts", .ops = &mov_ops, },
> - { .name = "call", .ops = &call_ops, },
> - { .name = "callq", .ops = &call_ops, },
> - { .name = "cmp", .ops = &mov_ops, },
> - { .name = "cmpb", .ops = &mov_ops, },
> - { .name = "cmpl", .ops = &mov_ops, },
> - { .name = "cmpq", .ops = &mov_ops, },
> - { .name = "cmpw", .ops = &mov_ops, },
> - { .name = "cmpxch", .ops = &mov_ops, },
> - { .name = "dec", .ops = &dec_ops, },
> - { .name = "decl", .ops = &dec_ops, },
> - { .name = "imul", .ops = &mov_ops, },
> - { .name = "inc", .ops = &dec_ops, },
> - { .name = "incl", .ops = &dec_ops, },
> - { .name = "ja", .ops = &jump_ops, },
> - { .name = "jae", .ops = &jump_ops, },
> - { .name = "jb", .ops = &jump_ops, },
> - { .name = "jbe", .ops = &jump_ops, },
> - { .name = "jc", .ops = &jump_ops, },
> - { .name = "jcxz", .ops = &jump_ops, },
> - { .name = "je", .ops = &jump_ops, },
> - { .name = "jecxz", .ops = &jump_ops, },
> - { .name = "jg", .ops = &jump_ops, },
> - { .name = "jge", .ops = &jump_ops, },
> - { .name = "jl", .ops = &jump_ops, },
> - { .name = "jle", .ops = &jump_ops, },
> - { .name = "jmp", .ops = &jump_ops, },
> - { .name = "jmpq", .ops = &jump_ops, },
> - { .name = "jna", .ops = &jump_ops, },
> - { .name = "jnae", .ops = &jump_ops, },
> - { .name = "jnb", .ops = &jump_ops, },
> - { .name = "jnbe", .ops = &jump_ops, },
> - { .name = "jnc", .ops = &jump_ops, },
> - { .name = "jne", .ops = &jump_ops, },
> - { .name = "jng", .ops = &jump_ops, },
> - { .name = "jnge", .ops = &jump_ops, },
> - { .name = "jnl", .ops = &jump_ops, },
> - { .name = "jnle", .ops = &jump_ops, },
> - { .name = "jno", .ops = &jump_ops, },
> - { .name = "jnp", .ops = &jump_ops, },
> - { .name = "jns", .ops = &jump_ops, },
> - { .name = "jnz", .ops = &jump_ops, },
> - { .name = "jo", .ops = &jump_ops, },
> - { .name = "jp", .ops = &jump_ops, },
> - { .name = "jpe", .ops = &jump_ops, },
> - { .name = "jpo", .ops = &jump_ops, },
> - { .name = "jrcxz", .ops = &jump_ops, },
> - { .name = "js", .ops = &jump_ops, },
> - { .name = "jz", .ops = &jump_ops, },
> - { .name = "lea", .ops = &mov_ops, },
> - { .name = "lock", .ops = &lock_ops, },
> - { .name = "mov", .ops = &mov_ops, },
> - { .name = "movb", .ops = &mov_ops, },
> - { .name = "movdqa", .ops = &mov_ops, },
> - { .name = "movl", .ops = &mov_ops, },
> - { .name = "movq", .ops = &mov_ops, },
> - { .name = "movslq", .ops = &mov_ops, },
> - { .name = "movzbl", .ops = &mov_ops, },
> - { .name = "movzwl", .ops = &mov_ops, },
> - { .name = "nop", .ops = &nop_ops, },
> - { .name = "nopl", .ops = &nop_ops, },
> - { .name = "nopw", .ops = &nop_ops, },
> - { .name = "or", .ops = &mov_ops, },
> - { .name = "orl", .ops = &mov_ops, },
> - { .name = "test", .ops = &mov_ops, },
> - { .name = "testb", .ops = &mov_ops, },
> - { .name = "testl", .ops = &mov_ops, },
> - { .name = "xadd", .ops = &mov_ops, },
> - { .name = "xbeginl", .ops = &jump_ops, },
> - { .name = "xbeginq", .ops = &jump_ops, },
> - { .name = "retq", .ops = &ret_ops, },
> -};
> -
> -struct instructions_arch {
> - struct ins *ins;
> - struct list_head list;
> -};
> -
> -static int ins__key_cmp(const void *name, const void *insp)
> -{
> - const struct ins *ins = insp;
> -
> - return strcmp(name, ins->name);
> -}
> -
> -static int ins__cmp(const void *a, const void *b)
> -{
> - const struct ins *ia = a;
> - const struct ins *ib = b;
> -
> - return strcmp(ia->name, ib->name);
> -}
> -
> -static struct ins *list_add__ins_arch(struct instructions_arch *head,
> - const char *name, struct ins_ops *ops)
> +struct ins *list_add__ins_arch(struct instructions_arch *head,
> + const char *name, struct ins_ops *ops)
> {
> struct instructions_arch *ins_arch;
> struct ins *ins;
> @@ -501,8 +401,8 @@ static struct ins *list_add__ins_arch(struct instructions_arch *head,
> return NULL;
> }
>
> -static struct ins *list_search__ins_arch(struct instructions_arch *head,
> - const char *name)
> +struct ins *list_search__ins_arch(struct instructions_arch *head,
> + const char *name)
> {
> struct instructions_arch *pos;
>
> @@ -513,106 +413,6 @@ static struct ins *list_search__ins_arch(struct instructions_arch *head,
> return NULL;
> }
>
> -static struct ins *ins__find_powerpc(const char *name)
> -{
> - int i;
> - struct ins *ins;
> - struct ins_ops *ops;
> - static struct instructions_arch head = {
> - .list = LIST_HEAD_INIT(head.list),
> - };
> -
> - /*
> - * - 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;
> -
> - /*
> - * Return if we already have object of 'struct ins' for this instruction
> - */
> - ins = list_search__ins_arch(&head, name);
> - if (ins)
> - return ins;
> -
> - 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;
> -
> - /*
> - * Add instruction to list so next time no need to
> - * allocate memory for it.
> - */
> - return list_add__ins_arch(&head, name, ops);
> -}
> -
> -static struct ins *ins__find_arm(const char *name)
> -{
> - struct ins *ins;
> - struct ins_ops *ops = &mov_ops;
> - regmatch_t match[2];
> - int ret;
> - static struct instructions_arch head = {
> - .list = LIST_HEAD_INIT(head.list),
> - };
> -
> - /*
> - * Return if we already have object of 'struct ins' for this instruction
> - */
> - ins = list_search__ins_arch(&head, name);
> - if (ins)
> - return ins;
> -
> - ret = regexec(&arm_call_insn, name, 2, match, 0);
> - if (!ret) {
> - ops = &call_ops;
> - } else {
> - ret = regexec(&arm_jump_insn, name, 2, match, 0);
> - if (!ret)
> - ops = &jump_ops;
> - }
> -
> - /*
> - * Add instruction to list so next time no need to
> - * allocate memory for it.
> - */
> - return list_add__ins_arch(&head, name, ops);
> -}
> -
> -static void ins__sort(struct ins *instructions, int nmemb)
> -{
> - qsort(instructions, nmemb, sizeof(struct ins), ins__cmp);
> -}
> -
> static const char *annotate__norm_arch(char *arch)
> {
> struct utsname uts;
> @@ -625,43 +425,18 @@ static const char *annotate__norm_arch(char *arch)
> return normalize_arch(arch);
> }
>
> -#define ARM_CONDS "(cc|cs|eq|ge|gt|hi|le|ls|lt|mi|ne|pl|vc|vs)"
> -
> static struct ins *ins__find(const char *name)
> {
> - static bool sorted;
> - struct ins *instructions;
> - int nmemb, ret;
> -
> - if (!sorted) {
> - ins__sort(instructions_x86, ARRAY_SIZE(instructions_x86));
> - if (!strcmp(norm_arch, "arm")) {
> - ret = regcomp(&arm_call_insn,
> - "^blx?" ARM_CONDS "?$", REG_EXTENDED);
> - ret |= regcomp(&arm_jump_insn,
> - "^bx?" ARM_CONDS "?$", REG_EXTENDED);
> - if (ret) {
> - pr_err("regcomp failed\n");
> - return NULL;
> - }
> - }
> - sorted = true;
> - }
> -
> - if (!strcmp(norm_arch, "x86")) {
> - instructions = instructions_x86;
> - nmemb = ARRAY_SIZE(instructions_x86);
> - } else if (!strcmp(norm_arch, "arm")) {
> + if (!strcmp(norm_arch, "x86"))
> + return ins__find_x86(name);
> + else if (!strcmp(norm_arch, "arm"))
> return ins__find_arm(name);
> - } else if (!strcmp(norm_arch, "powerpc")) {
> + else if (!strcmp(norm_arch, "powerpc"))
> return ins__find_powerpc(name);
> - } else {
> + else
> pr_err("perf annotate not supported by %s arch\n", norm_arch);
> - return NULL;
> - }
>
> - return bsearch(name, instructions, nmemb, sizeof(struct ins),
> - ins__key_cmp);
> + return NULL;
> }
>
> int symbol__alloc_hist(struct symbol *sym)
> diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
> index 7ba3579..91b705a 100644
> --- a/tools/perf/util/annotate.h
> +++ b/tools/perf/util/annotate.h
> @@ -42,11 +42,30 @@ struct ins_ops {
> struct ins_operands *ops);
> };
>
> +/* Defined in annotate.c */
> +extern struct ins_ops mov_ops;
> +extern struct ins_ops call_ops;
> +extern struct ins_ops dec_ops;
> +extern struct ins_ops jump_ops;
> +extern struct ins_ops lock_ops;
> +extern struct ins_ops nop_ops;
> +extern struct ins_ops ret_ops;
> +
> struct ins {
> const char *name;
> struct ins_ops *ops;
> };
>
> +struct instructions_arch {
> + struct ins *ins;
> + struct list_head list;
> +};
> +
> +struct ins *list_add__ins_arch(struct instructions_arch *head,
> + const char *name, struct ins_ops *ops);
> +struct ins *list_search__ins_arch(struct instructions_arch *head,
> + const char *name);
> +
> bool ins__is_jump(const struct ins *ins);
> bool ins__is_call(const struct ins *ins);
> bool ins__is_ret(const struct ins *ins);
> @@ -210,4 +229,8 @@ static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused,
>
> extern const char *disassembler_style;
>
> +struct ins *ins__find_x86(const char *name);
> +struct ins *ins__find_arm(const char *name);
> +struct ins *ins__find_powerpc(const char *name);
> +
> #endif /* __PERF_ANNOTATE_H */
> diff --git a/tools/perf/util/annotate/Build b/tools/perf/util/annotate/Build
> new file mode 100644
> index 0000000..ed87f1c
> --- /dev/null
> +++ b/tools/perf/util/annotate/Build
> @@ -0,0 +1,3 @@
> +libperf-y += x86.o
> +libperf-y += arm.o
> +libperf-y += powerpc.o
> diff --git a/tools/perf/util/annotate/arm.c b/tools/perf/util/annotate/arm.c
> new file mode 100644
> index 0000000..6bfc866
> --- /dev/null
> +++ b/tools/perf/util/annotate/arm.c
> @@ -0,0 +1,50 @@
> +#include "../annotate.h"
> +
> +static regex_t arm_call_insn, arm_jump_insn;
> +
> +#define ARM_CONDS "(cc|cs|eq|ge|gt|hi|le|ls|lt|mi|ne|pl|vc|vs)"
> +
> +static __attribute__((constructor)) void init_regex(void)
> +{
> + int ret;
> +
> + ret = regcomp(&arm_call_insn, "^blx?" ARM_CONDS "?$", REG_EXTENDED);
> + ret |= regcomp(&arm_jump_insn, "^bx?" ARM_CONDS "?$", REG_EXTENDED);
> +
> + if (ret)
> + pr_err("regcomp failed\n");
> +}
> +
> +struct ins *ins__find_arm(const char *name)
> +{
> + struct ins *ins;
> + struct ins_ops *ops = &mov_ops;
> + regmatch_t match[2];
> + int ret;
> + static struct instructions_arch head = {
> + .list = LIST_HEAD_INIT(head.list),
> + };
> +
> + /*
> + * Return if we already have object of 'struct ins' for this instruction
> + */
> + ins = list_search__ins_arch(&head, name);
> + if (ins)
> + return ins;
> +
> + ret = regexec(&arm_call_insn, name, 2, match, 0);
> + if (!ret) {
> + ops = &call_ops;
> + } else {
> + ret = regexec(&arm_jump_insn, name, 2, match, 0);
> + if (!ret)
> + ops = &jump_ops;
> + }
> +
> + /*
> + * Add instruction to list so next time no need to
> + * allocate memory for it.
> + */
> + return list_add__ins_arch(&head, name, ops);
> +
> +}
> diff --git a/tools/perf/util/annotate/powerpc.c b/tools/perf/util/annotate/powerpc.c
> new file mode 100644
> index 0000000..6088ce2
> --- /dev/null
> +++ b/tools/perf/util/annotate/powerpc.c
> @@ -0,0 +1,63 @@
> +#include "../annotate.h"
> +
> +struct ins *ins__find_powerpc(const char *name)
> +{
> + int i;
> + struct ins *ins;
> + struct ins_ops *ops;
> + static struct instructions_arch head = {
> + .list = LIST_HEAD_INIT(head.list),
> + };
> +
> + /*
> + * - 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;
> +
> + /*
> + * Return if we already have object of 'struct ins' for this instruction
> + */
> + ins = list_search__ins_arch(&head, name);
> + if (ins)
> + return ins;
> +
> + 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;
> +
> + /*
> + * Add instruction to list so next time no need to
> + * allocate memory for it.
> + */
> + return list_add__ins_arch(&head, name, ops);
> +}
> diff --git a/tools/perf/util/annotate/x86.c b/tools/perf/util/annotate/x86.c
> new file mode 100644
> index 0000000..b519197
> --- /dev/null
> +++ b/tools/perf/util/annotate/x86.c
> @@ -0,0 +1,107 @@
> +#include "../annotate.h"
> +
> +static struct ins instructions[] = {
> + { .name = "add", .ops = &mov_ops, },
> + { .name = "addl", .ops = &mov_ops, },
> + { .name = "addq", .ops = &mov_ops, },
> + { .name = "addw", .ops = &mov_ops, },
> + { .name = "and", .ops = &mov_ops, },
> + { .name = "bts", .ops = &mov_ops, },
> + { .name = "call", .ops = &call_ops, },
> + { .name = "callq", .ops = &call_ops, },
> + { .name = "cmp", .ops = &mov_ops, },
> + { .name = "cmpb", .ops = &mov_ops, },
> + { .name = "cmpl", .ops = &mov_ops, },
> + { .name = "cmpq", .ops = &mov_ops, },
> + { .name = "cmpw", .ops = &mov_ops, },
> + { .name = "cmpxch", .ops = &mov_ops, },
> + { .name = "dec", .ops = &dec_ops, },
> + { .name = "decl", .ops = &dec_ops, },
> + { .name = "imul", .ops = &mov_ops, },
> + { .name = "inc", .ops = &dec_ops, },
> + { .name = "incl", .ops = &dec_ops, },
> + { .name = "ja", .ops = &jump_ops, },
> + { .name = "jae", .ops = &jump_ops, },
> + { .name = "jb", .ops = &jump_ops, },
> + { .name = "jbe", .ops = &jump_ops, },
> + { .name = "jc", .ops = &jump_ops, },
> + { .name = "jcxz", .ops = &jump_ops, },
> + { .name = "je", .ops = &jump_ops, },
> + { .name = "jecxz", .ops = &jump_ops, },
> + { .name = "jg", .ops = &jump_ops, },
> + { .name = "jge", .ops = &jump_ops, },
> + { .name = "jl", .ops = &jump_ops, },
> + { .name = "jle", .ops = &jump_ops, },
> + { .name = "jmp", .ops = &jump_ops, },
> + { .name = "jmpq", .ops = &jump_ops, },
> + { .name = "jna", .ops = &jump_ops, },
> + { .name = "jnae", .ops = &jump_ops, },
> + { .name = "jnb", .ops = &jump_ops, },
> + { .name = "jnbe", .ops = &jump_ops, },
> + { .name = "jnc", .ops = &jump_ops, },
> + { .name = "jne", .ops = &jump_ops, },
> + { .name = "jng", .ops = &jump_ops, },
> + { .name = "jnge", .ops = &jump_ops, },
> + { .name = "jnl", .ops = &jump_ops, },
> + { .name = "jnle", .ops = &jump_ops, },
> + { .name = "jno", .ops = &jump_ops, },
> + { .name = "jnp", .ops = &jump_ops, },
> + { .name = "jns", .ops = &jump_ops, },
> + { .name = "jnz", .ops = &jump_ops, },
> + { .name = "jo", .ops = &jump_ops, },
> + { .name = "jp", .ops = &jump_ops, },
> + { .name = "jpe", .ops = &jump_ops, },
> + { .name = "jpo", .ops = &jump_ops, },
> + { .name = "jrcxz", .ops = &jump_ops, },
> + { .name = "js", .ops = &jump_ops, },
> + { .name = "jz", .ops = &jump_ops, },
> + { .name = "lea", .ops = &mov_ops, },
> + { .name = "lock", .ops = &lock_ops, },
> + { .name = "mov", .ops = &mov_ops, },
> + { .name = "movb", .ops = &mov_ops, },
> + { .name = "movdqa", .ops = &mov_ops, },
> + { .name = "movl", .ops = &mov_ops, },
> + { .name = "movq", .ops = &mov_ops, },
> + { .name = "movslq", .ops = &mov_ops, },
> + { .name = "movzbl", .ops = &mov_ops, },
> + { .name = "movzwl", .ops = &mov_ops, },
> + { .name = "nop", .ops = &nop_ops, },
> + { .name = "nopl", .ops = &nop_ops, },
> + { .name = "nopw", .ops = &nop_ops, },
> + { .name = "or", .ops = &mov_ops, },
> + { .name = "orl", .ops = &mov_ops, },
> + { .name = "test", .ops = &mov_ops, },
> + { .name = "testb", .ops = &mov_ops, },
> + { .name = "testl", .ops = &mov_ops, },
> + { .name = "xadd", .ops = &mov_ops, },
> + { .name = "xbeginl", .ops = &jump_ops, },
> + { .name = "xbeginq", .ops = &jump_ops, },
> + { .name = "retq", .ops = &ret_ops, },
> +};
> +
> +static int ins__cmp(const void *a, const void *b)
> +{
> + const struct ins *ia = a;
> + const struct ins *ib = b;
> +
> + return strcmp(ia->name, ib->name);
> +}
> +
> +static __attribute__((constructor)) void ins__sort(void)
> +{
> + qsort(instructions, ARRAY_SIZE(instructions), sizeof(struct ins),
> + ins__cmp);
> +}
> +
> +static int ins__key_cmp(const void *name, const void *insp)
> +{
> + const struct ins *ins = insp;
> +
> + return strcmp(name, ins->name);
> +}
> +
> +struct ins *ins__find_x86(const char *name)
> +{
> + return bsearch(name, instructions, ARRAY_SIZE(instructions),
> + sizeof(struct ins), ins__key_cmp);
> +}
> --
> 2.5.5

2016-10-10 16:39:38

by Naveen N. Rao

[permalink] [raw]
Subject: Re: [PATCH] perf annotate: Cleanup arch specific stuff

On 2016/10/10 01:24PM, Arnaldo Carvalho de Melo wrote:
> Em Mon, Oct 10, 2016 at 07:29:02PM +0530, Ravi Bangoria escreveu:
> > Move arch specific stuff from util/annotate.c to their respective
> > files in util/annotate directory.
> >
> > No functionality changes.
> >
> > Signed-off-by: Ravi Bangoria <[email protected]>
> > ---
> > tools/perf/util/Build | 1 +
> > tools/perf/util/annotate.c | 259 +++----------------------------------
> > tools/perf/util/annotate.h | 23 ++++
> > tools/perf/util/annotate/Build | 3 +
> > tools/perf/util/annotate/arm.c | 50 +++++++
> > tools/perf/util/annotate/powerpc.c | 63 +++++++++
> > tools/perf/util/annotate/x86.c | 107 +++++++++++++++
>
> We already have a per arch area: tools/perf/arch/

I think this was done to support cross-arch annotate similar to the
remote unwind support with util/libunwind/

- Naveen

2016-10-10 16:56:22

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: [PATCH] perf annotate: Cleanup arch specific stuff

Em Mon, Oct 10, 2016 at 10:19:28PM +0530, Ravi Bangoria escreveu:
>
>
> On Monday 10 October 2016 10:09 PM, Naveen N. Rao wrote:
> > On 2016/10/10 01:24PM, Arnaldo Carvalho de Melo wrote:
> >> Em Mon, Oct 10, 2016 at 07:29:02PM +0530, Ravi Bangoria escreveu:
> >>> Move arch specific stuff from util/annotate.c to their respective
> >>> files in util/annotate directory.
> >>>
> >>> No functionality changes.
> >>>
> >>> Signed-off-by: Ravi Bangoria <[email protected]>
> >>> ---
> >>> tools/perf/util/Build | 1 +
> >>> tools/perf/util/annotate.c | 259 +++----------------------------------
> >>> tools/perf/util/annotate.h | 23 ++++
> >>> tools/perf/util/annotate/Build | 3 +
> >>> tools/perf/util/annotate/arm.c | 50 +++++++
> >>> tools/perf/util/annotate/powerpc.c | 63 +++++++++
> >>> tools/perf/util/annotate/x86.c | 107 +++++++++++++++
> >> We already have a per arch area: tools/perf/arch/
> > I think this was done to support cross-arch annotate similar to the
> > remote unwind support with util/libunwind/
>
> Yes, because tools/perf/arch/ will only include host arch code.

Ok, thanks for clarifying.

- Arnaldo

2016-10-10 20:24:55

by Ravi Bangoria

[permalink] [raw]
Subject: Re: [PATCH] perf annotate: Cleanup arch specific stuff



On Monday 10 October 2016 10:09 PM, Naveen N. Rao wrote:
> On 2016/10/10 01:24PM, Arnaldo Carvalho de Melo wrote:
>> Em Mon, Oct 10, 2016 at 07:29:02PM +0530, Ravi Bangoria escreveu:
>>> Move arch specific stuff from util/annotate.c to their respective
>>> files in util/annotate directory.
>>>
>>> No functionality changes.
>>>
>>> Signed-off-by: Ravi Bangoria <[email protected]>
>>> ---
>>> tools/perf/util/Build | 1 +
>>> tools/perf/util/annotate.c | 259 +++----------------------------------
>>> tools/perf/util/annotate.h | 23 ++++
>>> tools/perf/util/annotate/Build | 3 +
>>> tools/perf/util/annotate/arm.c | 50 +++++++
>>> tools/perf/util/annotate/powerpc.c | 63 +++++++++
>>> tools/perf/util/annotate/x86.c | 107 +++++++++++++++
>> We already have a per arch area: tools/perf/arch/
> I think this was done to support cross-arch annotate similar to the
> remote unwind support with util/libunwind/

Yes, because tools/perf/arch/ will only include host arch code.

-Ravi

> - Naveen
>

2016-10-17 14:44:02

by Ravi Bangoria

[permalink] [raw]
Subject: Re: [PATCH] perf annotate: Cleanup arch specific stuff



On Monday 10 October 2016 10:26 PM, Arnaldo Carvalho de Melo wrote:
> Em Mon, Oct 10, 2016 at 10:19:28PM +0530, Ravi Bangoria escreveu:
>>
>> On Monday 10 October 2016 10:09 PM, Naveen N. Rao wrote:
>>> On 2016/10/10 01:24PM, Arnaldo Carvalho de Melo wrote:
>>>> Em Mon, Oct 10, 2016 at 07:29:02PM +0530, Ravi Bangoria escreveu:
>>>>> Move arch specific stuff from util/annotate.c to their respective
>>>>> files in util/annotate directory.
>>>>>
>>>>> No functionality changes.
>>>>>
>>>>> Signed-off-by: Ravi Bangoria <[email protected]>
>>>>> ---
>>>>> tools/perf/util/Build | 1 +
>>>>> tools/perf/util/annotate.c | 259 +++----------------------------------
>>>>> tools/perf/util/annotate.h | 23 ++++
>>>>> tools/perf/util/annotate/Build | 3 +
>>>>> tools/perf/util/annotate/arm.c | 50 +++++++
>>>>> tools/perf/util/annotate/powerpc.c | 63 +++++++++
>>>>> tools/perf/util/annotate/x86.c | 107 +++++++++++++++
>>>> We already have a per arch area: tools/perf/arch/
>>> I think this was done to support cross-arch annotate similar to the
>>> remote unwind support with util/libunwind/
>> Yes, because tools/perf/arch/ will only include host arch code.
> Ok, thanks for clarifying.

Hi Arnaldo,

Are you ok with this patchset. Please let me know if you want to respin it.

-Ravi

> - Arnaldo
>

2016-10-17 14:46:16

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: [PATCH] perf annotate: Cleanup arch specific stuff

Em Mon, Oct 17, 2016 at 08:13:38PM +0530, Ravi Bangoria escreveu:
>
>
> On Monday 10 October 2016 10:26 PM, Arnaldo Carvalho de Melo wrote:
> > Em Mon, Oct 10, 2016 at 10:19:28PM +0530, Ravi Bangoria escreveu:
> >>
> >> On Monday 10 October 2016 10:09 PM, Naveen N. Rao wrote:
> >>> On 2016/10/10 01:24PM, Arnaldo Carvalho de Melo wrote:
> >>>> Em Mon, Oct 10, 2016 at 07:29:02PM +0530, Ravi Bangoria escreveu:
> >>>>> Move arch specific stuff from util/annotate.c to their respective
> >>>>> files in util/annotate directory.
> >>>>>
> >>>>> No functionality changes.
> >>>>>
> >>>>> Signed-off-by: Ravi Bangoria <[email protected]>
> >>>>> ---
> >>>>> tools/perf/util/Build | 1 +
> >>>>> tools/perf/util/annotate.c | 259 +++----------------------------------
> >>>>> tools/perf/util/annotate.h | 23 ++++
> >>>>> tools/perf/util/annotate/Build | 3 +
> >>>>> tools/perf/util/annotate/arm.c | 50 +++++++
> >>>>> tools/perf/util/annotate/powerpc.c | 63 +++++++++
> >>>>> tools/perf/util/annotate/x86.c | 107 +++++++++++++++
> >>>> We already have a per arch area: tools/perf/arch/
> >>> I think this was done to support cross-arch annotate similar to the
> >>> remote unwind support with util/libunwind/
> >> Yes, because tools/perf/arch/ will only include host arch code.
> > Ok, thanks for clarifying.
>
> Hi Arnaldo,
>
> Are you ok with this patchset. Please let me know if you want to respin it.

We're in the merge window, and I'm having to deal with other patches
requiring more work than I was expecting to invest on them, so no time
to revisit this, sorry, but I have not forgot about it, will get back to
it as time permits,

Thanks,

- Arnaldo

> -Ravi
>
> > - Arnaldo
> >

2016-10-17 14:49:52

by Ravi Bangoria

[permalink] [raw]
Subject: Re: [PATCH] perf annotate: Cleanup arch specific stuff



On Monday 17 October 2016 08:15 PM, Arnaldo Carvalho de Melo wrote:
> Em Mon, Oct 17, 2016 at 08:13:38PM +0530, Ravi Bangoria escreveu:
>>
>> On Monday 10 October 2016 10:26 PM, Arnaldo Carvalho de Melo wrote:
>>> Em Mon, Oct 10, 2016 at 10:19:28PM +0530, Ravi Bangoria escreveu:
>>>> On Monday 10 October 2016 10:09 PM, Naveen N. Rao wrote:
>>>>> On 2016/10/10 01:24PM, Arnaldo Carvalho de Melo wrote:
>>>>>> Em Mon, Oct 10, 2016 at 07:29:02PM +0530, Ravi Bangoria escreveu:
>>>>>>> Move arch specific stuff from util/annotate.c to their respective
>>>>>>> files in util/annotate directory.
>>>>>>>
>>>>>>> No functionality changes.
>>>>>>>
>>>>>>> Signed-off-by: Ravi Bangoria <[email protected]>
>>>>>>> ---
>>>>>>> tools/perf/util/Build | 1 +
>>>>>>> tools/perf/util/annotate.c | 259 +++----------------------------------
>>>>>>> tools/perf/util/annotate.h | 23 ++++
>>>>>>> tools/perf/util/annotate/Build | 3 +
>>>>>>> tools/perf/util/annotate/arm.c | 50 +++++++
>>>>>>> tools/perf/util/annotate/powerpc.c | 63 +++++++++
>>>>>>> tools/perf/util/annotate/x86.c | 107 +++++++++++++++
>>>>>> We already have a per arch area: tools/perf/arch/
>>>>> I think this was done to support cross-arch annotate similar to the
>>>>> remote unwind support with util/libunwind/
>>>> Yes, because tools/perf/arch/ will only include host arch code.
>>> Ok, thanks for clarifying.
>> Hi Arnaldo,
>>
>> Are you ok with this patchset. Please let me know if you want to respin it.
> We're in the merge window, and I'm having to deal with other patches
> requiring more work than I was expecting to invest on them, so no time
> to revisit this, sorry, but I have not forgot about it, will get back to
> it as time permits,

Sure, no issues. :)

-Ravi