diff --git a/src/freedreno/decode/rnnutil.c b/src/freedreno/decode/rnnutil.c index 38b676a1d6e..c73c74ff289 100644 --- a/src/freedreno/decode/rnnutil.c +++ b/src/freedreno/decode/rnnutil.c @@ -10,16 +10,32 @@ #include #include +#include #include #include #include #include +#include "rnn.h" #include "rnnutil.h" +static bool +in_range(struct rnndomain *dom, uint32_t regbase) +{ + return (dom->minoff <= regbase) && (regbase <= dom->maxoff); +} + static struct rnndomain * finddom(struct rnn *rnn, uint32_t regbase) { + /* A2XX/A3XX have split domains with common regs.. but the ranges + * overlap so we can't just use in_range() for a fast compare: + * + * Everything else has dom[0]==dom[1] so we can skip the extra + * lookup. + */ + if (rnn->dom[0] == rnn->dom[1]) + return rnn->dom[0]; if (rnndec_checkaddr(rnn->vc, rnn->dom[0], regbase, 0)) return rnn->dom[0]; return rnn->dom[1]; @@ -118,9 +134,13 @@ rnn_regname(struct rnn *rnn, uint32_t regbase, int color) { static char buf[128]; struct rnndecaddrinfo *info; + struct rnndomain *dom = finddom(rnn, regbase); + + if (!in_range(dom, regbase)) + return NULL; info = rnndec_decodeaddr(color ? rnn->vc : rnn->vc_nocolor, - finddom(rnn, regbase), regbase, 0); + dom, regbase, 0); if (info) { strcpy(buf, info->name); free(info->name); diff --git a/src/freedreno/rnn/rnn.c b/src/freedreno/rnn/rnn.c index db29978e298..b954bbf9e3a 100644 --- a/src/freedreno/rnn/rnn.c +++ b/src/freedreno/rnn/rnn.c @@ -712,6 +712,8 @@ static void parsedomain(struct rnndb *db, char *file, xmlNode *node) { cur->varinfo.varsetstr = varsetstr; cur->varinfo.variantsstr = variantsstr; cur->file = file; + cur->maxoff = 0; + cur->minoff = ~0; ADDARRAY(db->domains, cur); } xmlNode *chain = node->children; @@ -720,6 +722,8 @@ static void parsedomain(struct rnndb *db, char *file, xmlNode *node) { if (chain->type != XML_ELEMENT_NODE) { } else if ((delem = trydelem(db, file, chain))) { ADDARRAY(cur->subelems, delem); + cur->minoff = MIN2(cur->minoff, delem->offset); + cur->maxoff = MAX2(cur->maxoff, delem->offset + (delem->length * delem->stride)); } else if (!trytop(db, file, chain) && !trydoc(db, file, chain)) { rnn_err(db, "%s:%d: wrong tag in domain: <%s>\n", file, chain->line, chain->name); } diff --git a/src/freedreno/rnn/rnn.h b/src/freedreno/rnn/rnn.h index b87a306822c..5cd785d0dde 100644 --- a/src/freedreno/rnn/rnn.h +++ b/src/freedreno/rnn/rnn.h @@ -164,6 +164,8 @@ struct rnndomain { int subelemsmax; char *fullname; char *file; + unsigned minoff; + unsigned maxoff; }; struct rnngroup {