mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-12-25 01:01:04 +00:00
Generate spvasm.vim
Generate a vim syntax file for SPIR-V assembly. Copy the resulting spvasm.vim into your $HOME/.vim/syntax directory to get syntax highlighting in Vim. Also, suggest that the grammar file include information about what opcodes can be used in OpSpecConstantOp.
This commit is contained in:
parent
68c5f0436f
commit
f8cc397573
2
CHANGES
2
CHANGES
@ -1,6 +1,8 @@
|
||||
Revision history for SPIRV-Tools
|
||||
|
||||
v2016.7-dev 2016-12-13
|
||||
- Add build target spirv-tools-vimsyntax to generate spvasm.vim, a SPIR-V
|
||||
assembly syntax file for Vim.
|
||||
|
||||
v2016.6 2016-12-13
|
||||
- Published the C++ interface for assembling, disassembling, validation, and
|
||||
|
10
README.md
10
README.md
@ -89,6 +89,13 @@ Currently supported optimizations:
|
||||
For the latest list with detailed documentation, please refer to
|
||||
[`include/spirv-tools/optimizer.hpp`](include/spirv-tools/optimizer.hpp).
|
||||
|
||||
### Extras
|
||||
|
||||
* [Utility filters](#utility-filters)
|
||||
* Build target `spirv-tools-vimsyntax` generates file `spvasm.vim`.
|
||||
Copy that file into your `$HOME/.vim/syntax` directory to get SPIR-V assembly syntax
|
||||
highlighting in Vim. This build target is not built by default.
|
||||
|
||||
## Source code
|
||||
|
||||
The SPIR-V Tools are maintained by members of the The Khronos Group Inc.,
|
||||
@ -332,6 +339,9 @@ tests.
|
||||
## Future Work
|
||||
<a name="future"></a>
|
||||
|
||||
_See the [projects pages](https://github.com/KhronosGroup/SPIRV-Tools/projects)
|
||||
for more information._
|
||||
|
||||
### Assembler and disassembler
|
||||
|
||||
* The disassembler could emit helpful annotations in comments. For example:
|
||||
|
@ -13,6 +13,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
set(GRAMMAR_PROCESSING_SCRIPT "${spirv-tools_SOURCE_DIR}/utils/generate_grammar_tables.py")
|
||||
set(VIMSYNTAX_PROCESSING_SCRIPT "${spirv-tools_SOURCE_DIR}/utils/generate_vim_syntax.py")
|
||||
set(XML_REGISTRY_PROCESSING_SCRIPT "${spirv-tools_SOURCE_DIR}/utils/generate_registry_tables.py")
|
||||
|
||||
# macro() definitions are used in the following because we need to append .inc
|
||||
@ -34,6 +35,22 @@ macro(spvtools_core_tables VERSION)
|
||||
list(APPEND OPERAND_CPP_DEPENDS ${GRAMMAR_KINDS_INC_FILE})
|
||||
endmacro(spvtools_core_tables)
|
||||
|
||||
macro(spvtools_vimsyntax VERSION CLVERSION)
|
||||
set(GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${VERSION}/spirv.core.grammar.json")
|
||||
set(GLSL_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${VERSION}/extinst.glsl.std.450.grammar.json")
|
||||
set(OPENCL_GRAMMAR_JSON_FILE "${CMAKE_CURRENT_SOURCE_DIR}/extinst-1.0.opencl.std.grammar.json")
|
||||
set(VIMSYNTAX_FILE "${spirv-tools_BINARY_DIR}/spvasm.vim")
|
||||
add_custom_command(OUTPUT ${VIMSYNTAX_FILE}
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${VIMSYNTAX_PROCESSING_SCRIPT}
|
||||
--spirv-core-grammar=${GRAMMAR_JSON_FILE}
|
||||
--extinst-glsl-grammar=${GLSL_GRAMMAR_JSON_FILE}
|
||||
--extinst-opencl-grammar=${OPENCL_GRAMMAR_JSON_FILE}
|
||||
>${VIMSYNTAX_FILE}
|
||||
DEPENDS ${VIMSYNTAX_PROCESSING_SCRIPT} ${GRAMMAR_JSON_FILE}
|
||||
${GLSL_GRAMMAR_JSON_FILE} ${OPENCL_GRAMMAR_JSON_FILE}
|
||||
COMMENT "Generate spvasm.vim: Vim syntax file for SPIR-V assembly.")
|
||||
endmacro(spvtools_vimsyntax)
|
||||
|
||||
macro(spvtools_glsl_tables VERSION)
|
||||
set(CORE_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${VERSION}/spirv.core.grammar.json")
|
||||
set(GLSL_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${VERSION}/extinst.glsl.std.450.grammar.json")
|
||||
@ -67,6 +84,9 @@ spvtools_core_tables("1.1")
|
||||
spvtools_opencl_tables("1.0")
|
||||
spvtools_glsl_tables("1.0")
|
||||
|
||||
spvtools_vimsyntax("1.1" "1.0")
|
||||
add_custom_target(spirv-tools-vimsyntax DEPENDS ${VIMSYNTAX_FILE})
|
||||
|
||||
|
||||
# Extract the list of known generators from the SPIR-V XML registry file.
|
||||
set(GENERATOR_INC_FILE ${spirv-tools_BINARY_DIR}/generators.inc)
|
||||
|
192
utils/generate_vim_syntax.py
Executable file
192
utils/generate_vim_syntax.py
Executable file
@ -0,0 +1,192 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright (c) 2016 Google Inc.
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
"""Generates Vim syntax rules for SPIR-V assembly (.spvasm) files"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import json
|
||||
|
||||
PREAMBLE="""" Vim syntax file
|
||||
" Language: spvasm
|
||||
" Generated by SPIRV-Tools
|
||||
|
||||
if version < 600
|
||||
syntax clear
|
||||
elseif exists("b:current_syntax")
|
||||
finish
|
||||
endif
|
||||
|
||||
syn case match
|
||||
"""
|
||||
|
||||
POSTAMBLE="""
|
||||
|
||||
syntax keyword spvasmTodo TODO FIXME contained
|
||||
|
||||
syn match spvasmIdNumber /%\d\+\>/
|
||||
|
||||
" The assembler treats the leading minus sign as part of the number token.
|
||||
" This applies to integers, and to floats below.
|
||||
syn match spvasmNumber /-\?\<\d\+\>/
|
||||
|
||||
" Floating point literals.
|
||||
" In general, C++ requires at least digit in the mantissa, and the
|
||||
" floating point is optional. This applies to both the regular decimal float
|
||||
" case and the hex float case.
|
||||
|
||||
" First case: digits before the optional decimal, no trailing digits.
|
||||
syn match spvasmFloat /-\?\d\+\.\?\(e[+-]\d\+\)\?/
|
||||
" Second case: optional digits before decimal, trailing digits
|
||||
syn match spvasmFloat /-\?\d*\.\d\+\(e[+-]\d\+\)\?/
|
||||
|
||||
" First case: hex digits before the optional decimal, no trailing hex digits.
|
||||
syn match spvasmFloat /-\?0[xX]\\x\+\.\?p[-+]\d\+/
|
||||
" Second case: optional hex digits before decimal, trailing hex digits
|
||||
syn match spvasmFloat /-\?0[xX]\\x*\.\\x\+p[-+]\d\+/
|
||||
|
||||
syn match spvasmComment /;.*$/ contains=spvasmTodo
|
||||
syn region spvasmString start=/"/ skip=/\\\\"/ end=/"/
|
||||
syn match spvasmId /%[a-zA-Z_][a-zA-Z_0-9]*/
|
||||
|
||||
" Highlight unknown constants and statements as errors
|
||||
syn match spvasmError /[a-zA-Z][a-zA-Z_0-9]*/
|
||||
|
||||
|
||||
if version >= 508 || !exists("did_c_syn_inits")
|
||||
if version < 508
|
||||
let did_c_syn_inits = 1
|
||||
command -nargs=+ HiLink hi link <args>
|
||||
else
|
||||
command -nargs=+ HiLink hi def link <args>
|
||||
endif
|
||||
|
||||
HiLink spvasmStatement Statement
|
||||
HiLink spvasmNumber Number
|
||||
HiLink spvasmComment Comment
|
||||
HiLink spvasmString String
|
||||
HiLink spvasmFloat Float
|
||||
HiLink spvasmConstant Constant
|
||||
HiLink spvasmIdNumber Identifier
|
||||
HiLink spvasmId Identifier
|
||||
HiLink spvasmTodo Todo
|
||||
|
||||
delcommand HiLink
|
||||
endif
|
||||
|
||||
let b:current_syntax = "spvasm"
|
||||
"""
|
||||
|
||||
# This list is taken from the description of OpSpecConstantOp in SPIR-V 1.1.
|
||||
# TODO(dneto): Propose that this information be embedded in the grammar file.
|
||||
SPEC_CONSTANT_OP_OPCODES = """
|
||||
OpSConvert, OpFConvert
|
||||
OpSNegate, OpNot
|
||||
OpIAdd, OpISub
|
||||
OpIMul, OpUDiv, OpSDiv, OpUMod, OpSRem, OpSMod
|
||||
OpShiftRightLogical, OpShiftRightArithmetic, OpShiftLeftLogical
|
||||
OpBitwiseOr, OpBitwiseXor, OpBitwiseAnd
|
||||
OpVectorShuffle, OpCompositeExtract, OpCompositeInsert
|
||||
OpLogicalOr, OpLogicalAnd, OpLogicalNot,
|
||||
OpLogicalEqual, OpLogicalNotEqual
|
||||
OpSelect
|
||||
OpIEqual, OpINotEqual
|
||||
OpULessThan, OpSLessThan
|
||||
OpUGreaterThan, OpSGreaterThan
|
||||
OpULessThanEqual, OpSLessThanEqual
|
||||
OpUGreaterThanEqual, OpSGreaterThanEqual
|
||||
|
||||
OpQuantizeToF16
|
||||
|
||||
OpConvertFToS, OpConvertSToF
|
||||
OpConvertFToU, OpConvertUToF
|
||||
OpUConvert
|
||||
OpConvertPtrToU, OpConvertUToPtr
|
||||
OpGenericCastToPtr, OpPtrCastToGeneric
|
||||
OpBitcast
|
||||
OpFNegate
|
||||
OpFAdd, OpFSub
|
||||
OpFMul, OpFDiv
|
||||
OpFRem, OpFMod
|
||||
OpAccessChain, OpInBoundsAccessChain
|
||||
OpPtrAccessChain, OpInBoundsPtrAccessChain"""
|
||||
|
||||
|
||||
def EmitAsStatement(name):
|
||||
"""Emits the given name as a statement token"""
|
||||
print('syn keyword spvasmStatement', name)
|
||||
|
||||
|
||||
def EmitAsEnumerant(name):
|
||||
"""Emits the given name as an named operand token"""
|
||||
print('syn keyword spvasmConstant', name)
|
||||
|
||||
|
||||
def main():
|
||||
"""Parses arguments, then generates the Vim syntax rules for SPIR-V assembly
|
||||
on stdout."""
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser(description='Generate SPIR-V info tables')
|
||||
parser.add_argument('--spirv-core-grammar', metavar='<path>',
|
||||
type=str, required=True,
|
||||
help='input JSON grammar file for core SPIR-V '
|
||||
'instructions')
|
||||
parser.add_argument('--extinst-glsl-grammar', metavar='<path>',
|
||||
type=str, required=False, default=None,
|
||||
help='input JSON grammar file for GLSL extended '
|
||||
'instruction set')
|
||||
parser.add_argument('--extinst-opencl-grammar', metavar='<path>',
|
||||
type=str, required=False, default=None,
|
||||
help='input JSON grammar file for OpenGL extended '
|
||||
'instruction set')
|
||||
args = parser.parse_args()
|
||||
|
||||
# Generate the syntax rules.
|
||||
print(PREAMBLE)
|
||||
|
||||
core = json.loads(open(args.spirv_core_grammar).read())
|
||||
print('\n" Core instructions')
|
||||
for inst in core["instructions"]:
|
||||
EmitAsStatement(inst['opname'])
|
||||
print('\n" Core operand enums')
|
||||
for operand_kind in core["operand_kinds"]:
|
||||
if 'enumerants' in operand_kind:
|
||||
for e in operand_kind['enumerants']:
|
||||
EmitAsEnumerant(e['enumerant'])
|
||||
|
||||
if args.extinst_glsl_grammar is not None:
|
||||
print('\n" GLSL.std.450 extended instructions')
|
||||
glsl = json.loads(open(args.extinst_glsl_grammar).read())
|
||||
# These opcodes are really enumerant operands for the OpExtInst
|
||||
# instruction.
|
||||
for inst in glsl["instructions"]:
|
||||
EmitAsEnumerant(inst['opname'])
|
||||
|
||||
if args.extinst_opencl_grammar is not None:
|
||||
print('\n" OpenCL.std extended instructions')
|
||||
opencl = json.loads(open(args.extinst_opencl_grammar).read())
|
||||
for inst in opencl["instructions"]:
|
||||
EmitAsEnumerant(inst['opname'])
|
||||
|
||||
print('\n" OpSpecConstantOp opcodes')
|
||||
for word in SPEC_CONSTANT_OP_OPCODES.split(' '):
|
||||
stripped = word.strip('\n,')
|
||||
if stripped != "":
|
||||
# Treat as an enumerant, but without the leading "Op"
|
||||
EmitAsEnumerant(stripped[2:])
|
||||
print(POSTAMBLE)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue
Block a user