(
&mut self,
cpu: &mut Cpu,
code: &BlockTable,
from: &lifter::Block,
)
| 166 | } |
| 167 | |
| 168 | fn calculate_used_bits( |
| 169 | &mut self, |
| 170 | cpu: &mut Cpu, |
| 171 | code: &BlockTable, |
| 172 | from: &lifter::Block, |
| 173 | ) -> Result<(), Error> { |
| 174 | let Some(lifter) = self.lifter.as_mut() |
| 175 | else { |
| 176 | self.state.calculate_used_bits(); |
| 177 | return Ok(()); |
| 178 | }; |
| 179 | |
| 180 | if let lifter::BlockExit::Branch { |
| 181 | target: lifter::Target::External(pcode::Value::Const(target, _)), |
| 182 | fallthrough: lifter::Target::External(pcode::Value::Const(fallthrough, _)), |
| 183 | .. |
| 184 | } = from.exit |
| 185 | { |
| 186 | let target = lifter.get_or_lift_block(cpu, code, from.context, target)?; |
| 187 | |
| 188 | // Fork evaluation state and evaluate uses in the target branch. |
| 189 | let mut fork = self.state.clone(); |
| 190 | fork.find_loads_and_uses(&target, false); |
| 191 | fork.calculate_used_bits(); |
| 192 | |
| 193 | let fallthrough = lifter.get_or_lift_block(cpu, code, from.context, fallthrough)?; |
| 194 | |
| 195 | // Evaluate uses in the fallthrough from the current branch. |
| 196 | self.state.find_loads_and_uses(&fallthrough, false); |
| 197 | self.state.calculate_used_bits(); |
| 198 | |
| 199 | self.state.merge(&fork); |
| 200 | } |
| 201 | else { |
| 202 | self.state.calculate_used_bits(); |
| 203 | } |
| 204 | |
| 205 | Ok(()) |
| 206 | } |
| 207 | } |
| 208 | |
| 209 | /// Pushes the resized version of `stmt` to `block`. |
no test coverage detected