1+ use std:: collections:: HashMap ;
2+
3+ type Instruction = ( u32 , u32 , & ' static str ) ;
4+
5+ pub const INSTRUCTIONS : [ ( u32 , u32 , & str ) ; 204 ] = [
6+ ( 0xe003 , 0x0000 , "c.addi4spn" ) ,
7+ ( 0xe003 , 0x2000 , "c.fld" ) ,
8+ ( 0xe003 , 0x4000 , "c.lw" ) ,
9+ ( 0xfe00707f , 0x0e007033 , "czero.nez" ) , // Example instructions
10+ ] ;
11+
12+ /// Build a fast 2048-elements dispatch table for accelerated lookup
13+ pub fn build_dispatch_table ( ) -> [ & ' static [ ( u32 , u32 , & ' static str ) ] ; 2048 ] {
14+ const EMPTY : & [ Instruction ] = & [ ] ;
15+
16+ let mut dispatch_table: [ & [ ( u32 , u32 , & str ) ] ; 2048 ] = [ EMPTY ; 2048 ] ;
17+ let mut temp_table: Vec < Vec < Instruction > > = vec ! [ vec![ ] ; 2048 ] ;
18+
19+ for & ( mask, pattern, mnemonic) in INSTRUCTIONS . iter ( ) {
20+ let index = ( ( pattern & 127 ) + ( ( pattern & 0xe000 ) >> 5 ) ) as usize ;
21+ temp_table[ index] . push ( ( mask, pattern, mnemonic) ) ;
22+ }
23+
24+ for ( i, instructions) in temp_table. into_iter ( ) . enumerate ( ) {
25+ if !instructions. is_empty ( ) {
26+ dispatch_table[ i] = Box :: leak ( instructions. into_boxed_slice ( ) ) ;
27+ }
28+ }
29+
30+ dispatch_table
31+ }
32+
33+ pub fn match_instruction ( w : u32 , dispatch_table : & [ & [ ( u32 , u32 , & ' static str ) ] ; 2048 ] ) -> Option < & ' static str > {
34+ let index = ( ( w & 127 ) + ( ( w & 0xe000 ) >> 5 ) ) as usize ;
35+
36+ for & ( mask, pattern, mnemonic) in dispatch_table[ index] . iter ( ) {
37+ if ( w & mask) == pattern {
38+ return Some ( mnemonic) ;
39+ }
40+ }
41+
42+ None
43+ }
44+
45+ #[ test]
46+ fn test_dispatch_array ( ) {
47+ let dispatch_table = build_dispatch_table ( ) ;
48+ let w: u32 = 0x00000033 ;
49+ if let Some ( mnemonic) = match_instruction ( w, & dispatch_table) {
50+ println ! ( "Instruction matched: {}" , mnemonic) ;
51+ } else {
52+ println ! ( "No matching instruction found!" ) ;
53+ }
54+ }
0 commit comments