14ac1bedfSNick Fitzgerald //! Encoding support for pulley bytecode.
24ac1bedfSNick Fitzgerald
34ac1bedfSNick Fitzgerald use crate::imms::*;
44ac1bedfSNick Fitzgerald use crate::opcode::{ExtendedOpcode, Opcode};
54ac1bedfSNick Fitzgerald use crate::regs::*;
64ac1bedfSNick Fitzgerald
7c63f31bdSAlex Crichton /// Helper trait to encode instructions into a "sink".
8c63f31bdSAlex Crichton pub trait Encode {
9c63f31bdSAlex Crichton /// The encoded width of this instruction.
10c63f31bdSAlex Crichton const WIDTH: u8;
11c63f31bdSAlex Crichton
12c63f31bdSAlex Crichton /// Encodes this operand or instruction into the provided `sink`.
encode<E>(&self, sink: &mut E) where E: Extend<u8>134ac1bedfSNick Fitzgerald fn encode<E>(&self, sink: &mut E)
144ac1bedfSNick Fitzgerald where
154ac1bedfSNick Fitzgerald E: Extend<u8>;
164ac1bedfSNick Fitzgerald }
174ac1bedfSNick Fitzgerald
184ac1bedfSNick Fitzgerald impl Encode for u8 {
19c63f31bdSAlex Crichton const WIDTH: u8 = 1;
20c63f31bdSAlex Crichton
encode<E>(&self, sink: &mut E) where E: Extend<u8>,214ac1bedfSNick Fitzgerald fn encode<E>(&self, sink: &mut E)
224ac1bedfSNick Fitzgerald where
234ac1bedfSNick Fitzgerald E: Extend<u8>,
244ac1bedfSNick Fitzgerald {
254ac1bedfSNick Fitzgerald sink.extend(core::iter::once(*self));
264ac1bedfSNick Fitzgerald }
274ac1bedfSNick Fitzgerald }
284ac1bedfSNick Fitzgerald
294ac1bedfSNick Fitzgerald impl Encode for u16 {
30c63f31bdSAlex Crichton const WIDTH: u8 = 2;
31c63f31bdSAlex Crichton
encode<E>(&self, sink: &mut E) where E: Extend<u8>,324ac1bedfSNick Fitzgerald fn encode<E>(&self, sink: &mut E)
334ac1bedfSNick Fitzgerald where
344ac1bedfSNick Fitzgerald E: Extend<u8>,
354ac1bedfSNick Fitzgerald {
364ac1bedfSNick Fitzgerald sink.extend(self.to_le_bytes());
374ac1bedfSNick Fitzgerald }
384ac1bedfSNick Fitzgerald }
394ac1bedfSNick Fitzgerald
404ac1bedfSNick Fitzgerald impl Encode for u32 {
41c63f31bdSAlex Crichton const WIDTH: u8 = 4;
42c63f31bdSAlex Crichton
encode<E>(&self, sink: &mut E) where E: Extend<u8>,434ac1bedfSNick Fitzgerald fn encode<E>(&self, sink: &mut E)
444ac1bedfSNick Fitzgerald where
454ac1bedfSNick Fitzgerald E: Extend<u8>,
464ac1bedfSNick Fitzgerald {
474ac1bedfSNick Fitzgerald sink.extend(self.to_le_bytes());
484ac1bedfSNick Fitzgerald }
494ac1bedfSNick Fitzgerald }
504ac1bedfSNick Fitzgerald
514ac1bedfSNick Fitzgerald impl Encode for u64 {
52c63f31bdSAlex Crichton const WIDTH: u8 = 8;
53c63f31bdSAlex Crichton
encode<E>(&self, sink: &mut E) where E: Extend<u8>,544ac1bedfSNick Fitzgerald fn encode<E>(&self, sink: &mut E)
554ac1bedfSNick Fitzgerald where
564ac1bedfSNick Fitzgerald E: Extend<u8>,
574ac1bedfSNick Fitzgerald {
584ac1bedfSNick Fitzgerald sink.extend(self.to_le_bytes());
594ac1bedfSNick Fitzgerald }
604ac1bedfSNick Fitzgerald }
614ac1bedfSNick Fitzgerald
62128decddSAlex Crichton impl Encode for u128 {
63128decddSAlex Crichton const WIDTH: u8 = 16;
64128decddSAlex Crichton
encode<E>(&self, sink: &mut E) where E: Extend<u8>,65128decddSAlex Crichton fn encode<E>(&self, sink: &mut E)
66128decddSAlex Crichton where
67128decddSAlex Crichton E: Extend<u8>,
68128decddSAlex Crichton {
69128decddSAlex Crichton sink.extend(self.to_le_bytes());
70128decddSAlex Crichton }
71128decddSAlex Crichton }
72128decddSAlex Crichton
734ac1bedfSNick Fitzgerald impl Encode for i8 {
74c63f31bdSAlex Crichton const WIDTH: u8 = 1;
75c63f31bdSAlex Crichton
encode<E>(&self, sink: &mut E) where E: Extend<u8>,764ac1bedfSNick Fitzgerald fn encode<E>(&self, sink: &mut E)
774ac1bedfSNick Fitzgerald where
784ac1bedfSNick Fitzgerald E: Extend<u8>,
794ac1bedfSNick Fitzgerald {
804ac1bedfSNick Fitzgerald sink.extend(core::iter::once(*self as u8));
814ac1bedfSNick Fitzgerald }
824ac1bedfSNick Fitzgerald }
834ac1bedfSNick Fitzgerald
844ac1bedfSNick Fitzgerald impl Encode for i16 {
85c63f31bdSAlex Crichton const WIDTH: u8 = 2;
86c63f31bdSAlex Crichton
encode<E>(&self, sink: &mut E) where E: Extend<u8>,874ac1bedfSNick Fitzgerald fn encode<E>(&self, sink: &mut E)
884ac1bedfSNick Fitzgerald where
894ac1bedfSNick Fitzgerald E: Extend<u8>,
904ac1bedfSNick Fitzgerald {
914ac1bedfSNick Fitzgerald sink.extend(self.to_le_bytes());
924ac1bedfSNick Fitzgerald }
934ac1bedfSNick Fitzgerald }
944ac1bedfSNick Fitzgerald
954ac1bedfSNick Fitzgerald impl Encode for i32 {
96c63f31bdSAlex Crichton const WIDTH: u8 = 4;
97c63f31bdSAlex Crichton
encode<E>(&self, sink: &mut E) where E: Extend<u8>,984ac1bedfSNick Fitzgerald fn encode<E>(&self, sink: &mut E)
994ac1bedfSNick Fitzgerald where
1004ac1bedfSNick Fitzgerald E: Extend<u8>,
1014ac1bedfSNick Fitzgerald {
1024ac1bedfSNick Fitzgerald sink.extend(self.to_le_bytes());
1034ac1bedfSNick Fitzgerald }
1044ac1bedfSNick Fitzgerald }
1054ac1bedfSNick Fitzgerald
1064ac1bedfSNick Fitzgerald impl Encode for i64 {
107c63f31bdSAlex Crichton const WIDTH: u8 = 8;
108c63f31bdSAlex Crichton
encode<E>(&self, sink: &mut E) where E: Extend<u8>,1094ac1bedfSNick Fitzgerald fn encode<E>(&self, sink: &mut E)
1104ac1bedfSNick Fitzgerald where
1114ac1bedfSNick Fitzgerald E: Extend<u8>,
1124ac1bedfSNick Fitzgerald {
1134ac1bedfSNick Fitzgerald sink.extend(self.to_le_bytes());
1144ac1bedfSNick Fitzgerald }
1154ac1bedfSNick Fitzgerald }
1164ac1bedfSNick Fitzgerald
117128decddSAlex Crichton impl Encode for i128 {
118128decddSAlex Crichton const WIDTH: u8 = 16;
119128decddSAlex Crichton
encode<E>(&self, sink: &mut E) where E: Extend<u8>,120128decddSAlex Crichton fn encode<E>(&self, sink: &mut E)
121128decddSAlex Crichton where
122128decddSAlex Crichton E: Extend<u8>,
123128decddSAlex Crichton {
124128decddSAlex Crichton sink.extend(self.to_le_bytes());
125128decddSAlex Crichton }
126128decddSAlex Crichton }
127128decddSAlex Crichton
1284ac1bedfSNick Fitzgerald impl Encode for XReg {
129c63f31bdSAlex Crichton const WIDTH: u8 = 1;
130c63f31bdSAlex Crichton
encode<E>(&self, sink: &mut E) where E: Extend<u8>,1314ac1bedfSNick Fitzgerald fn encode<E>(&self, sink: &mut E)
1324ac1bedfSNick Fitzgerald where
1334ac1bedfSNick Fitzgerald E: Extend<u8>,
1344ac1bedfSNick Fitzgerald {
135ff92e7afSKarl Meakin sink.extend(core::iter::once(self.to_u8()));
1364ac1bedfSNick Fitzgerald }
1374ac1bedfSNick Fitzgerald }
1384ac1bedfSNick Fitzgerald
1394ac1bedfSNick Fitzgerald impl Encode for FReg {
140c63f31bdSAlex Crichton const WIDTH: u8 = 1;
141c63f31bdSAlex Crichton
encode<E>(&self, sink: &mut E) where E: Extend<u8>,1424ac1bedfSNick Fitzgerald fn encode<E>(&self, sink: &mut E)
1434ac1bedfSNick Fitzgerald where
1444ac1bedfSNick Fitzgerald E: Extend<u8>,
1454ac1bedfSNick Fitzgerald {
146ff92e7afSKarl Meakin sink.extend(core::iter::once(self.to_u8()));
1474ac1bedfSNick Fitzgerald }
1484ac1bedfSNick Fitzgerald }
1494ac1bedfSNick Fitzgerald
1504ac1bedfSNick Fitzgerald impl Encode for VReg {
151c63f31bdSAlex Crichton const WIDTH: u8 = 1;
152c63f31bdSAlex Crichton
encode<E>(&self, sink: &mut E) where E: Extend<u8>,1534ac1bedfSNick Fitzgerald fn encode<E>(&self, sink: &mut E)
1544ac1bedfSNick Fitzgerald where
1554ac1bedfSNick Fitzgerald E: Extend<u8>,
1564ac1bedfSNick Fitzgerald {
157ff92e7afSKarl Meakin sink.extend(core::iter::once(self.to_u8()));
1584ac1bedfSNick Fitzgerald }
1594ac1bedfSNick Fitzgerald }
1604ac1bedfSNick Fitzgerald
1614ac1bedfSNick Fitzgerald impl Encode for PcRelOffset {
162c63f31bdSAlex Crichton const WIDTH: u8 = 4;
163c63f31bdSAlex Crichton
encode<E>(&self, sink: &mut E) where E: Extend<u8>,1644ac1bedfSNick Fitzgerald fn encode<E>(&self, sink: &mut E)
1654ac1bedfSNick Fitzgerald where
1664ac1bedfSNick Fitzgerald E: Extend<u8>,
1674ac1bedfSNick Fitzgerald {
1684ac1bedfSNick Fitzgerald i32::from(*self).encode(sink);
1694ac1bedfSNick Fitzgerald }
1704ac1bedfSNick Fitzgerald }
1714ac1bedfSNick Fitzgerald
172128decddSAlex Crichton impl<D: Reg, S1: Reg, S2: Reg> Encode for BinaryOperands<D, S1, S2> {
173c63f31bdSAlex Crichton const WIDTH: u8 = 2;
174c63f31bdSAlex Crichton
encode<E>(&self, sink: &mut E) where E: Extend<u8>,1757059c570SKarl Meakin fn encode<E>(&self, sink: &mut E)
1767059c570SKarl Meakin where
1777059c570SKarl Meakin E: Extend<u8>,
1787059c570SKarl Meakin {
1797059c570SKarl Meakin self.to_bits().encode(sink);
1807059c570SKarl Meakin }
1817059c570SKarl Meakin }
1827059c570SKarl Meakin
1831e4c470aSAlex Crichton impl<D: Reg, S1: Reg> Encode for BinaryOperands<D, S1, U6> {
1841e4c470aSAlex Crichton const WIDTH: u8 = 2;
1851e4c470aSAlex Crichton
encode<E>(&self, sink: &mut E) where E: Extend<u8>,1861e4c470aSAlex Crichton fn encode<E>(&self, sink: &mut E)
1871e4c470aSAlex Crichton where
1881e4c470aSAlex Crichton E: Extend<u8>,
1891e4c470aSAlex Crichton {
1901e4c470aSAlex Crichton self.to_bits().encode(sink);
1911e4c470aSAlex Crichton }
1921e4c470aSAlex Crichton }
1931e4c470aSAlex Crichton
194e4fd50d1SAlex Crichton impl<R: Reg + Encode> Encode for UpperRegSet<R> {
195e4fd50d1SAlex Crichton const WIDTH: u8 = 2;
196c63f31bdSAlex Crichton
encode<E>(&self, sink: &mut E) where E: Extend<u8>,197ff92e7afSKarl Meakin fn encode<E>(&self, sink: &mut E)
198ff92e7afSKarl Meakin where
199ff92e7afSKarl Meakin E: Extend<u8>,
200ff92e7afSKarl Meakin {
201ff92e7afSKarl Meakin self.to_bitset().0.encode(sink);
202ff92e7afSKarl Meakin }
203ff92e7afSKarl Meakin }
204ff92e7afSKarl Meakin
2059260ce47SAlex Crichton impl Encode for AddrO32 {
2069260ce47SAlex Crichton const WIDTH: u8 = 5;
2079260ce47SAlex Crichton
encode<E>(&self, sink: &mut E) where E: Extend<u8>,2089260ce47SAlex Crichton fn encode<E>(&self, sink: &mut E)
2099260ce47SAlex Crichton where
2109260ce47SAlex Crichton E: Extend<u8>,
2119260ce47SAlex Crichton {
2129260ce47SAlex Crichton self.addr.encode(sink);
2139260ce47SAlex Crichton self.offset.encode(sink);
2149260ce47SAlex Crichton }
2159260ce47SAlex Crichton }
2169260ce47SAlex Crichton
2179260ce47SAlex Crichton impl Encode for AddrZ {
2189260ce47SAlex Crichton const WIDTH: u8 = 5;
2199260ce47SAlex Crichton
encode<E>(&self, sink: &mut E) where E: Extend<u8>,2209260ce47SAlex Crichton fn encode<E>(&self, sink: &mut E)
2219260ce47SAlex Crichton where
2229260ce47SAlex Crichton E: Extend<u8>,
2239260ce47SAlex Crichton {
2249260ce47SAlex Crichton self.addr.encode(sink);
2259260ce47SAlex Crichton self.offset.encode(sink);
2269260ce47SAlex Crichton }
2279260ce47SAlex Crichton }
2289260ce47SAlex Crichton
2299260ce47SAlex Crichton impl Encode for AddrG32 {
2309260ce47SAlex Crichton const WIDTH: u8 = 4;
2319260ce47SAlex Crichton
encode<E>(&self, sink: &mut E) where E: Extend<u8>,2329260ce47SAlex Crichton fn encode<E>(&self, sink: &mut E)
2339260ce47SAlex Crichton where
2349260ce47SAlex Crichton E: Extend<u8>,
2359260ce47SAlex Crichton {
2369260ce47SAlex Crichton self.to_bits().encode(sink);
2379260ce47SAlex Crichton }
2389260ce47SAlex Crichton }
2399260ce47SAlex Crichton
2409260ce47SAlex Crichton impl Encode for AddrG32Bne {
2419260ce47SAlex Crichton const WIDTH: u8 = 4;
2429260ce47SAlex Crichton
encode<E>(&self, sink: &mut E) where E: Extend<u8>,2439260ce47SAlex Crichton fn encode<E>(&self, sink: &mut E)
2449260ce47SAlex Crichton where
2459260ce47SAlex Crichton E: Extend<u8>,
2469260ce47SAlex Crichton {
2479260ce47SAlex Crichton self.to_bits().encode(sink);
2489260ce47SAlex Crichton }
2499260ce47SAlex Crichton }
2509260ce47SAlex Crichton
2514ac1bedfSNick Fitzgerald macro_rules! impl_encoders {
2524ac1bedfSNick Fitzgerald (
2534ac1bedfSNick Fitzgerald $(
2544ac1bedfSNick Fitzgerald $( #[$attr:meta] )*
2554ac1bedfSNick Fitzgerald $snake_name:ident = $name:ident $( {
2564ac1bedfSNick Fitzgerald $(
2574ac1bedfSNick Fitzgerald $( #[$field_attr:meta] )*
2584ac1bedfSNick Fitzgerald $field:ident : $field_ty:ty
2594ac1bedfSNick Fitzgerald ),*
2604ac1bedfSNick Fitzgerald } )? ;
2614ac1bedfSNick Fitzgerald )*
2624ac1bedfSNick Fitzgerald ) => {
2634ac1bedfSNick Fitzgerald $(
2644ac1bedfSNick Fitzgerald $( #[$attr] )*
2654ac1bedfSNick Fitzgerald pub fn $snake_name<E>(into: &mut E $( $( , $field : impl Into<$field_ty> )* )? )
2664ac1bedfSNick Fitzgerald where
2674ac1bedfSNick Fitzgerald E: Extend<u8>,
2684ac1bedfSNick Fitzgerald {
2694ac1bedfSNick Fitzgerald into.extend(core::iter::once(Opcode::$name as u8));
2704ac1bedfSNick Fitzgerald $(
2714ac1bedfSNick Fitzgerald $(
2724ac1bedfSNick Fitzgerald $field.into().encode(into);
2734ac1bedfSNick Fitzgerald )*
2744ac1bedfSNick Fitzgerald )?
2754ac1bedfSNick Fitzgerald }
276c63f31bdSAlex Crichton
277c63f31bdSAlex Crichton impl Encode for crate::op::$name {
278c63f31bdSAlex Crichton const WIDTH: u8 = 1 $($( + <$field_ty as Encode>::WIDTH)*)?;
279c63f31bdSAlex Crichton
280c63f31bdSAlex Crichton fn encode<E>(&self, sink: &mut E)
281c63f31bdSAlex Crichton where
282c63f31bdSAlex Crichton E: Extend<u8>,
283c63f31bdSAlex Crichton {
284c63f31bdSAlex Crichton let Self { $( $( $field ),* )? } = *self;
285c63f31bdSAlex Crichton $snake_name(sink $( $(, $field)* )?)
286c63f31bdSAlex Crichton }
287c63f31bdSAlex Crichton }
2884ac1bedfSNick Fitzgerald )*
2894ac1bedfSNick Fitzgerald };
2904ac1bedfSNick Fitzgerald }
2914ac1bedfSNick Fitzgerald for_each_op!(impl_encoders);
2924ac1bedfSNick Fitzgerald
2934ac1bedfSNick Fitzgerald macro_rules! impl_extended_encoders {
2944ac1bedfSNick Fitzgerald (
2954ac1bedfSNick Fitzgerald $(
2964ac1bedfSNick Fitzgerald $( #[$attr:meta] )*
2974ac1bedfSNick Fitzgerald $snake_name:ident = $name:ident $( {
2984ac1bedfSNick Fitzgerald $(
2994ac1bedfSNick Fitzgerald $( #[$field_attr:meta] )*
3004ac1bedfSNick Fitzgerald $field:ident : $field_ty:ty
3014ac1bedfSNick Fitzgerald ),*
3024ac1bedfSNick Fitzgerald } )? ;
3034ac1bedfSNick Fitzgerald )*
3044ac1bedfSNick Fitzgerald ) => {
3054ac1bedfSNick Fitzgerald $(
3064ac1bedfSNick Fitzgerald $( #[$attr] )*
3074ac1bedfSNick Fitzgerald pub fn $snake_name<E>(into: &mut E $( $( , $field : impl Into<$field_ty> )* )? )
3084ac1bedfSNick Fitzgerald where
3094ac1bedfSNick Fitzgerald E: Extend<u8>,
3104ac1bedfSNick Fitzgerald {
3114ac1bedfSNick Fitzgerald into.extend(core::iter::once(Opcode::ExtendedOp as u8));
3124ac1bedfSNick Fitzgerald into.extend((ExtendedOpcode::$name as u16).to_le_bytes());
3134ac1bedfSNick Fitzgerald $(
3144ac1bedfSNick Fitzgerald $(
3154ac1bedfSNick Fitzgerald $field.into().encode(into);
3164ac1bedfSNick Fitzgerald )*
3174ac1bedfSNick Fitzgerald )?
3184ac1bedfSNick Fitzgerald }
319c63f31bdSAlex Crichton
320c63f31bdSAlex Crichton impl Encode for crate::op::$name {
321c63f31bdSAlex Crichton const WIDTH: u8 = 3 $($( + <$field_ty as Encode>::WIDTH)*)?;
322c63f31bdSAlex Crichton
323c63f31bdSAlex Crichton fn encode<E>(&self, sink: &mut E)
324c63f31bdSAlex Crichton where
325c63f31bdSAlex Crichton E: Extend<u8>,
326c63f31bdSAlex Crichton {
327c63f31bdSAlex Crichton let Self { $( $( $field ),* )? } = *self;
328c63f31bdSAlex Crichton $snake_name(sink $( $(, $field)* )?)
329c63f31bdSAlex Crichton }
330c63f31bdSAlex Crichton }
3314ac1bedfSNick Fitzgerald )*
3324ac1bedfSNick Fitzgerald };
3334ac1bedfSNick Fitzgerald }
3344ac1bedfSNick Fitzgerald for_each_extended_op!(impl_extended_encoders);
335*c00e9ea2SChris Fallin
336*c00e9ea2SChris Fallin #[test]
337*c00e9ea2SChris Fallin #[cfg(feature = "std")]
nop_is_single_byte()338*c00e9ea2SChris Fallin fn nop_is_single_byte() {
339*c00e9ea2SChris Fallin // NOP needs to be a single byte so that it can be used to NOP out
340*c00e9ea2SChris Fallin // an instruction sequence of any length.
341*c00e9ea2SChris Fallin let inst = crate::op::Nop {};
342*c00e9ea2SChris Fallin let mut bytes = vec![];
343*c00e9ea2SChris Fallin inst.encode(&mut bytes);
344*c00e9ea2SChris Fallin assert_eq!(bytes.len(), 1);
345*c00e9ea2SChris Fallin }
346