jit: Inline 0x89 and 0x8b opcodes's reg variants

This commit is contained in:
Amaan Cheval 2018-04-18 16:15:42 +05:30 committed by Fabian
parent 7fec029937
commit 2128f07796
4 changed files with 95 additions and 2 deletions

View file

@ -93,9 +93,9 @@ const encodings = [
{ opcode: 0x86, nonfaulting: 1, e: 1, },
{ opcode: 0x87, nonfaulting: 1, os: 1, e: 1, },
{ opcode: 0x88, nonfaulting: 1, e: 1, },
{ opcode: 0x89, nonfaulting: 1, os: 1, e: 1, },
{ opcode: 0x89, custom: 1, nonfaulting: 1, os: 1, e: 1, },
{ opcode: 0x8A, nonfaulting: 1, e: 1, },
{ opcode: 0x8B, nonfaulting: 1, os: 1, e: 1, },
{ opcode: 0x8B, custom: 1, nonfaulting: 1, os: 1, e: 1, },
{ opcode: 0x8C, os: 1, e: 1, skip: 1, },
{ opcode: 0x8D, nonfaulting: 1, os: 1, e: 1, only_mem: 1, requires_prefix_call: 1, custom: 1, }, // lea

View file

@ -209,6 +209,20 @@ void gen_reg32s_eq_fn0(char const* fn, uint8_t fn_len, int32_t reg)
store_aligned_i32(&instruction_body);
}
void gen_fn1_ret(char const* fn, uint8_t fn_len, int32_t arg0)
{
int32_t fn_idx = get_fn_index(fn, fn_len, FN1_RET_TYPE_INDEX);
push_i32(&instruction_body, arg0);
call_fn(&instruction_body, fn_idx);
}
void gen_call_fn1_ret(char const* fn, uint8_t fn_len)
{
// generates: fn( _ ) where _ must be left on the stack before calling this, and fn returns a value
int32_t fn_idx = get_fn_index(fn, fn_len, FN1_RET_TYPE_INDEX);
call_fn(&instruction_body, fn_idx);
}
void gen_fn1(char const* fn, uint8_t fn_len, int32_t arg0)
{
int32_t fn_idx = get_fn_index(fn, fn_len, FN1_TYPE_INDEX);
@ -216,6 +230,26 @@ void gen_fn1(char const* fn, uint8_t fn_len, int32_t arg0)
call_fn(&instruction_body, fn_idx);
}
void gen_reg16_eq_fn1(char const* fn, uint8_t fn_len, int32_t arg0, int32_t reg)
{
// generates: reg16[reg] = fn(arg0)
int32_t fn_idx = get_fn_index(fn, fn_len, FN1_RET_TYPE_INDEX);
push_i32(&instruction_body, (int32_t) &reg16[reg]);
push_i32(&instruction_body, arg0);
call_fn(&instruction_body, fn_idx);
store_aligned_u16(&instruction_body);
}
void gen_reg32s_eq_fn1(char const* fn, uint8_t fn_len, int32_t arg0, int32_t reg)
{
// generates: reg32s[reg] = fn(arg0)
int32_t fn_idx = get_fn_index(fn, fn_len, FN1_RET_TYPE_INDEX);
push_i32(&instruction_body, (int32_t) &reg32s[reg]);
push_i32(&instruction_body, arg0);
call_fn(&instruction_body, fn_idx);
store_aligned_i32(&instruction_body);
}
void gen_fn1_reg16(char const* fn, uint8_t fn_len, int32_t reg)
{
// generates: fn(reg16[reg])
@ -232,6 +266,14 @@ void gen_fn1_reg32s(char const* fn, uint8_t fn_len, int32_t reg)
call_fn(&instruction_body, fn_idx);
}
void gen_call_fn2(char const* fn, uint8_t fn_len)
{
// generates: fn( _, _ ) where _ must be left on the stack before calling this
int32_t fn_idx = get_fn_index(fn, fn_len, FN2_TYPE_INDEX);
call_fn(&instruction_body, fn_idx);
}
void gen_fn2(char const* fn, uint8_t fn_len, int32_t arg0, int32_t arg1)
{
int32_t fn_idx = get_fn_index(fn, fn_len, FN2_TYPE_INDEX);

View file

@ -30,12 +30,19 @@ void gen_reg16_eq_fn0(char const* fn, uint8_t fn_len, int32_t reg);
void gen_reg32s_eq_fn0(char const* fn, uint8_t fn_len, int32_t reg);
void gen_fn0(char const* fn, uint8_t fn_len);
void gen_fn1(char const* fn, uint8_t fn_len, int32_t arg0);
void gen_reg16_eq_fn1(char const* fn, uint8_t fn_len, int32_t arg0, int32_t reg);
void gen_reg32s_eq_fn1(char const* fn, uint8_t fn_len, int32_t arg0, int32_t reg);
void gen_fn1_reg16(char const* fn, uint8_t fn_len, int32_t reg);
void gen_fn1_reg32s(char const* fn, uint8_t fn_len, int32_t reg);
void gen_fn2(char const* fn, uint8_t fn_len, int32_t arg0, int32_t arg1);
void gen_fn3(char const* fn, uint8_t fn_len, int32_t arg0, int32_t arg1, int32_t arg2);
void gen_fn0_ret(char const* fn, uint8_t fn_len);
void gen_fn1_ret(char const* fn, uint8_t fn_len, int32_t arg0);
void gen_call_fn1_ret(char const* fn, uint8_t fn_len);
void gen_call_fn2(char const* fn, uint8_t fn_len);
void gen_add_i32(void);
void gen_eqz_i32(void);

View file

@ -480,10 +480,54 @@ void instr16_89_mem(int32_t addr, int32_t r) { safe_write16(addr, read_reg16(r))
void instr32_89_reg(int32_t r2, int32_t r) { write_reg32(r2, read_reg32(r)); }
void instr32_89_mem(int32_t addr, int32_t r) { safe_write32(addr, read_reg32(r)); }
__attribute__((always_inline))
static void gen_mov16_r(int32_t r_src, int32_t r_dest)
{
// Effectively:
// reg16[get_reg16_index(r_dest)] = read_reg16(r_src);
gen_reg16_eq_fn1("read_reg16", 10, r_src, get_reg16_index(r_dest));
}
__attribute__((always_inline))
static void gen_mov32_r(int32_t r_src, int32_t r_dest)
{
// Effectively:
// reg32s[r_dest] = read_reg32(r_src);
gen_reg32s_eq_fn1("read_reg32", 10, r_src, r_dest);
}
void instr16_89_reg_jit(int32_t r_dest, int32_t r_src) { gen_mov16_r(r_src, r_dest); }
void instr32_89_reg_jit(int32_t r_dest, int32_t r_src) { gen_mov32_r(r_src, r_dest); }
void instr16_89_mem_jit(int32_t modrm_byte, int32_t r)
{
// XXX
gen_modrm_resolve(modrm_byte); gen_modrm_fn1("instr16_89_mem", 14, modrm_byte >> 3 & 7);
}
void instr32_89_mem_jit(int32_t modrm_byte, int32_t r)
{
// XXX
gen_modrm_resolve(modrm_byte); gen_modrm_fn1("instr32_89_mem", 14, modrm_byte >> 3 & 7);
}
DEFINE_MODRM_INSTR_READ8(instr_8A, write_reg8(r, ___))
DEFINE_MODRM_INSTR_READ16(instr16_8B, write_reg16(r, ___))
DEFINE_MODRM_INSTR_READ32(instr32_8B, write_reg32(r, ___))
void instr16_8B_reg_jit(int32_t r_src, int32_t r_dest) { gen_mov16_r(r_src, r_dest); }
void instr32_8B_reg_jit(int32_t r_src, int32_t r_dest) { gen_mov32_r(r_src, r_dest); }
void instr16_8B_mem_jit(int32_t modrm_byte, int32_t r)
{
// XXX
gen_modrm_resolve(modrm_byte); gen_modrm_fn1("instr16_8B_mem", 14, modrm_byte >> 3 & 7);
}
void instr32_8B_mem_jit(int32_t modrm_byte, int32_t r)
{
// XXX
gen_modrm_resolve(modrm_byte); gen_modrm_fn1("instr32_8B_mem", 14, modrm_byte >> 3 & 7);
}
void instr_8C_check_sreg(int32_t sreg) {
if(sreg >= 6)
{