~nabijaczleweli/yaxpeax-superh

aac3df6a316435b94fd22b108fe3438cdb889596 — Noa 2 years ago 692bfc5
Use bitflags for features list

That then allows us to remove the lifetime argument on SuperH and
SuperHDecoder, which makes everything a lot easier to work with.

Message-Id: <164133593706.28022.95407835631912381-1@git.sr.ht>
3 files changed, 41 insertions(+), 39 deletions(-)

M Cargo.toml
M build.rs
M src/lib.rs
M Cargo.toml => Cargo.toml +3 -0
@@ 13,6 13,9 @@ authors = ["наб <nabijaczleweli@nabijaczleweli.xyz>",
           "Noa"]


[dependencies]
bitflags = "1.3"

[dependencies.yaxpeax-arch]
version = "0.2.4"
default-features = false

M build.rs => build.rs +4 -4
@@ 500,7 500,7 @@ fn main() {
        let mut outf = File::create(dbg!(PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR")).join("instruction_feature.rs"))).expect("instruction_feature");

        writeln!(outf, "impl SuperHInstruction {{").unwrap();
        writeln!(outf, "    pub fn features(self) -> &'static [SuperHFeature] {{").unwrap();
        writeln!(outf, "    pub fn features(self) -> SuperHFeatures {{").unwrap();
        writeln!(outf, "        match self {{").unwrap();
        for (features, instructions) in feature_instructions {
            for (i, &(instr, argn)) in instructions.iter().enumerate() {


@@ 511,11 511,11 @@ fn main() {
                }
            }

            write!(outf, "=> &[").unwrap();
            write!(outf, "=> SuperHFeatures::empty()").unwrap();
            for f in features {
                write!(outf, "SuperHFeature::{}, ", f).unwrap();
                write!(outf, "| SuperHFeatures::{}", f).unwrap();
            }
            writeln!(outf, "],").unwrap();
            writeln!(outf, ",").unwrap();
        }
        writeln!(outf, "        }}").unwrap();
        writeln!(outf, "    }}").unwrap();

M src/lib.rs => src/lib.rs +34 -35
@@ 35,12 35,12 @@
//! # #[cfg(feature = "yaxpeax")]
//! # {
//! # use self::yaxpeax_superh::{SuperHInstructionDecodeError, SuperHExtendedDoubleRegister, SuperHDoubleRegister,
//! #                            SuperHInstruction, SuperHFeature, SuperHDecoder};
//! #                            SuperHInstruction, SuperHFeatures, SuperHDecoder};
//! # use self::yaxpeax_arch::{Decoder, U8Reader};
//! let cpu = SuperHDecoder {
//!     little_endian: false,
//!     fpscr_sz: true,
//!     features: &[SuperHFeature::FPU],
//!     features: SuperHFeatures::FPU,
//!     ..SuperHDecoder::SH4
//! };
//!


@@ 112,8 112,6 @@ extern crate std;
use core::fmt;
use core::convert::TryFrom;
#[cfg(feature = "yaxpeax")]
use core::marker::PhantomData;
#[cfg(feature = "yaxpeax")]
use yaxpeax_arch::{AddressDiff, Arch, DecodeError};




@@ 1640,12 1638,13 @@ pub struct Displacement8(pub u8);
#[repr(transparent)]
pub struct Displacement4(pub u8);

#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum SuperHFeature {
    FPU,
    MMU,
    /// [`CAS.L`](https://github.com/j-core/jcore-cpu/blob/00f398e/decode/decode_table_simple.vhd#L1919)
    J2,
bitflags::bitflags! {
    pub struct SuperHFeatures: u8 {
        const FPU = 0b0001;
        const MMU = 0b0010;
        /// [`CAS.L`](https://github.com/j-core/jcore-cpu/blob/00f398e/decode/decode_table_simple.vhd#L1919)
        const J2  = 0b0100;
    }
}

/// The revision of the ISA


@@ 1849,7 1848,7 @@ impl From<yaxpeax_arch::ReadError> for SuperHInstructionDecodeError {

#[cfg(feature = "yaxpeax")]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct SuperHDecoder<'f> {
pub struct SuperHDecoder {
    pub little_endian: bool,

    /// When `FPSCR.SZ` = 1, the SH-4 CPU core can perform data transfer by means of pair single-precision data transfer


@@ 1860,63 1859,63 @@ pub struct SuperHDecoder<'f> {
    pub fpscr_sz: bool,

    pub level: SuperHLevel,
    pub features: &'f [SuperHFeature],
    pub features: SuperHFeatures,
}

#[cfg(feature = "yaxpeax")]
impl SuperHDecoder<'_> {
impl SuperHDecoder {
    /// SuperH CPU in little-endian mode
    pub const SH1: SuperHDecoder<'static> = SuperHDecoder {
    pub const SH1: SuperHDecoder = SuperHDecoder {
        little_endian: true,
        fpscr_sz: false,
        level: SuperHLevel::Sh,
        features: &[],
        features: SuperHFeatures::empty(),
    };

    /// SH-2 CPU in little-endian mode
    pub const SH2: SuperHDecoder<'static> = SuperHDecoder {
    pub const SH2: SuperHDecoder = SuperHDecoder {
        little_endian: true,
        fpscr_sz: false,
        level: SuperHLevel::Sh2,
        features: &[],
        features: SuperHFeatures::empty(),
    };

    /// J-core J2 CPU in little-endian mode
    pub const J2: SuperHDecoder<'static> = SuperHDecoder {
    pub const J2: SuperHDecoder = SuperHDecoder {
        little_endian: true,
        fpscr_sz: false,
        level: SuperHLevel::J2,
        features: &[SuperHFeature::J2],
        features: SuperHFeatures::J2,
    };

    /// SH-3 CPU with MMU in little-endian mode
    pub const SH3: SuperHDecoder<'static> = SuperHDecoder {
    pub const SH3: SuperHDecoder = SuperHDecoder {
        little_endian: true,
        fpscr_sz: false,
        level: SuperHLevel::Sh3,
        features: &[SuperHFeature::MMU],
        features: SuperHFeatures::MMU,
    };

    /// SH-4 CPU with MMU and FPU (double-precision instructions off) in little-endian mode
    pub const SH4: SuperHDecoder<'static> = SuperHDecoder {
    pub const SH4: SuperHDecoder = SuperHDecoder {
        little_endian: true,
        fpscr_sz: false,
        level: SuperHLevel::Sh4,
        features: &[SuperHFeature::MMU, SuperHFeature::FPU],
        features: SuperHFeatures::MMU.union(SuperHFeatures::FPU),
    };
}

#[cfg(feature = "yaxpeax")]
impl<'f> yaxpeax_arch::Decoder<SuperH<'_>> for SuperHDecoder<'_> {
    fn decode_into<T: yaxpeax_arch::Reader<<SuperH<'f> as Arch>::Address, <SuperH<'f> as Arch>::Word>>(&self, inst: &mut SuperHInstruction, words: &mut T)
                                                                                                       -> Result<(), <SuperH<'_> as Arch>::DecodeError> {
impl yaxpeax_arch::Decoder<SuperH> for SuperHDecoder {
    fn decode_into<T: yaxpeax_arch::Reader<<SuperH as Arch>::Address, <SuperH as Arch>::Word>>(&self, inst: &mut SuperHInstruction, words: &mut T)
                                                                                                       -> Result<(), <SuperH as Arch>::DecodeError> {
        *inst = self.decode(words)?;
        Ok(())
    }

    fn decode<T: yaxpeax_arch::Reader<<SuperH<'f> as Arch>::Address, <SuperH<'f> as Arch>::Word>>(
    fn decode<T: yaxpeax_arch::Reader<<SuperH as Arch>::Address, <SuperH as Arch>::Word>>(
        &self, words: &mut T)
        -> Result<SuperHInstruction, <SuperH<'_> as Arch>::DecodeError> {
        -> Result<SuperHInstruction, <SuperH as Arch>::DecodeError> {
        // mov #0x69,r4 (1110nnnniiiiiiii) encodes as 69 e4 in LE and e4 69 in BE
        let ins = ((words.next()? as u16) << (if self.little_endian { 0 } else { 8 })) | ((words.next()? as u16) << (if self.little_endian { 8 } else { 0 }));



@@ 1926,7 1925,7 @@ impl<'f> yaxpeax_arch::Decoder<SuperH<'_>> for SuperHDecoder<'_> {
            return Err(SuperHInstructionDecodeError::NotFound);
        }

        if !ret.features().iter().all(|rf| self.features.contains(rf)) {
        if !self.features.contains(ret.features()) {
            return Err(SuperHInstructionDecodeError::NotFound);
        }



@@ 1935,26 1934,26 @@ impl<'f> yaxpeax_arch::Decoder<SuperH<'_>> for SuperHDecoder<'_> {
}

#[cfg(feature = "yaxpeax")]
impl<'f> Default for SuperHDecoder<'f> {
    fn default() -> SuperHDecoder<'f> {
impl Default for SuperHDecoder {
    fn default() -> SuperHDecoder {
        SuperHDecoder {
            little_endian: true,
            fpscr_sz: false,
            level: SuperHLevel::Sh,
            features: &[],
            features: SuperHFeatures::empty(),
        }
    }
}


#[cfg(feature = "yaxpeax")]
pub struct SuperH<'f>(PhantomData<&'f ()>);
pub struct SuperH;
#[cfg(feature = "yaxpeax")]
impl<'f> Arch for SuperH<'f> {
impl Arch for SuperH {
    type Address = u32;
    type Word = u8;
    type Instruction = SuperHInstruction;
    type DecodeError = SuperHInstructionDecodeError;
    type Decoder = SuperHDecoder<'f>;
    type Decoder = SuperHDecoder;
    type Operand = ();
}