rspirv/grammar/
reflect.rs

1//! Reflect functions for SPIR-V instructions.
2
3use crate::spirv;
4
5/// Returns true if the given opcode is for a location debug instruction.
6pub fn is_location_debug(opcode: spirv::Op) -> bool {
7    matches!(opcode, spirv::Op::Line | spirv::Op::NoLine)
8}
9
10/// Returns true if the given opcode is for a non-location debug instruction.
11pub fn is_nonlocation_debug(opcode: spirv::Op) -> bool {
12    matches!(
13        opcode,
14        spirv::Op::SourceContinued
15            | spirv::Op::Source
16            | spirv::Op::SourceExtension
17            | spirv::Op::Name
18            | spirv::Op::MemberName
19            | spirv::Op::String
20    )
21}
22
23/// Returns true if the given opcode is for a debug instruction.
24pub fn is_debug(opcode: spirv::Op) -> bool {
25    is_location_debug(opcode) || is_nonlocation_debug(opcode)
26}
27
28/// Returns true if the given opcode is for an annotation instruction.
29pub fn is_annotation(opcode: spirv::Op) -> bool {
30    matches!(
31        opcode,
32        spirv::Op::Decorate
33            | spirv::Op::MemberDecorate
34            | spirv::Op::DecorationGroup
35            | spirv::Op::GroupDecorate
36            | spirv::Op::GroupMemberDecorate
37            | spirv::Op::DecorateString
38            | spirv::Op::MemberDecorateStringGOOGLE
39    )
40}
41
42/// Returns true if the given opcode is for a type-declaring instruction.
43pub fn is_type(opcode: spirv::Op) -> bool {
44    matches!(
45        opcode,
46        spirv::Op::TypeVoid
47            | spirv::Op::TypeBool
48            | spirv::Op::TypeInt
49            | spirv::Op::TypeFloat
50            | spirv::Op::TypeVector
51            | spirv::Op::TypeMatrix
52            | spirv::Op::TypeImage
53            | spirv::Op::TypeSampler
54            | spirv::Op::TypeSampledImage
55            | spirv::Op::TypeArray
56            | spirv::Op::TypeRuntimeArray
57            | spirv::Op::TypeStruct
58            | spirv::Op::TypeOpaque
59            | spirv::Op::TypePointer
60            | spirv::Op::TypeFunction
61            | spirv::Op::TypeEvent
62            | spirv::Op::TypeDeviceEvent
63            | spirv::Op::TypeReserveId
64            | spirv::Op::TypeQueue
65            | spirv::Op::TypePipe
66            | spirv::Op::TypeAccelerationStructureKHR
67            | spirv::Op::TypeRayQueryKHR
68            | spirv::Op::TypeForwardPointer
69    )
70}
71
72/// Returns true if the given opcode is for a constant-defining instruction.
73pub fn is_constant(opcode: spirv::Op) -> bool {
74    matches!(
75        opcode,
76        spirv::Op::ConstantTrue
77            | spirv::Op::ConstantFalse
78            | spirv::Op::Constant
79            | spirv::Op::ConstantComposite
80            | spirv::Op::ConstantSampler
81            | spirv::Op::ConstantNull
82            | spirv::Op::SpecConstantTrue
83            | spirv::Op::SpecConstantFalse
84            | spirv::Op::SpecConstant
85            | spirv::Op::SpecConstantComposite
86            | spirv::Op::SpecConstantOp
87            | spirv::Op::ConstantCompositeContinuedINTEL
88            | spirv::Op::SpecConstantCompositeContinuedINTEL
89    )
90}
91
92/// Returns true if the given opcode is for a variable-defining instruction.
93pub fn is_variable(opcode: spirv::Op) -> bool {
94    opcode == spirv::Op::Variable
95}
96
97/// Returns true if the given opcode is a return instruction.
98pub fn is_return(opcode: spirv::Op) -> bool {
99    matches!(opcode, spirv::Op::Return | spirv::Op::ReturnValue)
100}
101
102/// Returns true if the given opcode aborts execution.
103pub fn is_abort(opcode: spirv::Op) -> bool {
104    matches!(
105        opcode,
106        spirv::Op::Kill
107            | spirv::Op::TerminateInvocation
108            | spirv::Op::TerminateRayKHR
109            | spirv::Op::IgnoreIntersectionKHR
110            | spirv::Op::EmitMeshTasksEXT
111            | spirv::Op::Unreachable
112    )
113}
114
115/// Returns true if the given opcode is a return instruction or it aborts
116/// execution.
117pub fn is_return_or_abort(opcode: spirv::Op) -> bool {
118    is_return(opcode) || is_abort(opcode)
119}
120
121/// Returns true if the given opcode is a branch instruction.
122pub fn is_branch(opcode: spirv::Op) -> bool {
123    matches!(
124        opcode,
125        spirv::Op::Branch | spirv::Op::BranchConditional | spirv::Op::Switch
126    )
127}
128
129/// Returns true if the given opcode is for a terminator instruction.
130pub fn is_block_terminator(opcode: spirv::Op) -> bool {
131    is_branch(opcode) || is_return_or_abort(opcode)
132}