diff options
| author | iximeow <me@iximeow.net> | 2019-11-28 02:22:02 -0800 | 
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2020-01-12 17:08:59 -0800 | 
| commit | 693e21378ecec332254d48642cd7b751cabeb6da (patch) | |
| tree | 045f11fa14331e92ce65f48f53b6a350b06a1e60 | |
| parent | d1de407ea3a157e7b0aa39ac03e5d16a001bd783 (diff) | |
update msp430 to revised decoder trait
| -rw-r--r-- | src/lib.rs | 66 | ||||
| -rw-r--r-- | test/test.rs | 18 | 
2 files changed, 43 insertions, 41 deletions
| @@ -8,7 +8,7 @@ extern crate serde;  extern crate yaxpeax_arch;  extern crate termion; -use yaxpeax_arch::{Arch, Decodable, LengthedInstruction}; +use yaxpeax_arch::{Arch, Decoder, LengthedInstruction};  mod display; @@ -23,6 +23,7 @@ pub struct MSP430;  impl Arch for MSP430 {      type Address = u16;      type Instruction = Instruction; +    type Decoder = InstDecoder;      type Operand = Operand;  } @@ -124,15 +125,18 @@ pub enum Operand {      Nothing  } -impl Decodable for Instruction { -    fn decode<T: IntoIterator<Item=u8>>(bytes: T) -> Option<Self> { -        let mut instr = Instruction::blank(); -        match instr.decode_into(bytes) { -            Some(_) => Some(instr), +#[derive(Default, Debug)] +pub struct InstDecoder {} + +impl Decoder<Instruction> for InstDecoder { +    fn decode<T: IntoIterator<Item=u8>>(&self, bytes: T) -> Option<Instruction> { +        let mut inst = Instruction::blank(); +        match self.decode_into(&mut inst, bytes) { +            Some(_) => Some(inst),              None => None          }      } -    fn decode_into<T: IntoIterator<Item=u8>>(&mut self, bytes: T) -> Option<()> { +    fn decode_into<T: IntoIterator<Item=u8>>(&self, inst: &mut Instruction, bytes: T) -> Option<()> {          let mut bytes_iter = bytes.into_iter();          let word: Vec<u8> = bytes_iter.by_ref().take(2).collect(); @@ -212,15 +216,15 @@ impl Decodable for Instruction {              return true;          } -        self.op_width = Width::W; +        inst.op_width = Width::W;          match fullword {              /*              instrword if instrword < 0x1000 => {                  // MSP430X instructions go here -                self.opcode = Opcode::Invalid(instrword); -                self.operands[0] = Operand::Nothing; -                self.operands[1] = Operand::Nothing; +                inst.opcode = Opcode::Invalid(instrword); +                inst.operands[0] = Operand::Nothing; +                inst.operands[1] = Operand::Nothing;                  return None;              }, */              instrword if instrword < 0x2000 => { @@ -228,7 +232,7 @@ impl Decodable for Instruction {                  let (opcode_idx, operands) = ((instrword & 0x0380) >> 7, instrword & 0x7f);                  match opcode_idx {                      x if x < 6 => { -                        self.opcode = [ +                        inst.opcode = [                              Opcode::RRC,                              Opcode::SWPB,                              Opcode::RRA, @@ -236,11 +240,11 @@ impl Decodable for Instruction {                              Opcode::PUSH,                              Opcode::CALL                          ][x as usize]; -                        self.op_width = if operands & 0b01000000 == 0 { +                        inst.op_width = if operands & 0b01000000 == 0 {                              Width::W                          } else {                              if x == 1 || x == 3 || x == 5 { -                                self.opcode = Opcode::Invalid(instrword); +                                inst.opcode = Opcode::Invalid(instrword);                                  return None;                              }                              Width:: B @@ -250,26 +254,26 @@ impl Decodable for Instruction {                              ((instrword & 0x0030) >> 4) as u8,                              (instrword & 0x000f) as u8                          ); -                        if !decode_operand(&mut bytes_iter, source, As, &mut self.operands[0]) { -                            self.opcode = Opcode::Invalid(instrword); +                        if !decode_operand(&mut bytes_iter, source, As, &mut inst.operands[0]) { +                            inst.opcode = Opcode::Invalid(instrword);                              return None;                          }; -                        self.operands[1] = Operand::Nothing; +                        inst.operands[1] = Operand::Nothing;                          Some(())                      },                      6 => {                          if operands == 0 { -                            self.opcode = Opcode::RETI; -                            self.operands[0] = Operand::Nothing; -                            self.operands[1] = Operand::Nothing; +                            inst.opcode = Opcode::RETI; +                            inst.operands[0] = Operand::Nothing; +                            inst.operands[1] = Operand::Nothing;                              Some(())                          } else { -                            self.opcode = Opcode::Invalid(instrword); +                            inst.opcode = Opcode::Invalid(instrword);                              return None;                          }                      }                      7 => { -                        self.opcode = Opcode::Invalid(instrword); +                        inst.opcode = Opcode::Invalid(instrword);                          return None;                      }                      _ => { @@ -279,7 +283,7 @@ impl Decodable for Instruction {              },              instrword if instrword < 0x4000 => {                  let (opcode_idx, offset) = ((instrword & 0x1c00) >> 10, instrword & 0x3ff); -                self.opcode = [ +                inst.opcode = [                      Opcode::JNE,                      Opcode::JEQ,                      Opcode::JNC, @@ -289,13 +293,13 @@ impl Decodable for Instruction {                      Opcode::JL,                      Opcode::JMP                  ][opcode_idx as usize]; -                self.operands[0] = Operand::Offset(((offset as i16) << 6) >> 6); -                self.operands[1] = Operand::Nothing; +                inst.operands[0] = Operand::Offset(((offset as i16) << 6) >> 6); +                inst.operands[1] = Operand::Nothing;                  Some(())              },              instrword @ _ => {                  let (opcode_idx, operands) = ((instrword & 0xf000) >> 12, instrword & 0x0fff); -                self.opcode = [ +                inst.opcode = [                      Opcode::MOV,                      Opcode::ADD,                      Opcode::ADDC, @@ -309,7 +313,7 @@ impl Decodable for Instruction {                      Opcode::XOR,                      Opcode::AND                  ][(opcode_idx - 4) as usize]; -                self.op_width = if operands & 0b01000000 == 0 { Width::W } else { Width:: B }; +                inst.op_width = if operands & 0b01000000 == 0 { Width::W } else { Width:: B };                  #[allow(non_snake_case)]                  let (source, Ad, As, dest) = (                      ((instrword & 0x0f00) >> 8) as u8, @@ -317,12 +321,12 @@ impl Decodable for Instruction {                      ((instrword & 0x0030) >> 4) as u8,                      (instrword & 0x000f) as u8                  ); -                if !decode_operand(&mut bytes_iter, source, As, &mut self.operands[0]) { -                    self.opcode = Opcode::Invalid(instrword); +                if !decode_operand(&mut bytes_iter, source, As, &mut inst.operands[0]) { +                    inst.opcode = Opcode::Invalid(instrword);                      return None;                  } -                if !decode_operand(&mut bytes_iter, dest, Ad, &mut self.operands[1]) { -                    self.opcode = Opcode::Invalid(instrword); +                if !decode_operand(&mut bytes_iter, dest, Ad, &mut inst.operands[1]) { +                    inst.opcode = Opcode::Invalid(instrword);                      return None;                  }                  Some(()) diff --git a/test/test.rs b/test/test.rs index 48cf90b..5a59df4 100644 --- a/test/test.rs +++ b/test/test.rs @@ -1,28 +1,26 @@  extern crate yaxpeax_arch;  extern crate yaxpeax_msp430_mc; -use yaxpeax_arch::Decodable; -use yaxpeax_msp430_mc::{Instruction, Opcode}; +use yaxpeax_arch::{Arch, Decoder}; +use yaxpeax_msp430_mc::{Opcode, MSP430};  #[test]  fn test_decode() { +    let decoder = <MSP430 as Arch>::Decoder::default(); +      let data = [0x02, 0x12]; -    let mut instr = Instruction::blank(); -    instr.decode_into(data.iter().map(|x| *x)); +    let instr = decoder.decode(data.iter().cloned()).unwrap();      assert!(instr.opcode == Opcode::PUSH);      let data = [0xb1, 0x92, 0x8d, 0x49]; -    let mut instr = Instruction::blank(); -    instr.decode_into(data.iter().map(|x| *x)); +    let instr = decoder.decode(data.iter().cloned()).unwrap();      assert!(instr.opcode == Opcode::CMP);      let data = [0x12, 0x00, 0x3f, 0x40]; -    let mut instr = Instruction::blank(); -    instr.decode_into(data.iter().map(|x| *x)); +    let instr = decoder.decode(data.iter().cloned()).unwrap();      assert!(instr.opcode == Opcode::RRC);      let data = [0x20, 0x0e]; -    let mut instr = Instruction::blank(); -    instr.decode_into(data.iter().map(|x| *x)); +    let instr = decoder.decode(data.iter().cloned()).unwrap();      assert!(instr.opcode == Opcode::PUSH);  } | 
