jit stosb/stosw/stosd

This commit is contained in:
Fabian 2021-04-09 21:52:00 -05:00
parent 4de8584cff
commit 6049e0c46c
3 changed files with 35 additions and 5 deletions

View file

@ -232,10 +232,10 @@ const encodings = [
{ opcode: 0xA8, custom: 1, imm8: 1, },
{ opcode: 0xA9, custom: 1, os: 1, imm1632: 1, },
{ opcode: 0xAA, block_boundary: 1, custom: 1, is_string: 1, },
{ opcode: 0xAA, block_boundary: 0, custom: 1, is_string: 1, },
{ opcode: 0xF2AA, block_boundary: 1, custom: 1, is_string: 1, },
{ opcode: 0xF3AA, block_boundary: 1, custom: 1, is_string: 1, },
{ opcode: 0xAB, block_boundary: 1, custom: 1, is_string: 1, os: 1, },
{ opcode: 0xAB, block_boundary: 0, custom: 1, is_string: 1, os: 1, },
{ opcode: 0xF2AB, block_boundary: 1, custom: 1, is_string: 1, os: 1, },
{ opcode: 0xF3AB, block_boundary: 1, custom: 1, is_string: 1, os: 1, },

View file

@ -517,15 +517,12 @@ pub unsafe fn stosw_rep(is_asize_32: bool) {
pub unsafe fn stosd_rep(is_asize_32: bool) {
string_instruction(is_asize_32, 0, Instruction::Stos, Size::D, Rep::Z)
}
#[no_mangle]
pub unsafe fn stosb_no_rep(is_asize_32: bool) {
string_instruction(is_asize_32, 0, Instruction::Stos, Size::B, Rep::None)
}
#[no_mangle]
pub unsafe fn stosw_no_rep(is_asize_32: bool) {
string_instruction(is_asize_32, 0, Instruction::Stos, Size::W, Rep::None)
}
#[no_mangle]
pub unsafe fn stosd_no_rep(is_asize_32: bool) {
string_instruction(is_asize_32, 0, Instruction::Stos, Size::D, Rep::None)
}

View file

@ -4557,6 +4557,39 @@ fn gen_string_ins(ctx: &mut JitContext, ins: String, size: u8, prefix: u8) {
}
return;
},
String::STOS => {
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();
if size == 8 {
codegen::gen_safe_write8(ctx, &address_local, &ctx.reg(regs::AL));
ctx.builder.free_local(address_local);
}
else if size == 16 {
codegen::gen_safe_write16(ctx, &address_local, &ctx.reg(regs::AX));
ctx.builder.free_local(address_local);
}
else {
codegen::gen_safe_write32(ctx, &address_local, &ctx.reg(regs::EAX));
ctx.builder.free_local(address_local);
}
codegen::gen_get_reg32(ctx, regs::EDI);
get_direction(ctx, size);
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;
},
_ => {},
}
}