merge push16_ss* and push32_ss* functions

This commit is contained in:
Awal Garg 2018-08-18 11:10:31 +05:30 committed by Fabian
parent 2f5b1311c6
commit b6aa8efc37
2 changed files with 57 additions and 157 deletions

View file

@ -571,7 +571,16 @@ 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) {
pub fn gen_push16(ctx: &mut JitContext, imm: ImmVal) {
if ctx.cpu.ssize_32() {
gen_push16_ss(ctx, imm, BitSize::DWORD)
}
else {
gen_push16_ss(ctx, imm, BitSize::WORD)
}
}
fn gen_push16_ss(ctx: &mut JitContext, imm: ImmVal, bits: BitSize) {
match imm {
ImmVal::REG(r) => {
ctx.builder
@ -588,57 +597,19 @@ pub fn gen_push16_ss16(ctx: &mut JitContext, imm: ImmVal) {
};
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 sp_reg = match bits {
BitSize::WORD => global_pointers::get_reg16_offset(regs::SP),
BitSize::DWORD => global_pointers::get_reg32_offset(regs::ESP),
};
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.load_aligned_i32(sp_reg);
ctx.builder.instruction_body.push_i32(2);
ctx.builder.instruction_body.sub_i32();
let reg32_updated_local = ctx.builder.tee_new_local();
let reg_updated_local = ctx.builder.tee_new_local();
if bits == BitSize::WORD {
ctx.builder.instruction_body.push_i32(0xFFFF);
ctx.builder.instruction_body.and_i32();
}
if !ctx.cpu.has_flat_segmentation() {
ctx.builder
@ -651,15 +622,25 @@ pub fn gen_push16_ss32(ctx: &mut JitContext, imm: ImmVal) {
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);
ctx.builder.instruction_body.push_i32(sp_reg as i32);
ctx.builder.instruction_body.get_local(&reg_updated_local);
match bits {
BitSize::WORD => ctx.builder.instruction_body.store_aligned_u16(),
BitSize::DWORD => ctx.builder.instruction_body.store_aligned_i32(),
};
ctx.builder.free_local(reg_updated_local);
}
pub fn gen_push32_ss16(ctx: &mut JitContext, imm: ImmVal) {
pub fn gen_push32(ctx: &mut JitContext, imm: ImmVal) {
if ctx.cpu.ssize_32() {
gen_push32_ss(ctx, imm, BitSize::DWORD)
}
else {
gen_push32_ss(ctx, imm, BitSize::WORD)
}
}
fn gen_push32_ss(ctx: &mut JitContext, imm: ImmVal, bits: BitSize) {
match imm {
ImmVal::REG(r) => {
ctx.builder
@ -675,13 +656,18 @@ pub fn gen_push32_ss16(ctx: &mut JitContext, imm: ImmVal) {
};
let value_local = ctx.builder.set_new_local();
ctx.builder
.instruction_body
.load_aligned_u16(global_pointers::get_reg16_offset(regs::SP));
let sp_reg = match bits {
BitSize::WORD => global_pointers::get_reg16_offset(regs::SP),
BitSize::DWORD => global_pointers::get_reg32_offset(regs::ESP),
};
ctx.builder.instruction_body.load_aligned_i32(sp_reg);
ctx.builder.instruction_body.push_i32(4);
ctx.builder.instruction_body.sub_i32();
ctx.builder.instruction_body.push_i32(0xFFFF);
ctx.builder.instruction_body.and_i32();
if bits == BitSize::WORD {
ctx.builder.instruction_body.push_i32(0xFFFF);
ctx.builder.instruction_body.and_i32();
}
let new_sp_local = ctx.builder.tee_new_local();
if !ctx.cpu.has_flat_segmentation() {
@ -697,56 +683,13 @@ pub fn gen_push32_ss16(ctx: &mut JitContext, imm: ImmVal) {
ctx.builder.free_local(value_local);
ctx.builder.free_local(sp_local);
ctx.builder
.instruction_body
.push_i32(global_pointers::get_reg16_offset(regs::SP) as i32);
ctx.builder.instruction_body.push_i32(sp_reg as i32);
ctx.builder.instruction_body.get_local(&new_sp_local);
ctx.builder.instruction_body.store_aligned_u16();
ctx.builder.free_local(new_sp_local);
}
pub fn gen_push32_ss32(ctx: &mut JitContext, imm: ImmVal) {
match imm {
ImmVal::REG(r) => {
ctx.builder
.instruction_body
.load_aligned_i32(global_pointers::get_reg32_offset(r));
},
ImmVal::CONST(imm) => {
ctx.builder.instruction_body.push_i32(imm as i32);
},
ImmVal::MEM => {
gen_safe_read32(ctx);
},
match bits {
BitSize::WORD => ctx.builder.instruction_body.store_aligned_u16(),
BitSize::DWORD => ctx.builder.instruction_body.store_aligned_i32(),
};
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(4);
ctx.builder.instruction_body.sub_i32();
let new_esp_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_write32(ctx, &sp_local, &value_local);
ctx.builder.free_local(value_local);
ctx.builder.free_local(sp_local);
ctx.builder
.instruction_body
.push_i32(global_pointers::get_reg32_offset(regs::ESP) as i32);
ctx.builder.instruction_body.get_local(&new_esp_local);
ctx.builder.instruction_body.store_aligned_i32();
ctx.builder.free_local(new_esp_local);
ctx.builder.free_local(new_sp_local);
}
fn gen_safe_read_write(

View file

@ -96,60 +96,17 @@ pub fn instr_F3_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
jit_handle_prefix(ctx, instr_flags)
}
fn push16_reg_jit(ctx: &mut JitContext, r: u32) {
if ctx.cpu.ssize_32() {
codegen::gen_push16_ss32(ctx, ImmVal::REG(r));
}
else {
codegen::gen_push16_ss16(ctx, ImmVal::REG(r));
}
}
fn push32_reg_jit(ctx: &mut JitContext, r: u32) {
if ctx.cpu.ssize_32() {
codegen::gen_push32_ss32(ctx, ImmVal::REG(r));
}
else {
codegen::gen_push32_ss16(ctx, ImmVal::REG(r));
}
}
fn push16_imm_jit(ctx: &mut JitContext, imm: u32) {
if ctx.cpu.ssize_32() {
codegen::gen_push16_ss32(ctx, ImmVal::CONST(imm));
}
else {
codegen::gen_push16_ss16(ctx, ImmVal::CONST(imm));
}
}
fn push32_imm_jit(ctx: &mut JitContext, imm: u32) {
if ctx.cpu.ssize_32() {
codegen::gen_push32_ss32(ctx, ImmVal::CONST(imm));
}
else {
codegen::gen_push32_ss16(ctx, ImmVal::CONST(imm));
}
}
fn push16_reg_jit(ctx: &mut JitContext, r: u32) { codegen::gen_push16(ctx, ImmVal::REG(r)); }
fn push32_reg_jit(ctx: &mut JitContext, r: u32) { codegen::gen_push32(ctx, ImmVal::REG(r)); }
fn push16_imm_jit(ctx: &mut JitContext, imm: u32) { codegen::gen_push16(ctx, ImmVal::CONST(imm)); }
fn push32_imm_jit(ctx: &mut JitContext, imm: u32) { codegen::gen_push32(ctx, ImmVal::CONST(imm)); }
fn push16_mem_jit(ctx: &mut JitContext, modrm_byte: u8) {
codegen::gen_modrm_resolve(ctx, modrm_byte);
if ctx.cpu.ssize_32() {
codegen::gen_push16_ss32(ctx, ImmVal::MEM);
}
else {
codegen::gen_push16_ss16(ctx, ImmVal::MEM);
}
codegen::gen_push16(ctx, ImmVal::MEM);
}
fn push32_mem_jit(ctx: &mut JitContext, modrm_byte: u8) {
codegen::gen_modrm_resolve(ctx, modrm_byte);
if ctx.cpu.ssize_32() {
codegen::gen_push32_ss32(ctx, ImmVal::MEM);
}
else {
codegen::gen_push32_ss16(ctx, ImmVal::MEM);
}
codegen::gen_push32(ctx, ImmVal::MEM);
}
fn pop16_reg_jit(ctx: &mut JitContext, reg: u32) {