Home | History | Annotate | Download | only in source
      1 // Copyright (c) 2015-2016 The Khronos Group Inc.
      2 //
      3 // Permission is hereby granted, free of charge, to any person obtaining a
      4 // copy of this software and/or associated documentation files (the
      5 // "Materials"), to deal in the Materials without restriction, including
      6 // without limitation the rights to use, copy, modify, merge, publish,
      7 // distribute, sublicense, and/or sell copies of the Materials, and to
      8 // permit persons to whom the Materials are furnished to do so, subject to
      9 // the following conditions:
     10 //
     11 // The above copyright notice and this permission notice shall be included
     12 // in all copies or substantial portions of the Materials.
     13 //
     14 // MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
     15 // KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
     16 // SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
     17 //    https://www.khronos.org/registry/
     18 //
     19 // THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     20 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     21 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     22 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
     23 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     24 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     25 // MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
     26 
     27 #ifndef LIBSPIRV_ASSEMBLY_GRAMMAR_H_
     28 #define LIBSPIRV_ASSEMBLY_GRAMMAR_H_
     29 
     30 #include "operand.h"
     31 #include "spirv-tools/libspirv.h"
     32 #include "spirv/1.1/spirv.h"
     33 #include "table.h"
     34 
     35 namespace libspirv {
     36 
     37 // Encapsulates the grammar to use for SPIR-V assembly.
     38 // Contains methods to query for valid instructions and operands.
     39 class AssemblyGrammar {
     40  public:
     41   explicit AssemblyGrammar(const spv_const_context context)
     42       : target_env_(context->target_env),
     43         operandTable_(context->operand_table),
     44         opcodeTable_(context->opcode_table),
     45         extInstTable_(context->ext_inst_table) {}
     46 
     47   // Returns true if the internal tables have been initialized with valid data.
     48   bool isValid() const;
     49 
     50   // Returns the SPIR-V target environment.
     51   spv_target_env target_env() const { return target_env_; }
     52 
     53   // Fills in the desc parameter with the information about the opcode
     54   // of the given name. Returns SPV_SUCCESS if the opcode was found, and
     55   // SPV_ERROR_INVALID_LOOKUP if the opcode does not exist.
     56   spv_result_t lookupOpcode(const char* name, spv_opcode_desc* desc) const;
     57 
     58   // Fills in the desc parameter with the information about the opcode
     59   // of the valid. Returns SPV_SUCCESS if the opcode was found, and
     60   // SPV_ERROR_INVALID_LOOKUP if the opcode does not exist.
     61   spv_result_t lookupOpcode(SpvOp opcode, spv_opcode_desc* desc) const;
     62 
     63   // Fills in the desc parameter with the information about the given
     64   // operand. Returns SPV_SUCCESS if the operand was found, and
     65   // SPV_ERROR_INVALID_LOOKUP otherwise.
     66   spv_result_t lookupOperand(spv_operand_type_t type, const char* name,
     67                              size_t name_len, spv_operand_desc* desc) const;
     68 
     69   // Fills in the desc parameter with the information about the given
     70   // operand. Returns SPV_SUCCESS if the operand was found, and
     71   // SPV_ERROR_INVALID_LOOKUP otherwise.
     72   spv_result_t lookupOperand(spv_operand_type_t type, uint32_t operand,
     73                              spv_operand_desc* desc) const;
     74 
     75   // Finds the opcode for the given OpSpecConstantOp opcode name. The name
     76   // should not have the "Op" prefix.  For example, "IAdd" corresponds to
     77   // the integer add opcode for OpSpecConstantOp.  On success, returns
     78   // SPV_SUCCESS and sends the discovered operation code through the opcode
     79   // parameter.  On failure, returns SPV_ERROR_INVALID_LOOKUP.
     80   spv_result_t lookupSpecConstantOpcode(const char* name, SpvOp* opcode) const;
     81 
     82   // Returns SPV_SUCCESS if the given opcode is valid as the opcode operand
     83   // to OpSpecConstantOp.
     84   spv_result_t lookupSpecConstantOpcode(SpvOp opcode) const;
     85 
     86   // Parses a mask expression string for the given operand type.
     87   //
     88   // A mask expression is a sequence of one or more terms separated by '|',
     89   // where each term is a named enum value for a given type. No whitespace
     90   // is permitted.
     91   //
     92   // On success, the value is written to pValue, and SPV_SUCCESS is returned.
     93   // The operand type is defined by the type parameter, and the text to be
     94   // parsed is defined by the textValue parameter.
     95   spv_result_t parseMaskOperand(const spv_operand_type_t type,
     96                                 const char* textValue, uint32_t* pValue) const;
     97 
     98   // Writes the extended operand with the given type and text to the *extInst
     99   // parameter.
    100   // Returns SPV_SUCCESS if the value could be found.
    101   spv_result_t lookupExtInst(spv_ext_inst_type_t type, const char* textValue,
    102                              spv_ext_inst_desc* extInst) const;
    103 
    104   // Writes the extended operand with the given type and first encoded word
    105   // to the *extInst parameter.
    106   // Returns SPV_SUCCESS if the value could be found.
    107   spv_result_t lookupExtInst(spv_ext_inst_type_t type, uint32_t firstWord,
    108                              spv_ext_inst_desc* extInst) const;
    109 
    110   // Inserts the operands expected after the given typed mask onto the front
    111   // of the given pattern.
    112   //
    113   // Each set bit in the mask represents zero or more operand types that should
    114   // be prepended onto the pattern. Operands for a less significant bit always
    115   // appear before operands for a more significant bit.
    116   //
    117   // If a set bit is unknown, then we assume it has no operands.
    118   void prependOperandTypesForMask(const spv_operand_type_t type,
    119                                   const uint32_t mask,
    120                                   spv_operand_pattern_t* pattern) const;
    121 
    122  private:
    123   const spv_target_env target_env_;
    124   const spv_operand_table operandTable_;
    125   const spv_opcode_table opcodeTable_;
    126   const spv_ext_inst_table extInstTable_;
    127 };
    128 }
    129 
    130 #endif  // LIBSPIRV_ASSEMBLY_GRAMMAR_H_
    131