summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2021-07-06 18:19:19 -0700
committeriximeow <me@iximeow.net>2021-07-06 18:21:16 -0700
commite98b04b473465a161aefd8d6cf7213f08b54758f (patch)
tree99e3c5ae7792e36229afeb20750e1b81b33d7210
parent0eed3ca0c9413071a15bd5171a3522a413aae383 (diff)
update yaxpeax-arch to 0.2.3, tag 0.1.00.1.0
-rw-r--r--CHANGELOG7
-rw-r--r--Cargo.toml4
-rw-r--r--src/display.rs14
-rw-r--r--src/lib.rs91
-rw-r--r--test/test.rs20
5 files changed, 45 insertions, 91 deletions
diff --git a/CHANGELOG b/CHANGELOG
new file mode 100644
index 0000000..0c9b6f0
--- /dev/null
+++ b/CHANGELOG
@@ -0,0 +1,7 @@
+# 0.1.0
+
+update yaxpeax-arch to 0.2.3, apply API updates
+
+# 0.0.5
+
+first version with changelog, theoretically complete
diff --git a/Cargo.toml b/Cargo.toml
index 89c8a4a..c4f97b8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,14 +1,14 @@
[package]
name = "yaxpeax-msp430"
-version = "0.0.6"
+version = "0.1.0"
authors = [ "iximeow <me@iximeow.net>" ]
license = "0BSD"
repository = "http://git.iximeow.net/yaxpeax-msp430/"
description = "msp430 decoders for the yaxpeax project"
[dependencies]
-yaxpeax-arch = { version = "0.0.5", default-features = false, features = [] }
+yaxpeax-arch = { version = "0.2.3", default-features = false, features = [] }
"serde" = { version = "1.0", optional = true }
"serde_derive" = { version = "1.0", optional = true }
diff --git a/src/display.rs b/src/display.rs
index 54147f7..12153b1 100644
--- a/src/display.rs
+++ b/src/display.rs
@@ -1,6 +1,6 @@
-use ::{MSP430, Operand, Opcode, Instruction, Width, DecodeError};
+use ::{MSP430, Operand, Opcode, Instruction, Width};
-use std::fmt::{self, Display, Formatter};
+use std::fmt::{Display, Formatter};
use std;
use yaxpeax_arch::{Arch, Colorize, NoColors, ShowContextual, YaxColors};
@@ -12,16 +12,6 @@ impl Display for Instruction {
}
}
-impl fmt::Display for DecodeError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match self {
- DecodeError::ExhaustedInput => write!(f, "exhausted input"),
- DecodeError::InvalidOpcode => write!(f, "invalid opcode"),
- DecodeError::InvalidOperand => write!(f, "invalid operand"),
- }
- }
-}
-
/// No per-operand when contextualizing an instruction.
pub struct NoContext;
diff --git a/src/lib.rs b/src/lib.rs
index 8d3a257..71d9b4e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -7,23 +7,20 @@ extern crate serde;
extern crate yaxpeax_arch;
-use yaxpeax_arch::{Arch, AddressDiff, Decoder, LengthedInstruction};
+use yaxpeax_arch::{Arch, AddressDiff, Decoder, LengthedInstruction, Reader, StandardDecodeError, U16le};
mod display;
pub use display::NoContext;
-#[cfg(feature="use-serde")]
-#[derive(Debug, Serialize, Deserialize)]
-pub struct MSP430;
-
-#[cfg(not(feature="use-serde"))]
+#[cfg_attr(feature="use-serde", derive(Serialize, Deserialize))]
#[derive(Debug)]
pub struct MSP430;
impl Arch for MSP430 {
type Address = u16;
+ type Word = U16le;
type Instruction = Instruction;
- type DecodeError = DecodeError;
+ type DecodeError = StandardDecodeError;
type Decoder = InstDecoder;
type Operand = Operand;
}
@@ -126,19 +123,6 @@ pub enum Operand {
Nothing
}
-#[derive(Debug, PartialEq)]
-pub enum DecodeError {
- ExhaustedInput,
- InvalidOpcode,
- InvalidOperand,
-}
-
-impl yaxpeax_arch::DecodeError for DecodeError {
- fn data_exhausted(&self) -> bool { self == &DecodeError::ExhaustedInput }
- fn bad_opcode(&self) -> bool { self == &DecodeError::InvalidOpcode }
- fn bad_operand(&self) -> bool { self == &DecodeError::InvalidOperand }
-}
-
impl yaxpeax_arch::Instruction for Instruction {
// TODO: this is wrong!!
fn well_defined(&self) -> bool { true }
@@ -174,10 +158,7 @@ impl Default for InstDecoder {
}
}
-impl Decoder<Instruction> for InstDecoder {
- type Error = DecodeError;
-
- fn decode_into<T: IntoIterator<Item=u8>>(&self, inst: &mut Instruction, bytes: T) -> Result<(), Self::Error> {
+/*
let mut bytes_iter = bytes.into_iter();
let word: Vec<u8> = bytes_iter.by_ref().take(2).collect();
@@ -186,42 +167,32 @@ impl Decoder<Instruction> for InstDecoder {
[low, high] => (high as u16) << 8 | (low as u16),
_ => unreachable!()
};
+ */
- fn decode_operand<T: Iterator<Item=u8>>(bytes: &mut T, reg: u8, mode: u8, oper: &mut Operand) -> bool {
+impl Decoder<MSP430> for InstDecoder {
+ fn decode_into<T: Reader<<MSP430 as Arch>::Address, <MSP430 as Arch>::Word>>(&self, inst: &mut Instruction, words: &mut T) -> Result<(), <MSP430 as Arch>::DecodeError> {
+ let fullword = words.next()?.0;
+
+ fn decode_operand<T: Reader<<MSP430 as Arch>::Address, <MSP430 as Arch>::Word>>(words: &mut T, reg: u8, mode: u8, oper: &mut Operand) -> Result<(), StandardDecodeError> {
*oper = match reg {
0 => {
if mode == 0 {
Operand::Register(reg)
} else if mode == 1 {
- let next = match bytes.take(2).collect::<Vec<u8>>()[..] {
- [] | [_] => { return false; },
- [low, high] => { ((high as u16) << 8) | (low as u16) },
- _ => { unreachable!() }
- };
- Operand::Symbolic(next)
+ Operand::Symbolic(words.next()?.0)
} else if mode == 2 {
Operand::RegisterIndirect(reg)
} else if mode == 3 {
- let next = match bytes.take(2).collect::<Vec<u8>>()[..] {
- [] | [_] => { return false; },
- [low, high] => { ((high as u16) << 8) | (low as u16) },
- _ => { unreachable!() }
- };
- Operand::Immediate(next)
+ Operand::Immediate(words.next()?.0)
} else {
- return false;
+ return Err(StandardDecodeError::InvalidOperand);
}
},
2 => {
match mode {
0 => { Operand::Register(reg) },
1 => {
- let next = match bytes.take(2).collect::<Vec<u8>>()[..] {
- [] | [_] => { return false; },
- [low, high] => { ((high as u16) << 8) | (low as u16) },
- _ => { unreachable!() }
- };
- Operand::Absolute(next)
+ Operand::Absolute(words.next()?.0)
},
2 => { Operand::Const8 },
3 => { Operand::Const4 },
@@ -241,12 +212,7 @@ impl Decoder<Instruction> for InstDecoder {
match mode {
0 => { Operand::Register(reg) },
1 => {
- let next = match bytes.take(2).collect::<Vec<u8>>()[..] {
- [] | [_] => { return false; },
- [low, high] => { ((high as u16) << 8) | (low as u16) },
- _ => { unreachable!() }
- };
- Operand::Indexed(reg, next)
+ Operand::Indexed(reg, words.next()?.0)
},
2 => { Operand::RegisterIndirect(reg) },
3 => { Operand::IndirectAutoinc(reg) },
@@ -254,7 +220,7 @@ impl Decoder<Instruction> for InstDecoder {
}
}
};
- return true;
+ return Ok(());
}
inst.op_width = Width::W;
@@ -271,7 +237,7 @@ impl Decoder<Instruction> for InstDecoder {
instrword if instrword < 0x2000 => {
// microcorruption msp430 is non-standard and accepts invalid instructions..
if !self.microcorruption_quirks() {
- return Err(DecodeError::InvalidOpcode);
+ return Err(StandardDecodeError::InvalidOpcode);
}
let (opcode_idx, operands) = ((instrword & 0x0380) >> 7, instrword & 0x7f);
@@ -290,7 +256,7 @@ impl Decoder<Instruction> for InstDecoder {
} else {
if x == 1 || x == 3 || x == 5 {
inst.opcode = Opcode::Invalid(instrword);
- return Err(DecodeError::InvalidOpcode);
+ return Err(StandardDecodeError::InvalidOpcode);
}
Width:: B
};
@@ -299,10 +265,7 @@ impl Decoder<Instruction> for InstDecoder {
((instrword & 0x0030) >> 4) as u8,
(instrword & 0x000f) as u8
);
- if !decode_operand(&mut bytes_iter, source, As, &mut inst.operands[0]) {
- inst.opcode = Opcode::Invalid(instrword);
- return Err(DecodeError::InvalidOperand);
- };
+ decode_operand(words, source, As, &mut inst.operands[0])?;
inst.operands[1] = Operand::Nothing;
Ok(())
},
@@ -314,12 +277,12 @@ impl Decoder<Instruction> for InstDecoder {
Ok(())
} else {
inst.opcode = Opcode::Invalid(instrword);
- return Err(DecodeError::InvalidOperand);
+ return Err(StandardDecodeError::InvalidOperand);
}
}
7 => {
inst.opcode = Opcode::Invalid(instrword);
- return Err(DecodeError::InvalidOpcode);
+ return Err(StandardDecodeError::InvalidOpcode);
}
_ => {
unreachable!();
@@ -366,14 +329,8 @@ impl Decoder<Instruction> for InstDecoder {
((instrword & 0x0030) >> 4) as u8,
(instrword & 0x000f) as u8
);
- if !decode_operand(&mut bytes_iter, source, As, &mut inst.operands[0]) {
- inst.opcode = Opcode::Invalid(instrword);
- return Err(DecodeError::InvalidOperand);
- }
- if !decode_operand(&mut bytes_iter, dest, Ad, &mut inst.operands[1]) {
- inst.opcode = Opcode::Invalid(instrword);
- return Err(DecodeError::InvalidOperand);
- }
+ decode_operand(words, source, As, &mut inst.operands[0])?;
+ decode_operand(words, dest, Ad, &mut inst.operands[1])?;
Ok(())
}
}
diff --git a/test/test.rs b/test/test.rs
index 663b080..eb2399e 100644
--- a/test/test.rs
+++ b/test/test.rs
@@ -1,26 +1,26 @@
extern crate yaxpeax_arch;
extern crate yaxpeax_msp430;
-use yaxpeax_arch::{Arch, Decoder};
+use yaxpeax_arch::{Arch, Decoder, U8Reader};
use yaxpeax_msp430::{Opcode, MSP430};
#[test]
fn test_decode() {
- let decoder = <MSP430 as Arch>::Decoder::default();
+ fn decode(bytes: &[u8]) -> yaxpeax_msp430::Instruction {
+ let decoder = <MSP430 as Arch>::Decoder::default();
+ let mut reader = U8Reader::new(bytes);
+ decoder.decode(&mut reader).unwrap()
+ }
- let data = [0x02, 0x12];
- let instr = decoder.decode(data.iter().cloned()).unwrap();
+ let instr = decode(&[0x02, 0x12][..]);
assert!(instr.opcode == Opcode::PUSH);
- let data = [0xb1, 0x92, 0x8d, 0x49];
- let instr = decoder.decode(data.iter().cloned()).unwrap();
+ let instr = decode(&[0xb1, 0x92, 0x8d, 0x49][..]);
assert!(instr.opcode == Opcode::CMP);
- let data = [0x12, 0x00, 0x3f, 0x40];
- let instr = decoder.decode(data.iter().cloned()).unwrap();
+ let instr = decode(&[0x12, 0x00, 0x3f, 0x40][..]);
assert!(instr.opcode == Opcode::RRC);
- let data = [0x20, 0x0e];
- let instr = decoder.decode(data.iter().cloned()).unwrap();
+ let instr = decode(&[0x20, 0x0e][..]);
assert!(instr.opcode == Opcode::PUSH);
}