mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 07:28:11 +02:00
nir/nir_lower_calls_to_builtins: trivially handle IA64 mangled functions
Using __attribute__((overloadable)) when declaring nir ops with variable-width params in clc results in their symbol names being (IA64) mangled; this change enables the mangled names to be handled when later lowering the calls. Signed-off-by: Simon Perretta <simon.perretta@imgtec.com> Acked-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36873>
This commit is contained in:
parent
082f4b79ae
commit
880098158d
1 changed files with 20 additions and 5 deletions
|
|
@ -3,6 +3,7 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include "nir.h"
|
||||
#include "nir_builder.h"
|
||||
|
||||
|
|
@ -18,7 +19,7 @@
|
|||
*
|
||||
* Mangling allows for multiple definitions of the same instruction with
|
||||
* different vector lengths and bit sizes. This could be combined with
|
||||
* __attribute_((overloadable)) for seamless overloads.
|
||||
* __attribute__((overloadable)) for seamless overloads.
|
||||
*
|
||||
* In effect, this pass re-implements nir_builder dynamically. This exposes
|
||||
* low-level hardware intrinsics to internal driver programs. It is intended for
|
||||
|
|
@ -97,9 +98,23 @@ lower(nir_builder *b, nir_instr *instr, void *data)
|
|||
|
||||
nir_call_instr *call = nir_instr_as_call(instr);
|
||||
nir_function *func = call->callee;
|
||||
const char *intr_name = func->name;
|
||||
unsigned len = strlen(intr_name);
|
||||
|
||||
/* If the function name has been (IA64) mangled,
|
||||
* parse out its length and unmangled name.
|
||||
*/
|
||||
if (!strncmp("_Z", intr_name, strlen("_Z")) && isdigit(intr_name[2])) {
|
||||
char *endptr;
|
||||
len = strtol(&intr_name[2], &endptr, 10);
|
||||
intr_name = endptr;
|
||||
}
|
||||
|
||||
const char *nir_prefix = "nir_";
|
||||
const unsigned nir_prefix_len = strlen(nir_prefix);
|
||||
|
||||
/* We reserve all functions prefixed nir_* as builtins needing lowering. */
|
||||
if (strncmp("nir_", func->name, strlen("nir_")) != 0)
|
||||
if (strncmp(nir_prefix, intr_name, nir_prefix_len) != 0)
|
||||
return false;
|
||||
|
||||
/* Strip the nir_ prefix to give the name of an ALU opcode or intrinsic. Also
|
||||
|
|
@ -107,9 +122,9 @@ lower(nir_builder *b, nir_instr *instr, void *data)
|
|||
* can recover vector lengths / bit sizes from the NIR. This implements a
|
||||
* crude form of function overloading.
|
||||
*/
|
||||
const char *intr_name = func->name + strlen("nir_");
|
||||
intr_name += nir_prefix_len;
|
||||
const char *suffix = strstr(intr_name, "__");
|
||||
unsigned len = (suffix != NULL) ? (suffix - intr_name) : strlen(intr_name);
|
||||
len = (suffix != NULL) ? (suffix - intr_name) : (len - nir_prefix_len);
|
||||
|
||||
/* From this point on, we must not fail. Remove the call. */
|
||||
b->cursor = nir_instr_remove(&call->instr);
|
||||
|
|
@ -135,7 +150,7 @@ lower(nir_builder *b, nir_instr *instr, void *data)
|
|||
}
|
||||
|
||||
/* We must have matched something! */
|
||||
fprintf(stderr, "unknown opcode %s\n", func->name);
|
||||
fprintf(stderr, "unknown opcode %.*s\n", len, intr_name);
|
||||
UNREACHABLE("invalid nir opcode/intrinsic");
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue