add gen_push16_ss{16,32}

This adds the ImmVal enum type too.
This commit is contained in:
Awal Garg 2018-08-17 20:58:44 +05:30 committed by Fabian
parent 8da18d339e
commit 5c2ab56b3b
3 changed files with 109 additions and 16 deletions

View file

@ -1,4 +1,4 @@
use cpu::BitSize;
use cpu::{BitSize, ImmVal};
use global_pointers;
use jit::JitContext;
use modrm;
@ -608,3 +608,91 @@ pub fn gen_task_switch_test_mmx(ctx: &mut JitContext) {
ctx.builder.instruction_body.block_end();
}
pub fn gen_push16_ss16(ctx: &mut JitContext, imm: ImmVal) {
match imm {
ImmVal::REG(r) => {
ctx.builder
.instruction_body
.load_aligned_u16(global_pointers::get_reg16_offset(r));
},
ImmVal::CONST(imm) => {
ctx.builder.instruction_body.push_i32(imm as i32);
},
ImmVal::MEM => {
// NOTE: It's important that this match stays atop so gen_safe_read16 gets called early enough
gen_safe_read16(ctx);
},
};
let value_local = ctx.builder.set_new_local();
ctx.builder
.instruction_body
.load_aligned_i32(global_pointers::get_reg16_offset(regs::SP));
ctx.builder.instruction_body.push_i32(2);
ctx.builder.instruction_body.sub_i32();
let reg16_updated_local = ctx.builder.tee_new_local();
ctx.builder.instruction_body.push_i32(0xFFFF);
ctx.builder.instruction_body.and_i32();
if !ctx.cpu.has_flat_segmentation() {
ctx.builder
.instruction_body
.load_aligned_i32(global_pointers::get_seg_offset(regs::SS));
ctx.builder.instruction_body.add_i32();
}
let sp_local = ctx.builder.set_new_local();
gen_safe_write16(ctx, &sp_local, &value_local);
ctx.builder.free_local(sp_local);
ctx.builder.free_local(value_local);
ctx.builder
.instruction_body
.push_i32(global_pointers::get_reg16_offset(regs::SP) as i32);
ctx.builder.instruction_body.get_local(&reg16_updated_local);
ctx.builder.instruction_body.store_aligned_u16();
ctx.builder.free_local(reg16_updated_local);
}
pub fn gen_push16_ss32(ctx: &mut JitContext, imm: ImmVal) {
match imm {
ImmVal::REG(r) => {
ctx.builder
.instruction_body
.load_aligned_u16(global_pointers::get_reg16_offset(r));
},
ImmVal::CONST(imm) => {
ctx.builder.instruction_body.push_i32(imm as i32);
},
ImmVal::MEM => {
// NOTE: It's important that this match stays atop so gen_safe_read16 gets called early enough
gen_safe_read16(ctx);
},
};
let value_local = ctx.builder.set_new_local();
ctx.builder
.instruction_body
.load_aligned_i32(global_pointers::get_reg32_offset(regs::ESP));
ctx.builder.instruction_body.push_i32(2);
ctx.builder.instruction_body.sub_i32();
let reg32_updated_local = ctx.builder.tee_new_local();
if !ctx.cpu.has_flat_segmentation() {
ctx.builder
.instruction_body
.load_aligned_i32(global_pointers::get_seg_offset(regs::SS));
ctx.builder.instruction_body.add_i32();
}
let sp_local = ctx.builder.set_new_local();
gen_safe_write16(ctx, &sp_local, &value_local);
ctx.builder.free_local(sp_local);
ctx.builder.free_local(value_local);
ctx.builder
.instruction_body
.push_i32(global_pointers::get_reg32_offset(regs::ESP) as i32);
ctx.builder.instruction_body.get_local(&reg32_updated_local);
ctx.builder.instruction_body.store_aligned_i32();
ctx.builder.free_local(reg32_updated_local);
}

View file

@ -27,6 +27,13 @@ pub enum BitSize {
DWORD,
}
#[derive(Copy, Clone, Eq, PartialEq)]
pub enum ImmVal {
REG(u32),
CONST(u32),
MEM,
}
pub fn read8(addr: u32) -> u8 { unsafe { unsafe_cpu::read8(addr) } }
pub fn read16(addr: u32) -> u16 { unsafe { unsafe_cpu::read16(addr) } }
pub fn read32(addr: u32) -> u32 { unsafe { unsafe_cpu::read32(addr) } }

View file

@ -1,6 +1,7 @@
#![allow(non_snake_case)]
use codegen;
use cpu::ImmVal;
use cpu_context::CpuContext;
use global_pointers;
use jit::JitContext;
@ -96,13 +97,12 @@ pub fn instr_F3_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
}
fn push16_reg_jit(ctx: &mut JitContext, r: u32) {
let name = if ctx.cpu.ssize_32() {
"push16_ss32"
if ctx.cpu.ssize_32() {
codegen::gen_push16_ss32(ctx, ImmVal::REG(r));
}
else {
"push16_ss16"
};
codegen::gen_fn1_reg16(ctx, name, r);
codegen::gen_push16_ss16(ctx, ImmVal::REG(r));
}
}
fn push32_reg_jit(ctx: &mut JitContext, r: u32) {
@ -116,13 +116,12 @@ fn push32_reg_jit(ctx: &mut JitContext, r: u32) {
}
fn push16_imm_jit(ctx: &mut JitContext, imm: u32) {
let name = if ctx.cpu.ssize_32() {
"push16_ss32"
if ctx.cpu.ssize_32() {
codegen::gen_push16_ss32(ctx, ImmVal::CONST(imm));
}
else {
"push16_ss16"
};
codegen::gen_fn1_const(ctx, name, imm)
codegen::gen_push16_ss16(ctx, ImmVal::CONST(imm));
}
}
fn push32_imm_jit(ctx: &mut JitContext, imm: u32) {
@ -137,13 +136,12 @@ fn push32_imm_jit(ctx: &mut JitContext, imm: u32) {
fn push16_mem_jit(ctx: &mut JitContext, modrm_byte: u8) {
codegen::gen_modrm_resolve(ctx, modrm_byte);
let name = if ctx.cpu.ssize_32() {
"push16_ss32_mem"
if ctx.cpu.ssize_32() {
codegen::gen_push16_ss32(ctx, ImmVal::MEM);
}
else {
"push16_ss16_mem"
};
codegen::gen_modrm_fn0(ctx, name)
codegen::gen_push16_ss16(ctx, ImmVal::MEM);
}
}
fn push32_mem_jit(ctx: &mut JitContext, modrm_byte: u8) {