* [PATCH] perf: Add Sparc annotate support.
@ 2018-10-17 3:55 David Miller
2018-10-17 12:39 ` Arnaldo Carvalho de Melo
2018-10-26 7:28 ` [tip:perf/urgent] perf annotate: Add Sparc support tip-bot for David Miller
0 siblings, 2 replies; 4+ messages in thread
From: David Miller @ 2018-10-17 3:55 UTC (permalink / raw)
To: acme; +Cc: linux-kernel
Signed-off-by: David S. Miller <davem@davemloft.net>
---
tools/perf/arch/sparc/annotate/instructions.c | 169 ++++++++++++++++++
tools/perf/util/annotate.c | 8 +
2 files changed, 177 insertions(+)
create mode 100644 tools/perf/arch/sparc/annotate/instructions.c
diff --git a/tools/perf/arch/sparc/annotate/instructions.c b/tools/perf/arch/sparc/annotate/instructions.c
new file mode 100644
index 000000000000..2614c010c235
--- /dev/null
+++ b/tools/perf/arch/sparc/annotate/instructions.c
@@ -0,0 +1,169 @@
+// SPDX-License-Identifier: GPL-2.0
+
+static int is_branch_cond(const char *cond)
+{
+ if (cond[0] == '\0')
+ return 1;
+
+ if (cond[0] == 'a' && cond[1] == '\0')
+ return 1;
+
+ if (cond[0] == 'c' &&
+ (cond[1] == 'c' || cond[1] == 's') &&
+ cond[2] == '\0')
+ return 1;
+
+ if (cond[0] == 'e' &&
+ (cond[1] == '\0' ||
+ (cond[1] == 'q' && cond[2] == '\0')))
+ return 1;
+
+ if (cond[0] == 'g' &&
+ (cond[1] == '\0' ||
+ (cond[1] == 't' && cond[2] == '\0') ||
+ (cond[1] == 'e' && cond[2] == '\0') ||
+ (cond[1] == 'e' && cond[2] == 'u' && cond[3] == '\0')))
+ return 1;
+
+ if (cond[0] == 'l' &&
+ (cond[1] == '\0' ||
+ (cond[1] == 't' && cond[2] == '\0') ||
+ (cond[1] == 'u' && cond[2] == '\0') ||
+ (cond[1] == 'e' && cond[2] == '\0') ||
+ (cond[1] == 'e' && cond[2] == 'u' && cond[3] == '\0')))
+ return 1;
+
+ if (cond[0] == 'n' &&
+ (cond[1] == '\0' ||
+ (cond[1] == 'e' && cond[2] == '\0') ||
+ (cond[1] == 'z' && cond[2] == '\0') ||
+ (cond[1] == 'e' && cond[2] == 'g' && cond[3] == '\0')))
+ return 1;
+
+ if (cond[0] == 'b' &&
+ cond[1] == 'p' &&
+ cond[2] == 'o' &&
+ cond[3] == 's' &&
+ cond[4] == '\0')
+ return 1;
+
+ if (cond[0] == 'v' &&
+ (cond[1] == 'c' || cond[1] == 's') &&
+ cond[2] == '\0')
+ return 1;
+
+ if (cond[0] == 'b' &&
+ cond[1] == 'z' &&
+ cond[2] == '\0')
+ return 1;
+
+ return 0;
+}
+
+static int is_branch_reg_cond(const char *cond)
+{
+ if ((cond[0] == 'n' || cond[0] == 'l') &&
+ cond[1] == 'z' &&
+ cond[2] == '\0')
+ return 1;
+
+ if (cond[0] == 'z' &&
+ cond[1] == '\0')
+ return 1;
+
+ if ((cond[0] == 'g' || cond[0] == 'l') &&
+ cond[1] == 'e' &&
+ cond[2] == 'z' &&
+ cond[3] == '\0')
+ return 1;
+
+ if (cond[0] == 'g' &&
+ cond[1] == 'z' &&
+ cond[2] == '\0')
+ return 1;
+
+ return 0;
+}
+
+static int is_branch_float_cond(const char *cond)
+{
+ if (cond[0] == '\0')
+ return 1;
+
+ if ((cond[0] == 'a' || cond[0] == 'e' ||
+ cond[0] == 'z' || cond[0] == 'g' ||
+ cond[0] == 'l' || cond[0] == 'n' ||
+ cond[0] == 'o' || cond[0] == 'u') &&
+ cond[1] == '\0')
+ return 1;
+
+ if (((cond[0] == 'g' && cond[1] == 'e') ||
+ (cond[0] == 'l' && (cond[1] == 'e' ||
+ cond[1] == 'g')) ||
+ (cond[0] == 'n' && (cond[1] == 'e' ||
+ cond[1] == 'z')) ||
+ (cond[0] == 'u' && (cond[1] == 'e' ||
+ cond[1] == 'g' ||
+ cond[1] == 'l'))) &&
+ cond[2] == '\0')
+ return 1;
+
+ if (cond[0] == 'u' &&
+ (cond[1] == 'g' || cond[1] == 'l') &&
+ cond[2] == 'e' &&
+ cond[3] == '\0')
+ return 1;
+
+ return 0;
+}
+
+static struct ins_ops *sparc__associate_instruction_ops(struct arch *arch, const char *name)
+{
+ struct ins_ops *ops = NULL;
+
+ if (!strcmp(name, "call") ||
+ !strcmp(name, "jmp") ||
+ !strcmp(name, "jmpl")) {
+ ops = &call_ops;
+ } else if (!strcmp(name, "ret") ||
+ !strcmp(name, "retl") ||
+ !strcmp(name, "return")) {
+ ops = &ret_ops;
+ } else if (!strcmp(name, "mov")) {
+ ops = &mov_ops;
+ } else {
+ if (name[0] == 'c' &&
+ (name[1] == 'w' || name[1] == 'x'))
+ name += 2;
+
+ if (name[0] == 'b') {
+ const char *cond = name + 1;
+
+ if (cond[0] == 'r') {
+ if (is_branch_reg_cond(cond + 1))
+ ops = &jump_ops;
+ } else if (is_branch_cond(cond)) {
+ ops = &jump_ops;
+ }
+ } else if (name[0] == 'f' && name[1] == 'b') {
+ if (is_branch_float_cond(name + 2))
+ ops = &jump_ops;
+ }
+ }
+
+ if (ops)
+ arch__associate_ins_ops(arch, name, ops);
+
+ return ops;
+}
+
+static int sparc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
+{
+ if (!arch->initialized) {
+ arch->initialized = true;
+ arch->associate_instruction_ops = sparc__associate_instruction_ops;
+ arch->objdump.comment_char = '#';
+ }
+
+ return 0;
+}
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 28cd6a17491b..6936daf89ddd 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -139,6 +139,7 @@ static int arch__associate_ins_ops(struct arch* arch, const char *name, struct i
#include "arch/x86/annotate/instructions.c"
#include "arch/powerpc/annotate/instructions.c"
#include "arch/s390/annotate/instructions.c"
+#include "arch/sparc/annotate/instructions.c"
static struct arch architectures[] = {
{
@@ -170,6 +171,13 @@ static struct arch architectures[] = {
.comment_char = '#',
},
},
+ {
+ .name = "sparc",
+ .init = sparc__annotate_init,
+ .objdump = {
+ .comment_char = '#',
+ },
+ },
};
static void ins__delete(struct ins_operands *ops)
--
2.19.1.328.g5a0cc8aca
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] perf: Add Sparc annotate support.
2018-10-17 3:55 [PATCH] perf: Add Sparc annotate support David Miller
@ 2018-10-17 12:39 ` Arnaldo Carvalho de Melo
2018-10-17 16:42 ` David Miller
2018-10-26 7:28 ` [tip:perf/urgent] perf annotate: Add Sparc support tip-bot for David Miller
1 sibling, 1 reply; 4+ messages in thread
From: Arnaldo Carvalho de Melo @ 2018-10-17 12:39 UTC (permalink / raw)
To: David Miller; +Cc: linux-kernel
Em Tue, Oct 16, 2018 at 08:55:55PM -0700, David Miller escreveu:
Great!
Could you try something like:
# perf record some_workload
# perf annotate --stdio2 hot_function
So that we can see this thing in action, i.e. sparc assembly annotated?
:-)
With 'perf annotate --tui hot_function' or 'perf top' 'A' you can
navigate, but for showing it in action in a git changelog comment
example --stdio is more convenient :-)
- Arnaldo
> Signed-off-by: David S. Miller <davem@davemloft.net>
> ---
> tools/perf/arch/sparc/annotate/instructions.c | 169 ++++++++++++++++++
> tools/perf/util/annotate.c | 8 +
> 2 files changed, 177 insertions(+)
> create mode 100644 tools/perf/arch/sparc/annotate/instructions.c
>
> diff --git a/tools/perf/arch/sparc/annotate/instructions.c b/tools/perf/arch/sparc/annotate/instructions.c
> new file mode 100644
> index 000000000000..2614c010c235
> --- /dev/null
> +++ b/tools/perf/arch/sparc/annotate/instructions.c
> @@ -0,0 +1,169 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +static int is_branch_cond(const char *cond)
> +{
> + if (cond[0] == '\0')
> + return 1;
> +
> + if (cond[0] == 'a' && cond[1] == '\0')
> + return 1;
> +
> + if (cond[0] == 'c' &&
> + (cond[1] == 'c' || cond[1] == 's') &&
> + cond[2] == '\0')
> + return 1;
> +
> + if (cond[0] == 'e' &&
> + (cond[1] == '\0' ||
> + (cond[1] == 'q' && cond[2] == '\0')))
> + return 1;
> +
> + if (cond[0] == 'g' &&
> + (cond[1] == '\0' ||
> + (cond[1] == 't' && cond[2] == '\0') ||
> + (cond[1] == 'e' && cond[2] == '\0') ||
> + (cond[1] == 'e' && cond[2] == 'u' && cond[3] == '\0')))
> + return 1;
> +
> + if (cond[0] == 'l' &&
> + (cond[1] == '\0' ||
> + (cond[1] == 't' && cond[2] == '\0') ||
> + (cond[1] == 'u' && cond[2] == '\0') ||
> + (cond[1] == 'e' && cond[2] == '\0') ||
> + (cond[1] == 'e' && cond[2] == 'u' && cond[3] == '\0')))
> + return 1;
> +
> + if (cond[0] == 'n' &&
> + (cond[1] == '\0' ||
> + (cond[1] == 'e' && cond[2] == '\0') ||
> + (cond[1] == 'z' && cond[2] == '\0') ||
> + (cond[1] == 'e' && cond[2] == 'g' && cond[3] == '\0')))
> + return 1;
> +
> + if (cond[0] == 'b' &&
> + cond[1] == 'p' &&
> + cond[2] == 'o' &&
> + cond[3] == 's' &&
> + cond[4] == '\0')
> + return 1;
> +
> + if (cond[0] == 'v' &&
> + (cond[1] == 'c' || cond[1] == 's') &&
> + cond[2] == '\0')
> + return 1;
> +
> + if (cond[0] == 'b' &&
> + cond[1] == 'z' &&
> + cond[2] == '\0')
> + return 1;
> +
> + return 0;
> +}
> +
> +static int is_branch_reg_cond(const char *cond)
> +{
> + if ((cond[0] == 'n' || cond[0] == 'l') &&
> + cond[1] == 'z' &&
> + cond[2] == '\0')
> + return 1;
> +
> + if (cond[0] == 'z' &&
> + cond[1] == '\0')
> + return 1;
> +
> + if ((cond[0] == 'g' || cond[0] == 'l') &&
> + cond[1] == 'e' &&
> + cond[2] == 'z' &&
> + cond[3] == '\0')
> + return 1;
> +
> + if (cond[0] == 'g' &&
> + cond[1] == 'z' &&
> + cond[2] == '\0')
> + return 1;
> +
> + return 0;
> +}
> +
> +static int is_branch_float_cond(const char *cond)
> +{
> + if (cond[0] == '\0')
> + return 1;
> +
> + if ((cond[0] == 'a' || cond[0] == 'e' ||
> + cond[0] == 'z' || cond[0] == 'g' ||
> + cond[0] == 'l' || cond[0] == 'n' ||
> + cond[0] == 'o' || cond[0] == 'u') &&
> + cond[1] == '\0')
> + return 1;
> +
> + if (((cond[0] == 'g' && cond[1] == 'e') ||
> + (cond[0] == 'l' && (cond[1] == 'e' ||
> + cond[1] == 'g')) ||
> + (cond[0] == 'n' && (cond[1] == 'e' ||
> + cond[1] == 'z')) ||
> + (cond[0] == 'u' && (cond[1] == 'e' ||
> + cond[1] == 'g' ||
> + cond[1] == 'l'))) &&
> + cond[2] == '\0')
> + return 1;
> +
> + if (cond[0] == 'u' &&
> + (cond[1] == 'g' || cond[1] == 'l') &&
> + cond[2] == 'e' &&
> + cond[3] == '\0')
> + return 1;
> +
> + return 0;
> +}
> +
> +static struct ins_ops *sparc__associate_instruction_ops(struct arch *arch, const char *name)
> +{
> + struct ins_ops *ops = NULL;
> +
> + if (!strcmp(name, "call") ||
> + !strcmp(name, "jmp") ||
> + !strcmp(name, "jmpl")) {
> + ops = &call_ops;
> + } else if (!strcmp(name, "ret") ||
> + !strcmp(name, "retl") ||
> + !strcmp(name, "return")) {
> + ops = &ret_ops;
> + } else if (!strcmp(name, "mov")) {
> + ops = &mov_ops;
> + } else {
> + if (name[0] == 'c' &&
> + (name[1] == 'w' || name[1] == 'x'))
> + name += 2;
> +
> + if (name[0] == 'b') {
> + const char *cond = name + 1;
> +
> + if (cond[0] == 'r') {
> + if (is_branch_reg_cond(cond + 1))
> + ops = &jump_ops;
> + } else if (is_branch_cond(cond)) {
> + ops = &jump_ops;
> + }
> + } else if (name[0] == 'f' && name[1] == 'b') {
> + if (is_branch_float_cond(name + 2))
> + ops = &jump_ops;
> + }
> + }
> +
> + if (ops)
> + arch__associate_ins_ops(arch, name, ops);
> +
> + return ops;
> +}
> +
> +static int sparc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
> +{
> + if (!arch->initialized) {
> + arch->initialized = true;
> + arch->associate_instruction_ops = sparc__associate_instruction_ops;
> + arch->objdump.comment_char = '#';
> + }
> +
> + return 0;
> +}
> diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
> index 28cd6a17491b..6936daf89ddd 100644
> --- a/tools/perf/util/annotate.c
> +++ b/tools/perf/util/annotate.c
> @@ -139,6 +139,7 @@ static int arch__associate_ins_ops(struct arch* arch, const char *name, struct i
> #include "arch/x86/annotate/instructions.c"
> #include "arch/powerpc/annotate/instructions.c"
> #include "arch/s390/annotate/instructions.c"
> +#include "arch/sparc/annotate/instructions.c"
>
> static struct arch architectures[] = {
> {
> @@ -170,6 +171,13 @@ static struct arch architectures[] = {
> .comment_char = '#',
> },
> },
> + {
> + .name = "sparc",
> + .init = sparc__annotate_init,
> + .objdump = {
> + .comment_char = '#',
> + },
> + },
> };
>
> static void ins__delete(struct ins_operands *ops)
> --
> 2.19.1.328.g5a0cc8aca
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] perf: Add Sparc annotate support.
2018-10-17 12:39 ` Arnaldo Carvalho de Melo
@ 2018-10-17 16:42 ` David Miller
0 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2018-10-17 16:42 UTC (permalink / raw)
To: acme; +Cc: linux-kernel
From: Arnaldo Carvalho de Melo <acme@redhat.com>
Date: Wed, 17 Oct 2018 09:39:02 -0300
> Em Tue, Oct 16, 2018 at 08:55:55PM -0700, David Miller escreveu:
>
> Great!
>
> Could you try something like:
>
> # perf record some_workload
> # perf annotate --stdio2 hot_function
>
> So that we can see this thing in action, i.e. sparc assembly annotated?
> :-)
>
> With 'perf annotate --tui hot_function' or 'perf top' 'A' you can
> navigate, but for showing it in action in a git changelog comment
> example --stdio is more convenient :-)
Sure :-)
This is run on __gettimeofday when running perf record on your "gtod"
test. (Still working on getting glibc to use the VDSO properly on
sparc :-( )
Samples: 7K of event 'cycles:ppp', 4000 Hz, Event count (approx.): 3086733887
__gettimeofday /lib32/libc-2.27.so [Percent: local period]
Percent│
│
│
│ Disassembly of section .text:
│
│ 000a6fa0 <__gettimeofday@@GLIBC_2.0>:
0.47 │ save %sp, -96, %sp
0.73 │ sethi %hi(0xe9000), %l7
│ → call __frame_state_for@@GLIBC_2.0+0x480
0.30 │ add %l7, 0x58, %l7 ! e9058 <nftw64@@GLIBC_2.3.3+0x818>
1.33 │ mov %i0, %o0
│ mov %i1, %o1
0.43 │ mov 0x74, %g1
│ ta 0x10
88.92 │ ↓ bcc 30
2.95 │ clr %g1
│ neg %o0
│ mov 1, %g1
0.31 │30: cmp %g1, 0
│ bne,pn %icc, a6fe4 <__gettimeofday@@GLIBC_2.0+0x44>
│ mov %o0, %i0
1.96 │ ← return %i7 + 8
2.62 │ nop
│ sethi %hi(0), %g1
│ neg %o0, %g2
│ add %g1, 0x160, %g1
│ ld [ %l7 + %g1 ], %g1
│ st %g2, [ %g7 + %g1 ]
│ ← return %i7 + 8
│ mov -1, %o0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [tip:perf/urgent] perf annotate: Add Sparc support
2018-10-17 3:55 [PATCH] perf: Add Sparc annotate support David Miller
2018-10-17 12:39 ` Arnaldo Carvalho de Melo
@ 2018-10-26 7:28 ` tip-bot for David Miller
1 sibling, 0 replies; 4+ messages in thread
From: tip-bot for David Miller @ 2018-10-26 7:28 UTC (permalink / raw)
To: linux-tip-commits; +Cc: tglx, acme, hpa, mingo, davem, linux-kernel
Commit-ID: 0ab41886648bb75b951bd41d8b5cecaca8e0ad66
Gitweb: https://git.kernel.org/tip/0ab41886648bb75b951bd41d8b5cecaca8e0ad66
Author: David Miller <davem@davemloft.net>
AuthorDate: Tue, 16 Oct 2018 20:55:55 -0700
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 18 Oct 2018 11:16:38 -0300
perf annotate: Add Sparc support
E.g.:
$ perf annotate --stdio2
Samples: 7K of event 'cycles:ppp', 4000 Hz, Event count (approx.): 3086733887
__gettimeofday /lib32/libc-2.27.so [Percent: local period]
Percent│
│
│
│ Disassembly of section .text:
│
│ 000a6fa0 <__gettimeofday@@GLIBC_2.0>:
0.47 │ save %sp, -96, %sp
0.73 │ sethi %hi(0xe9000), %l7
│ → call __frame_state_for@@GLIBC_2.0+0x480
0.30 │ add %l7, 0x58, %l7 ! e9058 <nftw64@@GLIBC_2.3.3+0x818>
1.33 │ mov %i0, %o0
│ mov %i1, %o1
0.43 │ mov 0x74, %g1
│ ta 0x10
88.92 │ ↓ bcc 30
2.95 │ clr %g1
│ neg %o0
│ mov 1, %g1
0.31 │30: cmp %g1, 0
│ bne,pn %icc, a6fe4 <__gettimeofday@@GLIBC_2.0+0x44>
│ mov %o0, %i0
1.96 │ ← return %i7 + 8
2.62 │ nop
│ sethi %hi(0), %g1
│ neg %o0, %g2
│ add %g1, 0x160, %g1
│ ld [ %l7 + %g1 ], %g1
│ st %g2, [ %g7 + %g1 ]
│ ← return %i7 + 8
│ mov -1, %o0
Signed-off-by: David S. Miller <davem@davemloft.net>
Link: http://lkml.kernel.org/r/20181016.205555.1070918198627611771.davem@davemloft.net
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/arch/sparc/annotate/instructions.c | 169 ++++++++++++++++++++++++++
tools/perf/util/annotate.c | 8 ++
2 files changed, 177 insertions(+)
diff --git a/tools/perf/arch/sparc/annotate/instructions.c b/tools/perf/arch/sparc/annotate/instructions.c
new file mode 100644
index 000000000000..2614c010c235
--- /dev/null
+++ b/tools/perf/arch/sparc/annotate/instructions.c
@@ -0,0 +1,169 @@
+// SPDX-License-Identifier: GPL-2.0
+
+static int is_branch_cond(const char *cond)
+{
+ if (cond[0] == '\0')
+ return 1;
+
+ if (cond[0] == 'a' && cond[1] == '\0')
+ return 1;
+
+ if (cond[0] == 'c' &&
+ (cond[1] == 'c' || cond[1] == 's') &&
+ cond[2] == '\0')
+ return 1;
+
+ if (cond[0] == 'e' &&
+ (cond[1] == '\0' ||
+ (cond[1] == 'q' && cond[2] == '\0')))
+ return 1;
+
+ if (cond[0] == 'g' &&
+ (cond[1] == '\0' ||
+ (cond[1] == 't' && cond[2] == '\0') ||
+ (cond[1] == 'e' && cond[2] == '\0') ||
+ (cond[1] == 'e' && cond[2] == 'u' && cond[3] == '\0')))
+ return 1;
+
+ if (cond[0] == 'l' &&
+ (cond[1] == '\0' ||
+ (cond[1] == 't' && cond[2] == '\0') ||
+ (cond[1] == 'u' && cond[2] == '\0') ||
+ (cond[1] == 'e' && cond[2] == '\0') ||
+ (cond[1] == 'e' && cond[2] == 'u' && cond[3] == '\0')))
+ return 1;
+
+ if (cond[0] == 'n' &&
+ (cond[1] == '\0' ||
+ (cond[1] == 'e' && cond[2] == '\0') ||
+ (cond[1] == 'z' && cond[2] == '\0') ||
+ (cond[1] == 'e' && cond[2] == 'g' && cond[3] == '\0')))
+ return 1;
+
+ if (cond[0] == 'b' &&
+ cond[1] == 'p' &&
+ cond[2] == 'o' &&
+ cond[3] == 's' &&
+ cond[4] == '\0')
+ return 1;
+
+ if (cond[0] == 'v' &&
+ (cond[1] == 'c' || cond[1] == 's') &&
+ cond[2] == '\0')
+ return 1;
+
+ if (cond[0] == 'b' &&
+ cond[1] == 'z' &&
+ cond[2] == '\0')
+ return 1;
+
+ return 0;
+}
+
+static int is_branch_reg_cond(const char *cond)
+{
+ if ((cond[0] == 'n' || cond[0] == 'l') &&
+ cond[1] == 'z' &&
+ cond[2] == '\0')
+ return 1;
+
+ if (cond[0] == 'z' &&
+ cond[1] == '\0')
+ return 1;
+
+ if ((cond[0] == 'g' || cond[0] == 'l') &&
+ cond[1] == 'e' &&
+ cond[2] == 'z' &&
+ cond[3] == '\0')
+ return 1;
+
+ if (cond[0] == 'g' &&
+ cond[1] == 'z' &&
+ cond[2] == '\0')
+ return 1;
+
+ return 0;
+}
+
+static int is_branch_float_cond(const char *cond)
+{
+ if (cond[0] == '\0')
+ return 1;
+
+ if ((cond[0] == 'a' || cond[0] == 'e' ||
+ cond[0] == 'z' || cond[0] == 'g' ||
+ cond[0] == 'l' || cond[0] == 'n' ||
+ cond[0] == 'o' || cond[0] == 'u') &&
+ cond[1] == '\0')
+ return 1;
+
+ if (((cond[0] == 'g' && cond[1] == 'e') ||
+ (cond[0] == 'l' && (cond[1] == 'e' ||
+ cond[1] == 'g')) ||
+ (cond[0] == 'n' && (cond[1] == 'e' ||
+ cond[1] == 'z')) ||
+ (cond[0] == 'u' && (cond[1] == 'e' ||
+ cond[1] == 'g' ||
+ cond[1] == 'l'))) &&
+ cond[2] == '\0')
+ return 1;
+
+ if (cond[0] == 'u' &&
+ (cond[1] == 'g' || cond[1] == 'l') &&
+ cond[2] == 'e' &&
+ cond[3] == '\0')
+ return 1;
+
+ return 0;
+}
+
+static struct ins_ops *sparc__associate_instruction_ops(struct arch *arch, const char *name)
+{
+ struct ins_ops *ops = NULL;
+
+ if (!strcmp(name, "call") ||
+ !strcmp(name, "jmp") ||
+ !strcmp(name, "jmpl")) {
+ ops = &call_ops;
+ } else if (!strcmp(name, "ret") ||
+ !strcmp(name, "retl") ||
+ !strcmp(name, "return")) {
+ ops = &ret_ops;
+ } else if (!strcmp(name, "mov")) {
+ ops = &mov_ops;
+ } else {
+ if (name[0] == 'c' &&
+ (name[1] == 'w' || name[1] == 'x'))
+ name += 2;
+
+ if (name[0] == 'b') {
+ const char *cond = name + 1;
+
+ if (cond[0] == 'r') {
+ if (is_branch_reg_cond(cond + 1))
+ ops = &jump_ops;
+ } else if (is_branch_cond(cond)) {
+ ops = &jump_ops;
+ }
+ } else if (name[0] == 'f' && name[1] == 'b') {
+ if (is_branch_float_cond(name + 2))
+ ops = &jump_ops;
+ }
+ }
+
+ if (ops)
+ arch__associate_ins_ops(arch, name, ops);
+
+ return ops;
+}
+
+static int sparc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
+{
+ if (!arch->initialized) {
+ arch->initialized = true;
+ arch->associate_instruction_ops = sparc__associate_instruction_ops;
+ arch->objdump.comment_char = '#';
+ }
+
+ return 0;
+}
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 28cd6a17491b..6936daf89ddd 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -139,6 +139,7 @@ static int arch__associate_ins_ops(struct arch* arch, const char *name, struct i
#include "arch/x86/annotate/instructions.c"
#include "arch/powerpc/annotate/instructions.c"
#include "arch/s390/annotate/instructions.c"
+#include "arch/sparc/annotate/instructions.c"
static struct arch architectures[] = {
{
@@ -170,6 +171,13 @@ static struct arch architectures[] = {
.comment_char = '#',
},
},
+ {
+ .name = "sparc",
+ .init = sparc__annotate_init,
+ .objdump = {
+ .comment_char = '#',
+ },
+ },
};
static void ins__delete(struct ins_operands *ops)
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2018-10-26 7:28 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-17 3:55 [PATCH] perf: Add Sparc annotate support David Miller
2018-10-17 12:39 ` Arnaldo Carvalho de Melo
2018-10-17 16:42 ` David Miller
2018-10-26 7:28 ` [tip:perf/urgent] perf annotate: Add Sparc support tip-bot for David Miller
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.