• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2015-2016 The Khronos Group Inc.
2 //
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
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
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.
14 
15 #ifndef LIBSPIRV_OPERAND_H_
16 #define LIBSPIRV_OPERAND_H_
17 
18 #include <deque>
19 
20 #include "spirv-tools/libspirv.h"
21 #include "table.h"
22 
23 // A sequence of operand types.
24 //
25 // A SPIR-V parser uses an operand pattern to describe what is expected
26 // next on the input.
27 //
28 // As we parse an instruction in text or binary form from left to right,
29 // we pop and push at the end of the pattern vector. Symbols later in the
30 // pattern vector are matched against the input before symbols earlier in the
31 // pattern vector are matched.
32 
33 // Using a vector in this way reduces memory traffic, which is good for
34 // performance.
35 using spv_operand_pattern_t = std::vector<spv_operand_type_t>;
36 
37 // Finds the named operand in the table. The type parameter specifies the
38 // operand's group. A handle of the operand table entry for this operand will
39 // be written into *entry.
40 spv_result_t spvOperandTableNameLookup(const spv_operand_table table,
41                                        const spv_operand_type_t type,
42                                        const char* name,
43                                        const size_t name_length,
44                                        spv_operand_desc* entry);
45 
46 // Finds the operand with value in the table. The type parameter specifies the
47 // operand's group. A handle of the operand table entry for this operand will
48 // be written into *entry.
49 spv_result_t spvOperandTableValueLookup(const spv_operand_table table,
50                                         const spv_operand_type_t type,
51                                         const uint32_t value,
52                                         spv_operand_desc* entry);
53 
54 // Gets the name string of the non-variable operand type.
55 const char* spvOperandTypeStr(spv_operand_type_t type);
56 
57 // Returns true if the given type is a concrete and also a mask.
58 bool spvOperandIsConcreteMask(spv_operand_type_t type);
59 
60 // Returns true if an operand of the given type is optional.
61 bool spvOperandIsOptional(spv_operand_type_t type);
62 
63 // Returns true if an operand type represents zero or more logical operands.
64 //
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
67 // operand.
68 bool spvOperandIsVariable(spv_operand_type_t type);
69 
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);
75 
76 // Appends the operands expected after the given typed mask onto the
77 // end of the given pattern.
78 //
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.
82 //
83 // If a set bit is unknown, then we assume it has no operands.
84 void spvPushOperandTypesForMask(const spv_operand_table operand_table,
85                                 const spv_operand_type_t mask_type,
86                                 const uint32_t mask,
87                                 spv_operand_pattern_t* pattern);
88 
89 // Expands an operand type representing zero or more logical operands,
90 // exactly once.
91 //
92 // If the given type represents potentially several logical operands,
93 // then prepend the given pattern with the first expansion of the logical
94 // operands, followed by original type.  Otherwise, don't modify the pattern.
95 //
96 // For example, the SPV_OPERAND_TYPE_VARIABLE_ID represents zero or more
97 // IDs.  In that case we would prepend the pattern with SPV_OPERAND_TYPE_ID
98 // followed by SPV_OPERAND_TYPE_VARIABLE_ID again.
99 //
100 // This also applies to zero or more tuples of logical operands.  In that case
101 // we prepend pattern with for the members of the tuple, followed by the
102 // original type argument.  The pattern must encode the fact that if any part
103 // of the tuple is present, then all tuple members should be.  So the first
104 // member of the tuple must be optional, and the remaining members
105 // non-optional.
106 //
107 // Returns true if we modified the pattern.
108 bool spvExpandOperandSequenceOnce(spv_operand_type_t type,
109                                   spv_operand_pattern_t* pattern);
110 
111 // Expands the first element in the pattern until it is a matchable operand
112 // type, then pops it off the front and returns it.  The pattern must not be
113 // empty.
114 //
115 // A matchable operand type is anything other than a zero-or-more-items
116 // operand type.
117 spv_operand_type_t spvTakeFirstMatchableOperand(spv_operand_pattern_t* pattern);
118 
119 // Calculates the corresponding post-immediate alternate pattern, which allows
120 // a limited set of operand types.
121 spv_operand_pattern_t spvAlternatePatternFollowingImmediate(
122     const spv_operand_pattern_t& pattern);
123 
124 // Is the operand an ID?
125 bool spvIsIdType(spv_operand_type_t type);
126 
127 #endif  // LIBSPIRV_OPERAND_H_
128