mirror of
https://github.com/torvalds/linux.git
synced 2026-11-10 17:11:02 +01:00
perf regs: Enable dumping of SIMD registers
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 <kan.liang@linux.intel.com> Signed-off-by: Kan Liang <kan.liang@linux.intel.com> Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
6e9c063d8f
commit
01ee8c1435
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -3715,9 +3715,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -3779,9 +3809,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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -1644,8 +1644,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);
|
||||
|
|
@ -1674,8 +1679,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);
|
||||
|
|
@ -1863,6 +1873,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;
|
||||
}
|
||||
|
|
@ -1899,6 +1921,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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user