1 //! Encoding support for pulley bytecode. 2 3 use crate::imms::*; 4 use crate::opcode::{ExtendedOpcode, Opcode}; 5 use crate::regs::*; 6 7 /// Helper trait to encode instructions into a "sink". 8 pub trait Encode { 9 /// The encoded width of this instruction. 10 const WIDTH: u8; 11 12 /// Encodes this operand or instruction into the provided `sink`. 13 fn encode<E>(&self, sink: &mut E) 14 where 15 E: Extend<u8>; 16 } 17 18 impl Encode for u8 { 19 const WIDTH: u8 = 1; 20 21 fn encode<E>(&self, sink: &mut E) 22 where 23 E: Extend<u8>, 24 { 25 sink.extend(core::iter::once(*self)); 26 } 27 } 28 29 impl Encode for u16 { 30 const WIDTH: u8 = 2; 31 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 u32 { 41 const WIDTH: u8 = 4; 42 43 fn encode<E>(&self, sink: &mut E) 44 where 45 E: Extend<u8>, 46 { 47 sink.extend(self.to_le_bytes()); 48 } 49 } 50 51 impl Encode for u64 { 52 const WIDTH: u8 = 8; 53 54 fn encode<E>(&self, sink: &mut E) 55 where 56 E: Extend<u8>, 57 { 58 sink.extend(self.to_le_bytes()); 59 } 60 } 61 62 impl Encode for i8 { 63 const WIDTH: u8 = 1; 64 65 fn encode<E>(&self, sink: &mut E) 66 where 67 E: Extend<u8>, 68 { 69 sink.extend(core::iter::once(*self as u8)); 70 } 71 } 72 73 impl Encode for i16 { 74 const WIDTH: u8 = 2; 75 76 fn encode<E>(&self, sink: &mut E) 77 where 78 E: Extend<u8>, 79 { 80 sink.extend(self.to_le_bytes()); 81 } 82 } 83 84 impl Encode for i32 { 85 const WIDTH: u8 = 4; 86 87 fn encode<E>(&self, sink: &mut E) 88 where 89 E: Extend<u8>, 90 { 91 sink.extend(self.to_le_bytes()); 92 } 93 } 94 95 impl Encode for i64 { 96 const WIDTH: u8 = 8; 97 98 fn encode<E>(&self, sink: &mut E) 99 where 100 E: Extend<u8>, 101 { 102 sink.extend(self.to_le_bytes()); 103 } 104 } 105 106 impl Encode for XReg { 107 const WIDTH: u8 = 1; 108 109 fn encode<E>(&self, sink: &mut E) 110 where 111 E: Extend<u8>, 112 { 113 sink.extend(core::iter::once(self.to_u8())); 114 } 115 } 116 117 impl Encode for FReg { 118 const WIDTH: u8 = 1; 119 120 fn encode<E>(&self, sink: &mut E) 121 where 122 E: Extend<u8>, 123 { 124 sink.extend(core::iter::once(self.to_u8())); 125 } 126 } 127 128 impl Encode for VReg { 129 const WIDTH: u8 = 1; 130 131 fn encode<E>(&self, sink: &mut E) 132 where 133 E: Extend<u8>, 134 { 135 sink.extend(core::iter::once(self.to_u8())); 136 } 137 } 138 139 impl Encode for PcRelOffset { 140 const WIDTH: u8 = 4; 141 142 fn encode<E>(&self, sink: &mut E) 143 where 144 E: Extend<u8>, 145 { 146 i32::from(*self).encode(sink); 147 } 148 } 149 150 impl<R: Reg> Encode for BinaryOperands<R> { 151 const WIDTH: u8 = 2; 152 153 fn encode<E>(&self, sink: &mut E) 154 where 155 E: Extend<u8>, 156 { 157 self.to_bits().encode(sink); 158 } 159 } 160 161 impl<R: Reg + Encode> Encode for RegSet<R> { 162 const WIDTH: u8 = 4; 163 164 fn encode<E>(&self, sink: &mut E) 165 where 166 E: Extend<u8>, 167 { 168 self.to_bitset().0.encode(sink); 169 } 170 } 171 172 macro_rules! impl_encoders { 173 ( 174 $( 175 $( #[$attr:meta] )* 176 $snake_name:ident = $name:ident $( { 177 $( 178 $( #[$field_attr:meta] )* 179 $field:ident : $field_ty:ty 180 ),* 181 } )? ; 182 )* 183 ) => { 184 $( 185 $( #[$attr] )* 186 pub fn $snake_name<E>(into: &mut E $( $( , $field : impl Into<$field_ty> )* )? ) 187 where 188 E: Extend<u8>, 189 { 190 into.extend(core::iter::once(Opcode::$name as u8)); 191 $( 192 $( 193 $field.into().encode(into); 194 )* 195 )? 196 } 197 198 impl Encode for crate::op::$name { 199 const WIDTH: u8 = 1 $($( + <$field_ty as Encode>::WIDTH)*)?; 200 201 fn encode<E>(&self, sink: &mut E) 202 where 203 E: Extend<u8>, 204 { 205 let Self { $( $( $field ),* )? } = *self; 206 $snake_name(sink $( $(, $field)* )?) 207 } 208 } 209 )* 210 }; 211 } 212 for_each_op!(impl_encoders); 213 214 macro_rules! impl_extended_encoders { 215 ( 216 $( 217 $( #[$attr:meta] )* 218 $snake_name:ident = $name:ident $( { 219 $( 220 $( #[$field_attr:meta] )* 221 $field:ident : $field_ty:ty 222 ),* 223 } )? ; 224 )* 225 ) => { 226 $( 227 $( #[$attr] )* 228 pub fn $snake_name<E>(into: &mut E $( $( , $field : impl Into<$field_ty> )* )? ) 229 where 230 E: Extend<u8>, 231 { 232 into.extend(core::iter::once(Opcode::ExtendedOp as u8)); 233 into.extend((ExtendedOpcode::$name as u16).to_le_bytes()); 234 $( 235 $( 236 $field.into().encode(into); 237 )* 238 )? 239 } 240 241 impl Encode for crate::op::$name { 242 const WIDTH: u8 = 3 $($( + <$field_ty as Encode>::WIDTH)*)?; 243 244 fn encode<E>(&self, sink: &mut E) 245 where 246 E: Extend<u8>, 247 { 248 let Self { $( $( $field ),* )? } = *self; 249 $snake_name(sink $( $(, $field)* )?) 250 } 251 } 252 )* 253 }; 254 } 255 for_each_extended_op!(impl_extended_encoders); 256