xref: /wasmtime-44.0.1/pulley/src/encode.rs (revision 60fc557c)
1 //! Encoding support for pulley bytecode.
2 
3 use crate::imms::*;
4 use crate::opcode::{ExtendedOpcode, Opcode};
5 use crate::regs::*;
6 
7 trait Encode {
8     fn encode<E>(&self, sink: &mut E)
9     where
10         E: Extend<u8>;
11 }
12 
13 impl Encode for u8 {
14     fn encode<E>(&self, sink: &mut E)
15     where
16         E: Extend<u8>,
17     {
18         sink.extend(core::iter::once(*self));
19     }
20 }
21 
22 impl Encode for u16 {
23     fn encode<E>(&self, sink: &mut E)
24     where
25         E: Extend<u8>,
26     {
27         sink.extend(self.to_le_bytes());
28     }
29 }
30 
31 impl Encode for u32 {
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 
40 impl Encode for u64 {
41     fn encode<E>(&self, sink: &mut E)
42     where
43         E: Extend<u8>,
44     {
45         sink.extend(self.to_le_bytes());
46     }
47 }
48 
49 impl Encode for i8 {
50     fn encode<E>(&self, sink: &mut E)
51     where
52         E: Extend<u8>,
53     {
54         sink.extend(core::iter::once(*self as u8));
55     }
56 }
57 
58 impl Encode for i16 {
59     fn encode<E>(&self, sink: &mut E)
60     where
61         E: Extend<u8>,
62     {
63         sink.extend(self.to_le_bytes());
64     }
65 }
66 
67 impl Encode for i32 {
68     fn encode<E>(&self, sink: &mut E)
69     where
70         E: Extend<u8>,
71     {
72         sink.extend(self.to_le_bytes());
73     }
74 }
75 
76 impl Encode for i64 {
77     fn encode<E>(&self, sink: &mut E)
78     where
79         E: Extend<u8>,
80     {
81         sink.extend(self.to_le_bytes());
82     }
83 }
84 
85 impl Encode for XReg {
86     fn encode<E>(&self, sink: &mut E)
87     where
88         E: Extend<u8>,
89     {
90         sink.extend(core::iter::once(self.to_u8()));
91     }
92 }
93 
94 impl Encode for FReg {
95     fn encode<E>(&self, sink: &mut E)
96     where
97         E: Extend<u8>,
98     {
99         sink.extend(core::iter::once(self.to_u8()));
100     }
101 }
102 
103 impl Encode for VReg {
104     fn encode<E>(&self, sink: &mut E)
105     where
106         E: Extend<u8>,
107     {
108         sink.extend(core::iter::once(self.to_u8()));
109     }
110 }
111 
112 impl Encode for PcRelOffset {
113     fn encode<E>(&self, sink: &mut E)
114     where
115         E: Extend<u8>,
116     {
117         i32::from(*self).encode(sink);
118     }
119 }
120 
121 impl<R: Reg> Encode for BinaryOperands<R> {
122     fn encode<E>(&self, sink: &mut E)
123     where
124         E: Extend<u8>,
125     {
126         self.to_bits().encode(sink);
127     }
128 }
129 
130 impl<R: Reg + Encode> Encode for RegSet<R> {
131     fn encode<E>(&self, sink: &mut E)
132     where
133         E: Extend<u8>,
134     {
135         self.to_bitset().0.encode(sink);
136     }
137 }
138 
139 macro_rules! impl_encoders {
140     (
141         $(
142             $( #[$attr:meta] )*
143                 $snake_name:ident = $name:ident $( {
144                 $(
145                     $( #[$field_attr:meta] )*
146                     $field:ident : $field_ty:ty
147                 ),*
148             } )? ;
149         )*
150     ) => {
151         $(
152             $( #[$attr] )*
153             pub fn $snake_name<E>(into: &mut E $( $( , $field : impl Into<$field_ty> )* )? )
154             where
155                 E: Extend<u8>,
156             {
157                 into.extend(core::iter::once(Opcode::$name as u8));
158                 $(
159                     $(
160                         $field.into().encode(into);
161                     )*
162                 )?
163             }
164         )*
165     };
166 }
167 for_each_op!(impl_encoders);
168 
169 macro_rules! impl_extended_encoders {
170     (
171         $(
172             $( #[$attr:meta] )*
173                 $snake_name:ident = $name:ident $( {
174                     $(
175                         $( #[$field_attr:meta] )*
176                         $field:ident : $field_ty:ty
177                     ),*
178                 } )? ;
179         )*
180     ) => {
181         $(
182             $( #[$attr] )*
183             pub fn $snake_name<E>(into: &mut E $( $( , $field : impl Into<$field_ty> )* )? )
184             where
185                 E: Extend<u8>,
186             {
187                 into.extend(core::iter::once(Opcode::ExtendedOp as u8));
188                 into.extend((ExtendedOpcode::$name as u16).to_le_bytes());
189                 $(
190                     $(
191                         $field.into().encode(into);
192                     )*
193                 )?
194             }
195         )*
196     };
197 }
198 for_each_extended_op!(impl_extended_encoders);
199