From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8CC1A3AA504; Mon, 6 Jul 2026 02:41:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.15 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783305674; cv=none; b=tSL2dJlHmAnI6P1Ao4UBWnhJP/b6tnmT6dfEUGCjFOhIe5/BrNP0YJmpYhuyVO38xhI4coY4MBCYyvKnW/eR0KZ/DYutKM8gGLmBHMR8mYICSB+e5BL0PoxKQ++i9CjbhXIcOx7TfkRyYq7EdRp1LIkYqo5DMByLvrbewXULIbo= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783305674; c=relaxed/simple; bh=QLonwGbvnsRdSL+cU+2KRQ46YwslaL7apgVEr9Z0j00=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=NmRtnz5rEaUqy7Xm/pLT1JP0hKDKVE7+jUgYO3ocd98oOCGaaIXtI2v+mUQYDbVa++rKfccPvsetgFZEcVftFD4ttr0icpUMij7DRi+LpNRMx53rJ/ravZpDkWcpOjblsdbaBcaBpdIpHhJUtzY7NG188+jS2yWr/m7mjHDEzWE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=aKrzd+V9; arc=none smtp.client-ip=198.175.65.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="aKrzd+V9" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1783305673; x=1814841673; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=QLonwGbvnsRdSL+cU+2KRQ46YwslaL7apgVEr9Z0j00=; b=aKrzd+V95v7GKl0ROJI20GLz+J5CljBZ2QTAEV/p5K0ugFAhbVE+oHur jc/9SDD4KZa601rxlvJTnlXTnbhDPvWVfPvNpuj0LEeRNGtkucYunUhiZ 4ZhMLeEGTzW781w47CU35N0dwhsIVhMSA8Fwp2ioety6s9+4VqO4pgWMX FrLc/dKiAOaT90FPsYn8TapPkxYFsVKPSqRB+tywhTIEz/EBIu3pvtgGQ 1EqbJMWq9iFNvwNnYGPoRF7z4wQXJdxnaENL/ouwv2heGcgBPRnRyUwT+ TVEyK+0uyzUsIBl5Q/DMmVgUvEDz2LQBW1i5vfiTBuDF7E0TO3dUX+dkH g==; X-CSE-ConnectionGUID: G5ctv5CGSIKNHXarMTG2Lw== X-CSE-MsgGUID: 3kKqMY0cSiysk4PPsaxiow== X-IronPort-AV: E=McAfee;i="6800,10657,11838"; a="87614062" X-IronPort-AV: E=Sophos;i="6.25,149,1779174000"; d="scan'208";a="87614062" Received: from orviesa007.jf.intel.com ([10.64.159.147]) by orvoesa107.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jul 2026 19:41:12 -0700 X-CSE-ConnectionGUID: QI7RvNDER26zjipYmHaJmQ== X-CSE-MsgGUID: Cuufc4GkQKi1ulwvFTLJmQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,149,1779174000"; d="scan'208";a="253716724" Received: from spr.sh.intel.com ([10.112.229.196]) by orviesa007.jf.intel.com with ESMTP; 05 Jul 2026 19:41:08 -0700 From: Dapeng Mi To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Ian Rogers , Adrian Hunter , Alexander Shishkin Cc: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Zide Chen , Falcon Thomas , Dapeng Mi , Xudong Hao , Dapeng Mi , Kan Liang Subject: [Patch v9 07/10] perf regs: Enable dumping of SIMD registers Date: Mon, 6 Jul 2026 10:34:41 +0800 Message-Id: <20260706023444.3067660-8-dapeng1.mi@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260706023444.3067660-1-dapeng1.mi@linux.intel.com> References: <20260706023444.3067660-1-dapeng1.mi@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Support dumping of SIMD registers with the new PERF_SAMPLE_REGS_ABI_SIMD ABI. Currently, the XMM, YMM, ZMM, OPMASK, eGPRs, and SSP registers on x86 platforms are supported with the PERF_SAMPLE_REGS_ABI_SIMD ABI. An example of the raw format output is displayed below. Example: $perf record -e cycles:p -Iax,bx,r8,r16,r31,ssp,xmm,ymm,zmm,opmask ./test $perf report -D ... ... 3342715685845 0x3afe8 [0xbc8]: PERF_RECORD_SAMPLE(IP, 0x1): 27776/27776: 0xffffffff91d7c18f period: 10000 addr: 0 ... intr regs: mask 0x18001010003 ABI 64-bit SIMD .... AX 0xffffed102de1a606 .... BX 0xffffed102de1a606 .... R8 0x0000000000000001 .... R16 0x0000000000000000 .... R31 0x0000000000000000 .... SSP 0x0000000000000000 ... SIMD ABI nr_vectors 32 vector_qwords 8 nr_pred 8 pred_qwords 1 .... ZMM[0][0] 0x616c2f656d6f682f .... ZMM[0][1] 0x696c2f7265737562 .... ZMM[0][2] 0x0000000000000000 .... ZMM[0][3] 0x0000000000000000 .... ZMM[0][4] 0x0000000000000000 .... ZMM[0][5] 0x0000000000000000 .... ZMM[0][6] 0x0000000000000000 .... ZMM[0][7] 0x0000000000000000 .... ZMM[1][0] 0x702f636578656269 .... ZMM[1][1] 0x65726f632d667265 .... ZMM[1][2] 0x0000000000000000 .... ZMM[1][3] 0x0000000000000000 .... ZMM[1][4] 0x0000000000000000 .... ZMM[1][5] 0x0000000000000000 .... ZMM[1][6] 0x0000000000000000 .... ZMM[1][7] 0x0000000000000000 ... ... .... ZMM[31][0] 0x0000000000000000 .... ZMM[31][1] 0x0000000000000000 .... ZMM[31][2] 0x0000000000000000 .... ZMM[31][3] 0x0000000000000000 .... ZMM[31][4] 0x0000000000000000 .... ZMM[31][5] 0x0000000000000000 .... ZMM[31][6] 0x0000000000000000 .... ZMM[31][7] 0x0000000000000000 .... OPMASK[0] 0x0000000000100221 .... OPMASK[1] 0x0000000000000020 .... OPMASK[2] 0x000000007fffffff .... OPMASK[3] 0x0000000000000000 .... OPMASK[4] 0x0000000000000000 .... OPMASK[5] 0x0000000000000000 .... OPMASK[6] 0x0000000000000000 .... OPMASK[7] 0x0000000000000000 ... ... Co-developed-by: Kan Liang Signed-off-by: Kan Liang Signed-off-by: Dapeng Mi --- tools/perf/builtin-script.c | 91 +++++++++++-- tools/perf/util/evsel.c | 68 +++++++++- tools/perf/util/sample.h | 5 + .../scripting-engines/trace-event-python.c | 125 ++++++++++++++++-- tools/perf/util/session.c | 82 ++++++++++++ tools/perf/util/synthetic-events.c | 38 +++++- 6 files changed, 387 insertions(+), 22 deletions(-) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 23f694c3f0c9..5768682dc95f 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -719,23 +719,96 @@ static int perf_session__check_output_opt(struct perf_session *session) return 0; } -static int perf_sample__fprintf_regs(struct regs_dump *regs, uint64_t mask, +static int perf_sample__fprintf_regs(struct regs_dump *regs, + struct perf_event_attr *attr, uint16_t e_machine, uint32_t e_flags, - FILE *fp) + FILE *fp, bool intr) { - unsigned i = 0, r; + const char *name = "unknown"; + int reg_c, idx, pred_base; + unsigned int i = 0, j, r; + uint16_t qwords; int printed = 0; + uint64_t mask; - if (!regs || !regs->regs) + if (!regs || (!regs->regs && !regs->simd_data)) return 0; printed += fprintf(fp, " ABI:%" PRIu64 " ", regs->abi); + mask = intr ? attr->sample_regs_intr : attr->sample_regs_user; for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) { - u64 val = regs->regs[i++]; + if (!regs->regs) + break; printed += fprintf(fp, "%5s:0x%"PRIx64" ", perf_reg_name(r, e_machine, e_flags, regs->abi), - val); + regs->regs[i++]); + } + + if (!regs->simd_data) + return printed; + + if (!regs->nr_vectors && !regs->nr_pred) + return printed; + + for (reg_c = 0; reg_c < 64; reg_c++) { + if (!regs->nr_vectors) + break; + if (intr) { + perf_intr_simd_reg_class_bitmap_qwords(e_machine, reg_c, + &qwords, /*pred=*/false); + } else { + perf_user_simd_reg_class_bitmap_qwords(e_machine, reg_c, + &qwords, /*pred=*/false); + } + if (regs->vector_qwords == qwords) { + name = perf_simd_reg_class_name(e_machine, reg_c, /*pred=*/false); + break; + } + } + + for (i = 0; i < regs->nr_vectors; i++) { + for (j = 0; j < regs->vector_qwords; j++) { + idx = i * regs->vector_qwords + j; + if (regs->vector_qwords > 1) { + printed += fprintf(fp, "%5s[%d][%d]:0x%" PRIx64 " ", + name, i, j, regs->simd_data[idx]); + } else { + printed += fprintf(fp, "%5s[%d]:0x%" PRIx64 " ", + name, i, regs->simd_data[idx]); + } + } + } + + name = "unknown"; + for (reg_c = 0; reg_c < 64; reg_c++) { + if (!regs->nr_pred) + break; + if (intr) { + perf_intr_simd_reg_class_bitmap_qwords(e_machine, reg_c, + &qwords, /*pred=*/true); + } else { + perf_user_simd_reg_class_bitmap_qwords(e_machine, reg_c, + &qwords, /*pred=*/true); + } + if (regs->pred_qwords == qwords) { + name = perf_simd_reg_class_name(e_machine, reg_c, /*pred=*/true); + break; + } + } + + pred_base = regs->nr_vectors * regs->vector_qwords; + for (i = 0; i < regs->nr_pred; i++) { + for (j = 0; j < regs->pred_qwords; j++) { + idx = pred_base + i * regs->pred_qwords + j; + if (regs->pred_qwords > 1) { + printed += fprintf(fp, "%5s[%d][%d]:0x%" PRIx64 " ", + name, i, j, regs->simd_data[idx]); + } else { + printed += fprintf(fp, "%5s[%d]:0x%" PRIx64 " ", + name, i, regs->simd_data[idx]); + } + } } return printed; @@ -801,7 +874,8 @@ static int perf_sample__fprintf_iregs(struct perf_sample *sample, return 0; return perf_sample__fprintf_regs(perf_sample__intr_regs(sample), - attr->sample_regs_intr, e_machine, e_flags, fp); + attr, e_machine, e_flags, fp, + /*intr=*/true); } static int perf_sample__fprintf_uregs(struct perf_sample *sample, @@ -814,7 +888,8 @@ static int perf_sample__fprintf_uregs(struct perf_sample *sample, return 0; return perf_sample__fprintf_regs(perf_sample__user_regs(sample), - attr->sample_regs_user, e_machine, e_flags, fp); + attr, e_machine, e_flags, fp, + /*intr=*/false); } static int perf_sample__fprintf_start(struct perf_script *script, diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 739b2ac3e5ec..bbec6008c5b2 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -3718,9 +3718,39 @@ int __evsel__parse_sample(struct evsel *evsel, union perf_event *event, array = (void *)array + sz; if (regs->abi & PERF_SAMPLE_REGS_ABI_SIMD) { - /* Skip SIMD-regs header. */ - sz = 4 * sizeof(u64); + u64 attr_nr_vectors = + hweight64(evsel->core.attr.sample_simd_vec_reg_user); + u64 attr_vec_qwords = + evsel->core.attr.sample_simd_vec_reg_qwords; + u64 attr_nr_pred = + hweight32(evsel->core.attr.sample_simd_pred_reg_user); + u64 attr_pred_qwords = + evsel->core.attr.sample_simd_pred_reg_qwords; + + OVERFLOW_CHECK_u64(array); + regs->nr_vectors = *(u64 *)array; + array = (void *)array + sizeof(u64); + OVERFLOW_CHECK_u64(array); + regs->vector_qwords = *(u64 *)array; + array = (void *)array + sizeof(u64); + OVERFLOW_CHECK_u64(array); + regs->nr_pred = *(u64 *)array; + array = (void *)array + sizeof(u64); + OVERFLOW_CHECK_u64(array); + regs->pred_qwords = *(u64 *)array; + array = (void *)array + sizeof(u64); + + if (regs->nr_vectors > attr_nr_vectors || + regs->vector_qwords > attr_vec_qwords || + regs->nr_pred > attr_nr_pred || + regs->pred_qwords > attr_pred_qwords) + goto out_efault; + + sz = (regs->nr_vectors * regs->vector_qwords + + regs->nr_pred * regs->pred_qwords) * sizeof(u64); OVERFLOW_CHECK(array, sz, max_size); + + regs->simd_data = (u64 *)array; array = (void *)array + sz; } } @@ -3782,9 +3812,39 @@ int __evsel__parse_sample(struct evsel *evsel, union perf_event *event, array = (void *)array + sz; if (regs->abi & PERF_SAMPLE_REGS_ABI_SIMD) { - /* Skip SIMD-regs header. */ - sz = 4 * sizeof(u64); + u64 attr_nr_vectors = + hweight64(evsel->core.attr.sample_simd_vec_reg_intr); + u64 attr_vec_qwords = + evsel->core.attr.sample_simd_vec_reg_qwords; + u64 attr_nr_pred = + hweight32(evsel->core.attr.sample_simd_pred_reg_intr); + u64 attr_pred_qwords = + evsel->core.attr.sample_simd_pred_reg_qwords; + + OVERFLOW_CHECK_u64(array); + regs->nr_vectors = *(u64 *)array; + array = (void *)array + sizeof(u64); + OVERFLOW_CHECK_u64(array); + regs->vector_qwords = *(u64 *)array; + array = (void *)array + sizeof(u64); + OVERFLOW_CHECK_u64(array); + regs->nr_pred = *(u64 *)array; + array = (void *)array + sizeof(u64); + OVERFLOW_CHECK_u64(array); + regs->pred_qwords = *(u64 *)array; + array = (void *)array + sizeof(u64); + + if (regs->nr_vectors > attr_nr_vectors || + regs->vector_qwords > attr_vec_qwords || + regs->nr_pred > attr_nr_pred || + regs->pred_qwords > attr_pred_qwords) + goto out_efault; + + sz = (regs->nr_vectors * regs->vector_qwords + + regs->nr_pred * regs->pred_qwords) * sizeof(u64); OVERFLOW_CHECK(array, sz, max_size); + + regs->simd_data = (u64 *)array; array = (void *)array + sz; } } diff --git a/tools/perf/util/sample.h b/tools/perf/util/sample.h index c4eae8b2fd06..cb4b16654876 100644 --- a/tools/perf/util/sample.h +++ b/tools/perf/util/sample.h @@ -16,6 +16,11 @@ struct regs_dump { u64 abi; u64 mask; u64 *regs; + u64 nr_vectors; + u64 vector_qwords; + u64 nr_pred; + u64 pred_qwords; + u64 *simd_data; /* Cached values/mask filled by first register access. */ u64 cache_regs[PERF_SAMPLE_REGS_CACHE_SIZE]; diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index de3adb32d180..31461946cc85 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -711,8 +711,8 @@ static void set_sample_datasrc_in_dict(PyObject *dict, _PyUnicode_FromString(decode)); } -static void regs_map(struct regs_dump *regs, uint64_t mask, uint16_t e_machine, uint32_t e_flags, - char *bf, int size) +static int regs_map(struct regs_dump *regs, uint64_t mask, uint16_t e_machine, + uint32_t e_flags, char *bf, int size) { unsigned int i = 0, r; int printed = 0; @@ -720,10 +720,10 @@ static void regs_map(struct regs_dump *regs, uint64_t mask, uint16_t e_machine, bf[0] = 0; if (size <= 0) - return; + return 0; if (!regs || !regs->regs) - return; + return 0; for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) { u64 val = regs->regs[i++]; @@ -732,6 +732,90 @@ static void regs_map(struct regs_dump *regs, uint64_t mask, uint16_t e_machine, "%5s:0x%" PRIx64 " ", perf_reg_name(r, e_machine, e_flags, regs->abi), val); } + + return printed; +} + +static void simd_regs_map(struct regs_dump *regs, struct perf_event_attr *attr, + uint16_t e_machine, char *bf, int size, int printed, bool intr) +{ + const char *name = "unknown"; + int reg_c, idx, pred_base; + unsigned int i = 0, j; + uint16_t qwords; + + if (size <= 0 || printed >= size) + return; + + if (!regs || !regs->simd_data) + return; + + if (!regs->nr_vectors && !regs->nr_pred) + return; + + for (reg_c = 0; reg_c < 64; reg_c++) { + if (!regs->nr_vectors) + break; + if (intr) { + perf_intr_simd_reg_class_bitmap_qwords(e_machine, reg_c, + &qwords, /*pred=*/false); + } else { + perf_user_simd_reg_class_bitmap_qwords(e_machine, reg_c, + &qwords, /*pred=*/false); + } + if (regs->vector_qwords == qwords) { + name = perf_simd_reg_class_name(e_machine, reg_c, /*pred=*/false); + break; + } + } + + for (i = 0; i < regs->nr_vectors; i++) { + for (j = 0; j < regs->vector_qwords; j++) { + idx = i * regs->vector_qwords + j; + if (regs->vector_qwords > 1) { + printed += scnprintf(bf + printed, size - printed, + "%5s[%d][%d]:0x%" PRIx64 " ", + name, i, j, regs->simd_data[idx]); + } else { + printed += scnprintf(bf + printed, size - printed, + "%5s[%d]:0x%" PRIx64 " ", + name, i, regs->simd_data[idx]); + } + } + } + + name = "unknown"; + for (reg_c = 0; reg_c < 64; reg_c++) { + if (!regs->nr_pred) + break; + if (intr) { + perf_intr_simd_reg_class_bitmap_qwords(e_machine, reg_c, + &qwords, /*pred=*/true); + } else { + perf_user_simd_reg_class_bitmap_qwords(e_machine, reg_c, + &qwords, /*pred=*/true); + } + if (regs->pred_qwords == qwords) { + name = perf_simd_reg_class_name(e_machine, reg_c, /*pred=*/true); + break; + } + } + + pred_base = regs->nr_vectors * regs->vector_qwords; + for (i = 0; i < regs->nr_pred; i++) { + for (j = 0; j < regs->pred_qwords; j++) { + idx = pred_base + i * regs->pred_qwords + j; + if (regs->pred_qwords > 1) { + printed += scnprintf(bf + printed, size - printed, + "%5s[%d][%d]:0x%" PRIx64 " ", + name, i, j, regs->simd_data[idx]); + } else { + printed += scnprintf(bf + printed, size - printed, + "%5s[%d]:0x%" PRIx64 " ", + name, i, regs->simd_data[idx]); + } + } + } } #define MAX_REG_SIZE 128 @@ -742,16 +826,36 @@ static int set_regs_in_dict(PyObject *dict, uint32_t e_flags) { struct perf_event_attr *attr = &sample->evsel->core.attr; - - int size = (__sw_hweight64(attr->sample_regs_intr) * MAX_REG_SIZE) + 1; + int intr_size, user_size, size; + struct regs_dump *regs; char *bf = NULL; + int printed; + + intr_size = (__sw_hweight64(attr->sample_regs_intr) * MAX_REG_SIZE) + 1; + user_size = (__sw_hweight64(attr->sample_regs_user) * MAX_REG_SIZE) + 1; + if (sample->intr_regs && attr->sample_simd_regs_enabled) { + regs = sample->intr_regs; + intr_size += (regs->nr_vectors * regs->vector_qwords + + regs->nr_pred * regs->pred_qwords) * MAX_REG_SIZE; + } + if (sample->user_regs && attr->sample_simd_regs_enabled) { + regs = sample->user_regs; + user_size += (regs->nr_vectors * regs->vector_qwords + + regs->nr_pred * regs->pred_qwords) * MAX_REG_SIZE; + } + size = intr_size > user_size ? intr_size : user_size; if (sample->intr_regs) { bf = malloc(size); if (!bf) return -1; - regs_map(sample->intr_regs, attr->sample_regs_intr, e_machine, e_flags, bf, size); + printed = regs_map(sample->intr_regs, attr->sample_regs_intr, + e_machine, e_flags, bf, size); + if (attr->sample_simd_regs_enabled) { + simd_regs_map(sample->intr_regs, attr, e_machine, bf, + size, printed, true); + } pydict_set_item_string_decref(dict, "iregs", _PyUnicode_FromString(bf)); @@ -763,7 +867,12 @@ static int set_regs_in_dict(PyObject *dict, if (!bf) return -1; } - regs_map(sample->user_regs, attr->sample_regs_user, e_machine, e_flags, bf, size); + printed = regs_map(sample->user_regs, attr->sample_regs_user, + e_machine, e_flags, bf, size); + if (attr->sample_simd_regs_enabled) { + simd_regs_map(sample->user_regs, attr, e_machine, bf, + size, printed, false); + } pydict_set_item_string_decref(dict, "uregs", _PyUnicode_FromString(bf)); diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 90d4e45f09f0..a5b596cd14be 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1446,6 +1446,86 @@ static void regs_dump__printf(u64 mask, struct regs_dump *regs, } } +static void simd_regs_dump__printf(uint16_t e_machine, struct regs_dump *regs, bool intr) +{ + const char *name = "unknown"; + const char *simd_header; + u32 i, j, idx, pred_base; + uint16_t qwords; + int reg_c; + + if (!(regs->abi & PERF_SAMPLE_REGS_ABI_SIMD)) + return; + + if (!regs->nr_vectors && !regs->nr_pred) + return; + + simd_header = "... SIMD ABI nr_vectors %" PRIu64 " vector_qwords %" PRIu64 \ + " nr_pred %" PRIu64 " pred_qwords %" PRIu64 "\n"; + printf(simd_header, regs->nr_vectors, regs->vector_qwords, + regs->nr_pred, regs->pred_qwords); + + for (reg_c = 0; reg_c < 64; reg_c++) { + if (!regs->nr_vectors) + break; + if (intr) { + perf_intr_simd_reg_class_bitmap_qwords(e_machine, reg_c, + &qwords, /*pred=*/false); + } else { + perf_user_simd_reg_class_bitmap_qwords(e_machine, reg_c, + &qwords, /*pred=*/false); + } + if (regs->vector_qwords == qwords) { + name = perf_simd_reg_class_name(e_machine, reg_c, /*pred=*/false); + break; + } + } + + for (i = 0; i < regs->nr_vectors; i++) { + for (j = 0; j < regs->vector_qwords; j++) { + idx = i * regs->vector_qwords + j; + if (regs->vector_qwords > 1) { + printf(".... %3s[%d][%d] 0x%016" PRIx64 "\n", + name, i, j, regs->simd_data[idx]); + } else { + printf(".... %3s[%d] 0x%016" PRIx64 "\n", + name, i, regs->simd_data[idx]); + } + } + } + + name = "unknown"; + for (reg_c = 0; reg_c < 64; reg_c++) { + if (!regs->nr_pred) + break; + if (intr) { + perf_intr_simd_reg_class_bitmap_qwords(e_machine, reg_c, + &qwords, /*pred=*/true); + } else { + perf_user_simd_reg_class_bitmap_qwords(e_machine, reg_c, + &qwords, /*pred=*/true); + } + if (regs->pred_qwords == qwords) { + name = perf_simd_reg_class_name(e_machine, reg_c, /*pred=*/true); + break; + } + } + + pred_base = regs->nr_vectors * regs->vector_qwords; + for (i = 0; i < regs->nr_pred; i++) { + for (j = 0; j < regs->pred_qwords; j++) { + idx = pred_base + i * regs->pred_qwords + j; + if (regs->pred_qwords > 1) { + printf(".... %3s[%d][%d] 0x%016" PRIx64 "\n", + name, i, j, regs->simd_data[idx]); + } else { + printf(".... %3s[%d] 0x%016" PRIx64 "\n", + name, i, regs->simd_data[idx]); + } + } + } +} + static const char *regs_abi[] = { [PERF_SAMPLE_REGS_ABI_NONE] = "none", [PERF_SAMPLE_REGS_ABI_32] = "32-bit", @@ -1486,6 +1566,7 @@ static void regs_user__printf(struct perf_sample *sample, uint16_t e_machine, ui if (user_regs->regs) regs__printf("user", user_regs, e_machine, e_flags); + simd_regs_dump__printf(e_machine, user_regs, /*intr=*/false); } static void regs_intr__printf(struct perf_sample *sample, uint16_t e_machine, uint32_t e_flags) @@ -1499,6 +1580,7 @@ static void regs_intr__printf(struct perf_sample *sample, uint16_t e_machine, ui if (intr_regs->regs) regs__printf("intr", intr_regs, e_machine, e_flags); + simd_regs_dump__printf(e_machine, intr_regs, /*intr=*/true); } static void stack_user__printf(struct stack_dump *dump) diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c index 503a239b0b10..728d42eaefeb 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -1527,8 +1527,13 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, if (sample->user_regs && sample->user_regs->abi) { result += sizeof(u64); sz = hweight64(sample->user_regs->mask) * sizeof(u64); - if (sample->user_regs->abi & PERF_SAMPLE_REGS_ABI_SIMD) + if (sample->user_regs->abi & PERF_SAMPLE_REGS_ABI_SIMD) { sz += 4 * sizeof(u64); + sz += (sample->user_regs->nr_vectors * + sample->user_regs->vector_qwords + + sample->user_regs->nr_pred * + sample->user_regs->pred_qwords) * sizeof(u64); + } result += sz; } else { result += sizeof(u64); @@ -1557,8 +1562,13 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, if (sample->intr_regs && sample->intr_regs->abi) { result += sizeof(u64); sz = hweight64(sample->intr_regs->mask) * sizeof(u64); - if (sample->intr_regs->abi & PERF_SAMPLE_REGS_ABI_SIMD) + if (sample->intr_regs->abi & PERF_SAMPLE_REGS_ABI_SIMD) { sz += 4 * sizeof(u64); + sz += (sample->intr_regs->nr_vectors * + sample->intr_regs->vector_qwords + + sample->intr_regs->nr_pred * + sample->intr_regs->pred_qwords) * sizeof(u64); + } result += sz; } else { result += sizeof(u64); @@ -1746,6 +1756,18 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_fo sz = hweight64(sample->user_regs->mask) * sizeof(u64); memcpy(array, sample->user_regs->regs, sz); array = (void *)array + sz; + if (sample->user_regs->abi & PERF_SAMPLE_REGS_ABI_SIMD) { + *array++ = sample->user_regs->nr_vectors; + *array++ = sample->user_regs->vector_qwords; + *array++ = sample->user_regs->nr_pred; + *array++ = sample->user_regs->pred_qwords; + sz = (sample->user_regs->nr_vectors * + sample->user_regs->vector_qwords + + sample->user_regs->nr_pred * + sample->user_regs->pred_qwords) * sizeof(u64); + memcpy(array, sample->user_regs->simd_data, sz); + array = (void *)array + sz; + } } else { *array++ = 0; } @@ -1782,6 +1804,18 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_fo sz = hweight64(sample->intr_regs->mask) * sizeof(u64); memcpy(array, sample->intr_regs->regs, sz); array = (void *)array + sz; + if (sample->intr_regs->abi & PERF_SAMPLE_REGS_ABI_SIMD) { + *array++ = sample->intr_regs->nr_vectors; + *array++ = sample->intr_regs->vector_qwords; + *array++ = sample->intr_regs->nr_pred; + *array++ = sample->intr_regs->pred_qwords; + sz = (sample->intr_regs->nr_vectors * + sample->intr_regs->vector_qwords + + sample->intr_regs->nr_pred * + sample->intr_regs->pred_qwords) * sizeof(u64); + memcpy(array, sample->intr_regs->simd_data, sz); + array = (void *)array + sz; + } } else { *array++ = 0; } -- 2.34.1