2025-02-28 14:17:32 +01:00
|
|
|
#!/usr/bin/perl -w
|
|
|
|
#
|
|
|
|
# Copyright 2025 Henri Verbeet
|
|
|
|
#
|
|
|
|
# This library is free software; you can redistribute it and/or
|
|
|
|
# modify it under the terms of the GNU Lesser General Public
|
|
|
|
# License as published by the Free Software Foundation; either
|
|
|
|
# version 2.1 of the License, or (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This library is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
# Lesser General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU Lesser General Public
|
|
|
|
# License along with this library; if not, write to the Free Software
|
|
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
|
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
use JSON;
|
|
|
|
use open ':utf8';
|
|
|
|
binmode STDOUT, ':utf8';
|
|
|
|
|
|
|
|
sub opcode_id($)
|
|
|
|
{
|
|
|
|
sprintf "0x%04x", shift;
|
|
|
|
}
|
|
|
|
|
2025-02-28 14:53:01 +01:00
|
|
|
sub fix_name($)
|
|
|
|
{
|
|
|
|
shift =~ s/([A-Z]+)/_$1/rg;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub operand_type_name(_)
|
|
|
|
{
|
|
|
|
"SPIRV_PARSER_OPERAND_TYPE${\uc fix_name shift}";
|
|
|
|
}
|
|
|
|
|
2025-02-28 14:17:32 +01:00
|
|
|
sub grammar_version($)
|
|
|
|
{
|
|
|
|
my ($grammar) = @_;
|
|
|
|
|
|
|
|
"$grammar->{major_version}.$grammar->{minor_version}.$grammar->{revision}";
|
|
|
|
}
|
|
|
|
|
2025-02-28 14:53:01 +01:00
|
|
|
sub instruction_operand(_)
|
|
|
|
{
|
|
|
|
my ($operand) = @_;
|
|
|
|
|
|
|
|
"{${\operand_type_name $operand->{kind}}" . (defined $operand->{quantifier} ? ", '$operand->{quantifier}'}" : "}");
|
|
|
|
}
|
|
|
|
|
2025-02-28 14:17:32 +01:00
|
|
|
sub print_opcode_info(_)
|
|
|
|
{
|
|
|
|
my ($instruction) = @_;
|
|
|
|
my $operand_count = @{$instruction->{operands} // []};
|
|
|
|
|
2025-02-28 14:53:01 +01:00
|
|
|
if (!$operand_count)
|
|
|
|
{
|
|
|
|
print " {${\opcode_id $instruction->{opcode}}, \"$instruction->{opname}\"},\n";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
print " {\n";
|
|
|
|
print " ${\opcode_id $instruction->{opcode}}, \"$instruction->{opname}\", $operand_count,\n";
|
|
|
|
print " (struct spirv_parser_instruction_operand[])\n";
|
|
|
|
print " {\n";
|
|
|
|
print " ${\instruction_operand},\n" foreach @{$instruction->{operands}};
|
|
|
|
print " }\n";
|
|
|
|
print " },\n";
|
2025-02-28 14:17:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
sub print_header($)
|
|
|
|
{
|
|
|
|
my ($grammar) = @_;
|
2025-02-28 14:53:01 +01:00
|
|
|
my @operand_types = sort {$a->{kind} cmp $b->{kind}} @{$grammar->{operand_kinds}};
|
2025-02-28 14:17:32 +01:00
|
|
|
|
|
|
|
print "/* This file is automatically generated from version ${\grammar_version $grammar} of the\n";
|
|
|
|
print " * machine-readable SPIR-V grammar.\n";
|
|
|
|
print " *\n";
|
|
|
|
print " * The original source is covered by the following license:\n";
|
|
|
|
print " *\n";
|
|
|
|
print map {" * $_" =~ s/ +$//r . "\n"} @{$grammar->{copyright}};
|
|
|
|
print " */\n\n";
|
|
|
|
|
2025-02-28 14:53:01 +01:00
|
|
|
print "enum spirv_parser_operand_type\n";
|
|
|
|
print "{\n";
|
|
|
|
print " ${\operand_type_name $_->{kind}},\n" foreach @operand_types;
|
|
|
|
print "};\n\n";
|
|
|
|
|
|
|
|
print "static const struct spirv_parser_operand_type_info\n";
|
|
|
|
print "{\n";
|
|
|
|
print " const char *name;\n";
|
|
|
|
print "}\n";
|
|
|
|
print "spirv_parser_operand_type_info[] =\n";
|
|
|
|
print "{\n";
|
|
|
|
print " [${\operand_type_name $_->{kind}}] = {\"$_->{kind}\"},\n" foreach @operand_types;
|
|
|
|
print "};\n\n";
|
|
|
|
|
2025-02-28 14:17:32 +01:00
|
|
|
print "static const struct spirv_parser_opcode_info\n";
|
|
|
|
print "{\n";
|
|
|
|
print " uint16_t op;\n";
|
|
|
|
print " const char *name;\n";
|
|
|
|
print " size_t operand_count;\n";
|
2025-02-28 14:53:01 +01:00
|
|
|
print " const struct spirv_parser_instruction_operand\n";
|
|
|
|
print " {\n";
|
|
|
|
print " enum spirv_parser_operand_type type;\n";
|
|
|
|
print " char quantifier;\n";
|
|
|
|
print " } *operands;\n";
|
2025-02-28 14:17:32 +01:00
|
|
|
print "}\n";
|
|
|
|
print "spirv_parser_opcode_info[] =\n";
|
|
|
|
print "{\n";
|
|
|
|
print_opcode_info foreach sort {$a->{opcode} <=> $b->{opcode}} @{$grammar->{instructions}};
|
|
|
|
print "};\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
die "No input file specified.\n" unless @ARGV;
|
|
|
|
print_header do
|
|
|
|
{
|
|
|
|
local $/;
|
|
|
|
open my $fh, '<', $ARGV[0] or die $!;
|
|
|
|
decode_json <$fh>;
|
|
|
|
};
|