1#[cfg(feature = "encode")]
4use crate::encode::Encode;
5use crate::imms::*;
6use crate::regs::*;
7
8macro_rules! define_op {
9 (
10 $(
11 $( #[$attr:meta] )*
12 $snake_name:ident = $name:ident $( { $( $field:ident : $field_ty:ty ),* } )? ;
13 )*
14 ) => {
15 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
21 #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
22 pub enum Op {
23 $(
24 $( #[$attr] )*
25 $name($name),
26 )*
27 ExtendedOp(ExtendedOp),
29 }
30
31 $(
32 $( #[$attr] )*
33 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
34 #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
35 pub struct $name { $(
36 $(
37 #[expect(missing_docs, reason = "macro-generated code")]
40 pub $field : $field_ty,
41 )*
42 )? }
43
44 impl From<$name> for Op {
45 #[inline]
46 fn from(op: $name) -> Self {
47 Self::$name(op)
48 }
49 }
50 )*
51 };
52}
53for_each_op!(define_op);
54
55impl From<ExtendedOp> for Op {
56 #[inline]
57 fn from(op: ExtendedOp) -> Self {
58 Op::ExtendedOp(op)
59 }
60}
61
62macro_rules! define_extended_op {
63 (
64 $(
65 $( #[$attr:meta] )*
66 $snake_name:ident = $name:ident $( { $( $field:ident : $field_ty:ty ),* } )? ;
67 )*
68 ) => {
69 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
73 #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
74 pub enum ExtendedOp {
75 $(
76 $( #[$attr] )*
77 $name($name),
78 )*
79 }
80
81 $(
82 $( #[$attr] )*
83 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
84 #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
85 pub struct $name { $(
86 $(
87 #[expect(missing_docs, reason = "macro-generated code")]
90 pub $field : $field_ty,
91 )*
92 )? }
93
94 #[doc(hidden)]
95 #[expect(non_camel_case_types, reason = "used in macros as an alternative to camel case")]
96 pub type $snake_name = $name;
97
98 impl From<$name> for Op {
99 #[inline]
100 fn from(op: $name) -> Self {
101 Self::ExtendedOp(ExtendedOp::$name(op))
102 }
103 }
104
105 impl From<$name> for ExtendedOp {
106 #[inline]
107 fn from(op: $name) -> Self {
108 Self::$name(op)
109 }
110 }
111 )*
112 };
113}
114for_each_extended_op!(define_extended_op);
115
116macro_rules! define_op_encode {
117 (
118 $(
119 $( #[$attr:meta] )*
120 $snake_name:ident = $name:ident $( { $( $field:ident : $field_ty:ty ),* } )? ;
121 )*
122 ) => {
123 impl Op {
124 #[cfg(feature = "encode")]
126 pub fn encode<E>(&self, into: &mut E)
127 where
128 E: Extend<u8>,
129 {
130 match self {
131 $(
132 Self::$name(op) => op.encode(into),
133 )*
134 Self::ExtendedOp(op) => op.encode(into),
135 }
136 }
137
138 #[cfg(feature = "encode")]
140 pub fn width(&self) -> u8 {
141 match self {
142 $(
143 Self::$name(_) => <$name as Encode>::WIDTH,
144 )*
145 Self::ExtendedOp(op) => op.width(),
146 }
147 }
148 }
149
150 $(
151 impl $name {
152 #[doc = concat!("`", stringify!($name), "`")]
154 #[cfg(feature = "encode")]
156 pub fn encode<E>(&self, into: &mut E)
157 where
158 E: Extend<u8>,
159 {
160 crate::encode::$snake_name(into $( $( , self.$field )* )?);
161 }
162 }
163 )*
164 };
165}
166for_each_op!(define_op_encode);
167
168macro_rules! define_extended_op_encode {
169 (
170 $(
171 $( #[$attr:meta] )*
172 $snake_name:ident = $name:ident $( { $( $field:ident : $field_ty:ty ),* } )? ;
173 )*
174 ) => {
175 impl ExtendedOp {
176 #[cfg(feature = "encode")]
178 pub fn encode<E>(&self, into: &mut E)
179 where
180 E: Extend<u8>,
181 {
182 match self {
183 $(
184 Self::$name(op) => op.encode(into),
185 )*
186 }
187 }
188
189 #[cfg(feature = "encode")]
191 pub fn width(&self) -> u8 {
192 match self {
193 $(
194 Self::$name(_) => <$name as Encode>::WIDTH,
195 )*
196 }
197 }
198 }
199
200 $(
201 impl $name {
202 #[doc = concat!("`", stringify!($name), "`")]
204 #[cfg(feature = "encode")]
206 pub fn encode<E>(&self, into: &mut E)
207 where
208 E: Extend<u8>,
209 {
210 crate::encode::$snake_name(into $( $( , self.$field )* )?);
211 }
212 }
213 )*
214 };
215}
216for_each_extended_op!(define_extended_op_encode);
217
218#[cfg(feature = "decode")]
220#[derive(Default)]
221pub struct MaterializeOpsVisitor<B> {
222 bytecode: B,
223}
224
225#[cfg(feature = "decode")]
226impl<B> MaterializeOpsVisitor<B> {
227 pub fn new(bytecode: B) -> Self {
229 Self { bytecode }
230 }
231}
232
233macro_rules! define_materialize_op_visitor {
234 (
235 $(
236 $( #[$attr:meta] )*
237 $snake_name:ident = $name:ident $( { $( $field:ident : $field_ty:ty ),* } )? ;
238 )*
239 ) => {
240 #[cfg(feature = "decode")]
241 impl<B: crate::decode::BytecodeStream> crate::decode::OpVisitor for MaterializeOpsVisitor<B> {
242 type BytecodeStream = B;
243
244 fn bytecode(&mut self) -> &mut Self::BytecodeStream {
245 &mut self.bytecode
246 }
247
248 type Return = crate::op::Op;
249
250 $(
251 $( #[$attr] )*
252 fn $snake_name(&mut self $( $( , $field : $field_ty )* )? ) -> Self::Return {
253 crate::op::Op::$name(crate::op::$name { $( $(
254 $field,
255 )* )? })
256 }
257 )*
258 }
259 };
260}
261for_each_op!(define_materialize_op_visitor);
262
263macro_rules! define_materialize_extended_op_visitor {
264 (
265 $(
266 $( #[$attr:meta] )*
267 $snake_name:ident = $name:ident $( { $( $field:ident : $field_ty:ty ),* } )? ;
268 )*
269 ) => {
270 #[cfg(feature = "decode")]
271 impl<B: crate::decode::BytecodeStream> crate::decode::ExtendedOpVisitor for MaterializeOpsVisitor<B> {
272 $(
273 $( #[$attr] )*
274 fn $snake_name(&mut self $( $( , $field : $field_ty )* )? ) -> Self::Return {
275 crate::op::ExtendedOp::$name(crate::op::$name { $( $(
276 $field,
277 )* )? }).into()
278 }
279 )*
280 }
281 };
282}
283for_each_extended_op!(define_materialize_extended_op_visitor);