1 // Copyright (c) 2015-2016 The Khronos Group Inc.
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 #ifndef SOURCE_OPERAND_H_
16 #define SOURCE_OPERAND_H_
21 #include "source/table.h"
22 #include "spirv-tools/libspirv.h"
24 // A sequence of operand types.
26 // A SPIR-V parser uses an operand pattern to describe what is expected
29 // As we parse an instruction in text or binary form from left to right,
30 // we pop and push at the end of the pattern vector. Symbols later in the
31 // pattern vector are matched against the input before symbols earlier in the
32 // pattern vector are matched.
34 // Using a vector in this way reduces memory traffic, which is good for
36 using spv_operand_pattern_t
= std::vector
<spv_operand_type_t
>;
38 // Finds the named operand in the table. The type parameter specifies the
39 // operand's group. A handle of the operand table entry for this operand will
40 // be written into *entry.
41 spv_result_t
spvOperandTableNameLookup(spv_target_env
,
42 const spv_operand_table table
,
43 const spv_operand_type_t type
,
45 const size_t name_length
,
46 spv_operand_desc
* entry
);
48 // Finds the operand with value in the table. The type parameter specifies the
49 // operand's group. A handle of the operand table entry for this operand will
50 // be written into *entry.
51 spv_result_t
spvOperandTableValueLookup(spv_target_env
,
52 const spv_operand_table table
,
53 const spv_operand_type_t type
,
55 spv_operand_desc
* entry
);
57 // Gets the name string of the non-variable operand type.
58 const char* spvOperandTypeStr(spv_operand_type_t type
);
60 // Returns true if an operand of the given type is optional.
61 bool spvOperandIsOptional(spv_operand_type_t type
);
63 // Returns true if an operand type represents zero or more logical operands.
65 // Note that a single logical operand may still be a variable number of words.
66 // For example, a literal string may be many words, but is just one logical
68 bool spvOperandIsVariable(spv_operand_type_t type
);
70 // Append a list of operand types to the end of the pattern vector.
71 // The types parameter specifies the source array of types, ending with
72 // SPV_OPERAND_TYPE_NONE.
73 void spvPushOperandTypes(const spv_operand_type_t
* types
,
74 spv_operand_pattern_t
* pattern
);
76 // Appends the operands expected after the given typed mask onto the
77 // end of the given pattern.
79 // Each set bit in the mask represents zero or more operand types that should
80 // be appended onto the pattern. Operands for a less significant bit always
81 // appear after operands for a more significant bit.
83 // If a set bit is unknown, then we assume it has no operands.
84 void spvPushOperandTypesForMask(spv_target_env
,
85 const spv_operand_table operand_table
,
86 const spv_operand_type_t mask_type
,
88 spv_operand_pattern_t
* pattern
);
90 // Expands an operand type representing zero or more logical operands,
93 // If the given type represents potentially several logical operands,
94 // then prepend the given pattern with the first expansion of the logical
95 // operands, followed by original type. Otherwise, don't modify the pattern.
97 // For example, the SPV_OPERAND_TYPE_VARIABLE_ID represents zero or more
98 // IDs. In that case we would prepend the pattern with SPV_OPERAND_TYPE_ID
99 // followed by SPV_OPERAND_TYPE_VARIABLE_ID again.
101 // This also applies to zero or more tuples of logical operands. In that case
102 // we prepend pattern with for the members of the tuple, followed by the
103 // original type argument. The pattern must encode the fact that if any part
104 // of the tuple is present, then all tuple members should be. So the first
105 // member of the tuple must be optional, and the remaining members
108 // Returns true if we modified the pattern.
109 bool spvExpandOperandSequenceOnce(spv_operand_type_t type
,
110 spv_operand_pattern_t
* pattern
);
112 // Expands the first element in the pattern until it is a matchable operand
113 // type, then pops it off the front and returns it. The pattern must not be
116 // A matchable operand type is anything other than a zero-or-more-items
118 spv_operand_type_t
spvTakeFirstMatchableOperand(spv_operand_pattern_t
* pattern
);
120 // Calculates the corresponding post-immediate alternate pattern, which allows
121 // a limited set of operand types.
122 spv_operand_pattern_t
spvAlternatePatternFollowingImmediate(
123 const spv_operand_pattern_t
& pattern
);
125 // Is the operand an ID?
126 bool spvIsIdType(spv_operand_type_t type
);
128 // Is the operand an input ID?
129 bool spvIsInIdType(spv_operand_type_t type
);
131 // Takes the opcode of an instruction and returns
132 // a function object that will return true if the index
133 // of the operand can be forward declared. This function will
134 // used in the SSA validation stage of the pipeline
135 std::function
<bool(unsigned)> spvOperandCanBeForwardDeclaredFunction(
138 // Takes the instruction key of a debug info extension instruction
139 // and returns a function object that will return true if the index
140 // of the operand can be forward declared. This function will
141 // used in the SSA validation stage of the pipeline
142 std::function
<bool(unsigned)> spvDbgInfoExtOperandCanBeForwardDeclaredFunction(
143 spv::Op opcode
, spv_ext_inst_type_t ext_type
, uint32_t key
);
145 #endif // SOURCE_OPERAND_H_