pulley_interpreter/
encode.rs1use crate::imms::*;
4use crate::opcode::{ExtendedOpcode, Opcode};
5use crate::regs::*;
6
7pub trait Encode {
9 const WIDTH: u8;
11
12 fn encode<E>(&self, sink: &mut E)
14 where
15 E: Extend<u8>;
16}
17
18impl Encode for u8 {
19 const WIDTH: u8 = 1;
20
21 fn encode<E>(&self, sink: &mut E)
22 where
23 E: Extend<u8>,
24 {
25 sink.extend(core::iter::once(*self));
26 }
27}
28
29impl Encode for u16 {
30 const WIDTH: u8 = 2;
31
32 fn encode<E>(&self, sink: &mut E)
33 where
34 E: Extend<u8>,
35 {
36 sink.extend(self.to_le_bytes());
37 }
38}
39
40impl Encode for u32 {
41 const WIDTH: u8 = 4;
42
43 fn encode<E>(&self, sink: &mut E)
44 where
45 E: Extend<u8>,
46 {
47 sink.extend(self.to_le_bytes());
48 }
49}
50
51impl Encode for u64 {
52 const WIDTH: u8 = 8;
53
54 fn encode<E>(&self, sink: &mut E)
55 where
56 E: Extend<u8>,
57 {
58 sink.extend(self.to_le_bytes());
59 }
60}
61
62impl Encode for u128 {
63 const WIDTH: u8 = 16;
64
65 fn encode<E>(&self, sink: &mut E)
66 where
67 E: Extend<u8>,
68 {
69 sink.extend(self.to_le_bytes());
70 }
71}
72
73impl Encode for i8 {
74 const WIDTH: u8 = 1;
75
76 fn encode<E>(&self, sink: &mut E)
77 where
78 E: Extend<u8>,
79 {
80 sink.extend(core::iter::once(*self as u8));
81 }
82}
83
84impl Encode for i16 {
85 const WIDTH: u8 = 2;
86
87 fn encode<E>(&self, sink: &mut E)
88 where
89 E: Extend<u8>,
90 {
91 sink.extend(self.to_le_bytes());
92 }
93}
94
95impl Encode for i32 {
96 const WIDTH: u8 = 4;
97
98 fn encode<E>(&self, sink: &mut E)
99 where
100 E: Extend<u8>,
101 {
102 sink.extend(self.to_le_bytes());
103 }
104}
105
106impl Encode for i64 {
107 const WIDTH: u8 = 8;
108
109 fn encode<E>(&self, sink: &mut E)
110 where
111 E: Extend<u8>,
112 {
113 sink.extend(self.to_le_bytes());
114 }
115}
116
117impl Encode for i128 {
118 const WIDTH: u8 = 16;
119
120 fn encode<E>(&self, sink: &mut E)
121 where
122 E: Extend<u8>,
123 {
124 sink.extend(self.to_le_bytes());
125 }
126}
127
128impl Encode for XReg {
129 const WIDTH: u8 = 1;
130
131 fn encode<E>(&self, sink: &mut E)
132 where
133 E: Extend<u8>,
134 {
135 sink.extend(core::iter::once(self.to_u8()));
136 }
137}
138
139impl Encode for FReg {
140 const WIDTH: u8 = 1;
141
142 fn encode<E>(&self, sink: &mut E)
143 where
144 E: Extend<u8>,
145 {
146 sink.extend(core::iter::once(self.to_u8()));
147 }
148}
149
150impl Encode for VReg {
151 const WIDTH: u8 = 1;
152
153 fn encode<E>(&self, sink: &mut E)
154 where
155 E: Extend<u8>,
156 {
157 sink.extend(core::iter::once(self.to_u8()));
158 }
159}
160
161impl Encode for PcRelOffset {
162 const WIDTH: u8 = 4;
163
164 fn encode<E>(&self, sink: &mut E)
165 where
166 E: Extend<u8>,
167 {
168 i32::from(*self).encode(sink);
169 }
170}
171
172impl<D: Reg, S1: Reg, S2: Reg> Encode for BinaryOperands<D, S1, S2> {
173 const WIDTH: u8 = 2;
174
175 fn encode<E>(&self, sink: &mut E)
176 where
177 E: Extend<u8>,
178 {
179 self.to_bits().encode(sink);
180 }
181}
182
183impl<D: Reg, S1: Reg> Encode for BinaryOperands<D, S1, U6> {
184 const WIDTH: u8 = 2;
185
186 fn encode<E>(&self, sink: &mut E)
187 where
188 E: Extend<u8>,
189 {
190 self.to_bits().encode(sink);
191 }
192}
193
194impl<R: Reg + Encode> Encode for UpperRegSet<R> {
195 const WIDTH: u8 = 2;
196
197 fn encode<E>(&self, sink: &mut E)
198 where
199 E: Extend<u8>,
200 {
201 self.to_bitset().0.encode(sink);
202 }
203}
204
205impl Encode for AddrO32 {
206 const WIDTH: u8 = 5;
207
208 fn encode<E>(&self, sink: &mut E)
209 where
210 E: Extend<u8>,
211 {
212 self.addr.encode(sink);
213 self.offset.encode(sink);
214 }
215}
216
217impl Encode for AddrZ {
218 const WIDTH: u8 = 5;
219
220 fn encode<E>(&self, sink: &mut E)
221 where
222 E: Extend<u8>,
223 {
224 self.addr.encode(sink);
225 self.offset.encode(sink);
226 }
227}
228
229impl Encode for AddrG32 {
230 const WIDTH: u8 = 4;
231
232 fn encode<E>(&self, sink: &mut E)
233 where
234 E: Extend<u8>,
235 {
236 self.to_bits().encode(sink);
237 }
238}
239
240impl Encode for AddrG32Bne {
241 const WIDTH: u8 = 4;
242
243 fn encode<E>(&self, sink: &mut E)
244 where
245 E: Extend<u8>,
246 {
247 self.to_bits().encode(sink);
248 }
249}
250
251macro_rules! impl_encoders {
252 (
253 $(
254 $( #[$attr:meta] )*
255 $snake_name:ident = $name:ident $( {
256 $(
257 $( #[$field_attr:meta] )*
258 $field:ident : $field_ty:ty
259 ),*
260 } )? ;
261 )*
262 ) => {
263 $(
264 $( #[$attr] )*
265 pub fn $snake_name<E>(into: &mut E $( $( , $field : impl Into<$field_ty> )* )? )
266 where
267 E: Extend<u8>,
268 {
269 into.extend(core::iter::once(Opcode::$name as u8));
270 $(
271 $(
272 $field.into().encode(into);
273 )*
274 )?
275 }
276
277 impl Encode for crate::op::$name {
278 const WIDTH: u8 = 1 $($( + <$field_ty as Encode>::WIDTH)*)?;
279
280 fn encode<E>(&self, sink: &mut E)
281 where
282 E: Extend<u8>,
283 {
284 let Self { $( $( $field ),* )? } = *self;
285 $snake_name(sink $( $(, $field)* )?)
286 }
287 }
288 )*
289 };
290}
291for_each_op!(impl_encoders);
292
293macro_rules! impl_extended_encoders {
294 (
295 $(
296 $( #[$attr:meta] )*
297 $snake_name:ident = $name:ident $( {
298 $(
299 $( #[$field_attr:meta] )*
300 $field:ident : $field_ty:ty
301 ),*
302 } )? ;
303 )*
304 ) => {
305 $(
306 $( #[$attr] )*
307 pub fn $snake_name<E>(into: &mut E $( $( , $field : impl Into<$field_ty> )* )? )
308 where
309 E: Extend<u8>,
310 {
311 into.extend(core::iter::once(Opcode::ExtendedOp as u8));
312 into.extend((ExtendedOpcode::$name as u16).to_le_bytes());
313 $(
314 $(
315 $field.into().encode(into);
316 )*
317 )?
318 }
319
320 impl Encode for crate::op::$name {
321 const WIDTH: u8 = 3 $($( + <$field_ty as Encode>::WIDTH)*)?;
322
323 fn encode<E>(&self, sink: &mut E)
324 where
325 E: Extend<u8>,
326 {
327 let Self { $( $( $field ),* )? } = *self;
328 $snake_name(sink $( $(, $field)* )?)
329 }
330 }
331 )*
332 };
333}
334for_each_extended_op!(impl_extended_encoders);