diff --git a/src/rust/cpu/string.rs b/src/rust/cpu/string.rs index fc2114b7..27d9ce0f 100644 --- a/src/rust/cpu/string.rs +++ b/src/rust/cpu/string.rs @@ -151,7 +151,7 @@ unsafe fn string_instruction( let mut movs_into_svga_lfb = false; let mut movs_reenter_fast_path = false; - if rep_fast { + let count_until_end_of_page = if rep_fast { match instruction { Instruction::Movs => { let (addr, skip) = @@ -186,9 +186,25 @@ unsafe fn string_instruction( _ => {}, }; + let count_until_end_of_page = u32::min( + count, + match instruction { + Instruction::Movs | Instruction::Cmps => u32::min( + count_until_end_of_page(direction, size_bytes, phys_src), + count_until_end_of_page(direction, size_bytes, phys_dst), + ), + Instruction::Stos | Instruction::Ins | Instruction::Scas => { + count_until_end_of_page(direction, size_bytes, phys_dst) + }, + Instruction::Lods | Instruction::Outs => { + count_until_end_of_page(direction, size_bytes, phys_src) + }, + }, + ); + match instruction { Instruction::Movs => { - let c = count * size_bytes as u32; + let c = count_until_end_of_page * size_bytes as u32; let overlap_interferes = if phys_src < phys_dst { // backward moves may overlap at the front of the destination string @@ -212,24 +228,14 @@ unsafe fn string_instruction( }, _ => {}, } + + count_until_end_of_page } + else { + 0 // not used + }; if rep_fast { - let count_until_end_of_page = u32::min( - count, - match instruction { - Instruction::Movs | Instruction::Cmps => u32::min( - count_until_end_of_page(direction, size_bytes, phys_src), - count_until_end_of_page(direction, size_bytes, phys_dst), - ), - Instruction::Stos | Instruction::Ins | Instruction::Scas => { - count_until_end_of_page(direction, size_bytes, phys_dst) - }, - Instruction::Lods | Instruction::Outs => { - count_until_end_of_page(direction, size_bytes, phys_src) - }, - }, - ); dbg_assert!(count_until_end_of_page > 0); if !skip_dirty_page {