xref: /wasmtime-44.0.1/pulley/src/encode.rs (revision c00e9ea2)
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