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_OPERAND_H_
28#define LIBSPIRV_OPERAND_H_
29
30#include <deque>
31
32#include "spirv-tools/libspirv.h"
33#include "table.h"
34
35// A sequence of operand types.
36//
37// A SPIR-V parser uses an operand pattern to describe what is expected
38// next on the input.
39//
40// As we parse an instruction in text or binary form from left to right,
41// we pull and push from the front of the pattern.
42using spv_operand_pattern_t = std::deque<spv_operand_type_t>;
43
44// Finds the named operand in the table. The type parameter specifies the
45// operand's group. A handle of the operand table entry for this operand will
46// be written into *entry.
47spv_result_t spvOperandTableNameLookup(const spv_operand_table table,
48                                       const spv_operand_type_t type,
49                                       const char* name,
50                                       const size_t name_length,
51                                       spv_operand_desc* entry);
52
53// Finds the operand with value in the table. The type parameter specifies the
54// operand's group. A handle of the operand table entry for this operand will
55// be written into *entry.
56spv_result_t spvOperandTableValueLookup(const spv_operand_table table,
57                                        const spv_operand_type_t type,
58                                        const uint32_t value,
59                                        spv_operand_desc* entry);
60
61// Gets the name string of the non-variable operand type.
62const char* spvOperandTypeStr(spv_operand_type_t type);
63
64// Returns true if the given type is a concrete and also a mask.
65bool spvOperandIsConcreteMask(spv_operand_type_t type);
66
67// Returns true if an operand of the given type is optional.
68bool spvOperandIsOptional(spv_operand_type_t type);
69
70// Returns true if an operand type represents zero or more logical operands.
71//
72// Note that a single logical operand may still be a variable number of words.
73// For example, a literal string may be many words, but is just one logical
74// operand.
75bool spvOperandIsVariable(spv_operand_type_t type);
76
77// Inserts a list of operand types into the front of the given pattern.
78// The types parameter specifies the source array of types, ending with
79// SPV_OPERAND_TYPE_NONE.
80void spvPrependOperandTypes(const spv_operand_type_t* types,
81                            spv_operand_pattern_t* pattern);
82
83// Inserts the operands expected after the given typed mask onto the
84// front of the given pattern.
85//
86// Each set bit in the mask represents zero or more operand types that should
87// be prepended onto the pattern.  Operands for a less significant bit always
88// appear before operands for a more significant bit.
89//
90// If a set bit is unknown, then we assume it has no operands.
91void spvPrependOperandTypesForMask(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#endif  // LIBSPIRV_OPERAND_H_
135