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
205macro_rules! impl_encoders {
206 (
207 $(
208 $( #[$attr:meta] )*
209 $snake_name:ident = $name:ident $( {
210 $(
211 $( #[$field_attr:meta] )*
212 $field:ident : $field_ty:ty
213 ),*
214 } )? ;
215 )*
216 ) => {
217 $(
218 $( #[$attr] )*
219 pub fn $snake_name<E>(into: &mut E $( $( , $field : impl Into<$field_ty> )* )? )
220 where
221 E: Extend<u8>,
222 {
223 into.extend(core::iter::once(Opcode::$name as u8));
224 $(
225 $(
226 $field.into().encode(into);
227 )*
228 )?
229 }
230
231 impl Encode for crate::op::$name {
232 const WIDTH: u8 = 1 $($( + <$field_ty as Encode>::WIDTH)*)?;
233
234 fn encode<E>(&self, sink: &mut E)
235 where
236 E: Extend<u8>,
237 {
238 let Self { $( $( $field ),* )? } = *self;
239 $snake_name(sink $( $(, $field)* )?)
240 }
241 }
242 )*
243 };
244}
245for_each_op!(impl_encoders);
246
247macro_rules! impl_extended_encoders {
248 (
249 $(
250 $( #[$attr:meta] )*
251 $snake_name:ident = $name:ident $( {
252 $(
253 $( #[$field_attr:meta] )*
254 $field:ident : $field_ty:ty
255 ),*
256 } )? ;
257 )*
258 ) => {
259 $(
260 $( #[$attr] )*
261 pub fn $snake_name<E>(into: &mut E $( $( , $field : impl Into<$field_ty> )* )? )
262 where
263 E: Extend<u8>,
264 {
265 into.extend(core::iter::once(Opcode::ExtendedOp as u8));
266 into.extend((ExtendedOpcode::$name as u16).to_le_bytes());
267 $(
268 $(
269 $field.into().encode(into);
270 )*
271 )?
272 }
273
274 impl Encode for crate::op::$name {
275 const WIDTH: u8 = 3 $($( + <$field_ty as Encode>::WIDTH)*)?;
276
277 fn encode<E>(&self, sink: &mut E)
278 where
279 E: Extend<u8>,
280 {
281 let Self { $( $( $field ),* )? } = *self;
282 $snake_name(sink $( $(, $field)* )?)
283 }
284 }
285 )*
286 };
287}
288for_each_extended_op!(impl_extended_encoders);