Skip to content

Commit cde2738

Browse files
committed
feat(encoding) Added LUT that supports operation variant.
1 parent f2aedb0 commit cde2738

File tree

5 files changed

+202
-119
lines changed

5 files changed

+202
-119
lines changed

examples/counter.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ fn main() {
1111
let program = [
1212
Instruction::LoadImmediate { destination: RegisterCode::new(0), segment: MaskedU8::new(0), immediate: c_max }, // li r0, c_max
1313
Instruction::DualSource { operation: operation::DualSource::Compare, sources: [RegisterCode::new(0), RegisterCode::new(1)] }, // cmp r0, r1
14-
Instruction::Branch { hint: None, condition: Flag::Zero, address: Address::Immediate { immediate: address::Immediate::new(8), mode: address::Mode::Relative }}, // jz pc+8
15-
Instruction::Memory { operation: operation::Memory::Branch, address: Address::Immediate { immediate: address::Immediate::new(4), mode: address::Mode::Absolute }}, // jmp 0
14+
Instruction::Branch { hint: None, condition: Flag::Zero, address: Address::Immediate { immediate: address::LargeImmediate::new(8), mode: address::Mode::Relative }}, // jz pc+8
15+
Instruction::Memory { operation: operation::Memory::Branch, address: Address::Immediate { immediate: address::LargeImmediate::new(4), mode: address::Mode::Absolute }}, // jmp 0
1616
Instruction::WaitForInterrupt // hlt
1717

1818
// pseudo code:
@@ -27,5 +27,5 @@ fn main() {
2727
];
2828

2929
// dbg!(Instruction::decode(0b1000_1000_1000_1000_0001_1000_0000010));
30-
dbg!(Instruction::decode(0b1111_1110_1001_1010_1001_1011_0000011));
30+
dbg!(Instruction::decode(0b11_111_110_100_110_101_0011_000_0100001));
3131
}

src/instruction.rs

+9-11
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ pub mod encoding;
66

77
use crate::instruction::address::Address;
88
use crate::instruction::flag::Flag;
9-
use crate::instruction::vector::{ComponentMapping};
109
use crate::num::{MaskedU8};
1110

1211
pub type SegmentCode = MaskedU8<0x3>;
@@ -22,16 +21,15 @@ pub enum Format {
2221
ExtractVectorComponents,
2322
MapVector,
2423
Branch,
25-
26-
DualSource,
27-
Destination,
28-
DestinationSource,
29-
DestinationDualSource,
30-
DestinationTripleSource,
31-
DualDestinationDualSource,
32-
Memory,
33-
SourceMemory,
34-
DestinationMemory
24+
DualSource(operation::DualSource),
25+
Destination(operation::Destination),
26+
DestinationSource(operation::DestinationSource),
27+
DestinationDualSource(operation::DestinationDualSource),
28+
DestinationTripleSource(operation::DestinationTripleSource),
29+
DualDestinationDualSource(operation::DualDestinationDualSource),
30+
Memory(operation::Memory),
31+
SourceMemory(operation::SourceMemory),
32+
DestinationMemory(operation::DestinationMemory)
3533
}
3634

3735
#[derive(Debug, Clone, Copy, PartialEq)]

src/instruction/address.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::instruction::RegisterCode;
22
use crate::num::{MaskedU16, MaskedU32, MaskedU8};
33

4-
pub type Immediate = MaskedU32<0x1FFFF>;
4+
pub type LargeImmediate = MaskedU32<0x1FFFF>;
55
pub type ScaleCode = MaskedU8<0x3>;
66

77
#[derive(Debug, Clone, Copy, PartialEq)]
@@ -10,18 +10,18 @@ pub enum Mode {
1010
Relative
1111
}
1212

13-
pub type BaseOffset = MaskedU16<0x1FFF>;
14-
pub type IndexedBaseOffset = MaskedU16<0x1FF>;
13+
pub type MediumImmediate = MaskedU16<0x1FFF>;
14+
pub type ShortImmediate = MaskedU16<0x1FF>;
1515

1616
#[derive(Debug, Clone, Copy, PartialEq)]
1717
pub enum IndexedBaseOffsetMode {
18-
Immediate(IndexedBaseOffset),
18+
Immediate(ShortImmediate),
1919
Register(RegisterCode)
2020
}
2121

2222
#[derive(Debug, Clone, Copy, PartialEq)]
2323
pub enum BaseMode {
24-
Offset(BaseOffset),
24+
Offset(MediumImmediate),
2525
RegisterOffset(RegisterCode),
2626
Indexed {
2727
index: RegisterCode,
@@ -32,15 +32,15 @@ pub enum BaseMode {
3232
#[derive(Debug, Clone, Copy, PartialEq)]
3333
pub enum Address {
3434
Immediate {
35-
immediate: Immediate,
36-
mode: Mode
35+
mode: Mode,
36+
immediate: LargeImmediate
3737
},
3838
Register {
39-
register: RegisterCode,
40-
mode: Mode
39+
mode: Mode,
40+
register: RegisterCode
4141
},
4242
Base {
43-
base: RegisterCode,
44-
mode: BaseMode
43+
mode: BaseMode,
44+
base: RegisterCode
4545
}
4646
}

src/instruction/encoding.rs

+107-35
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,40 @@
1-
use crate::instruction::{Format, Instruction, OperandCode, operation, RegisterCode, SegmentCode, vector};
1+
use crate::instruction::{address, Format, Instruction, OperandCode, operation, RegisterCode, SegmentCode, vector};
2+
use crate::instruction::address::Address;
23
use crate::instruction::vector::ComponentCode;
3-
use crate::num::MaskedU32;
4+
use crate::num::{MaskedU32, MaskedU8};
45

56
pub const OPERATION_MASK: u32 = 0x0000007F;
67

7-
pub const LOAD_IMMEDIATE_DESTINATION_FIELD : u32 = 0b0_00000000_00000000_00001111;
8-
pub const LOAD_IMMEDIATE_SEGMENT_FIELD : (u32, u32) = (4, 0b0_00000000_00000000_00110000);
9-
pub const LOAD_IMMEDIATE_IMMEDIATE_FIELD : (u32, u32) = (6, 0b0_00111111_11111111_11000000);
10-
pub const DECODE_VECTOR_DESTINATION_FIELD : u32 = 0b0_00000000_00000000_00001111;
11-
pub const ENABLE_0_FIELD: (u32, u32) = (4, 0b0_00000000_00000000_00010000);
12-
pub const ENABLE_1_FIELD: (u32, u32) = (5, 0b0_00000000_00000000_00100000);
13-
pub const ENABLE_2_FIELD: (u32, u32) = (6, 0b0_00000000_00000000_01000000);
14-
pub const ENABLE_3_FIELD: (u32, u32) = (7, 0b0_00000000_00000000_10000000);
15-
pub const DECODE_VECTOR_COMPONENT_0_FIELD : (u32, u32) = (8, 0b0_00000000_00001111_00000000);
16-
pub const DECODE_VECTOR_COMPONENT_1_FIELD : (u32, u32) = (12, 0b0_00000000_11110000_00000000);
17-
pub const DECODE_VECTOR_COMPONENT_2_FIELD : (u32, u32) = (16, 0b0_00001111_00000000_00000000);
18-
pub const DECODE_VECTOR_COMPONENT_3_FIELD : (u32, u32) = (20, 0b0_11110000_00000000_00000000);
19-
pub const MAP_VECTOR_TEMPORARY_FIELD : u32 = 0b0_00000000_00000000_00000001;
20-
pub const MAP_VECTOR_OPERAND_FIELD : (u32, u32) = (1, 0b0_00000000_00000000_00000110);
21-
pub const MAP_VECTOR_COMPONENT_0_FIELD : (u32, u32) = (3, 0b0_00000000_00000000_00011000);
22-
pub const MAP_VECTOR_COMPONENT_1_FIELD : (u32, u32) = (5, 0b0_00000000_00000000_01100000);
23-
pub const MAP_VECTOR_COMPONENT_2_FIELD : (u32, u32) = (7, 0b0_00000000_00000001_10000000);
24-
pub const MAP_VECTOR_COMPONENT_3_FIELD : (u32, u32) = (9, 0b0_00000000_00000110_00000000);
8+
pub const LOAD_IMMEDIATE_DESTINATION_FIELD : u32 = 0b0_00000000_00000000_00001111;
9+
pub const LOAD_IMMEDIATE_SEGMENT_FIELD : (u32, u32) = (4, 0b0_00000000_00000000_00110000);
10+
pub const LOAD_IMMEDIATE_IMMEDIATE_FIELD : (u32, u32) = (6, 0b0_00111111_11111111_11000000);
11+
pub const DECODE_VECTOR_DESTINATION_FIELD : u32 = 0b0_00000000_00000000_00001111;
12+
pub const ENABLE_0_FIELD : (u32, u32) = (4, 0b0_00000000_00000000_00010000);
13+
pub const ENABLE_1_FIELD : (u32, u32) = (5, 0b0_00000000_00000000_00100000);
14+
pub const ENABLE_2_FIELD : (u32, u32) = (6, 0b0_00000000_00000000_01000000);
15+
pub const ENABLE_3_FIELD : (u32, u32) = (7, 0b0_00000000_00000000_10000000);
16+
pub const DECODE_VECTOR_COMPONENT_0_FIELD : (u32, u32) = (8, 0b0_00000000_00001111_00000000);
17+
pub const DECODE_VECTOR_COMPONENT_1_FIELD : (u32, u32) = (12, 0b0_00000000_11110000_00000000);
18+
pub const DECODE_VECTOR_COMPONENT_2_FIELD : (u32, u32) = (16, 0b0_00001111_00000000_00000000);
19+
pub const DECODE_VECTOR_COMPONENT_3_FIELD : (u32, u32) = (20, 0b0_11110000_00000000_00000000);
20+
pub const MAP_VECTOR_TEMPORARY_FIELD : u32 = 0b0_00000000_00000000_00000001;
21+
pub const MAP_VECTOR_OPERAND_FIELD : (u32, u32) = (1, 0b0_00000000_00000000_00000110);
22+
pub const MAP_VECTOR_COMPONENT_0_FIELD : (u32, u32) = (3, 0b0_00000000_00000000_00011000);
23+
pub const MAP_VECTOR_COMPONENT_1_FIELD : (u32, u32) = (5, 0b0_00000000_00000000_01100000);
24+
pub const MAP_VECTOR_COMPONENT_2_FIELD : (u32, u32) = (7, 0b0_00000000_00000001_10000000);
25+
pub const MAP_VECTOR_COMPONENT_3_FIELD : (u32, u32) = (9, 0b0_00000000_00000110_00000000);
26+
27+
pub const ADDRESS_MODE_FIELD : (u32, u32) = (5, 0b0_00000000_00000000_11100000);
28+
pub const ADDRESS_LARGE_IMMEDIATE_FIELD : (u32, u32) = (8, 0b1_11111111_11111111_00000000);
29+
pub const ADDRESS_LARGE_IMMEDIATE_REGISTER_FIELD : (u32, u32) = (8, 0b0_00000000_00001111_00000000);
30+
31+
pub const ADDRESS_BASE_FIELD : (u32, u32) = (8, 0b0_00000000_00001111_00000000);
32+
pub const ADDRESS_MEDIUM_IMMEDIATE_FIELD : (u32, u32) = (12, 0b1_11111111_11110000_00000000);
33+
pub const ADDRESS_MEDIUM_IMMEDIATE_REGISTER_FIELD : (u32, u32) = (12, 0b0_00000000_11110000_00000000);
34+
35+
pub const ADDRESS_INDEX_FIELD : (u32, u32) = (12, 0b0_00000000_11110000_00000000);
36+
pub const ADDRESS_SHORT_IMMEDIATE_FIELD : (u32, u32) = (16, 0b1_11111111_00000000_00000000);
37+
pub const ADDRESS_SHORT_IMMEDIATE_REGISTER_FIELD : (u32, u32) = (16, 0b0_00001111_00000000_00000000);
2538

2639
impl Instruction {
2740
const fn decode_load_immediate_instruction_operands(operands: u32) -> (RegisterCode, SegmentCode, u16) {
@@ -31,7 +44,7 @@ impl Instruction {
3144
(destination, segment, immediate)
3245
}
3346

34-
fn decode_enable_fields(operands: u32) -> [bool; 4] {
47+
const fn decode_enable_fields(operands: u32) -> [bool; 4] {
3548
let enable_0 = ((operands & ENABLE_0_FIELD.1) >> ENABLE_0_FIELD.0) > 0;
3649
let enable_1 = ((operands & ENABLE_1_FIELD.1) >> ENABLE_1_FIELD.0) > 0;
3750
let enable_2 = ((operands & ENABLE_2_FIELD.1) >> ENABLE_2_FIELD.0) > 0;
@@ -56,16 +69,16 @@ impl Instruction {
5669
enable[3].then_some(component_3)
5770
])
5871
}
59-
60-
fn decode_map_vector_instruction_operands(operands: u32) -> (bool, OperandCode, [ComponentCode; vector::SIZE]) {
72+
73+
const fn decode_map_vector_instruction_operands(operands: u32) -> (bool, OperandCode, [ComponentCode; vector::SIZE]) {
6174
let temporary = operands & MAP_VECTOR_TEMPORARY_FIELD > 0;
6275
let operand = OperandCode::new(((operands & MAP_VECTOR_OPERAND_FIELD.1) >> MAP_VECTOR_OPERAND_FIELD.0) as u8);
63-
76+
6477
let component_0 = ComponentCode::new(((operands & MAP_VECTOR_COMPONENT_0_FIELD.1) >> MAP_VECTOR_COMPONENT_0_FIELD.0) as u8);
6578
let component_1 = ComponentCode::new(((operands & MAP_VECTOR_COMPONENT_1_FIELD.1) >> MAP_VECTOR_COMPONENT_1_FIELD.0) as u8);
6679
let component_2 = ComponentCode::new(((operands & MAP_VECTOR_COMPONENT_2_FIELD.1) >> MAP_VECTOR_COMPONENT_2_FIELD.0) as u8);
6780
let component_3 = ComponentCode::new(((operands & MAP_VECTOR_COMPONENT_3_FIELD.1) >> MAP_VECTOR_COMPONENT_3_FIELD.0) as u8);
68-
81+
6982
(temporary, operand, [
7083
component_0,
7184
component_1,
@@ -74,9 +87,65 @@ impl Instruction {
7487
])
7588
}
7689

90+
fn decode_address_field(operands: u32) -> Address {
91+
let mode = (operands & ADDRESS_MODE_FIELD.1) >> ADDRESS_MODE_FIELD.0;
92+
let immediate = mode == 0
93+
|| mode == 2
94+
|| mode == 6;
95+
96+
match mode {
97+
0..4 => {
98+
let mode = match mode {
99+
0 | 2 => address::Mode::Absolute,
100+
1 | 3 => address::Mode::Relative,
101+
_ => unreachable!(),
102+
};
103+
104+
if immediate {
105+
let immediate = address::LargeImmediate::new((operands & ADDRESS_LARGE_IMMEDIATE_FIELD.1) >> ADDRESS_LARGE_IMMEDIATE_FIELD.0);
106+
Address::Immediate { mode, immediate }
107+
} else {
108+
let register = RegisterCode::new(((operands & ADDRESS_LARGE_IMMEDIATE_REGISTER_FIELD.1) >> ADDRESS_LARGE_IMMEDIATE_REGISTER_FIELD.0) as u8);
109+
Address::Register { mode, register }
110+
}
111+
},
112+
4..8 => {
113+
let base = RegisterCode::new(((operands & ADDRESS_BASE_FIELD.1) >> ADDRESS_BASE_FIELD.0) as u8);
114+
let mode = match mode {
115+
4 => {
116+
let offset = address::MediumImmediate::new(((operands & ADDRESS_MEDIUM_IMMEDIATE_FIELD.1) >> ADDRESS_MEDIUM_IMMEDIATE_FIELD.0) as u16);
117+
address::BaseMode::Offset(offset)
118+
},
119+
5 => {
120+
let offset = RegisterCode::new(((operands & ADDRESS_MEDIUM_IMMEDIATE_REGISTER_FIELD.1) >> ADDRESS_MEDIUM_IMMEDIATE_REGISTER_FIELD.0) as u8);
121+
address::BaseMode::RegisterOffset(offset)
122+
},
123+
6 | 7 => {
124+
let index = RegisterCode::new(((operands & ADDRESS_SHORT_IMMEDIATE_FIELD.1) >> ADDRESS_SHORT_IMMEDIATE_FIELD.0) as u8);
125+
let offset = if immediate {
126+
let immediate = address::ShortImmediate::new(((operands & ADDRESS_SHORT_IMMEDIATE_FIELD.1) >> ADDRESS_SHORT_IMMEDIATE_FIELD.0) as u16);
127+
address::IndexedBaseOffsetMode::Immediate(immediate)
128+
} else {
129+
let register = RegisterCode::new(((operands & ADDRESS_SHORT_IMMEDIATE_REGISTER_FIELD.1) >> ADDRESS_SHORT_IMMEDIATE_REGISTER_FIELD.0) as u8);
130+
address::IndexedBaseOffsetMode::Register(register)
131+
};
132+
133+
address::BaseMode::Indexed {
134+
index,
135+
offset
136+
}
137+
},
138+
_ => unreachable!()
139+
};
140+
141+
Address::Base { mode, base }
142+
},
143+
_ => unreachable!()
144+
}
145+
}
146+
77147
pub fn decode(encoded: u32) -> Self {
78148
let operation = encoded & OPERATION_MASK;
79-
80149
let format = operation::MAPPINGS
81150
.get(operation as usize)
82151
.unwrap_or(&operation::MAPPINGS[0])
@@ -103,15 +172,18 @@ impl Instruction {
103172
Self::MapVector { temporary, operand, mappings: components, }
104173
},
105174
Format::Branch => todo!(),
106-
Format::DualSource => todo!(),
107-
Format::Destination => todo!(),
108-
Format::DestinationSource => todo!(),
109-
Format::DestinationDualSource => todo!(),
110-
Format::DestinationTripleSource => todo!(),
111-
Format::DualDestinationDualSource => todo!(),
112-
Format::Memory => todo!(),
113-
Format::SourceMemory => todo!(),
114-
Format::DestinationMemory => todo!()
175+
Format::DualSource(operation) => todo!(),
176+
Format::Destination(operation) => todo!(),
177+
Format::DestinationSource(operation) => todo!(),
178+
Format::DestinationDualSource(operation) => todo!(),
179+
Format::DestinationTripleSource(operation) => todo!(),
180+
Format::DualDestinationDualSource(operation) => todo!(),
181+
Format::Memory(operation) => {
182+
let address = Self::decode_address_field(operands);
183+
Self::Memory { operation, address }
184+
},
185+
Format::SourceMemory(operation) => todo!(),
186+
Format::DestinationMemory(operation) => todo!()
115187
}
116188
}
117189
}

0 commit comments

Comments
 (0)