jit: Inline 0x89 and 0x8b opcodes's reg variants
This commit is contained in:
parent
7fec029937
commit
2128f07796
|
@ -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
|
||||
|
|
|
@ -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) ®16[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) ®32s[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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue