movs: allow overlapping strings, as long as they don't overlay within a page
This commit is contained in:
parent
3bcd997904
commit
752869dbff
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue