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 ;
2
3
use crate :: instruction:: vector:: ComponentCode ;
3
- use crate :: num:: MaskedU32 ;
4
+ use crate :: num:: { MaskedU32 , MaskedU8 } ;
4
5
5
6
pub const OPERATION_MASK : u32 = 0x0000007F ;
6
7
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 ) ;
25
38
26
39
impl Instruction {
27
40
const fn decode_load_immediate_instruction_operands ( operands : u32 ) -> ( RegisterCode , SegmentCode , u16 ) {
@@ -31,7 +44,7 @@ impl Instruction {
31
44
( destination, segment, immediate)
32
45
}
33
46
34
- fn decode_enable_fields ( operands : u32 ) -> [ bool ; 4 ] {
47
+ const fn decode_enable_fields ( operands : u32 ) -> [ bool ; 4 ] {
35
48
let enable_0 = ( ( operands & ENABLE_0_FIELD . 1 ) >> ENABLE_0_FIELD . 0 ) > 0 ;
36
49
let enable_1 = ( ( operands & ENABLE_1_FIELD . 1 ) >> ENABLE_1_FIELD . 0 ) > 0 ;
37
50
let enable_2 = ( ( operands & ENABLE_2_FIELD . 1 ) >> ENABLE_2_FIELD . 0 ) > 0 ;
@@ -56,16 +69,16 @@ impl Instruction {
56
69
enable[ 3 ] . then_some ( component_3)
57
70
] )
58
71
}
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 ] ) {
61
74
let temporary = operands & MAP_VECTOR_TEMPORARY_FIELD > 0 ;
62
75
let operand = OperandCode :: new ( ( ( operands & MAP_VECTOR_OPERAND_FIELD . 1 ) >> MAP_VECTOR_OPERAND_FIELD . 0 ) as u8 ) ;
63
-
76
+
64
77
let component_0 = ComponentCode :: new ( ( ( operands & MAP_VECTOR_COMPONENT_0_FIELD . 1 ) >> MAP_VECTOR_COMPONENT_0_FIELD . 0 ) as u8 ) ;
65
78
let component_1 = ComponentCode :: new ( ( ( operands & MAP_VECTOR_COMPONENT_1_FIELD . 1 ) >> MAP_VECTOR_COMPONENT_1_FIELD . 0 ) as u8 ) ;
66
79
let component_2 = ComponentCode :: new ( ( ( operands & MAP_VECTOR_COMPONENT_2_FIELD . 1 ) >> MAP_VECTOR_COMPONENT_2_FIELD . 0 ) as u8 ) ;
67
80
let component_3 = ComponentCode :: new ( ( ( operands & MAP_VECTOR_COMPONENT_3_FIELD . 1 ) >> MAP_VECTOR_COMPONENT_3_FIELD . 0 ) as u8 ) ;
68
-
81
+
69
82
( temporary, operand, [
70
83
component_0,
71
84
component_1,
@@ -74,9 +87,65 @@ impl Instruction {
74
87
] )
75
88
}
76
89
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
+
77
147
pub fn decode ( encoded : u32 ) -> Self {
78
148
let operation = encoded & OPERATION_MASK ;
79
-
80
149
let format = operation:: MAPPINGS
81
150
. get ( operation as usize )
82
151
. unwrap_or ( & operation:: MAPPINGS [ 0 ] )
@@ -103,15 +172,18 @@ impl Instruction {
103
172
Self :: MapVector { temporary, operand, mappings : components, }
104
173
} ,
105
174
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 ! ( )
115
187
}
116
188
}
117
189
}
0 commit comments