Fix 8-bit jumps in 16-bit mode
This commit is contained in:
parent
c40a5ccf25
commit
9b2b3250df
|
@ -168,10 +168,10 @@ const encodings = [
|
|||
// loop, jcxz, etc.
|
||||
// Conditional jumps, but condition code not supported by code generator
|
||||
// (these are never generated by modern compilers)
|
||||
{ opcode: 0xE0, imm8s: 1, skip: 1, block_boundary: 1, /* jump_offset_imm: 1, conditional_jump: 1, */ },
|
||||
{ opcode: 0xE1, imm8s: 1, skip: 1, block_boundary: 1, /* jump_offset_imm: 1, conditional_jump: 1, */ },
|
||||
{ opcode: 0xE2, imm8s: 1, skip: 1, block_boundary: 1, /* jump_offset_imm: 1, conditional_jump: 1, */ },
|
||||
{ opcode: 0xE3, imm8s: 1, skip: 1, block_boundary: 1, /* jump_offset_imm: 1, conditional_jump: 1, */ },
|
||||
{ opcode: 0xE0, os: 1, imm8s: 1, skip: 1, block_boundary: 1, /* jump_offset_imm: 1, conditional_jump: 1, */ },
|
||||
{ opcode: 0xE1, os: 1, imm8s: 1, skip: 1, block_boundary: 1, /* jump_offset_imm: 1, conditional_jump: 1, */ },
|
||||
{ opcode: 0xE2, os: 1, imm8s: 1, skip: 1, block_boundary: 1, /* jump_offset_imm: 1, conditional_jump: 1, */ },
|
||||
{ opcode: 0xE3, os: 1, imm8s: 1, skip: 1, block_boundary: 1, /* jump_offset_imm: 1, conditional_jump: 1, */ },
|
||||
|
||||
// port functions aren't jumps, but they may modify eip due to how they are implemented
|
||||
{ opcode: 0xE4, block_boundary: 1, imm8: 1, skip: 1, }, // in
|
||||
|
@ -182,7 +182,7 @@ const encodings = [
|
|||
{ opcode: 0xE8, block_boundary: 1, jump_offset_imm: 1, os: 1, imm1632: 1, custom: 1, skip: 1, }, // call
|
||||
{ opcode: 0xE9, block_boundary: 1, jump_offset_imm: 1, no_next_instruction: 1, os: 1, imm1632: 1, custom: 1, skip: 1, },
|
||||
{ opcode: 0xEA, block_boundary: 1, no_next_instruction: 1, os: 1, imm1632: 1, extra_imm16: 1, skip: 1, }, // jmpf
|
||||
{ opcode: 0xEB, block_boundary: 1, jump_offset_imm: 1, no_next_instruction: 1, imm8s: 1, custom: 1, skip: 1, },
|
||||
{ opcode: 0xEB, block_boundary: 1, jump_offset_imm: 1, no_next_instruction: 1, os: 1, imm8s: 1, custom: 1, skip: 1, },
|
||||
|
||||
{ opcode: 0xEC, block_boundary: 1, skip: 1, }, // in
|
||||
{ opcode: 0xED, block_boundary: 1, os: 1, skip: 1, },
|
||||
|
@ -704,8 +704,8 @@ for(let i = 0; i < 8; i++)
|
|||
{ opcode: 0x04 | i << 3, nonfaulting: 1, eax: 1, imm8: 1, },
|
||||
{ opcode: 0x05 | i << 3, nonfaulting: 1, os: 1, eax: 1, imm1632: 1, },
|
||||
|
||||
{ opcode: 0x70 | i, block_boundary: 1, jump_offset_imm: 1, conditional_jump: 1, imm8s: 1, custom: 1, skip: 1, },
|
||||
{ opcode: 0x78 | i, block_boundary: 1, jump_offset_imm: 1, conditional_jump: 1, imm8s: 1, custom: 1, skip: 1, },
|
||||
{ opcode: 0x70 | i, block_boundary: 1, jump_offset_imm: 1, conditional_jump: 1, os: 1, imm8s: 1, custom: 1, skip: 1, },
|
||||
{ opcode: 0x78 | i, block_boundary: 1, jump_offset_imm: 1, conditional_jump: 1, os: 1, imm8s: 1, custom: 1, skip: 1, },
|
||||
|
||||
{ opcode: 0x80, nonfaulting: 1, e: 1, fixed_g: i, imm8: 1, },
|
||||
{ opcode: 0x81, nonfaulting: 1, os: 1, e: 1, fixed_g: i, imm1632: 1, },
|
||||
|
|
|
@ -371,39 +371,73 @@ void instr_6E() { outsb(); }
|
|||
void instr16_6F() { outsw(); }
|
||||
void instr32_6F() { outsd(); }
|
||||
|
||||
void instr_70(int32_t imm8) { jmpcc8( test_o(), imm8); }
|
||||
void instr_71(int32_t imm8) { jmpcc8(!test_o(), imm8); }
|
||||
void instr_72(int32_t imm8) { jmpcc8( test_b(), imm8); }
|
||||
void instr_73(int32_t imm8) { jmpcc8(!test_b(), imm8); }
|
||||
void instr_74(int32_t imm8) { jmpcc8( test_z(), imm8); }
|
||||
void instr_75(int32_t imm8) { jmpcc8(!test_z(), imm8); }
|
||||
void instr_76(int32_t imm8) { jmpcc8( test_be(), imm8); }
|
||||
void instr_77(int32_t imm8) { jmpcc8(!test_be(), imm8); }
|
||||
void instr_78(int32_t imm8) { jmpcc8( test_s(), imm8); }
|
||||
void instr_79(int32_t imm8) { jmpcc8(!test_s(), imm8); }
|
||||
void instr_7A(int32_t imm8) { jmpcc8( test_p(), imm8); }
|
||||
void instr_7B(int32_t imm8) { jmpcc8(!test_p(), imm8); }
|
||||
void instr_7C(int32_t imm8) { jmpcc8( test_l(), imm8); }
|
||||
void instr_7D(int32_t imm8) { jmpcc8(!test_l(), imm8); }
|
||||
void instr_7E(int32_t imm8) { jmpcc8( test_le(), imm8); }
|
||||
void instr_7F(int32_t imm8) { jmpcc8(!test_le(), imm8); }
|
||||
void instr16_70(int32_t imm8) { jmpcc16( test_o(), imm8); }
|
||||
void instr16_71(int32_t imm8) { jmpcc16(!test_o(), imm8); }
|
||||
void instr16_72(int32_t imm8) { jmpcc16( test_b(), imm8); }
|
||||
void instr16_73(int32_t imm8) { jmpcc16(!test_b(), imm8); }
|
||||
void instr16_74(int32_t imm8) { jmpcc16( test_z(), imm8); }
|
||||
void instr16_75(int32_t imm8) { jmpcc16(!test_z(), imm8); }
|
||||
void instr16_76(int32_t imm8) { jmpcc16( test_be(), imm8); }
|
||||
void instr16_77(int32_t imm8) { jmpcc16(!test_be(), imm8); }
|
||||
void instr16_78(int32_t imm8) { jmpcc16( test_s(), imm8); }
|
||||
void instr16_79(int32_t imm8) { jmpcc16(!test_s(), imm8); }
|
||||
void instr16_7A(int32_t imm8) { jmpcc16( test_p(), imm8); }
|
||||
void instr16_7B(int32_t imm8) { jmpcc16(!test_p(), imm8); }
|
||||
void instr16_7C(int32_t imm8) { jmpcc16( test_l(), imm8); }
|
||||
void instr16_7D(int32_t imm8) { jmpcc16(!test_l(), imm8); }
|
||||
void instr16_7E(int32_t imm8) { jmpcc16( test_le(), imm8); }
|
||||
void instr16_7F(int32_t imm8) { jmpcc16(!test_le(), imm8); }
|
||||
|
||||
void instr_70_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_o"); }
|
||||
void instr_71_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_no"); }
|
||||
void instr_72_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_b"); }
|
||||
void instr_73_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_nb"); }
|
||||
void instr_74_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_z"); }
|
||||
void instr_75_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_nz"); }
|
||||
void instr_76_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_be"); }
|
||||
void instr_77_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_nbe"); }
|
||||
void instr_78_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_s"); }
|
||||
void instr_79_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_ns"); }
|
||||
void instr_7A_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_p"); }
|
||||
void instr_7B_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_np"); }
|
||||
void instr_7C_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_l"); }
|
||||
void instr_7D_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_nl"); }
|
||||
void instr_7E_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_le"); }
|
||||
void instr_7F_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_nle"); }
|
||||
void instr32_70(int32_t imm8) { jmpcc32( test_o(), imm8); }
|
||||
void instr32_71(int32_t imm8) { jmpcc32(!test_o(), imm8); }
|
||||
void instr32_72(int32_t imm8) { jmpcc32( test_b(), imm8); }
|
||||
void instr32_73(int32_t imm8) { jmpcc32(!test_b(), imm8); }
|
||||
void instr32_74(int32_t imm8) { jmpcc32( test_z(), imm8); }
|
||||
void instr32_75(int32_t imm8) { jmpcc32(!test_z(), imm8); }
|
||||
void instr32_76(int32_t imm8) { jmpcc32( test_be(), imm8); }
|
||||
void instr32_77(int32_t imm8) { jmpcc32(!test_be(), imm8); }
|
||||
void instr32_78(int32_t imm8) { jmpcc32( test_s(), imm8); }
|
||||
void instr32_79(int32_t imm8) { jmpcc32(!test_s(), imm8); }
|
||||
void instr32_7A(int32_t imm8) { jmpcc32( test_p(), imm8); }
|
||||
void instr32_7B(int32_t imm8) { jmpcc32(!test_p(), imm8); }
|
||||
void instr32_7C(int32_t imm8) { jmpcc32( test_l(), imm8); }
|
||||
void instr32_7D(int32_t imm8) { jmpcc32(!test_l(), imm8); }
|
||||
void instr32_7E(int32_t imm8) { jmpcc32( test_le(), imm8); }
|
||||
void instr32_7F(int32_t imm8) { jmpcc32(!test_le(), imm8); }
|
||||
|
||||
void instr16_70_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_o"); }
|
||||
void instr16_71_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_no"); }
|
||||
void instr16_72_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_b"); }
|
||||
void instr16_73_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_nb"); }
|
||||
void instr16_74_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_z"); }
|
||||
void instr16_75_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_nz"); }
|
||||
void instr16_76_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_be"); }
|
||||
void instr16_77_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_nbe"); }
|
||||
void instr16_78_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_s"); }
|
||||
void instr16_79_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_ns"); }
|
||||
void instr16_7A_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_p"); }
|
||||
void instr16_7B_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_np"); }
|
||||
void instr16_7C_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_l"); }
|
||||
void instr16_7D_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_nl"); }
|
||||
void instr16_7E_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_le"); }
|
||||
void instr16_7F_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_nle"); }
|
||||
|
||||
void instr32_70_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_o"); }
|
||||
void instr32_71_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_no"); }
|
||||
void instr32_72_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_b"); }
|
||||
void instr32_73_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_nb"); }
|
||||
void instr32_74_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_z"); }
|
||||
void instr32_75_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_nz"); }
|
||||
void instr32_76_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_be"); }
|
||||
void instr32_77_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_nbe"); }
|
||||
void instr32_78_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_s"); }
|
||||
void instr32_79_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_ns"); }
|
||||
void instr32_7A_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_p"); }
|
||||
void instr32_7B_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_np"); }
|
||||
void instr32_7C_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_l"); }
|
||||
void instr32_7D_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_nl"); }
|
||||
void instr32_7E_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_le"); }
|
||||
void instr32_7F_jit(int32_t imm8) { jit_link_block_conditional(imm8, "test_nle"); }
|
||||
|
||||
DEFINE_MODRM_INSTR2_READ_WRITE_8(instr_80_0, add8(___, imm))
|
||||
DEFINE_MODRM_INSTR2_READ_WRITE_8(instr_80_1, or8(___, imm))
|
||||
|
@ -1413,10 +1447,15 @@ void instr_DF_5_reg(int32_t r) { task_switch_test(); fpu_fucomip(r); }
|
|||
void instr_DF_6_reg(int32_t r) { task_switch_test(); fpu_fcomip(r); }
|
||||
void instr_DF_7_reg(int32_t r) { trigger_ud(); }
|
||||
|
||||
void instr_E0(int32_t off) { loopne(off); }
|
||||
void instr_E1(int32_t off) { loope(off); }
|
||||
void instr_E2(int32_t off) { loop(off); }
|
||||
void instr_E3(int32_t off) { jcxz(off); }
|
||||
void instr16_E0(int32_t imm8s) { loopne16(imm8s); }
|
||||
void instr16_E1(int32_t imm8s) { loope16(imm8s); }
|
||||
void instr16_E2(int32_t imm8s) { loop16(imm8s); }
|
||||
void instr16_E3(int32_t imm8s) { jcxz16(imm8s); }
|
||||
|
||||
void instr32_E0(int32_t imm8s) { loopne32(imm8s); }
|
||||
void instr32_E1(int32_t imm8s) { loope32(imm8s); }
|
||||
void instr32_E2(int32_t imm8s) { loop32(imm8s); }
|
||||
void instr32_E3(int32_t imm8s) { jcxz32(imm8s); }
|
||||
|
||||
void instr_E4(int32_t port) {
|
||||
test_privileges_for_io(port, 1);
|
||||
|
@ -1491,14 +1530,22 @@ void instr32_EA(int32_t new_ip, int32_t cs) {
|
|||
dbg_assert(is_asize_32() || get_real_eip() < 0x10000);
|
||||
}
|
||||
|
||||
void instr_EB(int32_t imm8) {
|
||||
void instr16_EB(int32_t imm8) {
|
||||
// jmp near
|
||||
jmp_rel16(imm8);
|
||||
dbg_assert(is_asize_32() || get_real_eip() < 0x10000);
|
||||
}
|
||||
void instr32_EB(int32_t imm8) {
|
||||
// jmp near
|
||||
instruction_pointer[0] = instruction_pointer[0] + imm8;
|
||||
dbg_assert(is_asize_32() || get_real_eip() < 0x10000);
|
||||
}
|
||||
|
||||
void instr_EB_jit(int32_t imm8s) {
|
||||
gen_fn1_const("instr_EB", 8, imm8s);
|
||||
void instr16_EB_jit(int32_t imm8s) {
|
||||
gen_fn1_const("instr16_EB", 10, imm8s);
|
||||
}
|
||||
void instr32_EB_jit(int32_t imm8s) {
|
||||
gen_fn1_const("instr32_EB", 10, imm8s);
|
||||
}
|
||||
|
||||
void instr_EC() {
|
||||
|
|
|
@ -112,14 +112,6 @@ void jmp_rel16(int32_t rel16)
|
|||
*instruction_pointer = cs_offset + ((*instruction_pointer - cs_offset + rel16) & 0xFFFF);
|
||||
}
|
||||
|
||||
void jmpcc8(bool condition, int32_t imm8)
|
||||
{
|
||||
if(condition)
|
||||
{
|
||||
*instruction_pointer += imm8;
|
||||
}
|
||||
}
|
||||
|
||||
void jmpcc16(bool condition, int32_t imm16)
|
||||
{
|
||||
if(condition)
|
||||
|
@ -136,38 +128,15 @@ void jmpcc32(bool condition, int32_t imm32)
|
|||
}
|
||||
}
|
||||
|
||||
void loopne(int32_t imm8s)
|
||||
{
|
||||
if(decr_ecx_asize() && !getzf())
|
||||
{
|
||||
instruction_pointer[0] = instruction_pointer[0] + imm8s;
|
||||
}
|
||||
}
|
||||
|
||||
void loope(int32_t imm8s)
|
||||
{
|
||||
if(decr_ecx_asize() && getzf())
|
||||
{
|
||||
instruction_pointer[0] = instruction_pointer[0] + imm8s;
|
||||
}
|
||||
}
|
||||
|
||||
void loop(int32_t imm8s)
|
||||
{
|
||||
if(decr_ecx_asize())
|
||||
{
|
||||
instruction_pointer[0] = instruction_pointer[0] + imm8s;
|
||||
}
|
||||
}
|
||||
|
||||
void jcxz(int32_t imm8s)
|
||||
{
|
||||
if(get_reg_asize(ECX) == 0)
|
||||
{
|
||||
instruction_pointer[0] = instruction_pointer[0] + imm8s;
|
||||
}
|
||||
}
|
||||
void loopne16(int32_t imm8s) { jmpcc16(decr_ecx_asize() && !getzf(), imm8s); }
|
||||
void loope16(int32_t imm8s) { jmpcc16(decr_ecx_asize() && getzf(), imm8s); }
|
||||
void loop16(int32_t imm8s) { jmpcc16(decr_ecx_asize(), imm8s); }
|
||||
void jcxz16(int32_t imm8s) { jmpcc16(get_reg_asize(ECX) == 0, imm8s); }
|
||||
|
||||
void loopne32(int32_t imm8s) { jmpcc32(decr_ecx_asize() && !getzf(), imm8s); }
|
||||
void loope32(int32_t imm8s) { jmpcc32(decr_ecx_asize() && getzf(), imm8s); }
|
||||
void loop32(int32_t imm8s) { jmpcc32(decr_ecx_asize(), imm8s); }
|
||||
void jcxz32(int32_t imm8s) { jmpcc32(get_reg_asize(ECX) == 0, imm8s); }
|
||||
|
||||
void cmovcc16(bool condition, int32_t value, int32_t r)
|
||||
{
|
||||
|
|
|
@ -29,13 +29,17 @@ bool test_nl(void);
|
|||
bool test_nle(void);
|
||||
|
||||
void jmp_rel16(int32_t rel16);
|
||||
void jmpcc8(bool condition, int32_t imm8);
|
||||
void jmpcc16(bool condition, int32_t imm16);
|
||||
void jmpcc32(bool condition, int32_t imm32);
|
||||
void loope(int32_t imm8s);
|
||||
void loopne(int32_t imm8s);
|
||||
void loop(int32_t imm8s);
|
||||
void jcxz(int32_t imm8s);
|
||||
|
||||
void loope16(int32_t imm8s);
|
||||
void loopne16(int32_t imm8s);
|
||||
void loop16(int32_t imm8s);
|
||||
void jcxz16(int32_t imm8s);
|
||||
void loope32(int32_t imm8s);
|
||||
void loopne32(int32_t imm8s);
|
||||
void loop32(int32_t imm8s);
|
||||
void jcxz32(int32_t imm8s);
|
||||
|
||||
void cmovcc16(bool condition, int32_t value, int32_t r);
|
||||
void cmovcc32(bool condition, int32_t value, int32_t r);
|
||||
|
|
Loading…
Reference in a new issue