diff --git a/tools/qfcc/include/spirv.h b/tools/qfcc/include/spirv.h index 14ae12745..ec2433006 100644 --- a/tools/qfcc/include/spirv.h +++ b/tools/qfcc/include/spirv.h @@ -77,6 +77,4 @@ void spirv_set_addressing_model (module_t *module, SpvAddressingModel model); void spirv_set_memory_model (module_t *module, SpvMemoryModel model); 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 diff --git a/tools/qfcc/include/spirv_grammar.h b/tools/qfcc/include/spirv_grammar.h index f4b4156cd..96dd168ac 100644 --- a/tools/qfcc/include/spirv_grammar.h +++ b/tools/qfcc/include/spirv_grammar.h @@ -88,4 +88,11 @@ typedef struct spirv_grammar_s { spirv_kind_t *operand_kinds; } 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 diff --git a/tools/qfcc/source/glsl-builtins.c b/tools/qfcc/source/glsl-builtins.c index 4ff1e08cc..0391925d0 100644 --- a/tools/qfcc/source/glsl-builtins.c +++ b/tools/qfcc/source/glsl-builtins.c @@ -348,7 +348,7 @@ static gentype_t genDType = { #endif #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 = SRC_LINE diff --git a/tools/qfcc/source/spirv_grammar.c b/tools/qfcc/source/spirv_grammar.c index 5968410e3..af4134c2e 100644 --- a/tools/qfcc/source/spirv_grammar.c +++ b/tools/qfcc/source/spirv_grammar.c @@ -433,3 +433,42 @@ spirv_operand_kind (const char *set, const char *kind) } 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; +} diff --git a/tools/qfcc/source/target_spirv.c b/tools/qfcc/source/target_spirv.c index 38cc2e349..5e89f7b01 100644 --- a/tools/qfcc/source/target_spirv.c +++ b/tools/qfcc/source/target_spirv.c @@ -43,6 +43,7 @@ #include "tools/qfcc/include/options.h" #include "tools/qfcc/include/qfcc.h" #include "tools/qfcc/include/spirv.h" +#include "tools/qfcc/include/spirv_grammar.h" #include "tools/qfcc/include/statements.h" #include "tools/qfcc/include/strpool.h" #include "tools/qfcc/include/symtab.h" @@ -1803,7 +1804,7 @@ static unsigned spirv_intrinsic (const expr_t *e, spirvctx_t *ctx) { 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 start = 0; @@ -1813,7 +1814,7 @@ spirv_intrinsic (const expr_t *e, spirvctx_t *ctx) if (op == SpvOpExtInst) { auto set = expr_string (operands[0]); 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; } for (int i = start; i < count; i++) {