1use crate::imms::*;
4use crate::opcode::*;
5use crate::regs::*;
6use alloc::vec::Vec;
7use core::convert::Infallible;
8use core::ptr::NonNull;
9use cranelift_bitset::ScalarBitSet;
10use cranelift_bitset::scalar::ScalarBitSetStorage;
11
12pub type Result<T, E = DecodingError> = core::result::Result<T, E>;
14
15pub enum DecodingError {
17 UnexpectedEof {
20 position: usize,
22 },
23
24 InvalidOpcode {
26 position: usize,
28 code: u8,
30 },
31
32 InvalidExtendedOpcode {
34 position: usize,
36 code: u16,
38 },
39
40 InvalidReg {
42 position: usize,
44 reg: u8,
46 },
47}
48
49impl core::fmt::Debug for DecodingError {
50 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
51 core::fmt::Display::fmt(self, f)
52 }
53}
54
55impl core::fmt::Display for DecodingError {
56 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
57 match self {
58 Self::UnexpectedEof { position } => {
59 write!(f, "unexpected end-of-file at bytecode offset {position:#x}")
60 }
61 Self::InvalidOpcode { position, code } => {
62 write!(
63 f,
64 "found invalid opcode {code:#x} at bytecode offset {position:#x}"
65 )
66 }
67 Self::InvalidExtendedOpcode { position, code } => {
68 write!(
69 f,
70 "found invalid opcode {code:#x} at bytecode offset {position:#x}"
71 )
72 }
73 Self::InvalidReg { position, reg } => {
74 write!(
75 f,
76 "found invalid register {reg:#x} at bytecode offset {position:#x}"
77 )
78 }
79 }
80 }
81}
82
83#[cfg(feature = "std")]
84impl std::error::Error for DecodingError {}
85
86pub trait BytecodeStream: Copy {
98 type Error;
101
102 fn unexpected_eof(&self) -> Self::Error;
104
105 fn invalid_opcode(&self, code: u8) -> Self::Error;
107
108 fn invalid_extended_opcode(&self, code: u16) -> Self::Error;
110
111 fn invalid_reg(&self, reg: u8) -> Self::Error;
113
114 fn read<const N: usize>(&mut self) -> Result<[u8; N], Self::Error>;
117}
118
119#[derive(Clone, Copy, Debug)]
123pub struct SafeBytecodeStream<'a> {
124 bytecode: &'a [u8],
125 position: usize,
126}
127
128impl<'a> SafeBytecodeStream<'a> {
129 pub fn new(bytecode: &'a [u8]) -> Self {
132 Self {
133 bytecode,
134 position: 0,
135 }
136 }
137
138 pub fn position(&self) -> usize {
140 self.position
141 }
142
143 pub fn as_slice(&self) -> &[u8] {
145 &self.bytecode
146 }
147}
148
149impl BytecodeStream for SafeBytecodeStream<'_> {
150 fn read<const N: usize>(&mut self) -> Result<[u8; N], Self::Error> {
151 let (bytes, rest) = self
152 .bytecode
153 .split_first_chunk()
154 .ok_or_else(|| self.unexpected_eof())?;
155 self.bytecode = rest;
156 self.position += N;
157 Ok(*bytes)
158 }
159
160 type Error = DecodingError;
161
162 fn unexpected_eof(&self) -> Self::Error {
163 DecodingError::UnexpectedEof {
164 position: self.position,
165 }
166 }
167
168 fn invalid_opcode(&self, code: u8) -> Self::Error {
169 DecodingError::InvalidOpcode {
170 position: self.position - 1,
171 code,
172 }
173 }
174
175 fn invalid_extended_opcode(&self, code: u16) -> Self::Error {
176 DecodingError::InvalidExtendedOpcode {
177 position: self.position,
178 code,
179 }
180 }
181
182 fn invalid_reg(&self, reg: u8) -> Self::Error {
183 DecodingError::InvalidReg {
184 position: self.position,
185 reg,
186 }
187 }
188}
189
190#[derive(Clone, Copy, Debug)]
194pub struct UnsafeBytecodeStream(NonNull<u8>);
195
196impl UnsafeBytecodeStream {
197 pub unsafe fn new(pc: NonNull<u8>) -> Self {
209 UnsafeBytecodeStream(pc)
210 }
211
212 pub unsafe fn offset(&self, offset: isize) -> Self {
221 UnsafeBytecodeStream(unsafe { NonNull::new_unchecked(self.0.as_ptr().offset(offset)) })
222 }
223
224 pub fn as_ptr(&self) -> NonNull<u8> {
226 self.0
227 }
228}
229
230impl BytecodeStream for UnsafeBytecodeStream {
231 fn read<const N: usize>(&mut self) -> Result<[u8; N], Self::Error> {
232 let bytes = unsafe { self.0.cast::<[u8; N]>().as_ptr().read() };
233 self.0 = unsafe { NonNull::new_unchecked(self.0.as_ptr().add(N)) };
234 Ok(bytes)
235 }
236
237 type Error = Infallible;
238
239 fn unexpected_eof(&self) -> Self::Error {
240 unsafe { crate::unreachable_unchecked() }
241 }
242
243 fn invalid_opcode(&self, _code: u8) -> Self::Error {
244 unsafe { crate::unreachable_unchecked() }
245 }
246
247 fn invalid_extended_opcode(&self, _code: u16) -> Self::Error {
248 unsafe { crate::unreachable_unchecked() }
249 }
250
251 fn invalid_reg(&self, _reg: u8) -> Self::Error {
252 unsafe { crate::unreachable_unchecked() }
253 }
254}
255
256pub trait Decode: Sized {
259 fn decode<T>(bytecode: &mut T) -> Result<Self, T::Error>
261 where
262 T: BytecodeStream;
263}
264
265impl Decode for u8 {
266 fn decode<T>(bytecode: &mut T) -> Result<Self, T::Error>
267 where
268 T: BytecodeStream,
269 {
270 bytecode.read::<1>().map(|a| a[0])
271 }
272}
273
274impl Decode for u16 {
275 fn decode<T>(bytecode: &mut T) -> Result<Self, T::Error>
276 where
277 T: BytecodeStream,
278 {
279 Ok(u16::from_le_bytes(bytecode.read()?))
280 }
281}
282
283impl Decode for u32 {
284 fn decode<T>(bytecode: &mut T) -> Result<Self, T::Error>
285 where
286 T: BytecodeStream,
287 {
288 Ok(u32::from_le_bytes(bytecode.read()?))
289 }
290}
291
292impl Decode for u64 {
293 fn decode<T>(bytecode: &mut T) -> Result<Self, T::Error>
294 where
295 T: BytecodeStream,
296 {
297 Ok(u64::from_le_bytes(bytecode.read()?))
298 }
299}
300
301impl Decode for u128 {
302 fn decode<T>(bytecode: &mut T) -> Result<Self, T::Error>
303 where
304 T: BytecodeStream,
305 {
306 Ok(u128::from_le_bytes(bytecode.read()?))
307 }
308}
309
310impl Decode for i8 {
311 fn decode<T>(bytecode: &mut T) -> Result<Self, T::Error>
312 where
313 T: BytecodeStream,
314 {
315 bytecode.read::<1>().map(|a| a[0] as i8)
316 }
317}
318
319impl Decode for i16 {
320 fn decode<T>(bytecode: &mut T) -> Result<Self, T::Error>
321 where
322 T: BytecodeStream,
323 {
324 Ok(i16::from_le_bytes(bytecode.read()?))
325 }
326}
327
328impl Decode for i32 {
329 fn decode<T>(bytecode: &mut T) -> Result<Self, T::Error>
330 where
331 T: BytecodeStream,
332 {
333 Ok(i32::from_le_bytes(bytecode.read()?))
334 }
335}
336
337impl Decode for i64 {
338 fn decode<T>(bytecode: &mut T) -> Result<Self, T::Error>
339 where
340 T: BytecodeStream,
341 {
342 Ok(i64::from_le_bytes(bytecode.read()?))
343 }
344}
345
346impl Decode for i128 {
347 fn decode<T>(bytecode: &mut T) -> Result<Self, T::Error>
348 where
349 T: BytecodeStream,
350 {
351 Ok(i128::from_le_bytes(bytecode.read()?))
352 }
353}
354
355impl Decode for XReg {
356 fn decode<T>(bytecode: &mut T) -> Result<Self, T::Error>
357 where
358 T: BytecodeStream,
359 {
360 let byte = u8::decode(bytecode)?;
361 XReg::new(byte).ok_or_else(|| bytecode.invalid_reg(byte))
362 }
363}
364
365impl Decode for FReg {
366 fn decode<T>(bytecode: &mut T) -> Result<Self, T::Error>
367 where
368 T: BytecodeStream,
369 {
370 let byte = u8::decode(bytecode)?;
371 FReg::new(byte).ok_or_else(|| bytecode.invalid_reg(byte))
372 }
373}
374
375impl Decode for VReg {
376 fn decode<T>(bytecode: &mut T) -> Result<Self, T::Error>
377 where
378 T: BytecodeStream,
379 {
380 let byte = u8::decode(bytecode)?;
381 VReg::new(byte).ok_or_else(|| bytecode.invalid_reg(byte))
382 }
383}
384
385impl Decode for PcRelOffset {
386 fn decode<T>(bytecode: &mut T) -> Result<Self, T::Error>
387 where
388 T: BytecodeStream,
389 {
390 i32::decode(bytecode).map(|x| Self::from(x))
391 }
392}
393
394impl Decode for Opcode {
395 fn decode<T>(bytecode: &mut T) -> Result<Self, T::Error>
396 where
397 T: BytecodeStream,
398 {
399 let byte = u8::decode(bytecode)?;
400 match Opcode::new(byte) {
401 Some(v) => Ok(v),
402 None => Err(bytecode.invalid_opcode(byte)),
403 }
404 }
405}
406
407impl Decode for ExtendedOpcode {
408 fn decode<T>(bytecode: &mut T) -> Result<Self, T::Error>
409 where
410 T: BytecodeStream,
411 {
412 let word = u16::decode(bytecode)?;
413 match ExtendedOpcode::new(word) {
414 Some(v) => Ok(v),
415 None => Err(bytecode.invalid_extended_opcode(word)),
416 }
417 }
418}
419
420impl<D: Reg, S1: Reg, S2: Reg> Decode for BinaryOperands<D, S1, S2> {
421 fn decode<T>(bytecode: &mut T) -> Result<Self, T::Error>
422 where
423 T: BytecodeStream,
424 {
425 u16::decode(bytecode).map(|bits| Self::from_bits(bits))
426 }
427}
428
429impl<D: Reg, S1: Reg> Decode for BinaryOperands<D, S1, U6> {
430 fn decode<T>(bytecode: &mut T) -> Result<Self, T::Error>
431 where
432 T: BytecodeStream,
433 {
434 u16::decode(bytecode).map(|bits| Self::from_bits(bits))
435 }
436}
437
438impl<S: Decode + ScalarBitSetStorage> Decode for ScalarBitSet<S> {
439 fn decode<T>(bytecode: &mut T) -> Result<Self, T::Error>
440 where
441 T: BytecodeStream,
442 {
443 S::decode(bytecode).map(ScalarBitSet::from)
444 }
445}
446
447impl<R: Reg + Decode> Decode for UpperRegSet<R> {
448 fn decode<T>(bytecode: &mut T) -> Result<Self, T::Error>
449 where
450 T: BytecodeStream,
451 {
452 ScalarBitSet::decode(bytecode).map(Self::from)
453 }
454}
455
456impl Decode for AddrO32 {
457 fn decode<T>(bytecode: &mut T) -> Result<Self, T::Error>
458 where
459 T: BytecodeStream,
460 {
461 Ok(AddrO32 {
462 addr: XReg::decode(bytecode)?,
463 offset: i32::decode(bytecode)?,
464 })
465 }
466}
467
468impl Decode for AddrZ {
469 fn decode<T>(bytecode: &mut T) -> Result<Self, T::Error>
470 where
471 T: BytecodeStream,
472 {
473 Ok(AddrZ {
474 addr: XReg::decode(bytecode)?,
475 offset: i32::decode(bytecode)?,
476 })
477 }
478}
479
480impl Decode for AddrG32 {
481 fn decode<T>(bytecode: &mut T) -> Result<Self, T::Error>
482 where
483 T: BytecodeStream,
484 {
485 Ok(AddrG32::from_bits(u32::decode(bytecode)?))
486 }
487}
488
489impl Decode for AddrG32Bne {
490 fn decode<T>(bytecode: &mut T) -> Result<Self, T::Error>
491 where
492 T: BytecodeStream,
493 {
494 Ok(AddrG32Bne::from_bits(u32::decode(bytecode)?))
495 }
496}
497
498#[derive(Default)]
506pub struct Decoder {
507 _private: (),
508}
509
510impl Decoder {
511 pub fn new() -> Self {
513 Self::default()
514 }
515
516 pub fn decode_all<'a, V>(visitor: &mut V) -> Result<Vec<V::Return>>
521 where
522 V: OpVisitor<BytecodeStream = SafeBytecodeStream<'a>> + ExtendedOpVisitor,
523 {
524 let mut decoder = Decoder::new();
525 let mut results = Vec::new();
526
527 while !visitor.bytecode().as_slice().is_empty() {
528 results.push(decoder.decode_one(visitor)?);
529 }
530
531 Ok(results)
532 }
533}
534
535pub struct SequencedVisitor<'a, F, V1, V2> {
537 join: F,
538 v1: &'a mut V1,
539 v2: &'a mut V2,
540}
541
542impl<'a, F, V1, V2> SequencedVisitor<'a, F, V1, V2> {
543 pub fn new(join: F, v1: &'a mut V1, v2: &'a mut V2) -> Self {
548 SequencedVisitor { join, v1, v2 }
549 }
550}
551
552macro_rules! define_decoder {
553 (
554 $(
555 $( #[$attr:meta] )*
556 $snake_name:ident = $name:ident $( {
557 $(
558 $( #[$field_attr:meta] )*
559 $field:ident : $field_ty:ty
560 ),*
561 } )? ;
562 )*
563 ) => {
564 impl Decoder {
565 #[inline(always)]
570 pub fn decode_one<V>(
571 &mut self,
572 visitor: &mut V,
573 ) -> Result<V::Return, <V::BytecodeStream as BytecodeStream>::Error>
574 where
575 V: OpVisitor + ExtendedOpVisitor,
576 {
577 visitor.before_visit();
578
579 let byte = u8::decode(visitor.bytecode())?;
580 let opcode = Opcode::new(byte).ok_or_else(|| {
581 visitor.bytecode().invalid_opcode(byte)
582 })?;
583
584 match opcode {
585 $(
586 Opcode::$name => {
587 $(
588 $(
589 let $field = <$field_ty>::decode(
590 visitor.bytecode(),
591 )?;
592 )*
593 )?
594
595 let ret = visitor.$snake_name($( $( $field ),* )?);
596 visitor.after_visit();
597 Ok(ret)
598 },
599 )*
600 Opcode::ExtendedOp => {
601 decode_one_extended(visitor)
602 }
603 }
604 }
605 }
606
607 pub trait OpVisitor {
616 type BytecodeStream: BytecodeStream;
618
619 fn bytecode(&mut self) -> &mut Self::BytecodeStream;
621
622 type Return;
624
625 fn before_visit(&mut self) {}
629
630 fn after_visit(&mut self) {}
635
636 $(
637 $( #[$attr] )*
638 fn $snake_name(&mut self $( $( , $field : $field_ty )* )? ) -> Self::Return;
639 )*
640 }
641
642 impl<F, T, V1, V2> OpVisitor for SequencedVisitor<'_, F, V1, V2>
643 where
644 F: FnMut(V1::Return, V2::Return) -> T,
645 V1: OpVisitor,
646 V2: OpVisitor<BytecodeStream = V1::BytecodeStream>,
647 {
648 type BytecodeStream = V1::BytecodeStream;
649
650 fn bytecode(&mut self) -> &mut Self::BytecodeStream {
651 self.v1.bytecode()
652 }
653
654 type Return = T;
655
656 fn before_visit(&mut self) {
657 self.v1.before_visit();
658 self.v2.before_visit();
659 }
660
661 fn after_visit(&mut self) {
662 *self.v2.bytecode() = *self.v1.bytecode();
663 self.v1.after_visit();
664 self.v2.after_visit();
665 }
666
667 $(
668 $( #[$attr] )*
669 fn $snake_name(&mut self $( $( , $field : $field_ty )* )? ) -> Self::Return {
670 let a = self.v1.$snake_name( $( $( $field , )* )? );
671 let b = self.v2.$snake_name( $( $( $field , )* )? );
672 (self.join)(a, b)
673 }
674 )*
675 }
676 };
677}
678for_each_op!(define_decoder);
679
680macro_rules! define_extended_decoder {
681 (
682 $(
683 $( #[$attr:meta] )*
684 $snake_name:ident = $name:ident $( {
685 $(
686 $( #[$field_attr:meta] )*
687 $field:ident : $field_ty:ty
688 ),*
689 } )? ;
690 )*
691 ) => {
692 pub trait ExtendedOpVisitor: OpVisitor {
694 $(
695 $( #[$attr] )*
696 fn $snake_name(&mut self $( $( , $field : $field_ty )* )? ) -> Self::Return;
697 )*
698 }
699
700 fn decode_one_extended<V>(
701 visitor: &mut V,
702 ) -> Result<V::Return, <V::BytecodeStream as BytecodeStream>::Error>
703 where
704 V: ExtendedOpVisitor,
705 {
706 let code = u16::decode(visitor.bytecode())?;
707 let opcode = ExtendedOpcode::new(code).ok_or_else(|| {
708 visitor.bytecode().invalid_extended_opcode(code)
709 })?;
710
711 match opcode {
712 $(
713 ExtendedOpcode::$name => {
714 $(
715 $(
716 let $field = <$field_ty>::decode(
717 visitor.bytecode(),
718 )?;
719 )*
720 )?
721
722 let ret = visitor.$snake_name($( $( $field ),* )?);
723 visitor.after_visit();
724 Ok(ret)
725 }
726 )*
727 }
728 }
729
730
731 impl<F, T, V1, V2> ExtendedOpVisitor for SequencedVisitor<'_, F, V1, V2>
732 where
733 F: FnMut(V1::Return, V2::Return) -> T,
734 V1: ExtendedOpVisitor,
735 V2: ExtendedOpVisitor<BytecodeStream = V1::BytecodeStream>,
736 {
737 $(
738 $( #[$attr] )*
739 fn $snake_name(&mut self $( $( , $field : $field_ty )* )? ) -> Self::Return {
740 let a = self.v1.$snake_name( $( $( $field , )* )? );
741 let b = self.v2.$snake_name( $( $( $field , )* )? );
742 (self.join)(a, b)
743 }
744 )*
745 }
746 };
747}
748for_each_extended_op!(define_extended_decoder);
749
750pub mod operands {
753 use super::*;
754
755 macro_rules! define_operands_decoder {
756 (
757 $(
758 $( #[$attr:meta] )*
759 $snake_name:ident = $name:ident $( {
760 $(
761 $( #[$field_attr:meta] )*
762 $field:ident : $field_ty:ty
763 ),*
764 } )? ;
765 )*
766 ) => {
767 $(
768 #[allow(unused_variables, reason = "macro-generated")]
769 #[expect(missing_docs, reason = "macro-generated")]
770 pub fn $snake_name<T: BytecodeStream>(pc: &mut T) -> Result<($($($field_ty,)*)?), T::Error> {
771 Ok((($($((<$field_ty>::decode(pc))?,)*)?)))
772 }
773 )*
774 };
775 }
776
777 for_each_op!(define_operands_decoder);
778
779 pub fn extended<T: BytecodeStream>(pc: &mut T) -> Result<(ExtendedOpcode,), T::Error> {
782 Ok((ExtendedOpcode::decode(pc)?,))
783 }
784
785 for_each_extended_op!(define_operands_decoder);
786}