[qfcc] Implement spirv instruction lookup

Yay, no more magic numbers for intrinsics :)
This commit is contained in:
Bill Currie 2025-01-13 21:38:35 +09:00
parent 9dca83d40a
commit 041216182e
5 changed files with 50 additions and 5 deletions

View file

@ -77,6 +77,4 @@ void spirv_set_addressing_model (module_t *module, SpvAddressingModel model);
void spirv_set_memory_model (module_t *module, SpvMemoryModel model); void spirv_set_memory_model (module_t *module, SpvMemoryModel model);
bool spirv_write (struct pr_info_s *pr, const char *filename); bool spirv_write (struct pr_info_s *pr, const char *filename);
const struct plitem_s *spirv_operand_kind (const char *set, const char *kind);
#endif//__spirv_h #endif//__spirv_h

View file

@ -88,4 +88,11 @@ typedef struct spirv_grammar_s {
spirv_kind_t *operand_kinds; spirv_kind_t *operand_kinds;
} spirv_grammar_t; } spirv_grammar_t;
typedef struct plitem_s plitem_t;
typedef struct expr_s expr_t;
const plitem_t *spirv_operand_kind (const char *set, const char *kind);
uint32_t spirv_instruction_opcode (const char *set, const expr_t *opcode);
#endif//__spirv_grammar_h #endif//__spirv_grammar_h

View file

@ -348,7 +348,7 @@ static gentype_t genDType = {
#endif #endif
#define SPV(op) "@intrinsic(" #op ")" #define SPV(op) "@intrinsic(" #op ")"
#define GLSL(op) "@intrinsic(12, \"GLSL.std.450\", " #op ")" #define GLSL(op) "@intrinsic(OpExtInst, \"GLSL.std.450\", " #op ")"
static const char *glsl_general_functions = static const char *glsl_general_functions =
SRC_LINE SRC_LINE

View file

@ -433,3 +433,42 @@ spirv_operand_kind (const char *set, const char *kind)
} }
return nullptr; return nullptr;
} }
const uint32_t
spirv_instruction_opcode (const char *set, const expr_t *opcode)
{
if (!built) {
build_grammars ();
built = true;
}
if (is_integral_val (opcode)) {
return expr_integral (opcode);
}
if (opcode->type != ex_symbol) {
error (opcode, "not a an integer constant or symbol");
return 0;
}
spirv_grammar_t *grammar = nullptr;
for (int i = 0; builtin_json[i].name; i++) {
if (strcmp (builtin_json[i].name, set) == 0) {
grammar = builtin_json[i].grammar;
break;
}
}
if (!grammar) {
error (opcode, "unrecognized grammar set %s", set);
return 0;
}
const char *opname = opcode->symbol->name;
const spirv_instruction_t *instruction = nullptr;
instruction = bsearch (&(spirv_instruction_t) { .opname = opname },
grammar->instructions, grammar->num_instructions,
sizeof (spirv_instruction_t), spirv_instruction_cmp);
if (!instruction) {
error (opcode, "unknown instruction opcode %s", opname);
return 0;
}
return instruction->opcode;
}

View file

@ -43,6 +43,7 @@
#include "tools/qfcc/include/options.h" #include "tools/qfcc/include/options.h"
#include "tools/qfcc/include/qfcc.h" #include "tools/qfcc/include/qfcc.h"
#include "tools/qfcc/include/spirv.h" #include "tools/qfcc/include/spirv.h"
#include "tools/qfcc/include/spirv_grammar.h"
#include "tools/qfcc/include/statements.h" #include "tools/qfcc/include/statements.h"
#include "tools/qfcc/include/strpool.h" #include "tools/qfcc/include/strpool.h"
#include "tools/qfcc/include/symtab.h" #include "tools/qfcc/include/symtab.h"
@ -1803,7 +1804,7 @@ static unsigned
spirv_intrinsic (const expr_t *e, spirvctx_t *ctx) spirv_intrinsic (const expr_t *e, spirvctx_t *ctx)
{ {
auto intr = e->intrinsic; auto intr = e->intrinsic;
unsigned op = expr_integral (intr.opcode); unsigned op = spirv_instruction_opcode ("core", intr.opcode);
int count = list_count (&intr.operands); int count = list_count (&intr.operands);
int start = 0; int start = 0;
@ -1813,7 +1814,7 @@ spirv_intrinsic (const expr_t *e, spirvctx_t *ctx)
if (op == SpvOpExtInst) { if (op == SpvOpExtInst) {
auto set = expr_string (operands[0]); auto set = expr_string (operands[0]);
op_ids[0] = spirv_extinst_import (ctx->module, set, ctx); op_ids[0] = spirv_extinst_import (ctx->module, set, ctx);
op_ids[1] = expr_integral (operands[1]); op_ids[1] = spirv_instruction_opcode (set, operands[1]);
start = 2; start = 2;
} }
for (int i = start; i < count; i++) { for (int i = start; i < count; i++) {