Skip to content

Commit

Permalink
string instructions: don't #gp if count==0 (#978)
Browse files Browse the repository at this point in the history
  • Loading branch information
copy committed Apr 20, 2024
1 parent f2e479f commit 9ac9cff
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 128 deletions.
11 changes: 11 additions & 0 deletions src/rust/cpu/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2746,6 +2746,17 @@ pub fn get_seg_cs() -> i32 { unsafe { *segment_offsets.offset(CS as isize) } }

pub unsafe fn get_seg_ss() -> i32 { return *segment_offsets.offset(SS as isize); }

pub unsafe fn segment_prefix(default_segment: i32) -> i32 {
let prefix = *prefixes & prefix::PREFIX_MASK_SEGMENT;
if 0 != prefix {
dbg_assert!(prefix != prefix::SEG_PREFIX_ZERO);
prefix as i32 - 1
}
else {
default_segment
}
}

pub unsafe fn get_seg_prefix(default_segment: i32) -> OrPageFault<i32> {
dbg_assert!(!in_jit);
let prefix = *prefixes & prefix::PREFIX_MASK_SEGMENT;
Expand Down
96 changes: 36 additions & 60 deletions src/rust/cpu/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -630,20 +630,16 @@ pub unsafe fn instr16_F36D() { insw_rep(is_asize_32()); }
pub unsafe fn instr32_F26D() { insd_rep(is_asize_32()); }
pub unsafe fn instr32_F36D() { insd_rep(is_asize_32()); }

pub unsafe fn instr_6E() { outsb_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
pub unsafe fn instr_F26E() { outsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
pub unsafe fn instr_F36E() { outsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
pub unsafe fn instr_6E() { outsb_no_rep(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr_F26E() { outsb_rep(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr_F36E() { outsb_rep(is_asize_32(), segment_prefix(DS)); }

pub unsafe fn instr16_6F() {
outsw_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
}
pub unsafe fn instr32_6F() {
outsd_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
}
pub unsafe fn instr16_F26F() { outsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
pub unsafe fn instr16_F36F() { outsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
pub unsafe fn instr32_F26F() { outsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
pub unsafe fn instr32_F36F() { outsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
pub unsafe fn instr16_6F() { outsw_no_rep(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr32_6F() { outsd_no_rep(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr16_F26F() { outsw_rep(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr16_F36F() { outsw_rep(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr32_F26F() { outsd_rep(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr32_F36F() { outsd_rep(is_asize_32(), segment_prefix(DS)); }

pub unsafe fn instr16_70(imm8: i32) { jmpcc16(test_o(), imm8); }
pub unsafe fn instr16_71(imm8: i32) { jmpcc16(!test_o(), imm8); }
Expand Down Expand Up @@ -1123,42 +1119,26 @@ pub unsafe fn instr32_A3(moffs: i32) {
));
}

pub unsafe fn instr_A4() { movsb_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
pub unsafe fn instr_F2A4() { movsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
pub unsafe fn instr_F3A4() { movsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
pub unsafe fn instr_A4() { movsb_no_rep(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr_F2A4() { movsb_rep(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr_F3A4() { movsb_rep(is_asize_32(), segment_prefix(DS)); }

pub unsafe fn instr16_A5() {
movsw_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
}
pub unsafe fn instr32_A5() {
movsd_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
}
pub unsafe fn instr16_F2A5() { movsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
pub unsafe fn instr16_F3A5() { movsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
pub unsafe fn instr32_F2A5() { movsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
pub unsafe fn instr32_F3A5() { movsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
pub unsafe fn instr16_A5() { movsw_no_rep(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr32_A5() { movsd_no_rep(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr16_F2A5() { movsw_rep(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr16_F3A5() { movsw_rep(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr32_F2A5() { movsd_rep(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr32_F3A5() { movsd_rep(is_asize_32(), segment_prefix(DS)); }

pub unsafe fn instr_A6() { cmpsb_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
pub unsafe fn instr_F2A6() { cmpsb_repnz(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
pub unsafe fn instr_F3A6() { cmpsb_repz(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
pub unsafe fn instr16_A7() {
cmpsw_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
}
pub unsafe fn instr32_A7() {
cmpsd_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
}
pub unsafe fn instr16_F2A7() {
cmpsw_repnz(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
}
pub unsafe fn instr16_F3A7() {
cmpsw_repz(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
}
pub unsafe fn instr32_F2A7() {
cmpsd_repnz(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
}
pub unsafe fn instr32_F3A7() {
cmpsd_repz(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
}
pub unsafe fn instr_A6() { cmpsb_no_rep(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr_F2A6() { cmpsb_repnz(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr_F3A6() { cmpsb_repz(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr16_A7() { cmpsw_no_rep(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr32_A7() { cmpsd_no_rep(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr16_F2A7() { cmpsw_repnz(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr16_F3A7() { cmpsw_repz(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr32_F2A7() { cmpsd_repnz(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr32_F3A7() { cmpsd_repz(is_asize_32(), segment_prefix(DS)); }

pub unsafe fn instr_A8(imm8: i32) { test8(read_reg8(AL), imm8); }
pub unsafe fn instr16_A9(imm16: i32) { test16(read_reg16(AX), imm16); }
Expand All @@ -1175,20 +1155,16 @@ pub unsafe fn instr16_F3AB() { stosw_rep(is_asize_32()); }
pub unsafe fn instr32_F2AB() { stosd_rep(is_asize_32()); }
pub unsafe fn instr32_F3AB() { stosd_rep(is_asize_32()); }

pub unsafe fn instr_AC() { lodsb_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
pub unsafe fn instr_F2AC() { lodsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
pub unsafe fn instr_F3AC() { lodsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
pub unsafe fn instr_AC() { lodsb_no_rep(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr_F2AC() { lodsb_rep(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr_F3AC() { lodsb_rep(is_asize_32(), segment_prefix(DS)); }

pub unsafe fn instr16_AD() {
lodsw_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
}
pub unsafe fn instr32_AD() {
lodsd_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS)));
}
pub unsafe fn instr16_F2AD() { lodsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
pub unsafe fn instr16_F3AD() { lodsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
pub unsafe fn instr32_F2AD() { lodsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
pub unsafe fn instr32_F3AD() { lodsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); }
pub unsafe fn instr16_AD() { lodsw_no_rep(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr32_AD() { lodsd_no_rep(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr16_F2AD() { lodsw_rep(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr16_F3AD() { lodsw_rep(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr32_F2AD() { lodsd_rep(is_asize_32(), segment_prefix(DS)); }
pub unsafe fn instr32_F3AD() { lodsd_rep(is_asize_32(), segment_prefix(DS)); }

pub unsafe fn instr_AE() { scasb_no_rep(is_asize_32()); }
pub unsafe fn instr_F2AE() { scasb_repnz(is_asize_32()); }
Expand Down
139 changes: 74 additions & 65 deletions src/rust/cpu/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ enum Rep {
#[inline(always)]
unsafe fn string_instruction(
is_asize_32: bool,
ds: i32,
ds_or_prefix: i32,
instruction: Instruction,
size: Size,
rep: Rep,
Expand All @@ -71,6 +71,17 @@ unsafe fn string_instruction(

let direction = if 0 != *flags & FLAG_DIRECTION { -1 } else { 1 };

let mut count = match rep {
Rep::Z | Rep::NZ => {
let c = (read_reg32(ECX) & asize_mask) as u32;
if c == 0 {
return;
};
c
},
Rep::None => 0,
};

let es = match instruction {
Instruction::Movs
| Instruction::Cmps
Expand All @@ -79,6 +90,14 @@ unsafe fn string_instruction(
| Instruction::Ins => return_on_pagefault!(get_seg(ES)),
_ => 0,
};
let ds = match instruction {
Instruction::Movs
| Instruction::Cmps
| Instruction::Lods
| Instruction::Scas
| Instruction::Outs => return_on_pagefault!(get_seg(ds_or_prefix)),
_ => 0,
};

let size_bytes = match size {
Size::B => 1,
Expand Down Expand Up @@ -112,16 +131,6 @@ unsafe fn string_instruction(
| Instruction::Ins => read_reg32(EDI) & asize_mask,
_ => 0,
};
let mut count = match rep {
Rep::Z | Rep::NZ => {
let c = (read_reg32(ECX) & asize_mask) as u32;
if c == 0 {
return;
};
c
},
Rep::None => 0,
};

let port = match instruction {
Instruction::Ins | Instruction::Outs => {
Expand Down Expand Up @@ -509,47 +518,47 @@ unsafe fn string_instruction(
}

#[no_mangle]
pub unsafe fn movsb_rep(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Movs, Size::B, Rep::Z)
pub unsafe fn movsb_rep(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Movs, Size::B, Rep::Z)
}
#[no_mangle]
pub unsafe fn movsw_rep(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Movs, Size::W, Rep::Z)
pub unsafe fn movsw_rep(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Movs, Size::W, Rep::Z)
}
#[no_mangle]
pub unsafe fn movsd_rep(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Movs, Size::D, Rep::Z)
pub unsafe fn movsd_rep(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Movs, Size::D, Rep::Z)
}
pub unsafe fn movsb_no_rep(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Movs, Size::B, Rep::None)
pub unsafe fn movsb_no_rep(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Movs, Size::B, Rep::None)
}
pub unsafe fn movsw_no_rep(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Movs, Size::W, Rep::None)
pub unsafe fn movsw_no_rep(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Movs, Size::W, Rep::None)
}
pub unsafe fn movsd_no_rep(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Movs, Size::D, Rep::None)
pub unsafe fn movsd_no_rep(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Movs, Size::D, Rep::None)
}

#[no_mangle]
pub unsafe fn lodsb_rep(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Lods, Size::B, Rep::Z)
pub unsafe fn lodsb_rep(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Lods, Size::B, Rep::Z)
}
#[no_mangle]
pub unsafe fn lodsw_rep(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Lods, Size::W, Rep::Z)
pub unsafe fn lodsw_rep(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Lods, Size::W, Rep::Z)
}
#[no_mangle]
pub unsafe fn lodsd_rep(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Lods, Size::D, Rep::Z)
pub unsafe fn lodsd_rep(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Lods, Size::D, Rep::Z)
}
pub unsafe fn lodsb_no_rep(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Lods, Size::B, Rep::None)
pub unsafe fn lodsb_no_rep(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Lods, Size::B, Rep::None)
}
pub unsafe fn lodsw_no_rep(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Lods, Size::W, Rep::None)
pub unsafe fn lodsw_no_rep(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Lods, Size::W, Rep::None)
}
pub unsafe fn lodsd_no_rep(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Lods, Size::D, Rep::None)
pub unsafe fn lodsd_no_rep(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Lods, Size::D, Rep::None)
}

#[no_mangle]
Expand All @@ -575,40 +584,40 @@ pub unsafe fn stosd_no_rep(is_asize_32: bool) {
}

#[no_mangle]
pub unsafe fn cmpsb_repz(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Cmps, Size::B, Rep::Z)
pub unsafe fn cmpsb_repz(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Cmps, Size::B, Rep::Z)
}
#[no_mangle]
pub unsafe fn cmpsw_repz(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Cmps, Size::W, Rep::Z)
pub unsafe fn cmpsw_repz(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Cmps, Size::W, Rep::Z)
}
#[no_mangle]
pub unsafe fn cmpsd_repz(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Cmps, Size::D, Rep::Z)
pub unsafe fn cmpsd_repz(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Cmps, Size::D, Rep::Z)
}
#[no_mangle]
pub unsafe fn cmpsb_repnz(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Cmps, Size::B, Rep::NZ)
pub unsafe fn cmpsb_repnz(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Cmps, Size::B, Rep::NZ)
}
#[no_mangle]
pub unsafe fn cmpsw_repnz(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Cmps, Size::W, Rep::NZ)
pub unsafe fn cmpsw_repnz(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Cmps, Size::W, Rep::NZ)
}
#[no_mangle]
pub unsafe fn cmpsd_repnz(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Cmps, Size::D, Rep::NZ)
pub unsafe fn cmpsd_repnz(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Cmps, Size::D, Rep::NZ)
}
#[no_mangle]
pub unsafe fn cmpsb_no_rep(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Cmps, Size::B, Rep::None)
pub unsafe fn cmpsb_no_rep(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Cmps, Size::B, Rep::None)
}
#[no_mangle]
pub unsafe fn cmpsw_no_rep(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Cmps, Size::W, Rep::None)
pub unsafe fn cmpsw_no_rep(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Cmps, Size::W, Rep::None)
}
#[no_mangle]
pub unsafe fn cmpsd_no_rep(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Cmps, Size::D, Rep::None)
pub unsafe fn cmpsd_no_rep(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Cmps, Size::D, Rep::None)
}

#[no_mangle]
Expand Down Expand Up @@ -646,28 +655,28 @@ pub unsafe fn scasd_no_rep(is_asize_32: bool) {
}

#[no_mangle]
pub unsafe fn outsb_rep(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Outs, Size::B, Rep::Z)
pub unsafe fn outsb_rep(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Outs, Size::B, Rep::Z)
}
#[no_mangle]
pub unsafe fn outsw_rep(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Outs, Size::W, Rep::Z)
pub unsafe fn outsw_rep(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Outs, Size::W, Rep::Z)
}
#[no_mangle]
pub unsafe fn outsd_rep(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Outs, Size::D, Rep::Z)
pub unsafe fn outsd_rep(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Outs, Size::D, Rep::Z)
}
#[no_mangle]
pub unsafe fn outsb_no_rep(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Outs, Size::B, Rep::None)
pub unsafe fn outsb_no_rep(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Outs, Size::B, Rep::None)
}
#[no_mangle]
pub unsafe fn outsw_no_rep(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Outs, Size::W, Rep::None)
pub unsafe fn outsw_no_rep(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Outs, Size::W, Rep::None)
}
#[no_mangle]
pub unsafe fn outsd_no_rep(is_asize_32: bool, ds: i32) {
string_instruction(is_asize_32, ds, Instruction::Outs, Size::D, Rep::None)
pub unsafe fn outsd_no_rep(is_asize_32: bool, seg: i32) {
string_instruction(is_asize_32, seg, Instruction::Outs, Size::D, Rep::None)
}

#[no_mangle]
Expand Down
9 changes: 6 additions & 3 deletions src/rust/jit_instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use cpu::cpu::{
use cpu::global_pointers;
use jit::{Instruction, InstructionOperand, InstructionOperandDest, JitContext};
use modrm::{jit_add_seg_offset, jit_add_seg_offset_no_override, ModrmByte};
use prefix::SEG_PREFIX_ZERO;
use prefix::{PREFIX_66, PREFIX_67, PREFIX_F2, PREFIX_F3};
use prefix::{PREFIX_MASK_SEGMENT, SEG_PREFIX_ZERO};
use regs;
use regs::{AX, BP, BX, CX, DI, DX, SI, SP};
use regs::{CS, DS, ES, FS, GS, SS};
Expand Down Expand Up @@ -4934,9 +4934,12 @@ fn gen_string_ins(ctx: &mut JitContext, ins: String, size: u8, prefix: u8) {
ctx.builder.const_i32(ctx.cpu.asize_32() as i32);

if ins == String::OUTS || ins == String::CMPS || ins == String::LODS || ins == String::MOVS {
// TODO: check es/ds is null (only if rep && count!=0)
args += 1;
ctx.builder.const_i32(0);
jit_add_seg_offset(ctx, regs::DS);
let prefix = ctx.cpu.prefixes & PREFIX_MASK_SEGMENT;
dbg_assert!(prefix != SEG_PREFIX_ZERO);
let seg = if prefix != 0 { (prefix - 1) as u32 } else { regs::DS };
ctx.builder.const_i32(seg as i32);
}

let name = format!(
Expand Down

0 comments on commit 9ac9cff

Please sign in to comment.