1use std::marker::PhantomData;
2
3use crate::spirv;
4
5#[derive(Debug, PartialEq, Eq, Hash)]
7pub struct BaseInstruction<'a, Op: Clone + Copy>
8where
9 Op: Into<spirv::Word>,
10{
11 pub opname: &'a str,
13 pub opcode: Op,
15 pub capabilities: &'a [spirv::Capability],
17 pub extensions: &'a [&'a str],
19 pub operands: &'a [LogicalOperand],
23}
24
25pub type Instruction<'a> = BaseInstruction<'a, spirv::Op>;
26pub type ExtendedInstruction<'a> = BaseInstruction<'a, ExtInstOp>;
27
28#[derive(Debug, PartialEq, Eq, Hash, Clone)]
30pub struct LogicalOperand {
31 pub kind: OperandKind,
33 pub quantifier: OperandQuantifier,
35}
36
37#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
39pub enum OperandQuantifier {
40 One,
42 ZeroOrOne,
44 ZeroOrMore,
46}
47
48macro_rules! inst {
50 ($op:ident, [$( $cap:ident ),*], [$( $ext:expr ),*], [$( ($kind:ident, $quant:ident) ),*]) => {
51 Instruction {
52 opname: stringify!($op),
53 opcode: spirv::Op::$op,
54 capabilities: &[
55 $( spirv::Capability::$cap ),*
56 ],
57 extensions: &[
58 $( $ext ),*
59 ],
60 operands: &[
61 $( LogicalOperand {
62 kind: OperandKind::$kind,
63 quantifier: OperandQuantifier::$quant }
64 ),*
65 ],
66 }
67 }
68}
69
70macro_rules! ext_inst {
76 ($variant:ident, $opconst:ident, $opname:ident, [$( $cap:ident ),*], [$( $ext:expr ),*],
78 [$( ($kind:ident, $quant:ident) ),*]) => {
79 ext_inst!($variant, $opconst, $opname, [$($cap),*], [$($ext),*],
80 [$((OperandKind::$kind, $quant)),*],)
81 };
82 ($variant:ident, $opconst:ident, $opname:ident, [$( $cap:ident ),*], [$( $ext:expr ),*],
85 [$( ($kind:expr, $quant:ident) ),*], ) => {
86 ExtendedInstruction {
87 opname: stringify!($opname),
88 opcode: ExtInstOp::$variant(spirv::$opconst::$opname),
89 capabilities: &[
90 $( spirv::Capability::$cap ),*
91 ],
92 extensions: &[
93 $( $ext ),*
94 ],
95 operands: &[
96 $( LogicalOperand {
97 kind: $kind,
98 quantifier: OperandQuantifier::$quant }
99 ),*
100 ],
101 }
102 }
103}
104
105pub struct InstructionTable<Op: Into<spirv::Word> + Clone + Copy + Eq + 'static>(
109 &'static [BaseInstruction<'static, Op>],
110 PhantomData<Op>,
111);
112
113impl<Op: Into<spirv::Word> + Clone + Copy + Eq> InstructionTable<Op> {
114 pub fn lookup_opcode(
117 &self,
118 opcode: spirv::Word,
119 ) -> Option<&'static BaseInstruction<'static, Op>> {
120 self.0.iter().find(|inst| inst.opcode.into() == opcode)
121 }
122
123 pub fn get(&self, opcode: Op) -> &'static BaseInstruction<'static, Op> {
126 self.0
127 .iter()
128 .find(|inst| inst.opcode == opcode)
129 .expect("internal error")
130 }
131
132 pub fn iter(&self) -> impl Iterator<Item = &'static BaseInstruction<'static, Op>> {
133 self.0.iter()
134 }
135}
136
137include!("autogen_tables.rs");