1
- const MASK : u32 = 0x000F ;
1
+ const MASK : u32 = 0x000000FF ;
2
2
3
3
/// Get the opcode of an instruction
4
4
pub fn opcode ( instr : u32 ) -> u8 {
@@ -7,22 +7,22 @@ pub fn opcode(instr: u32) -> u8 {
7
7
8
8
/// Get the first argument of an instruction.
9
9
pub fn first_arg ( instr : u32 ) -> u8 {
10
- ( ( instr >> 4 ) & MASK ) as u8
10
+ ( ( instr >> 8 ) & MASK ) as u8
11
11
}
12
12
13
13
/// Get the second argument of an instruction.
14
14
pub fn second_arg ( instr : u32 ) -> u8 {
15
- ( ( instr >> 8 ) & MASK ) as u8
15
+ ( ( instr >> 16 ) & MASK ) as u8
16
16
}
17
17
18
18
/// Get the third argument of an instruction.
19
19
pub fn third_arg ( instr : u32 ) -> u8 {
20
- ( ( instr >> 12 ) & MASK ) as u8
20
+ ( ( instr >> 24 ) & MASK ) as u8
21
21
}
22
22
23
23
/// Create an instruction with the given opcode and arguments.
24
24
pub fn make_instr ( opcode : Opcode , arg1 : u8 , arg2 : u8 , arg3 : u8 ) -> u32 {
25
- opcode as u32 + ( ( arg1 as u32 ) << 4 ) + ( ( arg2 as u32 ) << 8 ) + ( ( arg3 as u32 ) << 12 )
25
+ opcode as u32 + ( ( arg1 as u32 ) << 8 ) + ( ( arg2 as u32 ) << 16 ) + ( ( arg3 as u32 ) << 24 )
26
26
}
27
27
28
28
/// Represents a high level instruction whose operands have a size of usize.
@@ -58,3 +58,23 @@ pub enum Opcode {
58
58
FDIV = 9 , // R(1) = R(2) // R(3)
59
59
EXP = 10 , // R(1) = R(2) ^ R(3)
60
60
}
61
+
62
+ #[ cfg( test) ]
63
+ mod tests {
64
+ use super :: * ;
65
+
66
+ #[ test]
67
+ fn encoding_and_decoding_works ( ) {
68
+ for i in 0 ..=255 {
69
+ for j in 0 ..=255 {
70
+ for k in 0 ..=255 {
71
+ let instr = make_instr ( Opcode :: MOV , i, j, k) ;
72
+ assert_eq ! ( opcode( instr) , Opcode :: MOV as u8 ) ;
73
+ assert_eq ! ( first_arg( instr) , i) ;
74
+ assert_eq ! ( second_arg( instr) , j) ;
75
+ assert_eq ! ( third_arg( instr) , k) ;
76
+ }
77
+ }
78
+ }
79
+ }
80
+ }
0 commit comments