add gen_push16_ss{16,32}
This adds the ImmVal enum type too.
This commit is contained in:
parent
8da18d339e
commit
5c2ab56b3b
|
@ -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(®16_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(®32_updated_local);
|
||||
ctx.builder.instruction_body.store_aligned_i32();
|
||||
ctx.builder.free_local(reg32_updated_local);
|
||||
}
|
||||
|
|
|
@ -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) } }
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue