1use super::ast::Op;
2use super::datapath::{Bin, Event, Instr, Reg};
3use super::{Error, Result};
4use crate::serialize::u32_to_u8s;
5
6impl Bin {
8 pub fn serialize(&self) -> Result<Vec<u8>> {
9 let b = self.clone();
10 let ists = b
11 .instrs
12 .into_iter()
13 .flat_map(std::iter::IntoIterator::into_iter);
14 b.events
15 .into_iter()
16 .flat_map(std::iter::IntoIterator::into_iter)
17 .chain(ists)
18 .collect()
19 }
20}
21impl IntoIterator for Event {
39 type Item = Result<u8>;
40 type IntoIter = ::std::vec::IntoIter<Result<u8>>;
41
42 fn into_iter(self) -> Self::IntoIter {
43 let v = &mut [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
44 u32_to_u8s(&mut v[0..=3], self.flag_idx);
45 u32_to_u8s(&mut v[4..=7], self.num_flag_instrs);
46 u32_to_u8s(&mut v[8..=11], self.body_idx);
47 u32_to_u8s(&mut v[12..=15], self.num_body_instrs);
48 v.iter()
49 .map(|u| Ok(*u))
50 .collect::<Vec<Result<u8>>>()
51 .into_iter()
52 }
53}
54
55impl IntoIterator for Instr {
68 type Item = Result<u8>;
69 type IntoIter = ::std::vec::IntoIter<Result<u8>>;
70
71 fn into_iter(self) -> Self::IntoIter {
72 let op = vec![Ok(serialize_op(self.op))];
73 op.into_iter()
74 .chain(self.res)
75 .chain(self.left)
76 .chain(self.right)
77 .collect::<Vec<Result<u8>>>() .into_iter()
79 }
80}
81
82fn serialize_op(o: Op) -> u8 {
83 match o {
84 Op::Add => 0,
85 Op::And => unreachable!(),
86 Op::Bind => 1,
87 Op::Def => 2,
88 Op::Div => 3,
89 Op::Equiv => 4,
90 Op::Ewma => 5,
91 Op::Gt => 6,
92 Op::If => 7,
93 Op::Lt => 8,
94 Op::Max => 9,
95 Op::MaxWrap => 10,
96 Op::Min => 11,
97 Op::Mul => 12,
98 Op::NotIf => 13,
99 Op::Or => unreachable!(),
100 Op::Sub => 14,
101 }
102}
103
104impl IntoIterator for Reg {
105 type Item = Result<u8>;
106 type IntoIter = ::std::vec::IntoIter<Result<u8>>;
107
108 fn into_iter(self) -> Self::IntoIter {
109 let reg = match self {
110 Reg::Control(i, _, is_volatile) => {
111 if i > 15 {
112 Err(Error::from(format!(
113 "Control Register index too big (max 15): {:?}",
114 i
115 )))
116 } else {
117 Ok((if is_volatile { 8u8 } else { 0u8 }, u32::from(i)))
120 }
121 }
122 Reg::ImmBool(bl) => Ok((1u8, bl as u32)),
123 Reg::ImmNum(num) => {
124 if num == u64::max_value() || num < (1 << 31) {
125 Ok((1u8, num as u32))
126 } else {
127 Err(Error::from(format!(
128 "ImmNum too big (max 32 bits): {:?}",
129 num
130 )))
131 }
132 }
133 Reg::Implicit(i, _) => {
134 if i > 5 {
135 Err(Error::from(format!(
136 "Implicit Register index too big (max 5): {:?}",
137 i
138 )))
139 } else {
140 Ok((2u8, u32::from(i)))
141 }
142 }
143 Reg::Local(i, _) => {
144 if i > 5 {
145 Err(Error::from(format!(
146 "Local Register index too big (max 5): {:?}",
147 i
148 )))
149 } else {
150 Ok((3u8, u32::from(i)))
151 }
152 }
153 Reg::Primitive(i, _) => {
154 if i > 15 {
155 Err(Error::from(format!(
156 "Primitive Register index too big (max 15): {:?}",
157 i
158 )))
159 } else {
160 Ok((4u8, u32::from(i)))
161 }
162 }
163 Reg::Report(i, _, is_volatile) => {
164 if i > 15 {
165 Err(Error::from(format!(
166 "Report Register index too big (max 15): {:?}",
167 i
168 )))
169 } else {
170 Ok((if is_volatile { 5u8 } else { 6u8 }, u32::from(i)))
175 }
176 }
177 Reg::Tmp(i, _) => {
178 if i > 15 {
179 Err(Error::from(format!(
180 "Tmp Register index too big (max 15): {:?}",
181 i
182 )))
183 } else {
184 Ok((7u8, u32::from(i)))
185 }
186 }
187 Reg::None => unreachable!(),
188 };
189
190 reg.map(|(typ, idx)| {
191 let v = &mut [typ, 0, 0, 0, 0];
192 u32_to_u8s(&mut v[1..5], idx);
193 v.iter()
194 .map(|u| Ok(*u))
195 .collect::<Vec<Result<u8>>>()
196 .into_iter()
197 })
198 .unwrap_or_else(|e| vec![Err(e)].into_iter())
199 }
200}
201
202impl Reg {
203 pub fn deserialize(_buf: &[u8]) -> Self {
204 unimplemented!()
205 }
206}
207
208#[cfg(test)]
209mod tests {
210 use crate::lang;
211 use crate::lang::ast::Op;
212 use crate::lang::datapath::{Bin, Event, Instr, Reg, Type};
213 #[test]
214 fn do_ser() {
215 let b = Bin {
217 events: vec![Event {
218 flag_idx: 1,
219 num_flag_instrs: 1,
220 body_idx: 2,
221 num_body_instrs: 1,
222 }],
223 instrs: vec![
224 Instr {
225 res: Reg::Report(6, Type::Num(Some(0)), true),
226 op: Op::Def,
227 left: Reg::Report(6, Type::Num(Some(0)), true),
228 right: Reg::ImmNum(0),
229 },
230 Instr {
231 res: Reg::Implicit(0, Type::Bool(None)),
232 op: Op::Bind,
233 left: Reg::Implicit(0, Type::Bool(None)),
234 right: Reg::ImmBool(true),
235 },
236 Instr {
237 res: Reg::Report(6, Type::Num(Some(0)), true),
238 op: Op::Bind,
239 left: Reg::Report(6, Type::Num(Some(0)), true),
240 right: Reg::ImmNum(4),
241 },
242 ],
243 };
244
245 let v = b.serialize().expect("serialize");
246 assert_eq!(
247 v,
248 vec![
249 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00,
251 0x00, 0x00, 0x02, 0x05, 0x06, 0x00, 0x00, 0x00, 0x05, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
253 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00,
255 0x00, 0x00, 0x01, 0x05, 0x06, 0x00, 0x00, 0x00, 0x05, 0x06, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00,
257 0x00, 0x00,
258 ]
259 );
260 }
261
262 #[test]
263 fn do_ser_max_imm() {
264 let b = Instr {
266 res: Reg::Tmp(0, Type::Num(None)),
267 op: Op::Add,
268 left: Reg::ImmNum(0x3fff_ffff),
269 right: Reg::ImmNum(0x3fff_ffff),
270 };
271
272 let v = b
273 .into_iter()
274 .collect::<lang::Result<Vec<u8>>>()
275 .expect("serialize");
276 assert_eq!(
277 v,
278 vec![
279 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0x3f, 0x01, 0xff, 0xff,
280 0xff, 0x3f,
281 ]
282 );
283 }
284
285 #[test]
286 fn do_ser_def_max_imm() {
287 let b = Instr {
289 res: Reg::Report(2, Type::Num(Some(u64::max_value())), true),
290 op: Op::Def,
291 left: Reg::Report(2, Type::Num(Some(u64::max_value())), true),
292 right: Reg::ImmNum(u64::max_value()),
293 };
294
295 let v = b
296 .into_iter()
297 .collect::<lang::Result<Vec<u8>>>()
298 .expect("serialize");
299 assert_eq!(
300 v,
301 vec![
302 0x02, 0x05, 0x02, 0x00, 0x00, 0x00, 0x05, 0x02, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff,
303 0xff, 0xff,
304 ]
305 );
306 }
307}