Remove use of raising cpu exceptions for trigger_ud
This commit is contained in:
parent
77525ef4ac
commit
70ae4b720a
|
@ -199,7 +199,8 @@ function gen_instruction_body_after_prefix(encodings, size)
|
|||
|
||||
default_case: {
|
||||
body: [].concat(
|
||||
gen_call(`::codegen::gen_fn0_const`, ["ctx", '"trigger_ud"'])
|
||||
gen_call(`::codegen::gen_fn0_const`, ["ctx", '"trigger_ud"']),
|
||||
"*instr_flags |= ::jit::JIT_INSTR_BLOCK_BOUNDARY_FLAG;"
|
||||
),
|
||||
}
|
||||
},
|
||||
|
@ -245,6 +246,20 @@ function gen_instruction_body_after_fixed_g(encoding, size)
|
|||
const reg_postfix = encoding.nonfaulting ? [APPEND_NONFAULTING_FLAG] : [];
|
||||
const mem_postfix = encoding.memory_nonfaulting ? [APPEND_NONFAULTING_FLAG] : [];
|
||||
|
||||
if(encoding.mem_ud)
|
||||
{
|
||||
mem_postfix.push(
|
||||
"*instr_flags |= ::jit::JIT_INSTR_BLOCK_BOUNDARY_FLAG;"
|
||||
);
|
||||
}
|
||||
|
||||
if(encoding.reg_ud)
|
||||
{
|
||||
reg_postfix.push(
|
||||
"*instr_flags |= ::jit::JIT_INSTR_BLOCK_BOUNDARY_FLAG;"
|
||||
);
|
||||
}
|
||||
|
||||
if(encoding.ignore_mod)
|
||||
{
|
||||
console.assert(!imm_read, "Unexpected instruction (ignore mod with immediate value)");
|
||||
|
|
163
gen/x86_table.js
163
gen/x86_table.js
|
@ -72,7 +72,7 @@ const encodings = [
|
|||
{ opcode: 0x60, os: 1, },
|
||||
{ opcode: 0x61, os: 1, },
|
||||
{ opcode: 0x62, e: 1, skip: 1, },
|
||||
{ opcode: 0x63, e: 1, },
|
||||
{ opcode: 0x63, e: 1, block_boundary: 1, }, // arpl
|
||||
{ opcode: 0x64, prefix: 1, },
|
||||
{ opcode: 0x65, prefix: 1, },
|
||||
{ opcode: 0x66, prefix: 1, },
|
||||
|
@ -106,8 +106,8 @@ const encodings = [
|
|||
{ opcode: 0x8A, nonfaulting: 1, e: 1, },
|
||||
{ opcode: 0x8B, custom: 1, nonfaulting: 1, os: 1, e: 1, },
|
||||
|
||||
{ opcode: 0x8C, os: 1, e: 1, skip: 1, },
|
||||
{ opcode: 0x8D, memory_nonfaulting: 1, os: 1, e: 1, only_mem: 1, requires_prefix_call: 1, custom: 1, }, // lea
|
||||
{ opcode: 0x8C, block_boundary: 1, os: 1, e: 1, skip: 1, }, // mov reg, sreg: block_boundary as it can trigger #ud
|
||||
{ opcode: 0x8D, reg_ud: 1, memory_nonfaulting: 1, os: 1, e: 1, requires_prefix_call: 1, custom: 1, }, // lea
|
||||
{ opcode: 0x8E, block_boundary: 1, e: 1, skip: 1, }, // mov sreg
|
||||
{ opcode: 0x8F, os: 1, e: 1, fixed_g: 0, requires_prefix_call: 1, custom: 1, }, // pop r/m
|
||||
|
||||
|
@ -281,29 +281,29 @@ const encodings = [
|
|||
{ opcode: 0x0F01, fixed_g: 6, e: 1, skip: 1, block_boundary: 1, },
|
||||
{ opcode: 0x0F01, fixed_g: 7, e: 1, skip: 1, block_boundary: 1, },
|
||||
|
||||
{ opcode: 0x0F02, os: 1, e: 1, skip: 1 },
|
||||
{ opcode: 0x0F03, os: 1, e: 1, skip: 1 },
|
||||
{ opcode: 0x0F04, skip: 1 },
|
||||
{ opcode: 0x0F05, skip: 1 },
|
||||
{ opcode: 0x0F02, os: 1, e: 1, skip: 1, block_boundary: 1, }, // lar
|
||||
{ opcode: 0x0F03, os: 1, e: 1, skip: 1, block_boundary: 1, }, // lsl
|
||||
{ opcode: 0x0F04, skip: 1, block_boundary: 1, },
|
||||
{ opcode: 0x0F05, skip: 1, block_boundary: 1, },
|
||||
{ opcode: 0x0F06, skip: 1, block_boundary: 1, }, // clts
|
||||
{ opcode: 0x0F07, skip: 1 },
|
||||
{ opcode: 0x0F08, skip: 1 },
|
||||
{ opcode: 0x0F07, skip: 1, block_boundary: 1, },
|
||||
{ opcode: 0x0F08, skip: 1, block_boundary: 1, },
|
||||
{ opcode: 0x0F09, skip: 1, block_boundary: 1, }, // wbinvd
|
||||
{ opcode: 0x0F0A, skip: 1 },
|
||||
{ opcode: 0x0F0A, skip: 1, block_boundary: 1, },
|
||||
// ud2
|
||||
// Technically has a next instruction, but Linux uses this for assertions
|
||||
// and embeds the assertion message after this instruction, which is likely
|
||||
// the most common use case of ud2
|
||||
{ opcode: 0x0F0B, skip: 1, block_boundary: 1, no_next_instruction: 1, },
|
||||
{ opcode: 0x0F0C, skip: 1 },
|
||||
{ opcode: 0x0F0D, skip: 1 },
|
||||
{ opcode: 0x0F0E, skip: 1 },
|
||||
{ opcode: 0x0F0F, skip: 1 },
|
||||
{ opcode: 0x0F0C, skip: 1, block_boundary: 1, },
|
||||
{ opcode: 0x0F0D, skip: 1, block_boundary: 1, },
|
||||
{ opcode: 0x0F0E, skip: 1, block_boundary: 1, },
|
||||
{ opcode: 0x0F0F, skip: 1, block_boundary: 1, },
|
||||
|
||||
{ opcode: 0x0F18, only_mem: 1, e: 1, },
|
||||
{ opcode: 0x0F18, e: 1, },
|
||||
{ opcode: 0x0F19, non_faulting: 1, custom: 1, e: 1, },
|
||||
{ opcode: 0x0F1A, skip: 1, },
|
||||
{ opcode: 0x0F1B, skip: 1, },
|
||||
{ opcode: 0x0F1A, skip: 1, block_boundary: 1, },
|
||||
{ opcode: 0x0F1B, skip: 1, block_boundary: 1, },
|
||||
{ opcode: 0x0F1C, non_faulting: 1, custom: 1, e: 1, },
|
||||
{ opcode: 0x0F1D, non_faulting: 1, custom: 1, e: 1, },
|
||||
{ opcode: 0x0F1E, non_faulting: 1, custom: 1, e: 1, },
|
||||
|
@ -313,18 +313,18 @@ const encodings = [
|
|||
{ opcode: 0x0F21, ignore_mod: 1, e: 1, skip: 1, block_boundary: 1, }, // mov reg, dreg
|
||||
{ opcode: 0x0F22, ignore_mod: 1, e: 1, skip: 1, block_boundary: 1, }, // mov creg, reg
|
||||
{ opcode: 0x0F23, ignore_mod: 1, e: 1, skip: 1, block_boundary: 1, }, // mov dreg, reg
|
||||
{ opcode: 0x0F24, skip: 1 },
|
||||
{ opcode: 0x0F25, skip: 1 },
|
||||
{ opcode: 0x0F26, skip: 1 },
|
||||
{ opcode: 0x0F27, skip: 1 },
|
||||
{ opcode: 0x0F24, skip: 1, block_boundary: 1, },
|
||||
{ opcode: 0x0F25, skip: 1, block_boundary: 1, },
|
||||
{ opcode: 0x0F26, skip: 1, block_boundary: 1, },
|
||||
{ opcode: 0x0F27, skip: 1, block_boundary: 1, },
|
||||
|
||||
{ opcode: 0x0F30, skip: 1, block_boundary: 1, }, // wrmsr
|
||||
{ opcode: 0x0F31, skip: 1, block_boundary: 1, }, // rdtsc
|
||||
{ opcode: 0x0F32, skip: 1, block_boundary: 1, }, // rdmsr
|
||||
{ opcode: 0x0F33, skip: 1 },
|
||||
{ opcode: 0x0F33, skip: 1, }, // rdpmc
|
||||
{ opcode: 0x0F34, skip: 1, block_boundary: 1, no_next_instruction: 1, }, // sysenter
|
||||
{ opcode: 0x0F35, skip: 1, block_boundary: 1, no_next_instruction: 1, }, // sysexit
|
||||
{ opcode: 0x0F36, skip: 1 },
|
||||
{ opcode: 0x0F36, skip: 1, block_boundary: 1, },
|
||||
{ opcode: 0x0F37, skip: 1 },
|
||||
{ opcode: 0x0F38, skip: 1 },
|
||||
{ opcode: 0x0F39, skip: 1 },
|
||||
|
@ -412,27 +412,27 @@ const encodings = [
|
|||
{ opcode: 0x0FAC, nonfaulting: 1, os: 1, e: 1, imm8: 1, mask_flags: af | of, },
|
||||
{ opcode: 0x0FAD, nonfaulting: 1, os: 1, e: 1, mask_flags: af | of, },
|
||||
|
||||
{ opcode: 0x0FA6, skip: 1 },
|
||||
{ opcode: 0x0FA7, skip: 1 },
|
||||
{ opcode: 0x0FA6, skip: 1, block_boundary: 1, }, // ud
|
||||
{ opcode: 0x0FA7, skip: 1, block_boundary: 1, }, // ud
|
||||
|
||||
{ opcode: 0x0FAA, skip: 1 },
|
||||
|
||||
{ opcode: 0x0FAE, e: 1, fixed_g: 0, only_mem: 1, task_switch_test: 1, skip: 1, block_boundary: 1, }, // fxsave
|
||||
{ opcode: 0x0FAE, e: 1, fixed_g: 1, only_mem: 1, task_switch_test: 1, skip: 1, block_boundary: 1, }, // fxrstor: block_boundary since it uses non-raising cpu exceptions
|
||||
{ opcode: 0x0FAE, e: 1, fixed_g: 2, only_mem: 1, sse: 1, skip: 1, block_boundary: 1, }, // ldmxcsr
|
||||
{ opcode: 0x0FAE, e: 1, fixed_g: 3, only_mem: 1, sse: 1, skip: 1, block_boundary: 1, }, // stmxcsr
|
||||
{ opcode: 0x0FAE, e: 1, fixed_g: 4, only_mem: 1, skip: 1, },
|
||||
{ opcode: 0x0FAE, e: 1, fixed_g: 0, reg_ud: 1, task_switch_test: 1, skip: 1, block_boundary: 1, }, // fxsave
|
||||
{ opcode: 0x0FAE, e: 1, fixed_g: 1, reg_ud: 1, task_switch_test: 1, skip: 1, block_boundary: 1, }, // fxrstor
|
||||
{ opcode: 0x0FAE, e: 1, fixed_g: 2, reg_ud: 1, sse: 1, skip: 1, block_boundary: 1, }, // ldmxcsr
|
||||
{ opcode: 0x0FAE, e: 1, fixed_g: 3, reg_ud: 1, sse: 1, skip: 1, block_boundary: 1, }, // stmxcsr
|
||||
|
||||
{ opcode: 0x0FAE, e: 1, fixed_g: 5, only_reg: 1, skip: 1, }, // lfence (reg, only 0), xrstor (mem)
|
||||
{ opcode: 0x0FAE, e: 1, fixed_g: 6, only_reg: 1, skip: 1, }, // mfence (reg, only 0)
|
||||
{ opcode: 0x0FAE, e: 1, fixed_g: 7, only_reg: 1, skip: 1, }, // sfence (reg, only 0), clflush (mem)
|
||||
{ opcode: 0x0FAE, e: 1, fixed_g: 4, reg_ud: 1, skip: 1, block_boundary: 1, }, // xsave (mem, not implemented)
|
||||
{ opcode: 0x0FAE, e: 1, fixed_g: 5, skip: 1, block_boundary: 1, }, // lfence (reg, only 0), xrstor (mem, not implemented)
|
||||
{ opcode: 0x0FAE, e: 1, fixed_g: 6, skip: 1, block_boundary: 1, }, // mfence (reg, only 0), xsaveopt (mem, not implemented)
|
||||
{ opcode: 0x0FAE, e: 1, fixed_g: 7, skip: 1, block_boundary: 1, }, // sfence (reg, only 0), clflush (mem)
|
||||
|
||||
{ opcode: 0x0FAF, nonfaulting: 1, os: 1, e: 1, mask_flags: af | zf }, // imul
|
||||
|
||||
{ opcode: 0x0FB0, nonfaulting: 1, e: 1 }, // cmxchg
|
||||
{ opcode: 0x0FB1, nonfaulting: 1, os: 1, e: 1 },
|
||||
{ opcode: 0x0FC7, e: 1, fixed_g: 1, only_mem: 1, }, // cmpxchg8b (memory)
|
||||
{ opcode: 0x0FC7, e: 1, fixed_g: 6, only_reg: 1, skip: 1, }, // rdrand
|
||||
{ opcode: 0x0FC7, e: 1, fixed_g: 1, reg_ud: 1, }, // cmpxchg8b (memory)
|
||||
{ opcode: 0x0FC7, e: 1, fixed_g: 6, mem_ud: 1, skip: 1, }, // rdrand
|
||||
|
||||
{ opcode: 0x0FB2, block_boundary: 1, os: 1, e: 1, skip: 1, }, // lss
|
||||
{ opcode: 0x0FB4, block_boundary: 1, os: 1, e: 1, skip: 1, }, // lfs
|
||||
|
@ -442,9 +442,9 @@ const encodings = [
|
|||
{ opcode: 0x0FB7, nonfaulting: 1, os: 1, e: 1, },
|
||||
|
||||
{ opcode: 0xF30FB8, os: 1, e: 1 }, // popcnt
|
||||
{ opcode: 0x0FB8, os: 1, e: 1, }, // ud
|
||||
{ opcode: 0x0FB8, os: 1, e: 1, block_boundary: 1, }, // ud
|
||||
|
||||
{ opcode: 0x0FB9, }, // ud2
|
||||
{ opcode: 0x0FB9, block_boundary: 1, }, // ud2
|
||||
|
||||
{ opcode: 0x0FBE, nonfaulting: 1, os: 1, e: 1, }, // movsx
|
||||
{ opcode: 0x0FBF, nonfaulting: 1, os: 1, e: 1, },
|
||||
|
@ -475,20 +475,20 @@ const encodings = [
|
|||
{ sse: 1, opcode: 0x660F11, e: 1 },
|
||||
{ sse: 1, opcode: 0xF20F11, e: 1 },
|
||||
{ sse: 1, opcode: 0x0F12, e: 1 },
|
||||
{ sse: 1, opcode: 0x660F12, only_mem: 1, e: 1 },
|
||||
{ sse: 1, opcode: 0x660F12, reg_ud: 1, e: 1 },
|
||||
{ sse: 1, opcode: 0xF20F12, e: 1, skip: 1, }, // sse3
|
||||
{ sse: 1, opcode: 0xF30F12, e: 1, skip: 1, }, // sse3
|
||||
{ sse: 1, opcode: 0x0F13, only_mem: 1, e: 1 },
|
||||
{ sse: 1, opcode: 0x660F13, only_mem: 1, e: 1 },
|
||||
{ sse: 1, opcode: 0x0F13, reg_ud: 1, e: 1 },
|
||||
{ sse: 1, opcode: 0x660F13, reg_ud: 1, e: 1 },
|
||||
{ sse: 1, opcode: 0x0F14, e: 1 },
|
||||
{ sse: 1, opcode: 0x660F14, e: 1 },
|
||||
{ sse: 1, opcode: 0x0F15, e: 1 },
|
||||
{ sse: 1, opcode: 0x660F15, e: 1 },
|
||||
{ sse: 1, opcode: 0x0F16, e: 1 },
|
||||
{ sse: 1, opcode: 0x660F16, only_mem: 1, e: 1 },
|
||||
{ sse: 1, opcode: 0x660F16, reg_ud: 1, e: 1 },
|
||||
{ sse: 1, opcode: 0xF30F16, skip: 1, }, // sse3
|
||||
{ sse: 1, opcode: 0x0F17, only_mem: 1, e: 1 },
|
||||
{ sse: 1, opcode: 0x660F17, only_mem: 1, e: 1 },
|
||||
{ sse: 1, opcode: 0x0F17, reg_ud: 1, e: 1 },
|
||||
{ sse: 1, opcode: 0x660F17, reg_ud: 1, e: 1 },
|
||||
|
||||
{ sse: 1, opcode: 0x0F28, e: 1 },
|
||||
{ sse: 1, opcode: 0x660F28, e: 1 },
|
||||
|
@ -498,8 +498,8 @@ const encodings = [
|
|||
{ sse: 1, opcode: 0x660F2A, e: 1, },
|
||||
{ sse: 1, opcode: 0xF20F2A, e: 1, },
|
||||
{ sse: 1, opcode: 0xF30F2A, e: 1, },
|
||||
{ sse: 1, opcode: 0x0F2B, only_mem: 1, e: 1 },
|
||||
{ sse: 1, opcode: 0x660F2B, only_mem: 1, e: 1 },
|
||||
{ sse: 1, opcode: 0x0F2B, reg_ud: 1, e: 1 },
|
||||
{ sse: 1, opcode: 0x660F2B, reg_ud: 1, e: 1 },
|
||||
|
||||
{ sse: 1, opcode: 0xF20F2C, e: 1, },
|
||||
{ sse: 1, opcode: 0x0F2C, e: 1, skip: 1, },
|
||||
|
@ -509,8 +509,8 @@ const encodings = [
|
|||
{ sse: 1, opcode: 0x0F2E, skip: 1 },
|
||||
{ sse: 1, opcode: 0x0F2F, skip: 1 },
|
||||
|
||||
{ sse: 1, opcode: 0x0F50, only_reg: 1, e: 1 },
|
||||
{ sse: 1, opcode: 0x660F50, only_reg: 1, e: 1 },
|
||||
{ sse: 1, opcode: 0x0F50, mem_ud: 1, e: 1 },
|
||||
{ sse: 1, opcode: 0x660F50, mem_ud: 1, e: 1 },
|
||||
{ sse: 1, opcode: 0x0F51, skip: 1 },
|
||||
{ sse: 1, opcode: 0x0F52, skip: 1 },
|
||||
|
||||
|
@ -574,9 +574,9 @@ const encodings = [
|
|||
{ sse: 1, opcode: 0x660F6B, e: 1 },
|
||||
{ sse: 1, opcode: 0x0F6B, e: 1 },
|
||||
{ sse: 1, opcode: 0x660F6C, e: 1 },
|
||||
{ sse: 1, opcode: 0x0F6C, e: 1, }, // ud
|
||||
{ sse: 1, opcode: 0x0F6C, e: 1, block_boundary: 1, }, // ud
|
||||
{ sse: 1, opcode: 0x660F6D, e: 1 },
|
||||
{ sse: 1, opcode: 0x0F6D, e: 1, }, // ud
|
||||
{ sse: 1, opcode: 0x0F6D, e: 1, block_boundary: 1, }, // ud
|
||||
{ sse: 1, opcode: 0x660F6E, e: 1 },
|
||||
{ sse: 1, opcode: 0x0F6E, e: 1 },
|
||||
{ sse: 1, opcode: 0xF30F6F, e: 1 },
|
||||
|
@ -588,26 +588,26 @@ const encodings = [
|
|||
{ sse: 1, opcode: 0xF20F70, e: 1, imm8: 1, },
|
||||
{ sse: 1, opcode: 0xF30F70, e: 1, imm8: 1, },
|
||||
|
||||
{ sse: 1, opcode: 0x0F71, e: 1, fixed_g: 2, imm8: 1, only_reg: 1, },
|
||||
{ sse: 1, opcode: 0x660F71, e: 1, fixed_g: 2, imm8: 1, only_reg: 1 },
|
||||
{ sse: 1, opcode: 0x0F71, e: 1, fixed_g: 4, imm8: 1, only_reg: 1, },
|
||||
{ sse: 1, opcode: 0x660F71, e: 1, fixed_g: 4, imm8: 1, only_reg: 1 },
|
||||
{ sse: 1, opcode: 0x0F71, e: 1, fixed_g: 6, imm8: 1, only_reg: 1, },
|
||||
{ sse: 1, opcode: 0x660F71, e: 1, fixed_g: 6, imm8: 1, only_reg: 1 },
|
||||
{ sse: 1, opcode: 0x0F71, e: 1, fixed_g: 2, imm8: 1, mem_ud: 1, },
|
||||
{ sse: 1, opcode: 0x660F71, e: 1, fixed_g: 2, imm8: 1, mem_ud: 1 },
|
||||
{ sse: 1, opcode: 0x0F71, e: 1, fixed_g: 4, imm8: 1, mem_ud: 1, },
|
||||
{ sse: 1, opcode: 0x660F71, e: 1, fixed_g: 4, imm8: 1, mem_ud: 1 },
|
||||
{ sse: 1, opcode: 0x0F71, e: 1, fixed_g: 6, imm8: 1, mem_ud: 1, },
|
||||
{ sse: 1, opcode: 0x660F71, e: 1, fixed_g: 6, imm8: 1, mem_ud: 1 },
|
||||
|
||||
{ sse: 1, opcode: 0x0F72, e: 1, fixed_g: 2, imm8: 1, only_reg: 1, },
|
||||
{ sse: 1, opcode: 0x660F72, e: 1, fixed_g: 2, imm8: 1, only_reg: 1 },
|
||||
{ sse: 1, opcode: 0x0F72, e: 1, fixed_g: 4, imm8: 1, only_reg: 1, },
|
||||
{ sse: 1, opcode: 0x660F72, e: 1, fixed_g: 4, imm8: 1, only_reg: 1 },
|
||||
{ sse: 1, opcode: 0x0F72, e: 1, fixed_g: 6, imm8: 1, only_reg: 1, },
|
||||
{ sse: 1, opcode: 0x660F72, e: 1, fixed_g: 6, imm8: 1, only_reg: 1 },
|
||||
{ sse: 1, opcode: 0x0F72, e: 1, fixed_g: 2, imm8: 1, mem_ud: 1, },
|
||||
{ sse: 1, opcode: 0x660F72, e: 1, fixed_g: 2, imm8: 1, mem_ud: 1 },
|
||||
{ sse: 1, opcode: 0x0F72, e: 1, fixed_g: 4, imm8: 1, mem_ud: 1, },
|
||||
{ sse: 1, opcode: 0x660F72, e: 1, fixed_g: 4, imm8: 1, mem_ud: 1 },
|
||||
{ sse: 1, opcode: 0x0F72, e: 1, fixed_g: 6, imm8: 1, mem_ud: 1, },
|
||||
{ sse: 1, opcode: 0x660F72, e: 1, fixed_g: 6, imm8: 1, mem_ud: 1 },
|
||||
|
||||
{ sse: 1, opcode: 0x0F73, e: 1, fixed_g: 2, imm8: 1, only_reg: 1, },
|
||||
{ sse: 1, opcode: 0x660F73, e: 1, fixed_g: 2, imm8: 1, only_reg: 1, },
|
||||
{ sse: 1, opcode: 0x660F73, e: 1, fixed_g: 3, imm8: 1, only_reg: 1 },
|
||||
{ sse: 1, opcode: 0x0F73, e: 1, fixed_g: 6, imm8: 1, only_reg: 1, },
|
||||
{ sse: 1, opcode: 0x660F73, e: 1, fixed_g: 6, imm8: 1, only_reg: 1 },
|
||||
{ sse: 1, opcode: 0x660F73, e: 1, fixed_g: 7, imm8: 1, only_reg: 1 },
|
||||
{ sse: 1, opcode: 0x0F73, e: 1, fixed_g: 2, imm8: 1, mem_ud: 1, },
|
||||
{ sse: 1, opcode: 0x660F73, e: 1, fixed_g: 2, imm8: 1, mem_ud: 1, },
|
||||
{ sse: 1, opcode: 0x660F73, e: 1, fixed_g: 3, imm8: 1, mem_ud: 1 },
|
||||
{ sse: 1, opcode: 0x0F73, e: 1, fixed_g: 6, imm8: 1, mem_ud: 1, },
|
||||
{ sse: 1, opcode: 0x660F73, e: 1, fixed_g: 6, imm8: 1, mem_ud: 1 },
|
||||
{ sse: 1, opcode: 0x660F73, e: 1, fixed_g: 7, imm8: 1, mem_ud: 1 },
|
||||
|
||||
{ sse: 1, opcode: 0x0F74, e: 1, },
|
||||
{ sse: 1, opcode: 0x660F74, e: 1, },
|
||||
|
@ -638,12 +638,12 @@ const encodings = [
|
|||
{ sse: 1, opcode: 0xF20FC2, e: 1, imm8: 1 },
|
||||
{ sse: 1, opcode: 0xF30FC2, e: 1, imm8: 1 },
|
||||
|
||||
{ opcode: 0x0FC3, e: 1, only_mem: 1, }, // movnti: Uses normal registers, hence not marked as sse
|
||||
{ opcode: 0x0FC3, e: 1, reg_ud: 1, }, // movnti: Uses normal registers, hence not marked as sse
|
||||
|
||||
{ sse: 1, opcode: 0x0FC4, e: 1, imm8: 1 },
|
||||
{ sse: 1, opcode: 0x660FC4, e: 1, imm8: 1 },
|
||||
{ sse: 1, opcode: 0x0FC5, e: 1, only_reg: 1, imm8: 1 },
|
||||
{ sse: 1, opcode: 0x660FC5, e: 1, only_reg: 1, imm8: 1, },
|
||||
{ sse: 1, opcode: 0x0FC5, e: 1, mem_ud: 1, imm8: 1 },
|
||||
{ sse: 1, opcode: 0x660FC5, e: 1, mem_ud: 1, imm8: 1, },
|
||||
|
||||
{ sse: 1, opcode: 0x0FC6, skip: 1, },
|
||||
|
||||
|
@ -661,11 +661,12 @@ const encodings = [
|
|||
{ sse: 1, opcode: 0x660FD5, e: 1 },
|
||||
|
||||
{ sse: 1, opcode: 0x660FD6, e: 1 },
|
||||
{ sse: 1, opcode: 0xF20FD6, only_reg: 1, e: 1 },
|
||||
{ sse: 1, opcode: 0xF30FD6, only_reg: 1, e: 1 },
|
||||
{ sse: 1, opcode: 0x0FD6, e: 1, }, // ud
|
||||
{ sse: 1, opcode: 0x0FD7, e: 1, only_reg: 1 },
|
||||
{ sse: 1, opcode: 0x660FD7, e: 1, only_reg: 1, },
|
||||
{ sse: 1, opcode: 0xF20FD6, mem_ud: 1, e: 1 },
|
||||
{ sse: 1, opcode: 0xF30FD6, mem_ud: 1, e: 1 },
|
||||
{ sse: 1, opcode: 0x0FD6, e: 1, block_boundary: 1, }, // ud
|
||||
|
||||
{ sse: 1, opcode: 0x0FD7, e: 1, mem_ud: 1 },
|
||||
{ sse: 1, opcode: 0x660FD7, e: 1, mem_ud: 1, },
|
||||
|
||||
{ sse: 1, opcode: 0x0FD8, e: 1 },
|
||||
{ sse: 1, opcode: 0x660FD8, e: 1 },
|
||||
|
@ -700,9 +701,9 @@ const encodings = [
|
|||
{ sse: 1, opcode: 0x660FE6, e: 1, skip: 1, },
|
||||
{ sse: 1, opcode: 0xF20FE6, e: 1, skip: 1, },
|
||||
{ sse: 1, opcode: 0xF30FE6, e: 1, skip: 1, },
|
||||
{ sse: 1, opcode: 0x0FE6, e: 1, }, // ud
|
||||
{ sse: 1, opcode: 0x0FE7, e: 1, only_mem: 1 },
|
||||
{ sse: 1, opcode: 0x660FE7, e: 1, only_mem: 1, },
|
||||
{ sse: 1, opcode: 0x0FE6, e: 1, block_boundary: 1, }, // ud
|
||||
{ sse: 1, opcode: 0x0FE7, e: 1, reg_ud: 1 },
|
||||
{ sse: 1, opcode: 0x660FE7, e: 1, reg_ud: 1, },
|
||||
|
||||
{ sse: 1, opcode: 0x0FE8, e: 1 },
|
||||
{ sse: 1, opcode: 0x660FE8, e: 1 },
|
||||
|
@ -737,8 +738,8 @@ const encodings = [
|
|||
{ sse: 1, opcode: 0x660FF6, e: 1 },
|
||||
// maskmovq (0FF7), maskmovdqu (660FF7) tested manually
|
||||
// Generated tests don't setup EDI as required (yet)
|
||||
{ sse: 1, opcode: 0x0FF7, only_reg: 1, e: 1, skip: 1, },
|
||||
{ sse: 1, opcode: 0x660FF7, only_reg: 1, e: 1, skip: 1, },
|
||||
{ sse: 1, opcode: 0x0FF7, mem_ud: 1, e: 1, skip: 1, },
|
||||
{ sse: 1, opcode: 0x660FF7, mem_ud: 1, e: 1, skip: 1, },
|
||||
|
||||
{ sse: 1, opcode: 0x0FF8, e: 1 },
|
||||
{ sse: 1, opcode: 0x660FF8, e: 1 },
|
||||
|
@ -755,7 +756,7 @@ const encodings = [
|
|||
{ sse: 1, opcode: 0x0FFE, e: 1 },
|
||||
{ sse: 1, opcode: 0x660FFE, e: 1 },
|
||||
|
||||
{ opcode: 0x0FFF, },
|
||||
{ opcode: 0x0FFF, block_boundary: 1, }, // ud
|
||||
];
|
||||
|
||||
for(let i = 0; i < 8; i++)
|
||||
|
|
|
@ -3486,6 +3486,7 @@ CPU.prototype.arpl = function(seg, r16)
|
|||
if(!this.protected_mode[0] || this.vm86_mode())
|
||||
{
|
||||
this.trigger_ud();
|
||||
return;
|
||||
}
|
||||
|
||||
this.flags_changed[0] &= ~flag_zero;
|
||||
|
@ -3513,6 +3514,7 @@ CPU.prototype.lar = function(selector, original)
|
|||
{
|
||||
dbg_log("lar #ud");
|
||||
this.trigger_ud();
|
||||
return;
|
||||
}
|
||||
|
||||
/** @const */
|
||||
|
@ -3550,6 +3552,7 @@ CPU.prototype.lsl = function(selector, original)
|
|||
{
|
||||
dbg_log("lsl #ud");
|
||||
this.trigger_ud();
|
||||
return;
|
||||
}
|
||||
|
||||
/** @const */
|
||||
|
|
|
@ -828,15 +828,6 @@ void trigger_de()
|
|||
|
||||
__attribute__((noinline))
|
||||
void trigger_ud()
|
||||
{
|
||||
dbg_log("#ud");
|
||||
dbg_trace();
|
||||
*instruction_pointer = *previous_ip;
|
||||
raise_exception(CPU_EXCEPTION_UD);
|
||||
}
|
||||
|
||||
__attribute__((noinline))
|
||||
void trigger_ud_non_raising()
|
||||
{
|
||||
dbg_log("#ud");
|
||||
dbg_trace();
|
||||
|
@ -1513,7 +1504,7 @@ bool task_switch_test_mmx()
|
|||
}
|
||||
else if(*cr & CR0_EM)
|
||||
{
|
||||
trigger_ud_non_raising();
|
||||
trigger_ud();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -418,17 +418,20 @@ 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 instr_8C_check_sreg(int32_t sreg) {
|
||||
bool instr_8C_check_sreg(int32_t sreg) {
|
||||
if(sreg >= 6)
|
||||
{
|
||||
dbg_log("mov sreg #ud");
|
||||
trigger_ud();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
void instr16_8C_reg(int32_t r, int32_t seg) { instr_8C_check_sreg(seg); write_reg16(r, sreg[seg]); }
|
||||
void instr16_8C_mem(int32_t addr, int32_t seg) { instr_8C_check_sreg(seg); safe_write16(addr, sreg[seg]); }
|
||||
void instr32_8C_reg(int32_t r, int32_t seg) { instr_8C_check_sreg(seg); write_reg32(r, sreg[seg]); }
|
||||
void instr32_8C_mem(int32_t addr, int32_t seg) { instr_8C_check_sreg(seg); safe_write32(addr, sreg[seg]); }
|
||||
void instr16_8C_reg(int32_t r, int32_t seg) { if(instr_8C_check_sreg(seg)) write_reg16(r, sreg[seg]); }
|
||||
void instr16_8C_mem(int32_t addr, int32_t seg) { if(instr_8C_check_sreg(seg)) safe_write16(addr, sreg[seg]); }
|
||||
void instr32_8C_reg(int32_t r, int32_t seg) { if(instr_8C_check_sreg(seg)) write_reg32(r, sreg[seg]); }
|
||||
void instr32_8C_mem(int32_t addr, int32_t seg) { if(instr_8C_check_sreg(seg)) safe_write32(addr, sreg[seg]); }
|
||||
|
||||
void instr16_8D_reg(int32_t r, int32_t r2)
|
||||
{
|
||||
|
|
|
@ -491,7 +491,7 @@ void instr16_8B_mem(int32_t addr, int32_t r);
|
|||
void instr16_8B_reg(int32_t r1, int32_t r);
|
||||
void instr32_8B_mem(int32_t addr, int32_t r);
|
||||
void instr32_8B_reg(int32_t r1, int32_t r);
|
||||
void instr_8C_check_sreg(int32_t sreg);
|
||||
bool instr_8C_check_sreg(int32_t sreg);
|
||||
void instr16_8C_reg(int32_t r, int32_t seg);
|
||||
void instr16_8C_mem(int32_t addr, int32_t seg);
|
||||
void instr32_8C_reg(int32_t r, int32_t seg);
|
||||
|
|
|
@ -24,58 +24,58 @@ bool apic_enabled = false;
|
|||
|
||||
void instr_0F00_0_mem(int32_t addr) {
|
||||
// sldt
|
||||
if(!protected_mode[0] || vm86_mode()) trigger_ud();
|
||||
if(!protected_mode[0] || vm86_mode()) { trigger_ud(); return; }
|
||||
safe_write16(addr, sreg[LDTR]);
|
||||
}
|
||||
void instr_0F00_0_reg(int32_t r) {
|
||||
if(!protected_mode[0] || vm86_mode()) trigger_ud();
|
||||
if(!protected_mode[0] || vm86_mode()) { trigger_ud(); return; }
|
||||
write_reg_osize(r, sreg[LDTR]);
|
||||
}
|
||||
void instr_0F00_1_mem(int32_t addr) {
|
||||
// str
|
||||
if(!protected_mode[0] || vm86_mode()) trigger_ud();
|
||||
if(!protected_mode[0] || vm86_mode()) { trigger_ud(); return; }
|
||||
safe_write16(addr, sreg[TR]);
|
||||
}
|
||||
void instr_0F00_1_reg(int32_t r) {
|
||||
if(!protected_mode[0] || vm86_mode()) trigger_ud();
|
||||
if(!protected_mode[0] || vm86_mode()) { trigger_ud(); return; }
|
||||
write_reg_osize(r, sreg[TR]);
|
||||
}
|
||||
void instr_0F00_2_mem(int32_t addr) {
|
||||
// lldt
|
||||
if(!protected_mode[0] || vm86_mode()) trigger_ud();
|
||||
if(!protected_mode[0] || vm86_mode()) { trigger_ud(); return; }
|
||||
if(cpl[0]) { trigger_gp_non_raising(0); return; }
|
||||
load_ldt(safe_read16(addr));
|
||||
}
|
||||
void instr_0F00_2_reg(int32_t r) {
|
||||
if(!protected_mode[0] || vm86_mode()) trigger_ud();
|
||||
if(!protected_mode[0] || vm86_mode()) { trigger_ud(); return; }
|
||||
if(cpl[0]) { trigger_gp_non_raising(0); return; }
|
||||
load_ldt(read_reg16(r));
|
||||
}
|
||||
void instr_0F00_3_mem(int32_t addr) {
|
||||
// ltr
|
||||
if(!protected_mode[0] || vm86_mode()) trigger_ud();
|
||||
if(!protected_mode[0] || vm86_mode()) { trigger_ud(); return; }
|
||||
if(cpl[0]) { trigger_gp_non_raising(0); return; }
|
||||
load_tr(safe_read16(addr));
|
||||
}
|
||||
void instr_0F00_3_reg(int32_t r) {
|
||||
if(!protected_mode[0] || vm86_mode()) trigger_ud();
|
||||
if(!protected_mode[0] || vm86_mode()) { trigger_ud(); return; }
|
||||
if(cpl[0]) { trigger_gp_non_raising(0); return; }
|
||||
load_tr(read_reg16(r));
|
||||
}
|
||||
void instr_0F00_4_mem(int32_t addr) {
|
||||
if(!protected_mode[0] || vm86_mode()) trigger_ud();
|
||||
if(!protected_mode[0] || vm86_mode()) { trigger_ud(); return; }
|
||||
verr(safe_read16(addr));
|
||||
}
|
||||
void instr_0F00_4_reg(int32_t r) {
|
||||
if(!protected_mode[0] || vm86_mode()) trigger_ud();
|
||||
if(!protected_mode[0] || vm86_mode()) { trigger_ud(); return; }
|
||||
verr(read_reg16(r));
|
||||
}
|
||||
void instr_0F00_5_mem(int32_t addr) {
|
||||
if(!protected_mode[0] || vm86_mode()) trigger_ud();
|
||||
if(!protected_mode[0] || vm86_mode()) { trigger_ud(); return; }
|
||||
verw(safe_read16(addr));
|
||||
}
|
||||
void instr_0F00_5_reg(int32_t r) {
|
||||
if(!protected_mode[0] || vm86_mode()) trigger_ud();
|
||||
if(!protected_mode[0] || vm86_mode()) { trigger_ud(); return; }
|
||||
verw(read_reg16(r));
|
||||
}
|
||||
|
||||
|
@ -316,7 +316,7 @@ void instr_0F13_mem(int32_t addr, int32_t r) {
|
|||
movl_r128_m64(addr, r);
|
||||
}
|
||||
|
||||
void instr_0F13_reg(int32_t r1, int32_t r2) { unimplemented_sse(); }
|
||||
void instr_0F13_reg(int32_t r1, int32_t r2) { trigger_ud(); }
|
||||
|
||||
void instr_660F13_reg(int32_t r1, int32_t r) { trigger_ud(); }
|
||||
void instr_660F13_mem(int32_t addr, int32_t r) {
|
||||
|
@ -414,7 +414,9 @@ void instr_660F17_mem(int32_t addr, int32_t r) {
|
|||
}
|
||||
void instr_660F17_reg(int32_t r1, int32_t r2) { trigger_ud(); }
|
||||
|
||||
void instr_0F18_reg(int32_t r1, int32_t r2) { trigger_ud(); }
|
||||
void instr_0F18_reg(int32_t r1, int32_t r2) {
|
||||
// reserved nop
|
||||
}
|
||||
void instr_0F18_mem(int32_t addr, int32_t r) {
|
||||
// prefetch
|
||||
// nop for us
|
||||
|
@ -476,6 +478,7 @@ void instr_0F21(int32_t r, int32_t dreg_index) {
|
|||
{
|
||||
dbg_log("#ud mov dreg 4/5 with cr4.DE set");
|
||||
trigger_ud();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -565,6 +568,7 @@ void instr_0F23(int32_t r, int32_t dreg_index) {
|
|||
{
|
||||
dbg_log("#ud mov dreg 4/5 with cr4.DE set");
|
||||
trigger_ud();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2176,7 +2180,7 @@ void instr_0FAE_1_reg(int32_t r) { trigger_ud(); }
|
|||
void instr_0FAE_1_mem(int32_t addr) {
|
||||
fxrstor(addr);
|
||||
}
|
||||
void instr_0FAE_2_reg(int32_t r) { trigger_ud(); }
|
||||
void instr_0FAE_2_reg(int32_t r) { unimplemented_sse(); }
|
||||
void instr_0FAE_2_mem(int32_t addr) {
|
||||
// ldmxcsr
|
||||
int32_t new_mxcsr = safe_read32s(addr);
|
||||
|
@ -2212,8 +2216,8 @@ void instr_0FAE_6_reg(int32_t r) {
|
|||
dbg_assert_message(r == 0, "Unexpected mfence encoding");
|
||||
}
|
||||
void instr_0FAE_6_mem(int32_t addr) {
|
||||
dbg_assert_message(false, "0fae/5 #ud");
|
||||
trigger_ud();
|
||||
// xsaveopt
|
||||
undefined_instruction();
|
||||
}
|
||||
void instr_0FAE_7_reg(int32_t r) {
|
||||
// sfence
|
||||
|
@ -2585,7 +2589,7 @@ void instr_0FC7_6_reg(int32_t r) {
|
|||
flags_changed[0] = 0;
|
||||
}
|
||||
void instr_0FC7_6_mem(int32_t addr) {
|
||||
undefined_instruction();
|
||||
trigger_ud();
|
||||
}
|
||||
|
||||
void instr_0FC8() { bswap(EAX); }
|
||||
|
|
|
@ -284,36 +284,11 @@ else {
|
|||
process.exit(1);
|
||||
}
|
||||
|
||||
if(exception === "DE" || exception === "GP")
|
||||
{
|
||||
// XXX: On gdb execution is stopped at this point. On v86 we
|
||||
// currently don't have this ability, so we record the exception
|
||||
// and continue execution
|
||||
recorded_exceptions.push(exception);
|
||||
return true;
|
||||
}
|
||||
|
||||
clearTimeout(test_timeout);
|
||||
|
||||
waiting_to_receive_next_test = true;
|
||||
emulator.stop();
|
||||
|
||||
if(current_test.fixture.exception !== exception)
|
||||
{
|
||||
process.send({
|
||||
failures: [{
|
||||
name: "Exception",
|
||||
actual: exception,
|
||||
expected: current_test.fixture.exception || "(none)",
|
||||
}],
|
||||
img_name: current_test.img_name,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
process.send(DONE_MSG);
|
||||
}
|
||||
|
||||
// XXX: On gdb execution is stopped at this point. On v86 we
|
||||
// currently don't have this ability, so we record the exception
|
||||
// and continue execution
|
||||
console.log("recorded", exception);
|
||||
recorded_exceptions.push(exception);
|
||||
return true;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue