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
pub const OFFSET_OP_CODE: usize = 57;
pub const OFFSET_OPERAND_1: usize = 38;
pub const OFFSET_OPERAND_2: usize = 19;
pub const OFFSET_OPERAND_3: usize = 0;
pub const OFFSET_IS_ADDRESS: usize = 18;
pub const OFFSET_IS_INDIRECT: usize = 17;
pub const OFFSET_IS_STATE: usize = 16;
pub const OFFSET_FLAGS: usize = OFFSET_IS_STATE;
pub(crate) const MASK_OP_CODE: u64 = 0x0000_0000_0000_007F;
pub(crate) const MASK_OPERAND: u64 = 0x0000_0000_0007_FFFF;
pub(crate) const MASK_VALUE: u64 = 0x0000_0000_0000_FFFF;
pub(crate) const MASK_IS_ADDRESS: u64 = 0x0000_0000_0004_0000;
pub(crate) const MASK_IS_INDIRECT: u64 = 0x0000_0000_0002_0000;
pub(crate) const MASK_IS_STATE: u64 = 0x0000_0000_0001_0000;
pub const LENGTH_OP_CODE: usize = 7;
pub const LENGTH_FLAGS: usize = 3;
pub const LENGTH_VALUE: usize = 16;
#[derive(Clone, Debug, PartialEq)]
pub struct InstructionFields {
pub op_code: u8,
pub operand1: OperandFields,
pub operand2: OperandFields,
pub operand3: OperandFields,
pub raw: u64,
}
#[derive(Clone, Debug, PartialEq)]
pub struct OperandFields {
pub is_address: bool,
pub is_indirect: bool,
pub is_state: bool,
pub value: u16,
pub raw: u64,
}
pub fn extract_fields(raw: u64) -> InstructionFields {
InstructionFields {
op_code: extract_op_code(raw),
operand1: extract_operand1(raw),
operand2: extract_operand2(raw),
operand3: extract_operand3(raw),
raw,
}
}
fn extract_op_code(raw: u64) -> u8 {
((raw >> OFFSET_OP_CODE) & MASK_OP_CODE) as u8
}
fn extract_operand1(raw: u64) -> OperandFields {
extract_operand(raw, OFFSET_OPERAND_1)
}
fn extract_operand2(raw: u64) -> OperandFields {
extract_operand(raw, OFFSET_OPERAND_2)
}
fn extract_operand3(raw: u64) -> OperandFields {
extract_operand(raw, OFFSET_OPERAND_3)
}
fn extract_operand(raw: u64, base: usize) -> OperandFields {
let o = (raw >> base) & MASK_OPERAND;
OperandFields {
is_address: o & MASK_IS_ADDRESS == MASK_IS_ADDRESS,
is_indirect: o & MASK_IS_INDIRECT == MASK_IS_INDIRECT,
is_state: o & MASK_IS_STATE == MASK_IS_STATE,
value: (o & MASK_VALUE) as u16,
raw: o,
}
}