#include "util/parse-branch-options.h"
 #include "util/evsel_config.h"
 #include "util/event.h"
-#include "util/parse-events-hybrid.h"
 #include "util/pmu-hybrid.h"
 #include "util/bpf-filter.h"
 #include "util/util.h"
 #endif
 }
 
-int parse_events_add_numeric(struct parse_events_state *parse_state,
-                            struct list_head *list,
-                            u32 type, u64 config,
-                            struct list_head *head_config)
+static int __parse_events_add_numeric(struct parse_events_state *parse_state,
+                               struct list_head *list,
+                               struct perf_pmu *pmu, u32 type, u64 config,
+                               struct list_head *head_config)
 {
        struct perf_event_attr attr;
        LIST_HEAD(config_terms);
        const char *name, *metric_id;
-       bool hybrid;
        int ret;
 
        memset(&attr, 0, sizeof(attr));
 
        name = get_config_name(head_config);
        metric_id = get_config_metric_id(head_config);
-       ret = parse_events__add_numeric_hybrid(parse_state, list, &attr,
-                                              name, metric_id,
-                                              &config_terms, &hybrid);
-       if (hybrid)
-               goto out_free_terms;
-
-       ret = add_event(list, &parse_state->idx, &attr, name, metric_id,
-                       &config_terms);
-out_free_terms:
+       ret = __add_event(list, &parse_state->idx, &attr, /*init_attr*/true, name,
+                       metric_id, pmu, &config_terms, /*auto_merge_stats=*/false,
+                       /*cpu_list=*/NULL) ? 0 : -ENOMEM;
        free_config_terms(&config_terms);
        return ret;
 }
 
+int parse_events_add_numeric(struct parse_events_state *parse_state,
+                            struct list_head *list,
+                            u32 type, u64 config,
+                            struct list_head *head_config,
+                            bool wildcard)
+{
+       struct perf_pmu *pmu = NULL;
+       bool found_supported = false;
+
+       if (!wildcard)
+               return __parse_events_add_numeric(parse_state, list, /*pmu=*/NULL,
+                                                 type, config, head_config);
+
+       while ((pmu = perf_pmu__scan(pmu)) != NULL) {
+               int ret;
+
+               if (!perf_pmu__supports_wildcard_numeric(pmu))
+                       continue;
+
+               found_supported = true;
+               ret = __parse_events_add_numeric(parse_state, list, pmu, pmu->type,
+                                                config, head_config);
+               if (ret)
+                       return ret;
+       }
+       return found_supported ? 0 : -EINVAL;
+}
+
 int parse_events_add_tool(struct parse_events_state *parse_state,
                          struct list_head *list,
                          int tool_event)
 
 
        list = alloc_list();
        ABORT_ON(!list);
-       err = parse_events_add_numeric(_parse_state, list, type, config, $3);
+       err = parse_events_add_numeric(_parse_state, list, type, config, $3,
+                                      /*wildcard=*/false);
        parse_events_terms__delete($3);
        if (err) {
                free_list_evsel(list);
 
        list = alloc_list();
        ABORT_ON(!list);
-       ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config, NULL));
+       ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config,
+                                         /*head_config=*/NULL,
+                                         /*wildcard=*/false));
        $$ = list;
 }
 |
 
        list = alloc_list();
        ABORT_ON(!list);
-       err = parse_events_add_numeric(_parse_state, list, (u32)$1, $3, $4);
+       err = parse_events_add_numeric(_parse_state, list, (u32)$1, $3, $4,
+                                      /*wildcard=*/false);
        parse_events_terms__delete($4);
        if (err) {
                free(list);
        num = strtoull($1 + 1, NULL, 16);
        ABORT_ON(errno);
        free($1);
-       err = parse_events_add_numeric(_parse_state, list, PERF_TYPE_RAW, num, $2);
+       err = parse_events_add_numeric(_parse_state, list, PERF_TYPE_RAW, num, $2,
+                                      /*wildcard=*/true);
        parse_events_terms__delete($2);
        if (err) {
                free(list);