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
#![allow(unused)]
use super::common;
use super::super::operand::{
FromDestination, FromSource,
Register, RawRegister, Global, Immediate, ConstantKey,
WildSource, WildDestination,
};
use super::super::instruction::Instruction;
#[derive(Debug, Copy, Clone)]
#[repr(u32)]
pub enum On {
Destination = 0b_0_00,
Source = 0b_1_00,
}
impl On {
pub const OFFSET: u32 = 2;
pub const MASK: u32 = 0b_1;
}
impl From<Instruction> for On {
fn from(instruction: Instruction) -> Self {
match instruction.0 >> Self::OFFSET & Self::MASK {
0b_0 => On::Destination,
0b_1 => On::Source,
_ => unreachable!(),
}
}
}
impl From<On> for Instruction {
fn from(value: On) -> Instruction {
Instruction(value as u32)
}
}
pub type DestinationType = common::WildDestinationType<3>;
pub type SourceType = common::WildSourceType<4>;
pub type IndexType = common::WildSourceType<6>;
pub struct DecodedIndex {
pub index_on: On,
pub destination: WildDestination<RawRegister>,
pub source: WildSource<RawRegister>,
pub index: WildSource<RawRegister>,
}
pub fn decode(instruction: Instruction) -> DecodedIndex {
let index_on = On::from(instruction);
let destination_type = DestinationType::from(instruction);
let destination = match destination_type {
DestinationType::Register => WildDestination::Register(RawRegister::from_destination(instruction)),
DestinationType::Global => WildDestination::Global(Global::from_destination(instruction)),
};
let source_type = SourceType::from(instruction);
let source = match source_type {
SourceType::Register => WildSource::Register(RawRegister::from_first(instruction)),
SourceType::Global => WildSource::Global(Global::from_first(instruction)),
SourceType::Immediate => WildSource::Immediate(Immediate::from_first(instruction)),
SourceType::Constant => WildSource::Constant(ConstantKey::from_first(instruction)),
};
let index_type = IndexType::from(instruction);
let index = match index_type {
IndexType::Register => WildSource::Register(RawRegister::from_second(instruction)),
IndexType::Global => WildSource::Global(Global::from_second(instruction)),
IndexType::Immediate => WildSource::Immediate(Immediate::from_second(instruction)),
IndexType::Constant => WildSource::Constant(ConstantKey::from_second(instruction)),
};
DecodedIndex { index_on, destination, source, index }
}