Re: [PATCH v6 3/7] perf annotate: Add support for powerpc
From: Arnaldo Carvalho de Melo <acme@kernel.org>
Date: 2016-09-19 15:26:16
Also in:
lkml
Em Fri, Aug 19, 2016 at 06:29:34PM +0530, Ravi Bangoria escreveu:
From: "Naveen N. Rao" <redacted>
+static struct ins *ins__find_powerpc(const char *name)
+{
+ int i;
+ struct ins *ins;
+ struct ins_ops *ops;
+ static struct instructions_powerpc head;
+ static bool list_initialized;
+
+ /*
+ * - 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;
+
+ if (!list_initialized) {
+ INIT_LIST_HEAD(&head.list);
+ list_initialized = true;
+ }
Why not ditch list_initialized and instead just declare the list as:
static struct instructions_powerpc head = {
.list = LIST_HEAD_INIT(head.list),
}
Just like the kernel sources do? See for instance:
net/core/net_namespace.c
struct net init_net = {
.dev_base_head = LIST_HEAD_INIT(init_net.dev_base_head),
};
quoted hunk ↗ jump to hunk
+ + /* + * Return if we already have object of 'struct ins' for this instruction + */ + ins = list_search__ins_powerpc(&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_powerpc(&head, name, ops); +} + static void ins__sort(struct ins *instructions, int nmemb) { qsort(instructions, nmemb, sizeof(struct ins), ins__cmp);@@ -585,6 +699,8 @@ static struct ins *ins__find(const char *name, const char *norm_arch) } else if (!strcmp(norm_arch, NORM_ARM)) { instructions = instructions_arm; nmemb = ARRAY_SIZE(instructions_arm); + } else if (!strcmp(norm_arch, NORM_POWERPC)) { + return ins__find_powerpc(name); } else { pr_err("perf annotate not supported by %s arch\n", norm_arch); return NULL;-- 2.5.5