blob: bc16261c0457547fb72e1d9626b31ce16b68053f [file] [log] [blame]
David Netofcc7d582015-10-27 15:31:10 -04001// Copyright (c) 2015 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#include "assembly_grammar.h"
28
29#include <algorithm>
30#include <cstring>
31
32#include "ext_inst.h"
33#include "opcode.h"
34
35namespace {
36
37/// @brief Parses a mask expression string for the given operand type.
38///
39/// A mask expression is a sequence of one or more terms separated by '|',
40/// where each term a named enum value for the given type. No whitespace
41/// is permitted.
42///
43/// On success, the value is written to pValue.
44///
45/// @param[in] operandTable operand lookup table
46/// @param[in] type of the operand
47/// @param[in] textValue word of text to be parsed
48/// @param[out] pValue where the resulting value is written
49///
50/// @return result code
51spv_result_t spvTextParseMaskOperand(const spv_operand_table operandTable,
52 const spv_operand_type_t type,
Lei Zhang1a0334e2015-11-02 09:41:20 -050053 const char* textValue, uint32_t* pValue) {
David Netofcc7d582015-10-27 15:31:10 -040054 if (textValue == nullptr) return SPV_ERROR_INVALID_TEXT;
55 size_t text_length = strlen(textValue);
56 if (text_length == 0) return SPV_ERROR_INVALID_TEXT;
Lei Zhang1a0334e2015-11-02 09:41:20 -050057 const char* text_end = textValue + text_length;
David Netofcc7d582015-10-27 15:31:10 -040058
59 // We only support mask expressions in ASCII, so the separator value is a
60 // char.
61 const char separator = '|';
62
63 // Accumulate the result by interpreting one word at a time, scanning
64 // from left to right.
65 uint32_t value = 0;
Lei Zhang1a0334e2015-11-02 09:41:20 -050066 const char* begin = textValue; // The left end of the current word.
67 const char* end = nullptr; // One character past the end of the current word.
David Netofcc7d582015-10-27 15:31:10 -040068 do {
69 end = std::find(begin, text_end, separator);
70
71 spv_operand_desc entry = nullptr;
72 if (spvOperandTableNameLookup(operandTable, type, begin, end - begin,
73 &entry)) {
74 return SPV_ERROR_INVALID_TEXT;
75 }
76 value |= entry->value;
77
78 // Advance to the next word by skipping over the separator.
79 begin = end + 1;
80 } while (end != text_end);
81
82 *pValue = value;
83 return SPV_SUCCESS;
84}
85} // anonymous namespace
86
87namespace libspirv {
88
89bool AssemblyGrammar::isValid() const {
90 return operandTable_ && opcodeTable_ && extInstTable_;
91}
92
Lei Zhang1a0334e2015-11-02 09:41:20 -050093spv_result_t AssemblyGrammar::lookupOpcode(const char* name,
94 spv_opcode_desc* desc) const {
David Netofcc7d582015-10-27 15:31:10 -040095 return spvOpcodeTableNameLookup(opcodeTable_, name, desc);
96}
97
Lei Zhangb36e7042015-10-28 13:40:52 -040098spv_result_t AssemblyGrammar::lookupOpcode(SpvOp opcode,
Lei Zhang1a0334e2015-11-02 09:41:20 -050099 spv_opcode_desc* desc) const {
David Netofcc7d582015-10-27 15:31:10 -0400100 return spvOpcodeTableValueLookup(opcodeTable_, opcode, desc);
101}
102
103spv_result_t AssemblyGrammar::lookupOperand(spv_operand_type_t type,
Lei Zhang1a0334e2015-11-02 09:41:20 -0500104 const char* name, size_t name_len,
105 spv_operand_desc* desc) const {
David Netofcc7d582015-10-27 15:31:10 -0400106 return spvOperandTableNameLookup(operandTable_, type, name, name_len, desc);
107}
108
109spv_result_t AssemblyGrammar::lookupOperand(spv_operand_type_t type,
110 uint32_t operand,
Lei Zhang1a0334e2015-11-02 09:41:20 -0500111 spv_operand_desc* desc) const {
David Netofcc7d582015-10-27 15:31:10 -0400112 return spvOperandTableValueLookup(operandTable_, type, operand, desc);
113}
114
115spv_result_t AssemblyGrammar::parseMaskOperand(const spv_operand_type_t type,
Lei Zhang1a0334e2015-11-02 09:41:20 -0500116 const char* textValue,
117 uint32_t* pValue) const {
David Netofcc7d582015-10-27 15:31:10 -0400118 return spvTextParseMaskOperand(operandTable_, type, textValue, pValue);
119}
120spv_result_t AssemblyGrammar::lookupExtInst(spv_ext_inst_type_t type,
Lei Zhang1a0334e2015-11-02 09:41:20 -0500121 const char* textValue,
122 spv_ext_inst_desc* extInst) const {
David Netofcc7d582015-10-27 15:31:10 -0400123 return spvExtInstTableNameLookup(extInstTable_, type, textValue, extInst);
124}
125
126spv_result_t AssemblyGrammar::lookupExtInst(spv_ext_inst_type_t type,
127 uint32_t firstWord,
Lei Zhang1a0334e2015-11-02 09:41:20 -0500128 spv_ext_inst_desc* extInst) const {
David Netofcc7d582015-10-27 15:31:10 -0400129 return spvExtInstTableValueLookup(extInstTable_, type, firstWord, extInst);
130}
131
132void AssemblyGrammar::prependOperandTypesForMask(
133 const spv_operand_type_t type, const uint32_t mask,
Lei Zhang1a0334e2015-11-02 09:41:20 -0500134 spv_operand_pattern_t* pattern) const {
David Netofcc7d582015-10-27 15:31:10 -0400135 spvPrependOperandTypesForMask(operandTable_, type, mask, pattern);
136}
137} // namespace libspirv