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 SOURCE_OPERAND_H_
16#define SOURCE_OPERAND_H_
17
18#include <functional>
19#include <vector>
20
21#include "source/table.h"
22#include "spirv-tools/libspirv.h"
23
24// A sequence of operand types.
25//
26// A SPIR-V parser uses an operand pattern to describe what is expected
27// next on the input.
28//
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.
33
34// Using a vector in this way reduces memory traffic, which is good for
35// performance.
36using spv_operand_pattern_t = std::vector<spv_operand_type_t>;
37
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.
41spv_result_t spvOperandTableNameLookup(spv_target_env,
42 const spv_operand_table table,
43 const spv_operand_type_t type,
44 const char* name,
45 const size_t name_length,
46 spv_operand_desc* entry);
47
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.
51spv_result_t spvOperandTableValueLookup(spv_target_env,
52 const spv_operand_table table,
53 const spv_operand_type_t type,
54 const uint32_t value,
55 spv_operand_desc* entry);
56
57// Gets the name string of the non-variable operand type.
58const char* spvOperandTypeStr(spv_operand_type_t type);
59
60// Returns true if the given type is concrete.
61bool spvOperandIsConcrete(spv_operand_type_t type);
62
63// Returns true if the given type is concrete and also a mask.
64bool spvOperandIsConcreteMask(spv_operand_type_t type);
65
66// Returns true if an operand of the given type is optional.
67bool spvOperandIsOptional(spv_operand_type_t type);
68
69// Returns true if an operand type represents zero or more logical operands.
70//
71// Note that a single logical operand may still be a variable number of words.
72// For example, a literal string may be many words, but is just one logical
73// operand.
74bool spvOperandIsVariable(spv_operand_type_t type);
75
76// Append a list of operand types to the end of the pattern vector.
77// The types parameter specifies the source array of types, ending with
78// SPV_OPERAND_TYPE_NONE.
79void spvPushOperandTypes(const spv_operand_type_t* types,
80 spv_operand_pattern_t* pattern);
81
82// Appends the operands expected after the given typed mask onto the
83// end of the given pattern.
84//
85// Each set bit in the mask represents zero or more operand types that should
86// be appended onto the pattern. Operands for a less significant bit always
87// appear after operands for a more significant bit.
88//
89// If a set bit is unknown, then we assume it has no operands.
90void spvPushOperandTypesForMask(spv_target_env,
91 const spv_operand_table operand_table,
92 const spv_operand_type_t mask_type,
93 const uint32_t mask,
94 spv_operand_pattern_t* pattern);
95
96// Expands an operand type representing zero or more logical operands,
97// exactly once.
98//
99// If the given type represents potentially several logical operands,
100// then prepend the given pattern with the first expansion of the logical
101// operands, followed by original type. Otherwise, don't modify the pattern.
102//
103// For example, the SPV_OPERAND_TYPE_VARIABLE_ID represents zero or more
104// IDs. In that case we would prepend the pattern with SPV_OPERAND_TYPE_ID
105// followed by SPV_OPERAND_TYPE_VARIABLE_ID again.
106//
107// This also applies to zero or more tuples of logical operands. In that case
108// we prepend pattern with for the members of the tuple, followed by the
109// original type argument. The pattern must encode the fact that if any part
110// of the tuple is present, then all tuple members should be. So the first
111// member of the tuple must be optional, and the remaining members
112// non-optional.
113//
114// Returns true if we modified the pattern.
115bool spvExpandOperandSequenceOnce(spv_operand_type_t type,
116 spv_operand_pattern_t* pattern);
117
118// Expands the first element in the pattern until it is a matchable operand
119// type, then pops it off the front and returns it. The pattern must not be
120// empty.
121//
122// A matchable operand type is anything other than a zero-or-more-items
123// operand type.
124spv_operand_type_t spvTakeFirstMatchableOperand(spv_operand_pattern_t* pattern);
125
126// Calculates the corresponding post-immediate alternate pattern, which allows
127// a limited set of operand types.
128spv_operand_pattern_t spvAlternatePatternFollowingImmediate(
129 const spv_operand_pattern_t& pattern);
130
131// Is the operand an ID?
132bool spvIsIdType(spv_operand_type_t type);
133
134// Is the operand an input ID?
135bool spvIsInIdType(spv_operand_type_t type);
136
137// Takes the opcode of an instruction and returns
138// a function object that will return true if the index
139// of the operand can be forward declared. This function will
140// used in the SSA validation stage of the pipeline
141std::function<bool(unsigned)> spvOperandCanBeForwardDeclaredFunction(
142 SpvOp opcode);
143
144// Takes the instruction key of a debug info extension instruction
145// and returns a function object that will return true if the index
146// of the operand can be forward declared. This function will
147// used in the SSA validation stage of the pipeline
148std::function<bool(unsigned)> spvDbgInfoExtOperandCanBeForwardDeclaredFunction(
149 spv_ext_inst_type_t ext_type, uint32_t key);
150
151#endif // SOURCE_OPERAND_H_
152