1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
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(())
}
}
|