All of lore.kernel.org
 help / color / mirror / Atom feed
From: Namhyung Kim <namhyung@kernel.org>
To: Tengda Wu <wutengda@huaweicloud.com>
Cc: james.clark@linaro.org, xueshuai@linux.alibaba.com,
	Adrian Hunter <adrian.hunter@intel.com>,
	Peter Zijlstra <peterz@infradead.org>,
	leo.yan@linux.dev, Li Huafei <lihuafei1@huawei.com>,
	Ian Rogers <irogers@google.com>,
	Kim Phillips <kim.phillips@arm.com>,
	Mark Rutland <mark.rutland@arm.com>,
	Arnaldo Carvalho de Melo <acme@kernel.org>,
	Ingo Molnar <mingo@redhat.com>, Bill Wendling <morbo@google.com>,
	Nick Desaulniers <nick.desaulniers+lkml@gmail.com>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Zecheng Li <zli94@ncsu.edu>,
	linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org,
	llvm@lists.linux.dev
Subject: Re: [PATCH v5 06/26] perf annotate: Introduce extract_op_location callback for arch-specific parsing
Date: Wed, 9 Sep 2026 11:01:33 -0400	[thread overview]
Message-ID: <aqF0zceTOQBjRJl1@google.com> (raw)
In-Reply-To: <a9f1bafb17bc2e2c6152f6e3a0c63b9d72a0e657.1788872630.git.wutengda@huaweicloud.com>

On Tue, Sep 08, 2026 at 01:05:09PM +0000, Tengda Wu wrote:
> Assembly syntax for operands varies significantly across different
> architectures, which prevents the operand location (op_loc) parsing
> logic in annotate_get_insn_location() from being directly reused.
> 
> To simplify the core logic and improve maintainability, move the
> operand parsing inside the for_each_insn_op_loc loop into arch-specific
> extract_op_location callbacks. This refactoring is intended to be a
> cleanup with no functional changes.
> 
> Signed-off-by: Li Huafei <lihuafei1@huawei.com>
> Signed-off-by: Tengda Wu <wutengda@huaweicloud.com>

Reviewed-by: Namhyung Kim <namhyung@kernel.org>

Thanks,
Namhyung

> ---
>  .../util/annotate-arch/annotate-powerpc.c     |  9 ++
>  tools/perf/util/annotate-arch/annotate-x86.c  | 79 ++++++++++++++++
>  tools/perf/util/annotate.c                    | 94 +------------------
>  tools/perf/util/annotate.h                    |  2 +
>  tools/perf/util/disasm.h                      |  4 +
>  5 files changed, 99 insertions(+), 89 deletions(-)
> 
> diff --git a/tools/perf/util/annotate-arch/annotate-powerpc.c b/tools/perf/util/annotate-arch/annotate-powerpc.c
> index 218207b52581..00b93296fc94 100644
> --- a/tools/perf/util/annotate-arch/annotate-powerpc.c
> +++ b/tools/perf/util/annotate-arch/annotate-powerpc.c
> @@ -390,6 +390,14 @@ static void update_insn_state_powerpc(struct type_state *state,
>  }
>  #endif /* HAVE_LIBDW_SUPPORT */
>  
> +static void extract_op_location_powerpc(const struct arch *arch __maybe_unused,
> +					struct disasm_line *dl,
> +					const char *op_str __maybe_unused, int op_idx,
> +					struct annotated_op_loc *op_loc)
> +{
> +	get_powerpc_regs(dl->raw.raw_insn, !op_idx, op_loc);
> +}
> +
>  const struct arch *arch__new_powerpc(const struct e_machine_and_e_flags *id,
>  				     const char *cpuid __maybe_unused)
>  {
> @@ -406,5 +414,6 @@ const struct arch *arch__new_powerpc(const struct e_machine_and_e_flags *id,
>  #ifdef HAVE_LIBDW_SUPPORT
>  	arch->update_insn_state = update_insn_state_powerpc;
>  #endif
> +	arch->extract_op_location = extract_op_location_powerpc;
>  	return arch;
>  }
> diff --git a/tools/perf/util/annotate-arch/annotate-x86.c b/tools/perf/util/annotate-arch/annotate-x86.c
> index 7e6136536393..1acf31a2c759 100644
> --- a/tools/perf/util/annotate-arch/annotate-x86.c
> +++ b/tools/perf/util/annotate-arch/annotate-x86.c
> @@ -1,6 +1,8 @@
>  // SPDX-License-Identifier: GPL-2.0
>  #include <string.h>
> +#include <stdlib.h>
>  #include <linux/compiler.h>
> +#include <linux/ctype.h>
>  #include <linux/zalloc.h>
>  #include <assert.h>
>  #include <inttypes.h>
> @@ -809,6 +811,82 @@ static void update_insn_state_x86(struct type_state *state,
>  }
>  #endif
>  
> +/*
> + * Get register number and access offset from the given instruction.
> + * It assumes AT&T x86 asm format like OFFSET(REG).
> + * Fills @reg and @offset when return 0.
> + */
> +static int extract_reg_offset(const struct arch *arch, const char *str,
> +			      struct annotated_op_loc *op_loc)
> +{
> +	char *p;
> +
> +	if (arch->objdump.register_char == 0)
> +		return -1;
> +
> +	/*
> +	 * It should start from offset, but it's possible to skip 0
> +	 * in the asm.  So 0(%rax) should be same as (%rax).
> +	 *
> +	 * However, it also start with a segment select register like
> +	 * %gs:0x18(%rbx).  In that case it should skip the part.
> +	 */
> +	if (*str == arch->objdump.register_char) {
> +		/* FIXME: Handle other segment registers */
> +		if (!strncmp(str, "%gs:", 4))
> +			op_loc->segment = INSN_SEG_X86_GS;
> +
> +		while (*str && !isdigit(*str) &&
> +		       *str != arch->objdump.memory_ref_char)
> +			str++;
> +	}
> +
> +	op_loc->offset = strtol(str, &p, 0);
> +	op_loc->reg1 = arch__dwarf_regnum(arch, p);
> +	if (op_loc->reg1 == -1)
> +		return -1;
> +
> +	/* Get the second register */
> +	if (op_loc->multi_regs)
> +		op_loc->reg2 = arch__dwarf_regnum(arch, p + 1);
> +
> +	return 0;
> +}
> +
> +static void extract_op_location_x86(const struct arch *arch,
> +				    struct disasm_line *dl __maybe_unused,
> +				    const char *op_str, int op_idx __maybe_unused,
> +				    struct annotated_op_loc *op_loc)
> +{
> +	if (op_str == NULL)
> +		return;
> +
> +	if (strchr(op_str, arch->objdump.memory_ref_char)) {
> +		op_loc->mem_ref = true;
> +		extract_reg_offset(arch, op_str, op_loc);
> +	} else {
> +		const char *s = op_str;
> +		char *p = NULL;
> +
> +		/* FIXME: Handle other segment registers */
> +		if (!strncmp(op_str, "%gs:", 4)) {
> +			op_loc->segment = INSN_SEG_X86_GS;
> +			op_loc->offset = strtol(op_str + 4, &p, 0);
> +			if (p && p != op_str + 4)
> +				op_loc->imm = true;
> +			return;
> +		}
> +
> +		if (*s == arch->objdump.register_char) {
> +			op_loc->reg1 = arch__dwarf_regnum(arch, s);
> +		} else if (*s == arch->objdump.imm_char) {
> +			op_loc->offset = strtol(s + 1, &p, 0);
> +			if (p && p != s + 1)
> +				op_loc->imm = true;
> +		}
> +	}
> +}
> +
>  const struct arch *arch__new_x86(const struct e_machine_and_e_flags *id, const char *cpuid)
>  {
>  	struct arch *arch = zalloc(sizeof(*arch));
> @@ -848,5 +926,6 @@ const struct arch *arch__new_x86(const struct e_machine_and_e_flags *id, const c
>  #ifdef HAVE_LIBDW_SUPPORT
>  	arch->update_insn_state = update_insn_state_x86;
>  #endif
> +	arch->extract_op_location = extract_op_location_x86;
>  	return arch;
>  }
> diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
> index f3d17d153b67..a3d48cf88dad 100644
> --- a/tools/perf/util/annotate.c
> +++ b/tools/perf/util/annotate.c
> @@ -2472,7 +2472,7 @@ int annotate_check_args(void)
>  	return 0;
>  }
>  
> -static int arch__dwarf_regnum(const struct arch *arch, const char *str)
> +int arch__dwarf_regnum(const struct arch *arch, const char *str)
>  {
>  	const char *p;
>  	char *regname, *q;
> @@ -2495,51 +2495,6 @@ static int arch__dwarf_regnum(const struct arch *arch, const char *str)
>  	return reg < 0 ? -1 : reg;
>  }
>  
> -/*
> - * Get register number and access offset from the given instruction.
> - * It assumes AT&T x86 asm format like OFFSET(REG).  Maybe it needs
> - * to revisit the format when it handles different architecture.
> - * Fills @reg and @offset when return 0.
> - */
> -static int extract_reg_offset(const struct arch *arch, const char *str,
> -			      struct annotated_op_loc *op_loc)
> -{
> -	char *p;
> -
> -	if (arch->objdump.register_char == 0)
> -		return -1;
> -
> -	/*
> -	 * It should start from offset, but it's possible to skip 0
> -	 * in the asm.  So 0(%rax) should be same as (%rax).
> -	 *
> -	 * However, it also start with a segment select register like
> -	 * %gs:0x18(%rbx).  In that case it should skip the part.
> -	 */
> -	if (*str == arch->objdump.register_char) {
> -		if (arch__is_x86(arch)) {
> -			/* FIXME: Handle other segment registers */
> -			if (!strncmp(str, "%gs:", 4))
> -				op_loc->segment = INSN_SEG_X86_GS;
> -		}
> -
> -		while (*str && !isdigit(*str) &&
> -		       *str != arch->objdump.memory_ref_char)
> -			str++;
> -	}
> -
> -	op_loc->offset = strtol(str, &p, 0);
> -	op_loc->reg1 = arch__dwarf_regnum(arch, p);
> -	if (op_loc->reg1 == -1)
> -		return -1;
> -
> -	/* Get the second register */
> -	if (op_loc->multi_regs)
> -		op_loc->reg2 = arch__dwarf_regnum(arch, p + 1);
> -
> -	return 0;
> -}
> -
>  /**
>   * annotate_get_insn_location - Get location of instruction
>   * @arch: the architecture info
> @@ -2595,50 +2550,11 @@ int annotate_get_insn_location(const struct arch *arch, struct disasm_line *dl,
>  		/* Invalidate the register by default */
>  		op_loc->reg1 = -1;
>  		op_loc->reg2 = -1;
> +		op_loc->mem_ref = mem_ref;
> +		op_loc->multi_regs = multi_regs;
>  
> -		if (insn_str == NULL) {
> -			if (!arch__is_powerpc(arch))
> -				continue;
> -		}
> -
> -		/*
> -		 * For powerpc, call get_powerpc_regs function which extracts the
> -		 * required fields for op_loc, ie reg1, reg2, offset from the
> -		 * raw instruction.
> -		 */
> -		if (arch__is_powerpc(arch)) {
> -			op_loc->mem_ref = mem_ref;
> -			op_loc->multi_regs = multi_regs;
> -			get_powerpc_regs(dl->raw.raw_insn, !i, op_loc);
> -		} else if (strchr(insn_str, arch->objdump.memory_ref_char)) {
> -			op_loc->mem_ref = true;
> -			op_loc->multi_regs = multi_regs;
> -			extract_reg_offset(arch, insn_str, op_loc);
> -		} else {
> -			const char *s = insn_str;
> -			char *p = NULL;
> -
> -			if (arch__is_x86(arch)) {
> -				/* FIXME: Handle other segment registers */
> -				if (!strncmp(insn_str, "%gs:", 4)) {
> -					op_loc->segment = INSN_SEG_X86_GS;
> -					op_loc->offset = strtol(insn_str + 4,
> -								&p, 0);
> -					if (p && p != insn_str + 4)
> -						op_loc->imm = true;
> -					continue;
> -				}
> -			}
> -
> -			if (*s == arch->objdump.register_char) {
> -				op_loc->reg1 = arch__dwarf_regnum(arch, s);
> -			}
> -			else if (*s == arch->objdump.imm_char) {
> -				op_loc->offset = strtol(s + 1, &p, 0);
> -				if (p && p != s + 1)
> -					op_loc->imm = true;
> -			}
> -		}
> +		if (arch->extract_op_location)
> +			arch->extract_op_location(arch, dl, insn_str, i, op_loc);
>  	}
>  
>  	return 0;
> diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
> index fa08d09b80f7..11b6e4780c02 100644
> --- a/tools/perf/util/annotate.h
> +++ b/tools/perf/util/annotate.h
> @@ -492,6 +492,8 @@ int annotate_parse_percent_type(const struct option *opt, const char *_str,
>  
>  int annotate_check_args(void);
>  
> +int arch__dwarf_regnum(const struct arch *arch, const char *str);
> +
>  /**
>   * struct annotated_op_loc - Location info of instruction operand
>   * @reg1: First register in the operand
> diff --git a/tools/perf/util/disasm.h b/tools/perf/util/disasm.h
> index 06c664fd4fc2..62c2949c4c30 100644
> --- a/tools/perf/util/disasm.h
> +++ b/tools/perf/util/disasm.h
> @@ -16,6 +16,7 @@ struct symbol;
>  struct data_loc_info;
>  struct type_state;
>  struct disasm_line;
> +struct annotated_op_loc;
>  
>  struct e_machine_and_e_flags {
>  	uint32_t e_flags;
> @@ -49,6 +50,9 @@ struct arch {
>  				struct data_loc_info *dloc, Dwarf_Die *cu_die,
>  				struct disasm_line *dl);
>  #endif
> +	void		(*extract_op_location)(const struct arch *arch, struct disasm_line *dl,
> +					       const char *op_str, int op_idx,
> +					       struct annotated_op_loc *op_loc);
>  };
>  
>  struct ins {
> -- 
> 2.34.1
> 

  parent reply	other threads:[~2026-09-09 15:01 UTC|newest]

Thread overview: 74+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-08 13:05 [PATCH v5 00/26] perf arm64: Support data type profiling Tengda Wu
2026-09-08 13:05 ` [PATCH v5 01/26] perf capstone: Symbolize address operands to match objdump on arm64 Tengda Wu
2026-09-08 13:18   ` sashiko-bot
2026-09-09 14:49     ` Namhyung Kim
2026-09-10  7:38       ` Tengda Wu
2026-09-08 13:05 ` [PATCH v5 02/26] perf llvm: Fix arm64 adrp instruction disassembly mismatch with objdump Tengda Wu
2026-09-08 13:16   ` sashiko-bot
2026-09-09 14:50   ` Namhyung Kim
2026-09-08 13:05 ` [PATCH v5 03/26] perf annotate-arm64: Generalize arm64_mov__parse to support more instructions Tengda Wu
2026-09-08 13:15   ` sashiko-bot
2026-09-09 14:52   ` Namhyung Kim
2026-09-08 13:05 ` [PATCH v5 04/26] perf annotate-arm64: Handle load and store instructions Tengda Wu
2026-09-08 13:15   ` sashiko-bot
2026-09-09 14:58   ` Namhyung Kim
2026-09-08 13:05 ` [PATCH v5 05/26] perf annotate: Normalize arch__dwarf_regnum() error return values Tengda Wu
2026-09-08 13:24   ` sashiko-bot
2026-09-08 17:57   ` Ian Rogers
2026-09-09 15:00     ` Namhyung Kim
2026-09-08 13:05 ` [PATCH v5 06/26] perf annotate: Introduce extract_op_location callback for arch-specific parsing Tengda Wu
2026-09-08 13:20   ` sashiko-bot
2026-09-09 15:01   ` Namhyung Kim [this message]
2026-09-08 13:05 ` [PATCH v5 07/26] perf dwarf-regs: Adapt get_dwarf_regnum() for arm64 Tengda Wu
2026-09-08 13:21   ` sashiko-bot
2026-09-09 15:03     ` Namhyung Kim
2026-09-08 13:05 ` [PATCH v5 08/26] perf annotate: Adapt arch__dwarf_regnum() " Tengda Wu
2026-09-08 13:15   ` sashiko-bot
2026-09-09 15:04   ` Namhyung Kim
2026-09-08 13:05 ` [PATCH v5 09/26] perf annotate-arm64: Implement extract_op_location() callback Tengda Wu
2026-09-08 13:18   ` sashiko-bot
2026-09-10  8:49     ` Tengda Wu
2026-09-08 13:05 ` [PATCH v5 10/26] perf annotate: Default to --itrace=i1i for data type profiling Tengda Wu
2026-09-08 13:15   ` sashiko-bot
2026-09-09 15:38   ` Adrian Hunter
2026-09-08 13:05 ` [PATCH v5 11/26] perf arm-spe: Set default synthesized event period to 1 Tengda Wu
2026-09-08 13:12   ` sashiko-bot
2026-09-08 13:05 ` [PATCH v5 12/26] perf annotate-data: Extract invalidate_reg_state() as a common helper Tengda Wu
2026-09-08 13:11   ` sashiko-bot
2026-09-08 13:05 ` [PATCH v5 13/26] perf annotate-arm64: Enable instruction tracking support Tengda Wu
2026-09-08 13:18   ` sashiko-bot
2026-09-10  9:20     ` Tengda Wu
2026-09-08 13:05 ` [PATCH v5 14/26] perf annotate-data: Add arch_get_reg_offset helper Tengda Wu
2026-09-08 13:22   ` sashiko-bot
2026-09-10 12:13     ` Tengda Wu
2026-09-08 13:05 ` [PATCH v5 15/26] perf annotate-arm64: Track return type after call instructions Tengda Wu
2026-09-08 13:14   ` sashiko-bot
2026-09-08 13:05 ` [PATCH v5 16/26] perf annotate-arm64: Support load instruction tracking Tengda Wu
2026-09-08 13:23   ` sashiko-bot
2026-09-10 13:19     ` Tengda Wu
2026-09-10 13:28   ` Tengda Wu
2026-09-08 13:05 ` [PATCH v5 17/26] perf annotate-arm64: Support store " Tengda Wu
2026-09-08 13:22   ` sashiko-bot
2026-09-08 13:05 ` [PATCH v5 18/26] perf annotate-data: Expand type_state_reg imm_value to u64 Tengda Wu
2026-09-08 13:26   ` sashiko-bot
2026-09-08 13:05 ` [PATCH v5 19/26] perf annotate-data: Track imm_value for stack variables Tengda Wu
2026-09-08 13:29   ` sashiko-bot
2026-09-08 13:05 ` [PATCH v5 20/26] perf annotate-x86: Delete stale stack state on store of untracked register Tengda Wu
2026-09-08 13:20   ` sashiko-bot
2026-09-08 13:05 ` [PATCH v5 21/26] perf annotate-arm64: Support stack variable tracking Tengda Wu
2026-09-08 13:36   ` sashiko-bot
2026-09-11  1:41     ` Tengda Wu
2026-09-08 13:05 ` [PATCH v5 22/26] perf annotate-arm64: Support 'mov' instruction tracking Tengda Wu
2026-09-08 13:27   ` sashiko-bot
2026-09-11  2:22     ` Tengda Wu
2026-09-08 13:05 ` [PATCH v5 23/26] perf annotate-arm64: Support 'add' " Tengda Wu
2026-09-08 13:27   ` sashiko-bot
2026-09-11  2:29     ` Tengda Wu
2026-09-08 13:06 ` [PATCH v5 24/26] perf annotate-arm64: Support 'adrp' instruction to track global variables Tengda Wu
2026-09-08 13:26   ` sashiko-bot
2026-09-08 13:06 ` [PATCH v5 25/26] perf annotate-arm64: Support per-cpu variable access tracking Tengda Wu
2026-09-08 13:30   ` sashiko-bot
2026-09-11 10:15     ` Tengda Wu
2026-09-08 13:06 ` [PATCH v5 26/26] perf annotate-arm64: Support 'mrs' instruction to track 'current' pointer Tengda Wu
2026-09-08 13:31   ` sashiko-bot
  -- strict thread matches above, loose matches on Subject: below --
2026-09-08 13:00 [PATCH v5 00/26] perf arm64: Support data type profiling Tengda Wu
2026-09-08 13:01 ` [PATCH v5 06/26] perf annotate: Introduce extract_op_location callback for arch-specific parsing Tengda Wu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aqF0zceTOQBjRJl1@google.com \
    --to=namhyung@kernel.org \
    --cc=acme@kernel.org \
    --cc=adrian.hunter@intel.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=irogers@google.com \
    --cc=james.clark@linaro.org \
    --cc=kim.phillips@arm.com \
    --cc=leo.yan@linux.dev \
    --cc=lihuafei1@huawei.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=llvm@lists.linux.dev \
    --cc=mark.rutland@arm.com \
    --cc=mingo@redhat.com \
    --cc=morbo@google.com \
    --cc=nick.desaulniers+lkml@gmail.com \
    --cc=peterz@infradead.org \
    --cc=wutengda@huaweicloud.com \
    --cc=xueshuai@linux.alibaba.com \
    --cc=zli94@ncsu.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.