On 26/05/2026 5:59 pm, Leo Yan wrote:
From: Leo Yan leo.yan@linaro.org
This patch introduces a new function cs_etm__instr_size() to calculate the instruction size based on ISA type and instruction address.
Given the trace data can be MB and most likely that will be A64/A32 on a lot of platforms, cs_etm__instr_addr() keeps a single ISA type check for A64/A32 and executes an optimized calculation (addr + offset * 4).
Signed-off-by: Leo Yan leo.yan@linaro.org Signed-off-by: Leo Yan leo.yan@arm.com
tools/perf/util/cs-etm.c | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-)
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index ab79d08f5a6095448470e2c3ec85ff3db2fb5634..5bff8811d61e423463b7bd4e20d599d5b5307a1a 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -1347,6 +1347,17 @@ static inline int cs_etm__t32_instr_size(struct cs_etm_queue *etmq, return ((instrBytes[1] & 0xF8) >= 0xE8) ? 4 : 2; } +static inline int cs_etm__instr_size(struct cs_etm_queue *etmq,
u8 trace_chan_id,enum cs_etm_isa isa, u64 addr)+{
- if (isa == CS_ETM_ISA_T32)
return cs_etm__t32_instr_size(etmq, trace_chan_id, addr);- /* Otherwise, 4-byte instruction size for A32/A64 */
- return 4;
+}
- static inline u64 cs_etm__first_executed_instr(struct cs_etm_packet *packet) { /*
@@ -1375,19 +1386,18 @@ static inline u64 cs_etm__instr_addr(struct cs_etm_queue *etmq, const struct cs_etm_packet *packet, u64 offset) {
- if (packet->isa == CS_ETM_ISA_T32) {
u64 addr = packet->start_addr;
- u64 addr = packet->start_addr;
while (offset) {addr += cs_etm__t32_instr_size(etmq,trace_chan_id, addr);offset--;}return addr;- }
- /* 4-byte instruction size for A32/A64 */
- if (packet->isa == CS_ETM_ISA_A64 || packet->isa == CS_ETM_ISA_A32)
return addr + offset * 4;
- /* Assume a 4 byte instruction size (A32/A64) */
- return packet->start_addr + offset * 4;
- while (offset) {
addr += cs_etm__instr_size(etmq, trace_chan_id,packet->isa, addr);offset--;- }
- return addr; }
static void cs_etm__update_last_branch_rb(struct cs_etm_queue *etmq, @@ -1540,16 +1550,8 @@ static void cs_etm__copy_insn(struct cs_etm_queue *etmq, return; }
- /*
* T32 instruction size might be 32-bit or 16-bit, decide by calling* cs_etm__t32_instr_size().*/- if (packet->isa == CS_ETM_ISA_T32)
sample->insn_len = cs_etm__t32_instr_size(etmq, trace_chan_id,sample->ip);- /* Otherwise, A64 and A32 instruction size are always 32-bit. */
- else
sample->insn_len = 4;
- sample->insn_len = cs_etm__instr_size(etmq, trace_chan_id,
packet->isa, sample->ip);cs_etm__mem_access(etmq, trace_chan_id, sample->ip, sample->insn_len, (void *)sample->insn, 0);
Reviewed-by: James Clark james.clark@linaro.org