diff --git a/gen/x86_table.js b/gen/x86_table.js index 731840d4..9827c630 100644 --- a/gen/x86_table.js +++ b/gen/x86_table.js @@ -246,7 +246,7 @@ const encodings = [ { opcode: 0xF2AD, block_boundary: 1, custom: 1, is_string: 1, os: 1, }, { opcode: 0xF3AD, block_boundary: 1, custom: 1, is_string: 1, os: 1, }, - { opcode: 0xAE, block_boundary: 1, custom: 1, is_string: 1, }, + { opcode: 0xAE, block_boundary: 0, custom: 1, is_string: 1, }, { opcode: 0xF2AE, block_boundary: 1, custom: 1, is_string: 1, }, { opcode: 0xF3AE, block_boundary: 1, custom: 1, is_string: 1, }, { opcode: 0xAF, block_boundary: 1, custom: 1, is_string: 1, os: 1, }, diff --git a/src/rust/cpu/string.rs b/src/rust/cpu/string.rs index 0cbcbda3..738bd6ce 100644 --- a/src/rust/cpu/string.rs +++ b/src/rust/cpu/string.rs @@ -593,7 +593,6 @@ pub unsafe fn scasw_repnz(is_asize_32: bool) { pub unsafe fn scasd_repnz(is_asize_32: bool) { string_instruction(is_asize_32, 0, Instruction::Scas, Size::D, Rep::NZ) } -#[no_mangle] pub unsafe fn scasb_no_rep(is_asize_32: bool) { string_instruction(is_asize_32, 0, Instruction::Scas, Size::B, Rep::None) } diff --git a/src/rust/jit_instructions.rs b/src/rust/jit_instructions.rs index d0fc7681..fb933ad7 100644 --- a/src/rust/jit_instructions.rs +++ b/src/rust/jit_instructions.rs @@ -8,7 +8,7 @@ use cpu::cpu::{ }; use cpu::global_pointers; use jit::{Instruction, InstructionOperand, JitContext}; -use modrm::{jit_add_seg_offset, ModrmByte}; +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 regs; @@ -4489,6 +4489,36 @@ fn gen_string_ins(ctx: &mut JitContext, ins: String, size: u8, prefix: u8) { } return; }, + (String::SCAS, 8) => { + if ctx.cpu.asize_32() { + codegen::gen_get_reg32(ctx, regs::EDI); + } + else { + codegen::gen_get_reg16(ctx, regs::EDI); + } + jit_add_seg_offset_no_override(ctx, regs::ES); + let address_local = ctx.builder.set_new_local(); + codegen::gen_safe_read8(ctx, &address_local); + ctx.builder.free_local(address_local); + let value = ctx.builder.set_new_local(); + gen_cmp8( + ctx, + &ctx.reg(regs::EAX), + &LocalOrImmediate::WasmLocal(&value), + ); + ctx.builder.free_local(value); + + codegen::gen_get_reg32(ctx, regs::EDI); + get_direction(ctx); + ctx.builder.add_i32(); + if ctx.cpu.asize_32() { + codegen::gen_set_reg32(ctx, regs::EDI); + } + else { + codegen::gen_set_reg16(ctx, regs::EDI); + } + return; + }, _ => {}, } } diff --git a/src/rust/modrm.rs b/src/rust/modrm.rs index 41a5383a..4cffb346 100644 --- a/src/rust/modrm.rs +++ b/src/rust/modrm.rs @@ -254,9 +254,17 @@ fn can_optimize_get_seg(ctx: &mut JitContext, segment: u32) -> bool { pub fn jit_add_seg_offset(ctx: &mut JitContext, default_segment: u32) { let prefix = ctx.cpu.prefixes & PREFIX_MASK_SEGMENT; - let seg = if prefix != 0 { prefix - 1 } else { default_segment }; - if can_optimize_get_seg(ctx, seg) || prefix == SEG_PREFIX_ZERO { + if prefix == SEG_PREFIX_ZERO { + return; + } + + let seg = if prefix != 0 { prefix - 1 } else { default_segment }; + jit_add_seg_offset_no_override(ctx, seg); +} + +pub fn jit_add_seg_offset_no_override(ctx: &mut JitContext, seg: u32) { + if can_optimize_get_seg(ctx, seg) { codegen::gen_profiler_stat_increment(ctx.builder, profiler::stat::SEG_OFFSET_OPTIMISED); return; }