1- const MASK : u32 = 0x000F ;
1+ const MASK : u32 = 0x000000FF ;
22
33/// Get the opcode of an instruction
44pub fn opcode ( instr : u32 ) -> u8 {
@@ -7,22 +7,22 @@ pub fn opcode(instr: u32) -> u8 {
77
88/// Get the first argument of an instruction.
99pub fn first_arg ( instr : u32 ) -> u8 {
10- ( ( instr >> 4 ) & MASK ) as u8
10+ ( ( instr >> 8 ) & MASK ) as u8
1111}
1212
1313/// Get the second argument of an instruction.
1414pub fn second_arg ( instr : u32 ) -> u8 {
15- ( ( instr >> 8 ) & MASK ) as u8
15+ ( ( instr >> 16 ) & MASK ) as u8
1616}
1717
1818/// Get the third argument of an instruction.
1919pub fn third_arg ( instr : u32 ) -> u8 {
20- ( ( instr >> 12 ) & MASK ) as u8
20+ ( ( instr >> 24 ) & MASK ) as u8
2121}
2222
2323/// Create an instruction with the given opcode and arguments.
2424pub 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 )
2626}
2727
2828/// Represents a high level instruction whose operands have a size of usize.
@@ -58,3 +58,23 @@ pub enum Opcode {
5858 FDIV = 9 , // R(1) = R(2) // R(3)
5959 EXP = 10 , // R(1) = R(2) ^ R(3)
6060}
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