summaryrefslogtreecommitdiff
path: root/arch/msp430/src/flag.rs
diff options
context:
space:
mode:
authorJoe Rozner <joe@deadbytes.net>2024-08-20 21:55:05 -0700
committerAlexander Taylor <alex@vector35.com>2024-08-22 19:35:30 -0400
commitf038c7c9a9646c2a126d693eab7d297cd25565e3 (patch)
tree51b1366dabb78fad2e2a7cc0518b3604620f66d8 /arch/msp430/src/flag.rs
parent2a9d07d7fefe5a6d7f7a482397060a96782142ac (diff)
Add msp430 architecture
Diffstat (limited to 'arch/msp430/src/flag.rs')
-rw-r--r--arch/msp430/src/flag.rs153
1 files changed, 153 insertions, 0 deletions
diff --git a/arch/msp430/src/flag.rs b/arch/msp430/src/flag.rs
new file mode 100644
index 00000000..115fe866
--- /dev/null
+++ b/arch/msp430/src/flag.rs
@@ -0,0 +1,153 @@
+use binaryninja::architecture;
+use binaryninja::architecture::FlagRole;
+
+use std::borrow::Cow;
+use std::collections::HashMap;
+
+// NOTE: GIE, CPUOFF, OSCOFF, SG0, and SG1 not implemented as it's not clear how they would be used
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub enum Flag {
+ C,
+ Z,
+ N,
+ V,
+}
+
+impl architecture::Flag for Flag {
+ type FlagClass = FlagClass;
+
+ fn name(&self) -> Cow<str> {
+ match self {
+ Self::C => "c".into(),
+ Self::Z => "z".into(),
+ Self::N => "n".into(),
+ Self::V => "v".into(),
+ }
+ }
+
+ fn role(&self, _class: Option<Self::FlagClass>) -> architecture::FlagRole {
+ match self {
+ Self::C => FlagRole::CarryFlagRole,
+ Self::Z => FlagRole::ZeroFlagRole,
+ Self::N => FlagRole::NegativeSignFlagRole,
+ Self::V => FlagRole::OverflowFlagRole,
+ }
+ }
+
+ fn id(&self) -> u32 {
+ match self {
+ Self::C => 0,
+ Self::Z => 1,
+ Self::N => 2,
+ Self::V => 8,
+ }
+ }
+}
+
+impl TryFrom<u32> for Flag {
+ type Error = ();
+ fn try_from(flag: u32) -> Result<Self, Self::Error> {
+ match flag {
+ 0 => Ok(Self::C),
+ 1 => Ok(Self::Z),
+ 2 => Ok(Self::N),
+ 8 => Ok(Self::V),
+ _ => Err(()),
+ }
+ }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub struct FlagClass {}
+
+impl architecture::FlagClass for FlagClass {
+ fn name(&self) -> Cow<str> {
+ unimplemented!()
+ }
+
+ fn id(&self) -> u32 {
+ unimplemented!()
+ }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub enum FlagGroup {}
+
+impl architecture::FlagGroup for FlagGroup {
+ type FlagType = Flag;
+ type FlagClass = FlagClass;
+
+ fn name(&self) -> Cow<str> {
+ unimplemented!()
+ }
+
+ fn id(&self) -> u32 {
+ unimplemented!()
+ }
+
+ fn flags_required(&self) -> Vec<Self::FlagType> {
+ unimplemented!()
+ }
+
+ fn flag_conditions(&self) -> HashMap<Self::FlagClass, architecture::FlagCondition> {
+ unimplemented!()
+ }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub enum FlagWrite {
+ All,
+ Nz,
+ Nvz,
+ Cnz,
+}
+
+impl architecture::FlagWrite for FlagWrite {
+ type FlagType = Flag;
+ type FlagClass = FlagClass;
+
+ fn name(&self) -> Cow<str> {
+ match self {
+ Self::All => "*".into(),
+ Self::Nz => "nz".into(),
+ Self::Nvz => "nvz".into(),
+ Self::Cnz => "cnz".into(),
+ }
+ }
+
+ fn class(&self) -> Option<Self::FlagClass> {
+ None
+ }
+
+ fn id(&self) -> u32 {
+ match self {
+ Self::All => 1,
+ Self::Nz => 2,
+ Self::Nvz => 3,
+ Self::Cnz => 4,
+ }
+ }
+
+ fn flags_written(&self) -> Vec<Self::FlagType> {
+ match self {
+ Self::All => vec![Flag::C, Flag::N, Flag::V, Flag::Z],
+ Self::Nz => vec![Flag::N, Flag::Z],
+ Self::Nvz => vec![Flag::N, Flag::V, Flag::Z],
+ Self::Cnz => vec![Flag::C, Flag::N, Flag::Z],
+ }
+ }
+}
+
+impl TryFrom<u32> for FlagWrite {
+ type Error = ();
+
+ fn try_from(value: u32) -> Result<Self, Self::Error> {
+ match value {
+ 1 => Ok(Self::All),
+ 2 => Ok(Self::Nz),
+ 3 => Ok(Self::Nvz),
+ 4 => Ok(Self::Cnz),
+ _ => Err(()),
+ }
+ }
+}