1
1
use core:: fmt;
2
2
use std:: { arch:: asm, panic, slice:: Iter } ;
3
3
4
+ use hashbrown:: HashMap ;
5
+
4
6
use crate :: {
5
7
com_bus:: communication_bus:: CommunicationBus ,
6
8
ins:: {
@@ -89,6 +91,8 @@ pub struct Cpu {
89
91
pub is_in_interrupt_handler : bool ,
90
92
/// The last interrupt handler that was "active" (i.e. was not terminated with intret).
91
93
pub last_interrupt_code : Option < u8 > ,
94
+ /// The decoded expressions cache.
95
+ decode_expression_cache : HashMap < u32 , Expression > ,
92
96
}
93
97
94
98
impl Cpu {
@@ -99,6 +103,7 @@ impl Cpu {
99
103
is_machine_mode : true ,
100
104
is_in_interrupt_handler : false ,
101
105
last_interrupt_code : None ,
106
+ decode_expression_cache : HashMap :: new ( ) ,
102
107
}
103
108
}
104
109
@@ -127,13 +132,17 @@ impl Cpu {
127
132
///
128
133
/// A u32 that is the calculated result of the expression.
129
134
#[ inline]
130
- fn decode_evaluate_u32_move_expression (
131
- & mut self ,
132
- expr : & u32 ,
133
- privilege : & PrivilegeLevel ,
134
- ) -> u32 {
135
- let mut decoder = Expression :: new ( ) ;
136
- decoder. unpack ( * expr) ;
135
+ fn decode_evaluate_u32_expression ( & mut self , expr : & u32 , privilege : & PrivilegeLevel ) -> u32 {
136
+ // Cache the decoded expression so we don't need to do this multiple times
137
+ // for the same expression.
138
+ let decoder = self
139
+ . decode_expression_cache
140
+ . entry ( * expr)
141
+ . or_insert_with ( || {
142
+ let mut expression = Expression :: new ( ) ;
143
+ expression. unpack ( * expr) ;
144
+ expression
145
+ } ) ;
137
146
138
147
// Determine the first and second operands.
139
148
let value_1 = match decoder. operand_1 {
@@ -911,54 +920,54 @@ impl Cpu {
911
920
912
921
/******** [Bit Operation Instructions] ********/
913
922
I :: LeftShiftU8ImmU32Reg ( imm, reg) => {
914
- let old_value = self . registers . read_reg_u32 ( reg, privilege) ;
915
- let shifted = self . perform_checked_left_shift_u32 ( old_value , * imm) ;
923
+ let value = self . registers . read_reg_u32 ( reg, privilege) ;
924
+ let shifted = self . perform_checked_left_shift_u32 ( value , * imm) ;
916
925
917
926
self . write_reg_u32 ( reg, shifted, privilege) ;
918
927
}
919
928
I :: LeftShiftU32RegU32Reg ( shift_reg, reg) => {
920
929
let shift_by = self . registers . read_reg_u32 ( shift_reg, privilege) ;
921
- let old_value = self . registers . read_reg_u32 ( reg, privilege) ;
922
- let shifted = self . perform_checked_left_shift_u32 ( old_value , shift_by as u8 ) ;
930
+ let value = self . registers . read_reg_u32 ( reg, privilege) ;
931
+ let shifted = self . perform_checked_left_shift_u32 ( value , shift_by as u8 ) ;
923
932
924
933
self . write_reg_u32 ( reg, shifted, privilege) ;
925
934
}
926
935
I :: ArithLeftShiftU8ImmU32Reg ( imm, reg) => {
927
- let old_value = self . registers . read_reg_u32 ( reg, privilege) ;
928
- let shifted = self . perform_arithmetic_left_shift_u32 ( old_value , * imm as u32 ) ;
936
+ let value = self . registers . read_reg_u32 ( reg, privilege) ;
937
+ let shifted = self . perform_arithmetic_left_shift_u32 ( value , * imm as u32 ) ;
929
938
930
939
self . write_reg_u32 ( reg, shifted, privilege) ;
931
940
}
932
941
I :: ArithLeftShiftU32RegU32Reg ( shift_reg, reg) => {
933
942
let shift_by = self . registers . read_reg_u32 ( shift_reg, privilege) ;
934
- let old_value = self . registers . read_reg_u32 ( reg, privilege) ;
935
- let shifted = self . perform_arithmetic_left_shift_u32 ( old_value , shift_by) ;
943
+ let value = self . registers . read_reg_u32 ( reg, privilege) ;
944
+ let shifted = self . perform_arithmetic_left_shift_u32 ( value , shift_by) ;
936
945
937
946
self . write_reg_u32 ( reg, shifted, privilege) ;
938
947
}
939
948
I :: RightShiftU8ImmU32Reg ( imm, reg) => {
940
- let old_value = self . registers . read_reg_u32 ( reg, privilege) ;
941
- let shifted = self . perform_right_shift_u32 ( old_value , * imm) ;
949
+ let value = self . registers . read_reg_u32 ( reg, privilege) ;
950
+ let shifted = self . perform_right_shift_u32 ( value , * imm) ;
942
951
943
952
self . write_reg_u32 ( reg, shifted, privilege) ;
944
953
}
945
954
I :: RightShiftU32RegU32Reg ( shift_reg, reg) => {
946
955
let shift_by = self . registers . read_reg_u32 ( shift_reg, privilege) ;
947
- let old_value = self . registers . read_reg_u32 ( reg, privilege) ;
948
- let shifted = self . perform_right_shift_u32 ( old_value , shift_by as u8 ) ;
956
+ let value = self . registers . read_reg_u32 ( reg, privilege) ;
957
+ let shifted = self . perform_right_shift_u32 ( value , shift_by as u8 ) ;
949
958
950
959
self . write_reg_u32 ( reg, shifted, privilege) ;
951
960
}
952
961
I :: ArithRightShiftU8ImmU32Reg ( imm, reg) => {
953
- let old_value = self . registers . read_reg_u32 ( reg, privilege) ;
954
- let shifted = self . perform_arithmetic_right_shift_u32 ( old_value , * imm as u32 ) ;
962
+ let value = self . registers . read_reg_u32 ( reg, privilege) ;
963
+ let shifted = self . perform_arithmetic_right_shift_u32 ( value , * imm as u32 ) ;
955
964
956
965
self . write_reg_u32 ( reg, shifted, privilege) ;
957
966
}
958
967
I :: ArithRightShiftU32RegU32Reg ( shift_reg, reg) => {
959
968
let shift_by = self . registers . read_reg_u32 ( shift_reg, privilege) ;
960
- let old_value = self . registers . read_reg_u32 ( reg, privilege) ;
961
- let shifted = self . perform_arithmetic_right_shift_u32 ( old_value , shift_by) ;
969
+ let value = self . registers . read_reg_u32 ( reg, privilege) ;
970
+ let shifted = self . perform_arithmetic_right_shift_u32 ( value , shift_by) ;
962
971
963
972
self . write_reg_u32 ( reg, shifted, privilege) ;
964
973
}
@@ -1041,20 +1050,20 @@ impl Cpu {
1041
1050
}
1042
1051
I :: MovU32ImmMemExpr ( imm, expr) => {
1043
1052
// mov imm, &[addr] - move immediate to address.
1044
- let addr = self . decode_evaluate_u32_move_expression ( expr, privilege) ;
1053
+ let addr = self . decode_evaluate_u32_expression ( expr, privilege) ;
1045
1054
1046
1055
com_bus. mem . set_u32 ( addr as usize , * imm) ;
1047
1056
}
1048
1057
I :: MovMemExprU32Reg ( expr, reg) => {
1049
1058
// mov &[addr], register - move value at address to register.
1050
- let addr = self . decode_evaluate_u32_move_expression ( expr, privilege) ;
1059
+ let addr = self . decode_evaluate_u32_expression ( expr, privilege) ;
1051
1060
let value = com_bus. mem . get_u32 ( addr as usize ) ;
1052
1061
1053
1062
self . write_reg_u32 ( reg, value, privilege) ;
1054
1063
}
1055
1064
I :: MovU32RegMemExpr ( reg, expr) => {
1056
1065
// mov ®, &[addr] - move value of a register to an address.
1057
- let addr = self . decode_evaluate_u32_move_expression ( expr, privilege) ;
1066
+ let addr = self . decode_evaluate_u32_expression ( expr, privilege) ;
1058
1067
let value = self . registers . read_reg_u32 ( reg, privilege) ;
1059
1068
1060
1069
com_bus. mem . set_u32 ( addr as usize , value) ;
0 commit comments