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