summaryrefslogtreecommitdiff
path: root/src/lib.rs
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2020-09-15 21:40:04 -0700
committeriximeow <me@iximeow.net>2020-09-15 21:40:04 -0700
commit624a153311e727f3a63a16045c6ba3d99de7d7e0 (patch)
tree66c7ad8350d26ee70f15115a88c26a26512d8614 /src/lib.rs
it's a start
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs129
1 files changed, 129 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..bfd0b37
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,129 @@
+use yaxpeax_arch::{Arch, AddressDiff, Decoder, LengthedInstruction, NoColors, YaxColors};
+
+use core::fmt;
+
+/// TODO: ia64 reference doc
+
+pub struct IA64;
+
+impl Arch for IA64 {
+ type Address = u64;
+ type Instruction = Instruction;
+ type DecodeError = DecodeError;
+ type Decoder = InstDecoder;
+ type Operand = Operand;
+}
+
+#[derive(Debug, PartialEq, Eq)]
+pub struct Instruction {}
+impl yaxpeax_arch::LengthedInstruction for Instruction {
+ type Unit = yaxpeax_arch::AddressDiff<u64>;
+ fn len(&self) -> Self::Unit { AddressDiff::from_const(1) }
+ fn min_size() -> Self::Unit { AddressDiff::from_const(1) }
+}
+impl yaxpeax_arch::Instruction for Instruction {
+ fn well_defined(&self) -> bool {
+ true
+ }
+}
+impl Default for Instruction {
+ fn default() -> Self {
+ Instruction { }
+ }
+}
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub enum DecodeError {
+ ExhaustedInput,
+ BadOpcode,
+ BadOperand,
+ BadBundle,
+}
+impl fmt::Display for DecodeError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ DecodeError::ExhaustedInput => f.write_str("exhausted input"),
+ DecodeError::BadBundle => f.write_str("bad bundle"),
+ DecodeError::BadOpcode => f.write_str("bad opcode"),
+ DecodeError::BadOperand => f.write_str("bad operand"),
+ }
+ }
+}
+impl yaxpeax_arch::DecodeError for DecodeError {
+ fn data_exhausted(&self) -> bool {
+ if let DecodeError::ExhaustedInput = self {
+ true
+ } else {
+ false
+ }
+ }
+ fn bad_opcode(&self) -> bool {
+ if let DecodeError::BadBundle = self {
+ true
+ } else if let DecodeError::BadOpcode = self {
+ true
+ } else {
+ false
+ }
+ }
+ fn bad_operand(&self) -> bool {
+ if let DecodeError::BadOperand = self {
+ true
+ } else {
+ false
+ }
+ }
+}
+#[derive(Default)]
+pub struct InstDecoder {}
+#[derive(Debug)]
+pub enum Operand {}
+
+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 bundle = bytes_iter.next().ok_or(DecodeError::ExhaustedInput)?;
+ let bundle_tag = bundle & 0x1f;
+ let bundle_desc = match bundle_tag {
+ 0x00 => { "M I I " },
+ 0x01 => { "M I I|" },
+ 0x02 => { "M I|I " },
+ 0x03 => { "M I|I|" },
+ 0x04 => { "M L X " },
+ 0x05 => { "M L X|" },
+ 0x06 => { return Err(DecodeError::BadBundle) },
+ 0x07 => { return Err(DecodeError::BadBundle) },
+ 0x08 => { "M M I " },
+ 0x09 => { "M M I|" },
+ 0x0a => { "M|M I " },
+ 0x0b => { "M|M I|" },
+ 0x0c => { "M F I " },
+ 0x0d => { "M F I|" },
+ 0x0e => { "M M F " },
+ 0x0f => { "M M F|" },
+ 0x10 => { "M I B " },
+ 0x11 => { "M I B|" },
+ 0x12 => { "M B B " },
+ 0x13 => { "M B B|" },
+ 0x14 => { return Err(DecodeError::BadBundle) },
+ 0x15 => { return Err(DecodeError::BadBundle) },
+ 0x16 => { "B B B " },
+ 0x17 => { "B B B|" },
+ 0x18 => { "M M B " },
+ 0x19 => { "M M B|" },
+ 0x1a => { return Err(DecodeError::BadBundle) },
+ 0x1b => { return Err(DecodeError::BadBundle) },
+ 0x1c => { "M F B " },
+ 0x1d => { "M F B|" },
+ 0x1e => { return Err(DecodeError::BadBundle) },
+ 0x1f => { return Err(DecodeError::BadBundle) },
+ _ => { unreachable!(); }
+ };
+ eprintln!("bundle tag: {}", bundle_desc);
+
+ // from here, `itanium-architecture-vol-1-2-3-4-reference-set-manual.pdf` volume 3 is
+ // remaining necessary details
+ Ok(())
+ }
+}