.. | .. |
---|
1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
---|
2 | | -#include "perf.h" |
---|
3 | | -#include "util/util.h" |
---|
| 2 | +#include <stdbool.h> |
---|
| 3 | +#include <stdlib.h> |
---|
| 4 | +#include <stdint.h> |
---|
| 5 | +#include <string.h> |
---|
| 6 | +#include <stdio.h> |
---|
4 | 7 | #include "util/debug.h" |
---|
5 | 8 | #include <subcmd/parse-options.h> |
---|
| 9 | +#include "util/perf_regs.h" |
---|
6 | 10 | #include "util/parse-regs-options.h" |
---|
7 | 11 | |
---|
8 | | -int |
---|
9 | | -parse_regs(const struct option *opt, const char *str, int unset) |
---|
| 12 | +static int |
---|
| 13 | +__parse_regs(const struct option *opt, const char *str, int unset, bool intr) |
---|
10 | 14 | { |
---|
11 | 15 | uint64_t *mode = (uint64_t *)opt->value; |
---|
12 | | - const struct sample_reg *r; |
---|
| 16 | + const struct sample_reg *r = NULL; |
---|
13 | 17 | char *s, *os = NULL, *p; |
---|
14 | 18 | int ret = -1; |
---|
| 19 | + uint64_t mask; |
---|
15 | 20 | |
---|
16 | 21 | if (unset) |
---|
17 | 22 | return 0; |
---|
.. | .. |
---|
21 | 26 | */ |
---|
22 | 27 | if (*mode) |
---|
23 | 28 | return -1; |
---|
| 29 | + |
---|
| 30 | + if (intr) |
---|
| 31 | + mask = arch__intr_reg_mask(); |
---|
| 32 | + else |
---|
| 33 | + mask = arch__user_reg_mask(); |
---|
24 | 34 | |
---|
25 | 35 | /* str may be NULL in case no arg is passed to -I */ |
---|
26 | 36 | if (str) { |
---|
.. | .. |
---|
36 | 46 | |
---|
37 | 47 | if (!strcmp(s, "?")) { |
---|
38 | 48 | fprintf(stderr, "available registers: "); |
---|
| 49 | +#ifdef HAVE_PERF_REGS_SUPPORT |
---|
39 | 50 | for (r = sample_reg_masks; r->name; r++) { |
---|
40 | | - fprintf(stderr, "%s ", r->name); |
---|
| 51 | + if (r->mask & mask) |
---|
| 52 | + fprintf(stderr, "%s ", r->name); |
---|
41 | 53 | } |
---|
| 54 | +#endif |
---|
42 | 55 | fputc('\n', stderr); |
---|
43 | 56 | /* just printing available regs */ |
---|
44 | 57 | goto error; |
---|
45 | 58 | } |
---|
| 59 | +#ifdef HAVE_PERF_REGS_SUPPORT |
---|
46 | 60 | for (r = sample_reg_masks; r->name; r++) { |
---|
47 | | - if (!strcasecmp(s, r->name)) |
---|
| 61 | + if ((r->mask & mask) && !strcasecmp(s, r->name)) |
---|
48 | 62 | break; |
---|
49 | 63 | } |
---|
50 | | - if (!r->name) { |
---|
51 | | - ui__warning("unknown register %s," |
---|
52 | | - " check man page\n", s); |
---|
| 64 | +#endif |
---|
| 65 | + if (!r || !r->name) { |
---|
| 66 | + ui__warning("Unknown register \"%s\", check man page or run \"perf record %s?\"\n", |
---|
| 67 | + s, intr ? "-I" : "--user-regs="); |
---|
53 | 68 | goto error; |
---|
54 | 69 | } |
---|
55 | 70 | |
---|
.. | .. |
---|
65 | 80 | |
---|
66 | 81 | /* default to all possible regs */ |
---|
67 | 82 | if (*mode == 0) |
---|
68 | | - *mode = PERF_REGS_MASK; |
---|
| 83 | + *mode = mask; |
---|
69 | 84 | error: |
---|
70 | 85 | free(os); |
---|
71 | 86 | return ret; |
---|
72 | 87 | } |
---|
| 88 | + |
---|
| 89 | +int |
---|
| 90 | +parse_user_regs(const struct option *opt, const char *str, int unset) |
---|
| 91 | +{ |
---|
| 92 | + return __parse_regs(opt, str, unset, false); |
---|
| 93 | +} |
---|
| 94 | + |
---|
| 95 | +int |
---|
| 96 | +parse_intr_regs(const struct option *opt, const char *str, int unset) |
---|
| 97 | +{ |
---|
| 98 | + return __parse_regs(opt, str, unset, true); |
---|
| 99 | +} |
---|