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 #[allow(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 #[allow(missing_docs, reason = "macro-generated code")]
90 pub $field : $field_ty,
91 )*
92 )? }
93
94 impl From<$name> for Op {
95 #[inline]
96 fn from(op: $name) -> Self {
97 Self::ExtendedOp(ExtendedOp::$name(op))
98 }
99 }
100
101 impl From<$name> for ExtendedOp {
102 #[inline]
103 fn from(op: $name) -> Self {
104 Self::$name(op)
105 }
106 }
107 )*
108 };
109}
110for_each_extended_op!(define_extended_op);
111
112macro_rules! define_op_encode {
113 (
114 $(
115 $( #[$attr:meta] )*
116 $snake_name:ident = $name:ident $( { $( $field:ident : $field_ty:ty ),* } )? ;
117 )*
118 ) => {
119 impl Op {
120 #[cfg(feature = "encode")]
122 pub fn encode<E>(&self, into: &mut E)
123 where
124 E: Extend<u8>,
125 {
126 match self {
127 $(
128 Self::$name(op) => op.encode(into),
129 )*
130 Self::ExtendedOp(op) => op.encode(into),
131 }
132 }
133
134 #[cfg(feature = "encode")]
136 pub fn width(&self) -> u8 {
137 match self {
138 $(
139 Self::$name(_) => <$name as Encode>::WIDTH,
140 )*
141 Self::ExtendedOp(op) => op.width(),
142 }
143 }
144 }
145
146 $(
147 impl $name {
148 #[doc = concat!("`", stringify!($name), "`")]
150 #[cfg(feature = "encode")]
152 pub fn encode<E>(&self, into: &mut E)
153 where
154 E: Extend<u8>,
155 {
156 crate::encode::$snake_name(into $( $( , self.$field )* )?);
157 }
158 }
159 )*
160 };
161}
162for_each_op!(define_op_encode);
163
164macro_rules! define_extended_op_encode {
165 (
166 $(
167 $( #[$attr:meta] )*
168 $snake_name:ident = $name:ident $( { $( $field:ident : $field_ty:ty ),* } )? ;
169 )*
170 ) => {
171 impl ExtendedOp {
172 #[cfg(feature = "encode")]
174 pub fn encode<E>(&self, into: &mut E)
175 where
176 E: Extend<u8>,
177 {
178 match self {
179 $(
180 Self::$name(op) => op.encode(into),
181 )*
182 }
183 }
184
185 #[cfg(feature = "encode")]
187 pub fn width(&self) -> u8 {
188 match self {
189 $(
190 Self::$name(_) => <$name as Encode>::WIDTH,
191 )*
192 }
193 }
194 }
195
196 $(
197 impl $name {
198 #[doc = concat!("`", stringify!($name), "`")]
200 #[cfg(feature = "encode")]
202 pub fn encode<E>(&self, into: &mut E)
203 where
204 E: Extend<u8>,
205 {
206 crate::encode::$snake_name(into $( $( , self.$field )* )?);
207 }
208 }
209 )*
210 };
211}
212for_each_extended_op!(define_extended_op_encode);
213
214#[cfg(feature = "decode")]
216#[derive(Default)]
217pub struct MaterializeOpsVisitor<B> {
218 bytecode: B,
219}
220
221#[cfg(feature = "decode")]
222impl<B> MaterializeOpsVisitor<B> {
223 pub fn new(bytecode: B) -> Self {
225 Self { bytecode }
226 }
227}
228
229macro_rules! define_materialize_op_visitor {
230 (
231 $(
232 $( #[$attr:meta] )*
233 $snake_name:ident = $name:ident $( { $( $field:ident : $field_ty:ty ),* } )? ;
234 )*
235 ) => {
236 #[cfg(feature = "decode")]
237 impl<B: crate::decode::BytecodeStream> crate::decode::OpVisitor for MaterializeOpsVisitor<B> {
238 type BytecodeStream = B;
239
240 fn bytecode(&mut self) -> &mut Self::BytecodeStream {
241 &mut self.bytecode
242 }
243
244 type Return = crate::op::Op;
245
246 $(
247 $( #[$attr] )*
248 fn $snake_name(&mut self $( $( , $field : $field_ty )* )? ) -> Self::Return {
249 crate::op::Op::$name(crate::op::$name { $( $(
250 $field,
251 )* )? })
252 }
253 )*
254 }
255 };
256}
257for_each_op!(define_materialize_op_visitor);
258
259macro_rules! define_materialize_extended_op_visitor {
260 (
261 $(
262 $( #[$attr:meta] )*
263 $snake_name:ident = $name:ident $( { $( $field:ident : $field_ty:ty ),* } )? ;
264 )*
265 ) => {
266 #[cfg(feature = "decode")]
267 impl<B: crate::decode::BytecodeStream> crate::decode::ExtendedOpVisitor for MaterializeOpsVisitor<B> {
268 $(
269 $( #[$attr] )*
270 fn $snake_name(&mut self $( $( , $field : $field_ty )* )? ) -> Self::Return {
271 crate::op::ExtendedOp::$name(crate::op::$name { $( $(
272 $field,
273 )* )? }).into()
274 }
275 )*
276 }
277 };
278}
279for_each_extended_op!(define_materialize_extended_op_visitor);