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