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(u8::try_from(self.index()).unwrap())); 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(u8::try_from(self.index()).unwrap())); 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(u8::try_from(self.index()).unwrap())); 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 macro_rules! impl_encoders { 122 ( 123 $( 124 $( #[$attr:meta] )* 125 $snake_name:ident = $name:ident $( { 126 $( 127 $( #[$field_attr:meta] )* 128 $field:ident : $field_ty:ty 129 ),* 130 } )? ; 131 )* 132 ) => { 133 $( 134 $( #[$attr] )* 135 pub fn $snake_name<E>(into: &mut E $( $( , $field : impl Into<$field_ty> )* )? ) 136 where 137 E: Extend<u8>, 138 { 139 into.extend(core::iter::once(Opcode::$name as u8)); 140 $( 141 $( 142 $field.into().encode(into); 143 )* 144 )? 145 } 146 )* 147 }; 148 } 149 for_each_op!(impl_encoders); 150 151 macro_rules! impl_extended_encoders { 152 ( 153 $( 154 $( #[$attr:meta] )* 155 $snake_name:ident = $name:ident $( { 156 $( 157 $( #[$field_attr:meta] )* 158 $field:ident : $field_ty:ty 159 ),* 160 } )? ; 161 )* 162 ) => { 163 $( 164 $( #[$attr] )* 165 pub fn $snake_name<E>(into: &mut E $( $( , $field : impl Into<$field_ty> )* )? ) 166 where 167 E: Extend<u8>, 168 { 169 into.extend(core::iter::once(Opcode::ExtendedOp as u8)); 170 into.extend((ExtendedOpcode::$name as u16).to_le_bytes()); 171 $( 172 $( 173 $field.into().encode(into); 174 )* 175 )? 176 } 177 )* 178 }; 179 } 180 for_each_extended_op!(impl_extended_encoders); 181