From dc9366f430874c25e4e44e2a365efea5fcc43382 Mon Sep 17 00:00:00 2001
From: iximeow <me@iximeow.net>
Date: Sun, 4 Aug 2019 19:08:56 -0700
Subject: fix the hex/bits mismatch

---
 src/armv7.rs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/armv7.rs b/src/armv7.rs
index e609086..52061c7 100644
--- a/src/armv7.rs
+++ b/src/armv7.rs
@@ -798,7 +798,7 @@ impl Decodable for Instruction {
                         println!("{:032b}", word);
                         println!("       {:05b}|{:04b}|{:04b}|{:04b}|1{:02b}1|{:04b}", flags, Rn, Rd, HiOffset, op, LoOffset);
                         match op {
-                            0x00 => {
+                            0b00 => {
                     // |c o n d|0 0 0 1|x x x x x x x x x x x x x x x x|1 0 0 1|x x x x|
                                 // this is swp or {ld,st}ex, conditional on bit 23
                                 match flags {
@@ -862,7 +862,7 @@ impl Decodable for Instruction {
                                     }
                                 }
                             }
-                            0x01 => {
+                            0b01 => {
                     // |c o n d|0 0 0 x|x x x x x x x x x x x x x x x x|1 0 1 1|x x x x|
                     // page A5-201
                                 self.opcode = Opcode::Incomplete(word);
@@ -895,13 +895,13 @@ impl Decodable for Instruction {
                                     }
                                 }
                             }
-                            0x10 => {
+                            0b10 => {
                     // |c o n d|0 0 0 x|x x x x x x x x x x x x x x x x|1 1 0 1|x x x x|
                     // page A5-201
                                 self.opcode = Opcode::Incomplete(word);
                                 return Some(());
                             }
-                            0x11 => {
+                            0b11 => {
                     // |c o n d|0 0 0 x|x x x x x x x x x x x x x x x x|1 1 1 1|x x x x|
                     // page A5-201
                                 self.opcode = Opcode::Incomplete(word);
-- 
cgit v1.1


From 8b9d5f9c6003864870dccfe2c0f71729d4b99564 Mon Sep 17 00:00:00 2001
From: iximeow <me@iximeow.net>
Date: Sun, 4 Aug 2019 19:12:25 -0700
Subject: fix issue with incorrectly decoding register shifts

---
 src/armv7.rs  |  2 +-
 test/armv7.rs | 15 +++++++++++++++
 test/test.rs  |  2 +-
 3 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/src/armv7.rs b/src/armv7.rs
index 52061c7..a5467e5 100644
--- a/src/armv7.rs
+++ b/src/armv7.rs
@@ -487,7 +487,7 @@ fn format_shift<T: std::fmt::Write>(f: &mut T, Rm: u8, shift: ShiftSpec, colors:
         },
         ShiftSpec::Register(v) => {
             let tpe = v & 0x3;
-            let Rs = v >> 2;
+            let Rs = v >> 3;
             write!(f, "{}, {} {}", reg_name_colorize(Rm, colors), shift_tpe_to_str(tpe), reg_name_colorize(Rs, colors))
         },
     }
diff --git a/test/armv7.rs b/test/armv7.rs
index c76cb4a..af5336c 100644
--- a/test/armv7.rs
+++ b/test/armv7.rs
@@ -163,6 +163,21 @@ fn test_decode_mov() {
 #[test]
 fn test_decode_arithmetic() {
     test_decode(
+        [0x18, 0x1d, 0x00, 0x00],
+        Instruction {
+            condition: ConditionCode::EQ,
+            opcode: Opcode::AND,
+            operands: Operands::ThreeOperandWithShift(
+                1, 0, 8, ShiftSpec::Register(104)
+            ),
+            s: false
+        }
+    );
+    test_display(
+        [0x18, 0x1d, 0x00, 0x00],
+        "andeq r1, r0, r8, lsl sp",
+    );
+    test_decode(
         [0x03, 0x30, 0x8f, 0xe0],
         Instruction {
             condition: ConditionCode::AL,
diff --git a/test/test.rs b/test/test.rs
index 7dd54ea..72b7e50 100644
--- a/test/test.rs
+++ b/test/test.rs
@@ -5,5 +5,5 @@ extern crate test;
 extern crate yaxpeax_arch;
 extern crate yaxpeax_arm;
 
-// mod armv7;
+mod armv7;
 mod armv8;
-- 
cgit v1.1


From 120adb21db26779729c026b576739b1de82bc198 Mon Sep 17 00:00:00 2001
From: iximeow <me@iximeow.net>
Date: Sun, 4 Aug 2019 19:12:54 -0700
Subject: decode blx

---
 src/armv7.rs  | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 test/armv7.rs |  4 +++
 2 files changed, 82 insertions(+), 4 deletions(-)

diff --git a/src/armv7.rs b/src/armv7.rs
index a5467e5..4a806f2 100644
--- a/src/armv7.rs
+++ b/src/armv7.rs
@@ -119,6 +119,9 @@ impl <T: std::fmt::Write> ShowContextual<u32, [Option<String>], T> for Instructi
                         write!(out, " ")?;
                         format_reg_list(out, list, colors)?;
                     },
+                    Operands::OneOperand(a) => {
+                        write!(out, " {}", reg_name_colorize(a, colors))?;
+                    },
                     Operands::TwoOperand(a, b) => {
                         write!(out, " {}, {}", reg_name_colorize(a, colors), reg_name_colorize(b, colors))?;
                     },
@@ -409,6 +412,7 @@ pub enum ShiftSpec {
 #[derive(Debug, PartialEq, Eq)]
 pub enum Operands {
     RegisterList(u16),
+    OneOperand(u8),
     TwoOperand(u8, u8),
     RegImm(u8, u32),
     RegRegList(u8, u16),
@@ -697,7 +701,34 @@ impl Decodable for Instruction {
         if cond == 0b1111 {
             // do unconditional instruction stuff
             self.condition = ConditionCode::AL;
-            self.opcode = Opcode::Incomplete(word);
+            let op1 = (word >> 20) as u8;
+            if op1 > 0x80 {
+                match (op1 >> 5) & 0b11 {
+                    0b00 => {
+                        self.opcode = Opcode::Incomplete(word);
+                    }
+                    0b01 => {
+                        self.opcode = Opcode::BLX;
+                        let operand = ((word & 0xffffff) as i32) << 8 >> 6;
+                        self.operands = Operands::BranchOffset(
+                            operand | (
+                                ((word >> 23) & 0b10) as i32
+                            )
+                        );
+                    }
+                    0b10 => {
+                        self.opcode = Opcode::Incomplete(word);
+                    }
+                    0b11 => {
+                        self.opcode = Opcode::Incomplete(word);
+                    }
+                    _ => {
+                        unreachable!();
+                    }
+                }
+            } else {
+                self.opcode = Opcode::Incomplete(word);
+            }
             return Some(());
         } else {
             self.condition = ConditionCode::build(cond);
@@ -915,11 +946,54 @@ impl Decodable for Instruction {
                     // misc instructions in Figure A3-4
 
                     if s == false && opcode >= 0b1000 && opcode < 0b1100 {
+                        let op2 = ((word >> 4) & 0x0f) as u8;
                         // the instruction looks like
                         // |c o n d|0 0 0|1 0 x x|0|x x x x|x x x x|x x x x x|x x|x|x x x x|
-                        // misc instructions (page A5-194)
-                        self.opcode = Opcode::Incomplete(word);
-                        return Some(());
+                        if op2 & 0x08 == 0x00 {
+                            let op2 = op2 & 0x07;
+                            // |c o n d|0 0 0|1 0 x x|0|x x x x|x x x x|x x x x|0|x x|x|x x x x|
+                            // misc instructions (page A5-194)
+                            match op2 {
+                                0b000 => {
+                                    
+                                },
+                                0b001 => {
+                                    
+                                },
+                                0b010 => {
+                                    
+                                },
+                                0b011 => {
+                                    if opcode & 0b11 == 0b01 {
+                                        self.opcode = Opcode::BLX;
+                                        self.operands = Operands::OneOperand((word & 0x0f) as u8);
+                                        return Some(());
+                                    } else {
+                                        return None;
+                                    }
+                                },
+                                0b100 => {
+                                    self.opcode = Opcode::Incomplete(word);
+                                    return Some(());
+                                },
+                                0b101 => {
+
+                                }
+                                0b110 => {
+                                },
+                                0b111 => {
+
+                                },
+                                _ => {
+                                    unreachable!();
+                                }
+                            }
+                        } else {
+                            // |c o n d|0 0 0|1 0 x x|0|x x x x|x x x x|x x x x|1|x x|x|x x x x|
+                            // multiply and multiply-accumulate 
+                            self.opcode = Opcode::Incomplete(word);
+                            return Some(());
+                        }
                     } else {
                         if opcode >= 16 {
                             unreachable!();
diff --git a/test/armv7.rs b/test/armv7.rs
index af5336c..f7ab079 100644
--- a/test/armv7.rs
+++ b/test/armv7.rs
@@ -86,6 +86,10 @@ fn test_decode_str_ldr() {
 #[test]
 fn test_decode_misc() {
     test_display(
+        [0x32, 0xff, 0x2f, 0xe1],
+        "blx r2"
+    );
+    test_display(
         [0x02, 0x00, 0xa0, 0xe3],
         "mov r0, 0x2"
     );
-- 
cgit v1.1


From c20df7acc8cb12db124ab1a819719fadc40227c3 Mon Sep 17 00:00:00 2001
From: iximeow <me@iximeow.net>
Date: Sun, 4 Aug 2019 19:16:11 -0700
Subject: immediates are not shifted, what was this about?

---
 src/armv7.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/armv7.rs b/src/armv7.rs
index 4a806f2..03d4b77 100644
--- a/src/armv7.rs
+++ b/src/armv7.rs
@@ -126,7 +126,7 @@ impl <T: std::fmt::Write> ShowContextual<u32, [Option<String>], T> for Instructi
                         write!(out, " {}, {}", reg_name_colorize(a, colors), reg_name_colorize(b, colors))?;
                     },
                     Operands::RegImm(a, imm) => {
-                        write!(out, " {}, {:#x}", reg_name_colorize(a, colors), imm * 4)?;
+                        write!(out, " {}, {:#x}", reg_name_colorize(a, colors), imm)?;
                     },
                     Operands::RegRegList(r, list) => {
                         write!(out, " {}, ", reg_name_colorize(r, colors))?;
-- 
cgit v1.1


From 77bc926bb3b0840bc91dd0774d01e8ca25c80616 Mon Sep 17 00:00:00 2001
From: iximeow <me@iximeow.net>
Date: Tue, 6 Aug 2019 20:51:42 -0700
Subject: armv7 test cases

---
 test/armv7.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/armv7.rs b/test/armv7.rs
index f7ab079..09f5333 100644
--- a/test/armv7.rs
+++ b/test/armv7.rs
@@ -330,7 +330,7 @@ fn test_decode_span() {
             instr);
         i += instr.len();
     }
-    panic!("done");
+//    panic!("done");
 }
 /*
  * from debian 5.0.10 bash 3.2-4_arm
-- 
cgit v1.1


From 22f9afd31c902ded123f175a95812955c965233f Mon Sep 17 00:00:00 2001
From: iximeow <me@iximeow.net>
Date: Tue, 6 Aug 2019 20:52:04 -0700
Subject: armv8 serde/no-serde support plus contextual display .. ish

---
 src/armv8/a64.rs | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/src/armv8/a64.rs b/src/armv8/a64.rs
index d640292..e58d2a2 100644
--- a/src/armv8/a64.rs
+++ b/src/armv8/a64.rs
@@ -116,6 +116,18 @@ mod docs {
     }
 }
 
+#[allow(non_snake_case)]
+impl <T: std::fmt::Write> ShowContextual<u64, [Option<String>], T> for Instruction {
+    fn contextualize(&self, colors: Option<&ColorSettings>, address: u64, context: Option<&[Option<String>]>, out: &mut T) -> std::fmt::Result {
+        write!(out, "{}", self)
+    }
+}
+
+#[cfg(feature="use-serde")]
+#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
+pub struct ARMv8 { }
+
+#[cfg(not(feature="use-serde"))]
 #[derive(Copy, Clone, Debug)]
 pub struct ARMv8 { }
 
-- 
cgit v1.1


From f6dd37f8dd6d9d307c881cf44b5cf1856cc4ab74 Mon Sep 17 00:00:00 2001
From: iximeow <me@iximeow.net>
Date: Mon, 30 Sep 2019 00:19:04 -0700
Subject: warnings-b-gone

---
 src/armv7.rs     | 25 +++++++++++++++----------
 src/armv8/a64.rs | 32 +++++++++++++++++---------------
 2 files changed, 32 insertions(+), 25 deletions(-)

diff --git a/src/armv7.rs b/src/armv7.rs
index 03d4b77..9fe6fea 100644
--- a/src/armv7.rs
+++ b/src/armv7.rs
@@ -1,5 +1,5 @@
-#[cfg(feature="use-serde")]
-use serde::{Serialize, Deserialize};
+//#[cfg(feature="use-serde")]
+//use serde::{Serialize, Deserialize};
 
 use std::fmt::{Display, Formatter};
 
@@ -15,7 +15,7 @@ impl Display for ConditionedOpcode {
 
 #[allow(non_snake_case)]
 impl <T: std::fmt::Write> ShowContextual<u32, [Option<String>], T> for Instruction {
-    fn contextualize(&self, colors: Option<&ColorSettings>, address: u32, context: Option<&[Option<String>]>, out: &mut T) -> std::fmt::Result {
+    fn contextualize(&self, colors: Option<&ColorSettings>, _address: u32, _context: Option<&[Option<String>]>, out: &mut T) -> std::fmt::Result {
         match self.opcode {
             Opcode::LDR(true, false, false) => {
                 match self.operands {
@@ -94,8 +94,9 @@ impl <T: std::fmt::Write> ShowContextual<u32, [Option<String>], T> for Instructi
                     _ => { unreachable!(); }
                 }
             }
-            Opcode::STM(add, pre, wback, usermode) |
-            Opcode::LDM(add, pre, wback, usermode) => {
+            // TODO: [add, pre, usermode]
+            Opcode::STM(_add, _pre, wback, _usermode) |
+            Opcode::LDM(_add, _pre, wback, _usermode) => {
                 match self.operands {
                     Operands::RegRegList(Rr, list) => {
                         ConditionedOpcode(self.opcode, self.condition).colorize(colors, out)?;
@@ -132,13 +133,15 @@ impl <T: std::fmt::Write> ShowContextual<u32, [Option<String>], T> for Instructi
                         write!(out, " {}, ", reg_name_colorize(r, colors))?;
                         format_reg_list(out, list, colors)?;
                     },
-                    Operands::TwoRegImm(a, b, imm) => {
+                    Operands::TwoRegImm(_a, _b, _imm) => {
+                        // TODO:
                         write!(out, " <unimplemented>")?;
                     },
                     Operands::ThreeOperand(a, b, c) => {
                         write!(out, " {}, {}, {}", reg_name_colorize(a, colors), reg_name_colorize(b, colors), reg_name_colorize(c, colors))?;
                     },
-                    Operands::ThreeOperandImm(a, b, imm) => {
+                    Operands::ThreeOperandImm(_a, _b, _imm) => {
+                        // TODO:
                         write!(out, " <unimplemented>")?;
                     },
                     Operands::ThreeOperandWithShift(a, b, c, shift) => {
@@ -148,7 +151,8 @@ impl <T: std::fmt::Write> ShowContextual<u32, [Option<String>], T> for Instructi
                     Operands::MulThreeRegs(a, b, c) => {
                         write!(out, " {}, {}, {}", reg_name_colorize(a, colors), reg_name_colorize(b, colors), reg_name_colorize(c, colors))?;
                     },
-                    Operands::MulFourRegs(a, b, c, d) => {
+                    Operands::MulFourRegs(_a, _b, _c, _d) => {
+                        // TODO:
                         write!(out, " <unimplemented>")?;
                     },
                     Operands::BranchOffset(imm) => {
@@ -655,7 +659,7 @@ impl ConditionCode {
             0b1100 => ConditionCode::GT,
             0b1101 => ConditionCode::LE,
             0b1110 => ConditionCode::AL,
-            _ => unsafe {
+            _ => {
                 // this means the argument `value` must never be outside [0,15]
                 // which itself means this function shouldn't be public
                 unreachable!();
@@ -897,7 +901,7 @@ impl Decodable for Instruction {
                     // |c o n d|0 0 0 x|x x x x x x x x x x x x x x x x|1 0 1 1|x x x x|
                     // page A5-201
                                 self.opcode = Opcode::Incomplete(word);
-                                return Some(());
+                                // return Some(());
                                 match flags {
                                     0b00010 => {
                                         // self.opcode = Opcode::STRHT_sub;
@@ -925,6 +929,7 @@ impl Decodable for Instruction {
                                         unreachable!();
                                     }
                                 }
+                                panic!("page a5-201");
                             }
                             0b10 => {
                     // |c o n d|0 0 0 x|x x x x x x x x x x x x x x x x|1 1 0 1|x x x x|
diff --git a/src/armv8/a64.rs b/src/armv8/a64.rs
index e58d2a2..3e0403a 100644
--- a/src/armv8/a64.rs
+++ b/src/armv8/a64.rs
@@ -1,9 +1,9 @@
-#[cfg(feature="use-serde")]
-use serde::{Serialize, Deserialize};
+//#[cfg(feature="use-serde")]
+//use serde::{Serialize, Deserialize};
 
 use std::fmt::{Display, Formatter};
 
-use yaxpeax_arch::{Arch, Colorize, Colored, ColorSettings, Decodable, LengthedInstruction, ShowContextual, YaxColors};
+use yaxpeax_arch::{Arch, ColorSettings, Decodable, LengthedInstruction, ShowContextual};
 
 #[allow(non_snake_case)]
 mod docs {
@@ -118,7 +118,7 @@ mod docs {
 
 #[allow(non_snake_case)]
 impl <T: std::fmt::Write> ShowContextual<u64, [Option<String>], T> for Instruction {
-    fn contextualize(&self, colors: Option<&ColorSettings>, address: u64, context: Option<&[Option<String>]>, out: &mut T) -> std::fmt::Result {
+    fn contextualize(&self, _colors: Option<&ColorSettings>, _address: u64, _context: Option<&[Option<String>]>, out: &mut T) -> std::fmt::Result {
         write!(out, "{}", self)
     }
 }
@@ -1545,7 +1545,7 @@ impl Decodable for Instruction {
                         } else {
                             self.opcode = Opcode::Invalid;
                         }
-                        unreachable!();
+                        unreachable!("decode Rd: {}, Rn: {}, imms: {}, Rm: {}, No0: {}", Rd, Rn, imms, Rm, No0);
                     }
                     _ => { unreachable!() }
                 }
@@ -1605,7 +1605,8 @@ impl Decodable for Instruction {
                             _ => {
                                 Opcode::Invalid
                             }
-                        }
+                        };
+                        unreachable!("Rt: {}, Rn: {}, Rt2: {}, Rs: {}", Rt, Rn, Rt2, Rs);
                     },
                     0b00001 => {
                         let Rt = (word & 0x1f) as u16;
@@ -1643,6 +1644,7 @@ impl Decodable for Instruction {
                             Operand::Nothing,
                             Operand::Nothing,
                         ];
+                        unreachable!("Rt: {}, Rn: {}, Rt2: {}, Rs: {}", Rt, Rn, Rt2, Rs);
                     },
                     0b01000 |
                     0b01001 => {
@@ -1687,19 +1689,19 @@ impl Decodable for Instruction {
                         let opc = (word >> 29) & 0x3;
                         let Rt = word & 0x1f;
                         let imm19 = (word >> 5) & 0x7fff;
-                        panic!("C3.3.5 V==1");
+                        panic!("C3.3.5 V==1. opc: {}, Rt: {}, imm19: {}", opc, Rt, imm19);
                     },
                     0b10000 => {
                         // load/store no-allocate pair (offset)
                         // V == 0
                         let opc_L = ((word >> 22) & 1) | ((word >> 29) & 0x6);
-                        panic!("C3.3.7 V==0");
+                        panic!("C3.3.7 V==0, opc_L: {}", opc_L);
                     },
                     0b10100 => {
                         // load/store no-allocate pair (offset)
                         // V == 1
                         let opc_L = ((word >> 22) & 1) | ((word >> 29) & 0x6);
-                        panic!("C3.3.7 V==1");
+                        panic!("C3.3.7 V==1, opc_L: {}", opc_L);
                     },
                     0b10001 => {
                         // load/store register pair (post-indexed)
@@ -1707,7 +1709,7 @@ impl Decodable for Instruction {
                         let Rt = (word & 0x1f) as u16;
                         let Rn = ((word >> 5) & 0x1f) as u16;
                         let Rt2 = ((word >> 10) & 0x1f) as u16;
-                        let mut imm7 = (((((word >> 15) & 0x7f) as i16) << 9) >> 9);
+                        let mut imm7 = ((((word >> 15) & 0x7f) as i16) << 9) >> 9;
                         let opc_L = ((word >> 22) & 1) | ((word >> 29) & 0x6);
                         let size = match opc_L {
                             0b000 => {
@@ -1757,7 +1759,7 @@ impl Decodable for Instruction {
                         // load/store register pair (post-indexed)
                         // V == 1
                         let opc_L = ((word >> 22) & 1) | ((word >> 29) & 0x6);
-                        panic!("C3.3.15 V==1");
+                        panic!("C3.3.15 V==1, opc_L: {}", opc_L);
                     },
                     0b10010 => {
                         // load/store register pair (offset)
@@ -1765,7 +1767,7 @@ impl Decodable for Instruction {
                         let Rt = (word & 0x1f) as u16;
                         let Rn = ((word >> 5) & 0x1f) as u16;
                         let Rt2 = ((word >> 10) & 0x1f) as u16;
-                        let mut imm7 = (((((word >> 15) & 0x7f) as i16) << 9) >> 9);
+                        let mut imm7 = ((((word >> 15) & 0x7f) as i16) << 9) >> 9;
                         let opc_L = ((word >> 22) & 1) | ((word >> 29) & 0x6);
                         let size = match opc_L {
                             0b000 => {
@@ -1815,7 +1817,7 @@ impl Decodable for Instruction {
                         // load/store register pair (offset)
                         // V == 1
                         let opc_L = ((word >> 22) & 1) | ((word >> 29) & 0x6);
-                        panic!("C3.3.14 V==1");
+                        panic!("C3.3.14 V==1, opc_L: {}", opc_L);
                     },
                     0b10011 => {
                         // load/store register pair (pre-indexed)
@@ -1823,7 +1825,7 @@ impl Decodable for Instruction {
                         let Rt = (word & 0x1f) as u16;
                         let Rn = ((word >> 5) & 0x1f) as u16;
                         let Rt2 = ((word >> 10) & 0x1f) as u16;
-                        let mut imm7 = (((((word >> 15) & 0x7f) as i16) << 9) >> 9);
+                        let mut imm7 = ((((word >> 15) & 0x7f) as i16) << 9) >> 9;
                         let opc_L = ((word >> 22) & 1) | ((word >> 29) & 0x6);
                         let size = match opc_L {
                             0b000 => {
@@ -1873,7 +1875,7 @@ impl Decodable for Instruction {
                         // load/store register pair (pre-indexed)
                         // V == 1
                         let opc_L = ((word >> 22) & 1) | ((word >> 29) & 0x6);
-                        panic!("C3.3.16 V==1");
+                        panic!("C3.3.16 V==1, opc_L: {}", opc_L);
                     },
                     0b11000 |
                     0b11001 => {
-- 
cgit v1.1