Generate code for task_switch_test{,_mmx}, use non-raising exceptions

This commit is contained in:
Fabian 2018-07-24 14:40:10 -06:00
parent 848b07a628
commit bdef74eced
12 changed files with 466 additions and 542 deletions

View file

@ -216,7 +216,23 @@ function gen_instruction_body_after_prefix(encodings, size)
function gen_instruction_body_after_fixed_g(encoding, size)
{
const instruction_prefix = [];
const instruction_postfix = encoding.block_boundary ? ["after_block_boundary();"] : [];
if(encoding.task_switch_test || encoding.sse)
{
instruction_prefix.push(
{
type: "if-else",
if_blocks: [
{
condition: encoding.sse ? "!task_switch_test_mmx()" : "!task_switch_test()",
body: ["return;"],
}
],
});
}
const imm_read = gen_read_imm_call(encoding, size);
const instruction_name = make_instruction_name(encoding, size);
@ -244,6 +260,7 @@ function gen_instruction_body_after_fixed_g(encoding, size)
// operands are always registers (0f20-0f24)
return [].concat(
instruction_prefix,
gen_call(instruction_name, ["modrm_byte & 7", "modrm_byte >> 3 & 7"]),
instruction_postfix
);
@ -266,6 +283,7 @@ function gen_instruction_body_after_fixed_g(encoding, size)
}
return [].concat(
instruction_prefix,
{
type: "if-else",
if_blocks: [
@ -306,6 +324,7 @@ function gen_instruction_body_after_fixed_g(encoding, size)
}
return [].concat(
instruction_prefix,
gen_call(instruction_name, args),
instruction_postfix
);

View file

@ -220,6 +220,15 @@ function gen_instruction_body_after_fixed_g(encoding, size)
instruction_postfix.push("*instr_flags |= ::jit::JIT_INSTR_BLOCK_BOUNDARY_FLAG;");
}
const instruction_prefix = [];
if(encoding.task_switch_test || encoding.sse)
{
instruction_prefix.push(
gen_call(encoding.sse ? "::codegen::gen_task_switch_test_mmx" : "::codegen::gen_task_switch_test", ["ctx"])
);
}
const APPEND_NONFAULTING_FLAG = "*instr_flags |= ::jit::JIT_INSTR_NONFAULTING_FLAG;";
const imm_read = gen_read_imm_call(encoding, size);
@ -245,6 +254,7 @@ function gen_instruction_body_after_fixed_g(encoding, size)
const args = ["ctx", `"${instruction_name}"`, "(modrm_byte & 7) as u32", "(modrm_byte >> 3 & 7) as u32"];
return [].concat(
instruction_prefix,
gen_call(`::codegen::gen_fn${args.length - 2}_const`, args),
reg_postfix,
instruction_postfix
@ -267,6 +277,7 @@ function gen_instruction_body_after_fixed_g(encoding, size)
}
return [].concat(
instruction_prefix,
{
type: "if-else",
if_blocks: [{
@ -307,6 +318,7 @@ function gen_instruction_body_after_fixed_g(encoding, size)
}
return [].concat(
instruction_prefix,
{
type: "if-else",
if_blocks: [{
@ -357,6 +369,7 @@ function gen_instruction_body_after_fixed_g(encoding, size)
}
return [].concat(
instruction_prefix,
imm_read_bindings,
gen_call(`::jit_instructions::${instruction_name}_jit`, args),
instruction_postfix
@ -392,6 +405,7 @@ function gen_instruction_body_after_fixed_g(encoding, size)
}
return [].concat(
instruction_prefix,
imm_read_bindings,
gen_call(`::codegen::gen_fn${args.length - 2}_const`, args),
instruction_postfix

View file

@ -123,7 +123,7 @@ const encodings = [
{ opcode: 0x98, nonfaulting: 1, os: 1, },
{ opcode: 0x99, nonfaulting: 1, os: 1, },
{ opcode: 0x9A, os: 1, imm1632: 1, extra_imm16: 1, skip: 1, block_boundary: 1, }, // callf
{ opcode: 0x9B, skip: 1, },
{ opcode: 0x9B, skip: 1, }, // fwait: block_boundary since it uses non-raising cpu exceptions
// pushf: block_boundary since it uses non-raising cpu exceptions
{ opcode: 0x9C, os: 1, block_boundary: 1, },
// popf: not a jump, but can cause an eip change due to updating the interrupt flag
@ -417,10 +417,10 @@ const encodings = [
{ opcode: 0x0FAA, skip: 1 },
{ opcode: 0x0FAE, e: 1, fixed_g: 0, only_mem: 1, skip: 1, }, // fxsave
{ opcode: 0x0FAE, e: 1, fixed_g: 1, only_mem: 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, skip: 1, block_boundary: 1, }, // ldmxcsr
{ opcode: 0x0FAE, e: 1, fixed_g: 3, only_mem: 1, skip: 1, block_boundary: 1, }, // stmxcsr
{ 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: 5, only_reg: 1, skip: 1, }, // lfence (reg, only 0), xrstor (mem)
@ -466,269 +466,269 @@ const encodings = [
// - Skipped are not implemented
// - Missing are sse3+, and floating point
{ opcode: 0x0F10, e: 1 },
{ opcode: 0xF30F10, e: 1 },
{ opcode: 0x660F10, e: 1 },
{ opcode: 0xF20F10, e: 1 },
{ opcode: 0x0F11, e: 1 },
{ opcode: 0xF30F11, e: 1 },
{ opcode: 0x660F11, e: 1 },
{ opcode: 0xF20F11, e: 1 },
{ opcode: 0x0F12, e: 1 },
{ opcode: 0x660F12, only_mem: 1, e: 1 },
{ opcode: 0xF20F12, e: 1, skip: 1, },
{ opcode: 0xF30F12, e: 1, skip: 1, },
{ opcode: 0x0F13, only_mem: 1, e: 1 },
{ opcode: 0x660F13, only_mem: 1, e: 1 },
{ opcode: 0x0F14, e: 1 },
{ opcode: 0x660F14, e: 1 },
{ opcode: 0x0F15, e: 1 },
{ opcode: 0x660F15, e: 1 },
{ opcode: 0x0F16, e: 1 },
{ opcode: 0x660F16, only_mem: 1, e: 1 },
{ opcode: 0x0F17, only_mem: 1, e: 1 },
{ opcode: 0x660F17, only_mem: 1, e: 1 },
{ sse: 1, opcode: 0x0F10, e: 1 },
{ sse: 1, opcode: 0xF30F10, e: 1 },
{ sse: 1, opcode: 0x660F10, e: 1 },
{ sse: 1, opcode: 0xF20F10, e: 1 },
{ sse: 1, opcode: 0x0F11, e: 1 },
{ sse: 1, opcode: 0xF30F11, e: 1 },
{ 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: 0xF20F12, e: 1, skip: 1, },
{ sse: 1, opcode: 0xF30F12, e: 1, skip: 1, },
{ sse: 1, opcode: 0x0F13, only_mem: 1, e: 1 },
{ sse: 1, opcode: 0x660F13, only_mem: 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: 0x0F17, only_mem: 1, e: 1 },
{ sse: 1, opcode: 0x660F17, only_mem: 1, e: 1 },
{ opcode: 0x0F28, e: 1 },
{ opcode: 0x660F28, e: 1 },
{ opcode: 0x0F29, e: 1 },
{ opcode: 0x660F29, e: 1 },
{ opcode: 0x0F2A, skip: 1 },
{ opcode: 0x0F2B, only_mem: 1, e: 1 },
{ opcode: 0x660F2B, only_mem: 1, e: 1 },
{ sse: 1, opcode: 0x0F28, e: 1 },
{ sse: 1, opcode: 0x660F28, e: 1 },
{ sse: 1, opcode: 0x0F29, e: 1 },
{ sse: 1, opcode: 0x660F29, e: 1 },
{ sse: 1, opcode: 0x0F2A, skip: 1 },
{ sse: 1, opcode: 0x0F2B, only_mem: 1, e: 1 },
{ sse: 1, opcode: 0x660F2B, only_mem: 1, e: 1 },
{ opcode: 0xF20F2C, e: 1, },
{ opcode: 0x0F2C, e: 1, skip: 1, },
{ opcode: 0xF30F2C, e: 1, skip: 1, },
{ opcode: 0x660F2C, e: 1, skip: 1, },
{ opcode: 0x0F2D, skip: 1 },
{ opcode: 0x0F2E, skip: 1 },
{ opcode: 0x0F2F, skip: 1 },
{ sse: 1, opcode: 0xF20F2C, e: 1, },
{ sse: 1, opcode: 0x0F2C, e: 1, skip: 1, },
{ sse: 1, opcode: 0xF30F2C, e: 1, skip: 1, },
{ sse: 1, opcode: 0x660F2C, e: 1, skip: 1, },
{ sse: 1, opcode: 0x0F2D, skip: 1 },
{ sse: 1, opcode: 0x0F2E, skip: 1 },
{ sse: 1, opcode: 0x0F2F, skip: 1 },
{ opcode: 0x0F50, only_reg: 1, e: 1 },
{ opcode: 0x660F50, only_reg: 1, e: 1 },
{ opcode: 0x0F51, skip: 1 },
{ opcode: 0x0F52, skip: 1 },
{ opcode: 0x0F53, skip: 1 },
{ opcode: 0x0F54, e: 1 },
{ opcode: 0x660F54, e: 1 },
{ opcode: 0x0F55, e: 1 },
{ opcode: 0x660F55, e: 1 },
{ opcode: 0x0F56, e: 1 },
{ opcode: 0x660F56, e: 1 },
{ opcode: 0x0F57, e: 1 },
{ opcode: 0x660F57, e: 1 },
{ sse: 1, opcode: 0x0F50, only_reg: 1, e: 1 },
{ sse: 1, opcode: 0x660F50, only_reg: 1, e: 1 },
{ sse: 1, opcode: 0x0F51, skip: 1 },
{ sse: 1, opcode: 0x0F52, skip: 1 },
{ sse: 1, opcode: 0x0F53, skip: 1 },
{ sse: 1, opcode: 0x0F54, e: 1 },
{ sse: 1, opcode: 0x660F54, e: 1 },
{ sse: 1, opcode: 0x0F55, e: 1 },
{ sse: 1, opcode: 0x660F55, e: 1 },
{ sse: 1, opcode: 0x0F56, e: 1 },
{ sse: 1, opcode: 0x660F56, e: 1 },
{ sse: 1, opcode: 0x0F57, e: 1 },
{ sse: 1, opcode: 0x660F57, e: 1 },
{ opcode: 0x0F58, skip: 1 },
{ opcode: 0x0F59, skip: 1 },
{ opcode: 0x0F5A, skip: 1 },
{ opcode: 0x0F5B, skip: 1 },
{ opcode: 0x0F5C, skip: 1 },
{ opcode: 0x0F5D, skip: 1 },
{ opcode: 0x0F5E, skip: 1 },
{ opcode: 0x0F5F, skip: 1 },
{ sse: 1, opcode: 0x0F58, skip: 1 },
{ sse: 1, opcode: 0x0F59, skip: 1 },
{ sse: 1, opcode: 0x0F5A, skip: 1 },
{ sse: 1, opcode: 0x0F5B, skip: 1 },
{ sse: 1, opcode: 0x0F5C, skip: 1 },
{ sse: 1, opcode: 0x0F5D, skip: 1 },
{ sse: 1, opcode: 0x0F5E, skip: 1 },
{ sse: 1, opcode: 0x0F5F, skip: 1 },
{ opcode: 0x660F60, e: 1 },
{ opcode: 0x0F60, e: 1 },
{ opcode: 0x660F61, e: 1 },
{ opcode: 0x0F61, e: 1 },
{ opcode: 0x660F62, e: 1 },
{ opcode: 0x0F62, e: 1 },
{ opcode: 0x660F63, e: 1 },
{ opcode: 0x0F63, e: 1 },
{ opcode: 0x660F64, e: 1 },
{ opcode: 0x0F64, e: 1 },
{ opcode: 0x660F65, e: 1 },
{ opcode: 0x0F65, e: 1 },
{ opcode: 0x660F66, e: 1 },
{ opcode: 0x0F66, e: 1 },
{ opcode: 0x660F67, e: 1 },
{ opcode: 0x0F67, e: 1 },
{ sse: 1, opcode: 0x660F60, e: 1 },
{ sse: 1, opcode: 0x0F60, e: 1 },
{ sse: 1, opcode: 0x660F61, e: 1 },
{ sse: 1, opcode: 0x0F61, e: 1 },
{ sse: 1, opcode: 0x660F62, e: 1 },
{ sse: 1, opcode: 0x0F62, e: 1 },
{ sse: 1, opcode: 0x660F63, e: 1 },
{ sse: 1, opcode: 0x0F63, e: 1 },
{ sse: 1, opcode: 0x660F64, e: 1 },
{ sse: 1, opcode: 0x0F64, e: 1 },
{ sse: 1, opcode: 0x660F65, e: 1 },
{ sse: 1, opcode: 0x0F65, e: 1 },
{ sse: 1, opcode: 0x660F66, e: 1 },
{ sse: 1, opcode: 0x0F66, e: 1 },
{ sse: 1, opcode: 0x660F67, e: 1 },
{ sse: 1, opcode: 0x0F67, e: 1 },
{ opcode: 0x660F68, e: 1 },
{ opcode: 0x0F68, e: 1 },
{ opcode: 0x660F69, e: 1 },
{ opcode: 0x0F69, e: 1 },
{ opcode: 0x660F6A, e: 1 },
{ opcode: 0x0F6A, e: 1 },
{ opcode: 0x660F6B, e: 1 },
{ opcode: 0x0F6B, e: 1 },
{ opcode: 0x660F6C, e: 1 },
{ opcode: 0x0F6C, e: 1, }, // ud
{ opcode: 0x660F6D, e: 1 },
{ opcode: 0x0F6D, e: 1, }, // ud
{ opcode: 0x660F6E, e: 1 },
{ opcode: 0x0F6E, e: 1 },
{ opcode: 0xF30F6F, e: 1 },
{ opcode: 0x660F6F, e: 1 },
{ opcode: 0x0F6F, e: 1 },
{ sse: 1, opcode: 0x660F68, e: 1 },
{ sse: 1, opcode: 0x0F68, e: 1 },
{ sse: 1, opcode: 0x660F69, e: 1 },
{ sse: 1, opcode: 0x0F69, e: 1 },
{ sse: 1, opcode: 0x660F6A, e: 1 },
{ sse: 1, opcode: 0x0F6A, e: 1 },
{ 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: 0x660F6D, e: 1 },
{ sse: 1, opcode: 0x0F6D, e: 1, }, // ud
{ sse: 1, opcode: 0x660F6E, e: 1 },
{ sse: 1, opcode: 0x0F6E, e: 1 },
{ sse: 1, opcode: 0xF30F6F, e: 1 },
{ sse: 1, opcode: 0x660F6F, e: 1 },
{ sse: 1, opcode: 0x0F6F, e: 1 },
{ opcode: 0x0F70, e: 1, imm8: 1, },
{ opcode: 0x660F70, e: 1, imm8: 1, },
{ opcode: 0xF20F70, e: 1, imm8: 1, },
{ opcode: 0xF30F70, e: 1, imm8: 1, },
{ sse: 1, opcode: 0x0F70, e: 1, imm8: 1, },
{ sse: 1, opcode: 0x660F70, e: 1, imm8: 1, },
{ sse: 1, opcode: 0xF20F70, e: 1, imm8: 1, },
{ sse: 1, opcode: 0xF30F70, e: 1, imm8: 1, },
{ opcode: 0x0F71, e: 1, fixed_g: 2, imm8: 1, only_reg: 1, },
{ opcode: 0x660F71, e: 1, fixed_g: 2, imm8: 1, only_reg: 1 },
{ opcode: 0x0F71, e: 1, fixed_g: 4, imm8: 1, only_reg: 1, },
{ opcode: 0x660F71, e: 1, fixed_g: 4, imm8: 1, only_reg: 1 },
{ opcode: 0x0F71, e: 1, fixed_g: 6, imm8: 1, only_reg: 1, },
{ opcode: 0x660F71, e: 1, fixed_g: 6, imm8: 1, only_reg: 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 },
{ opcode: 0x0F72, e: 1, fixed_g: 2, imm8: 1, only_reg: 1, },
{ opcode: 0x660F72, e: 1, fixed_g: 2, imm8: 1, only_reg: 1 },
{ opcode: 0x0F72, e: 1, fixed_g: 4, imm8: 1, only_reg: 1, },
{ opcode: 0x660F72, e: 1, fixed_g: 4, imm8: 1, only_reg: 1 },
{ opcode: 0x0F72, e: 1, fixed_g: 6, imm8: 1, only_reg: 1, },
{ opcode: 0x660F72, e: 1, fixed_g: 6, imm8: 1, only_reg: 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 },
{ opcode: 0x0F73, e: 1, fixed_g: 2, imm8: 1, only_reg: 1, },
{ opcode: 0x660F73, e: 1, fixed_g: 2, imm8: 1, only_reg: 1, },
{ opcode: 0x660F73, e: 1, fixed_g: 3, imm8: 1, only_reg: 1 },
{ opcode: 0x0F73, e: 1, fixed_g: 6, imm8: 1, only_reg: 1, },
{ opcode: 0x660F73, e: 1, fixed_g: 6, imm8: 1, only_reg: 1 },
{ opcode: 0x660F73, e: 1, fixed_g: 7, imm8: 1, only_reg: 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 },
{ opcode: 0x0F74, e: 1, },
{ opcode: 0x660F74, e: 1, },
{ opcode: 0x0F75, e: 1, },
{ opcode: 0x660F75, e: 1, },
{ opcode: 0x0F76, e: 1, },
{ opcode: 0x660F76, e: 1, },
{ opcode: 0x0F77 },
{ sse: 1, opcode: 0x0F74, e: 1, },
{ sse: 1, opcode: 0x660F74, e: 1, },
{ sse: 1, opcode: 0x0F75, e: 1, },
{ sse: 1, opcode: 0x660F75, e: 1, },
{ sse: 1, opcode: 0x0F76, e: 1, },
{ sse: 1, opcode: 0x660F76, e: 1, },
{ sse: 1, opcode: 0x0F77 },
{ opcode: 0x0F78, skip: 1 },
{ opcode: 0x0F79, skip: 1 },
{ opcode: 0x0F7A, skip: 1 },
{ opcode: 0x0F7B, skip: 1 },
{ opcode: 0x0F7C, skip: 1 },
{ opcode: 0x0F7D, skip: 1 },
{ sse: 1, opcode: 0x0F78, skip: 1 },
{ sse: 1, opcode: 0x0F79, skip: 1 },
{ sse: 1, opcode: 0x0F7A, skip: 1 },
{ sse: 1, opcode: 0x0F7B, skip: 1 },
{ sse: 1, opcode: 0x0F7C, skip: 1 },
{ sse: 1, opcode: 0x0F7D, skip: 1 },
{ opcode: 0x0F7E, e: 1 },
{ opcode: 0x660F7E, e: 1 },
{ opcode: 0xF30F7E, e: 1 },
{ opcode: 0x0F7F, e: 1 },
{ opcode: 0x660F7F, e: 1 },
{ opcode: 0xF30F7F, e: 1 },
{ sse: 1, opcode: 0x0F7E, e: 1 },
{ sse: 1, opcode: 0x660F7E, e: 1 },
{ sse: 1, opcode: 0xF30F7E, e: 1 },
{ sse: 1, opcode: 0x0F7F, e: 1 },
{ sse: 1, opcode: 0x660F7F, e: 1 },
{ sse: 1, opcode: 0xF30F7F, e: 1 },
{ opcode: 0x0FC2, skip: 1, },
{ sse: 1, opcode: 0x0FC2, skip: 1, },
{ opcode: 0x0FC3, e: 1, only_mem: 1, },
{ opcode: 0x0FC4, e: 1, imm8: 1 },
{ opcode: 0x660FC4, e: 1, imm8: 1 },
{ opcode: 0x0FC3, e: 1, only_mem: 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 },
{ opcode: 0x0FC5, e: 1, only_reg: 1, imm8: 1 },
{ opcode: 0x660FC5, e: 1, only_reg: 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, },
{ opcode: 0x0FC6, skip: 1, },
{ sse: 1, opcode: 0x0FC6, skip: 1, },
{ opcode: 0x0FD0, skip: 1, },
{ sse: 1, opcode: 0x0FD0, skip: 1, },
{ opcode: 0x0FD1, e: 1 },
{ opcode: 0x660FD1, e: 1 },
{ opcode: 0x0FD2, e: 1 },
{ opcode: 0x660FD2, e: 1 },
{ opcode: 0x0FD3, e: 1 },
{ opcode: 0x660FD3, e: 1 },
{ opcode: 0x0FD4, e: 1 },
{ opcode: 0x660FD4, e: 1 },
{ opcode: 0x0FD5, e: 1 },
{ opcode: 0x660FD5, e: 1 },
{ sse: 1, opcode: 0x0FD1, e: 1 },
{ sse: 1, opcode: 0x660FD1, e: 1 },
{ sse: 1, opcode: 0x0FD2, e: 1 },
{ sse: 1, opcode: 0x660FD2, e: 1 },
{ sse: 1, opcode: 0x0FD3, e: 1 },
{ sse: 1, opcode: 0x660FD3, e: 1 },
{ sse: 1, opcode: 0x0FD4, e: 1 },
{ sse: 1, opcode: 0x660FD4, e: 1 },
{ sse: 1, opcode: 0x0FD5, e: 1 },
{ sse: 1, opcode: 0x660FD5, e: 1 },
{ opcode: 0x660FD6, e: 1 },
{ opcode: 0xF20FD6, only_reg: 1, e: 1 },
{ opcode: 0xF30FD6, only_reg: 1, e: 1 },
{ opcode: 0x0FD6, e: 1, }, // ud
{ opcode: 0x0FD7, e: 1, only_reg: 1 },
{ opcode: 0x660FD7, e: 1, only_reg: 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, },
{ opcode: 0x0FD8, e: 1 },
{ opcode: 0x660FD8, e: 1 },
{ opcode: 0x0FD9, e: 1 },
{ opcode: 0x660FD9, e: 1 },
{ opcode: 0x0FDA, e: 1 },
{ opcode: 0x660FDA, e: 1 },
{ opcode: 0x0FDB, e: 1 },
{ opcode: 0x660FDB, e: 1 },
{ opcode: 0x0FDC, e: 1 },
{ opcode: 0x660FDC, e: 1 },
{ opcode: 0x0FDD, e: 1 },
{ opcode: 0x660FDD, e: 1 },
{ opcode: 0x0FDE, e: 1 },
{ opcode: 0x660FDE, e: 1 },
{ opcode: 0x0FDF, e: 1 },
{ opcode: 0x660FDF, e: 1 },
{ sse: 1, opcode: 0x0FD8, e: 1 },
{ sse: 1, opcode: 0x660FD8, e: 1 },
{ sse: 1, opcode: 0x0FD9, e: 1 },
{ sse: 1, opcode: 0x660FD9, e: 1 },
{ sse: 1, opcode: 0x0FDA, e: 1 },
{ sse: 1, opcode: 0x660FDA, e: 1 },
{ sse: 1, opcode: 0x0FDB, e: 1 },
{ sse: 1, opcode: 0x660FDB, e: 1 },
{ sse: 1, opcode: 0x0FDC, e: 1 },
{ sse: 1, opcode: 0x660FDC, e: 1 },
{ sse: 1, opcode: 0x0FDD, e: 1 },
{ sse: 1, opcode: 0x660FDD, e: 1 },
{ sse: 1, opcode: 0x0FDE, e: 1 },
{ sse: 1, opcode: 0x660FDE, e: 1 },
{ sse: 1, opcode: 0x0FDF, e: 1 },
{ sse: 1, opcode: 0x660FDF, e: 1 },
{ opcode: 0x0FE0, e: 1 },
{ opcode: 0x660FE0, e: 1 },
{ opcode: 0x0FE1, e: 1 },
{ opcode: 0x660FE1, e: 1 },
{ opcode: 0x0FE2, e: 1 },
{ opcode: 0x660FE2, e: 1 },
{ opcode: 0x0FE3, e: 1 },
{ opcode: 0x660FE3, e: 1 },
{ opcode: 0x0FE4, e: 1 },
{ opcode: 0x660FE4, e: 1 },
{ opcode: 0x0FE5, e: 1 },
{ opcode: 0x660FE5, e: 1 },
{ sse: 1, opcode: 0x0FE0, e: 1 },
{ sse: 1, opcode: 0x660FE0, e: 1 },
{ sse: 1, opcode: 0x0FE1, e: 1 },
{ sse: 1, opcode: 0x660FE1, e: 1 },
{ sse: 1, opcode: 0x0FE2, e: 1 },
{ sse: 1, opcode: 0x660FE2, e: 1 },
{ sse: 1, opcode: 0x0FE3, e: 1 },
{ sse: 1, opcode: 0x660FE3, e: 1 },
{ sse: 1, opcode: 0x0FE4, e: 1 },
{ sse: 1, opcode: 0x660FE4, e: 1 },
{ sse: 1, opcode: 0x0FE5, e: 1 },
{ sse: 1, opcode: 0x660FE5, e: 1 },
{ opcode: 0x660FE6, e: 1, skip: 1, },
{ opcode: 0xF20FE6, e: 1, skip: 1, },
{ opcode: 0xF30FE6, e: 1, skip: 1, },
{ opcode: 0x0FE6, e: 1, }, // ud
{ opcode: 0x0FE7, e: 1, only_mem: 1 },
{ opcode: 0x660FE7, e: 1, only_mem: 1, },
{ 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, },
{ opcode: 0x0FE8, e: 1 },
{ opcode: 0x660FE8, e: 1 },
{ opcode: 0x0FE9, e: 1 },
{ opcode: 0x660FE9, e: 1 },
{ opcode: 0x0FEA, e: 1 },
{ opcode: 0x660FEA, e: 1 },
{ opcode: 0x0FEB, e: 1 },
{ opcode: 0x660FEB, e: 1 },
{ opcode: 0x0FEC, e: 1 },
{ opcode: 0x660FEC, e: 1 },
{ opcode: 0x0FED, e: 1 },
{ opcode: 0x660FED, e: 1 },
{ opcode: 0x0FEE, e: 1 },
{ opcode: 0x660FEE, e: 1 },
{ opcode: 0x0FEF, e: 1 },
{ opcode: 0x660FEF, e: 1 },
{ sse: 1, opcode: 0x0FE8, e: 1 },
{ sse: 1, opcode: 0x660FE8, e: 1 },
{ sse: 1, opcode: 0x0FE9, e: 1 },
{ sse: 1, opcode: 0x660FE9, e: 1 },
{ sse: 1, opcode: 0x0FEA, e: 1 },
{ sse: 1, opcode: 0x660FEA, e: 1 },
{ sse: 1, opcode: 0x0FEB, e: 1 },
{ sse: 1, opcode: 0x660FEB, e: 1 },
{ sse: 1, opcode: 0x0FEC, e: 1 },
{ sse: 1, opcode: 0x660FEC, e: 1 },
{ sse: 1, opcode: 0x0FED, e: 1 },
{ sse: 1, opcode: 0x660FED, e: 1 },
{ sse: 1, opcode: 0x0FEE, e: 1 },
{ sse: 1, opcode: 0x660FEE, e: 1 },
{ sse: 1, opcode: 0x0FEF, e: 1 },
{ sse: 1, opcode: 0x660FEF, e: 1 },
{ opcode: 0x0FF0, skip: 1, },
{ sse: 1, opcode: 0x0FF0, skip: 1, },
{ opcode: 0x0FF1, e: 1 },
{ opcode: 0x660FF1, e: 1 },
{ opcode: 0x0FF2, e: 1 },
{ opcode: 0x660FF2, e: 1 },
{ opcode: 0x0FF3, e: 1 },
{ opcode: 0x660FF3, e: 1, },
{ opcode: 0x0FF4, e: 1 },
{ opcode: 0x660FF4, e: 1 },
{ opcode: 0x0FF5, e: 1 },
{ opcode: 0x660FF5, e: 1 },
{ opcode: 0x0FF6, e: 1 },
{ opcode: 0x660FF6, e: 1 },
{ sse: 1, opcode: 0x0FF1, e: 1 },
{ sse: 1, opcode: 0x660FF1, e: 1 },
{ sse: 1, opcode: 0x0FF2, e: 1 },
{ sse: 1, opcode: 0x660FF2, e: 1 },
{ sse: 1, opcode: 0x0FF3, e: 1 },
{ sse: 1, opcode: 0x660FF3, e: 1, },
{ sse: 1, opcode: 0x0FF4, e: 1 },
{ sse: 1, opcode: 0x660FF4, e: 1 },
{ sse: 1, opcode: 0x0FF5, e: 1 },
{ sse: 1, opcode: 0x660FF5, e: 1 },
{ sse: 1, opcode: 0x0FF6, e: 1 },
{ sse: 1, opcode: 0x660FF6, e: 1 },
// maskmovq (0FF7), maskmovdqu (660FF7) tested manually
// Generated tests don't setup EDI as required (yet)
{ opcode: 0x0FF7, only_reg: 1, e: 1, skip: 1, },
{ opcode: 0x660FF7, only_reg: 1, e: 1, skip: 1, },
{ sse: 1, opcode: 0x0FF7, only_reg: 1, e: 1, skip: 1, },
{ sse: 1, opcode: 0x660FF7, only_reg: 1, e: 1, skip: 1, },
{ opcode: 0x0FF8, e: 1 },
{ opcode: 0x660FF8, e: 1 },
{ opcode: 0x0FF9, e: 1 },
{ opcode: 0x660FF9, e: 1 },
{ opcode: 0x0FFA, e: 1 },
{ opcode: 0x660FFA, e: 1 },
{ opcode: 0x0FFB, e: 1 },
{ opcode: 0x660FFB, e: 1 },
{ opcode: 0x0FFC, e: 1 },
{ opcode: 0x660FFC, e: 1 },
{ opcode: 0x0FFD, e: 1 },
{ opcode: 0x660FFD, e: 1 },
{ opcode: 0x0FFE, e: 1 },
{ opcode: 0x660FFE, e: 1 },
{ sse: 1, opcode: 0x0FF8, e: 1 },
{ sse: 1, opcode: 0x660FF8, e: 1 },
{ sse: 1, opcode: 0x0FF9, e: 1 },
{ sse: 1, opcode: 0x660FF9, e: 1 },
{ sse: 1, opcode: 0x0FFA, e: 1 },
{ sse: 1, opcode: 0x660FFA, e: 1 },
{ sse: 1, opcode: 0x0FFB, e: 1 },
{ sse: 1, opcode: 0x660FFB, e: 1 },
{ sse: 1, opcode: 0x0FFC, e: 1 },
{ sse: 1, opcode: 0x660FFC, e: 1 },
{ sse: 1, opcode: 0x0FFD, e: 1 },
{ sse: 1, opcode: 0x660FFD, e: 1 },
{ sse: 1, opcode: 0x0FFE, e: 1 },
{ sse: 1, opcode: 0x660FFE, e: 1 },
{ opcode: 0x0FFF, },
];
@ -763,14 +763,14 @@ for(let i = 0; i < 8; i++)
{ opcode: 0xD2, nonfaulting: 1, e: 1, fixed_g: i, mask_flags: of | af, },
{ opcode: 0xD3, nonfaulting: 1, os: 1, e: 1, fixed_g: i, mask_flags: of | af, },
{ opcode: 0xD8, e: 1, fixed_g: i, skip: 1, },
{ opcode: 0xD9, e: 1, fixed_g: i, skip: 1, },
{ opcode: 0xDA, e: 1, fixed_g: i, skip: 1, },
{ opcode: 0xDB, e: 1, fixed_g: i, skip: 1, },
{ opcode: 0xDC, e: 1, fixed_g: i, skip: 1, },
{ opcode: 0xDD, e: 1, fixed_g: i, skip: 1, },
{ opcode: 0xDE, e: 1, fixed_g: i, skip: 1, },
{ opcode: 0xDF, e: 1, fixed_g: i, skip: 1, },
{ opcode: 0xD8, e: 1, fixed_g: i, skip: 1, task_switch_test: 1, },
{ opcode: 0xD9, e: 1, fixed_g: i, skip: 1, task_switch_test: 1, },
{ opcode: 0xDA, e: 1, fixed_g: i, skip: 1, task_switch_test: 1, },
{ opcode: 0xDB, e: 1, fixed_g: i, skip: 1, task_switch_test: 1, },
{ opcode: 0xDC, e: 1, fixed_g: i, skip: 1, task_switch_test: 1, },
{ opcode: 0xDD, e: 1, fixed_g: i, skip: 1, task_switch_test: 1, },
{ opcode: 0xDE, e: 1, fixed_g: i, skip: 1, task_switch_test: 1, },
{ opcode: 0xDF, e: 1, fixed_g: i, skip: 1, task_switch_test: 1, },
]);
}

View file

@ -810,11 +810,32 @@ void trigger_ud()
raise_exception(CPU_EXCEPTION_UD);
}
__attribute__((noinline))
void trigger_ud_non_raising()
{
dbg_log("#ud");
dbg_trace();
#if DEBUG
if(cpu_exception_hook(CPU_EXCEPTION_UD))
{
return;
}
#endif
*instruction_pointer = *previous_ip;
call_interrupt_vector(CPU_EXCEPTION_UD, false, false, 0);
}
__attribute__((noinline))
void trigger_nm()
{
#if DEBUG
if(cpu_exception_hook(CPU_EXCEPTION_NM))
{
return;
}
#endif
*instruction_pointer = *previous_ip;
raise_exception(CPU_EXCEPTION_NM);
call_interrupt_vector(CPU_EXCEPTION_NM, false, false, 0);
}
__attribute__((noinline))
@ -1355,28 +1376,34 @@ void invlpg(int32_t addr)
*last_virt_esp = -1;
}
void task_switch_test()
bool task_switch_test()
{
if(cr[0] & (CR0_EM | CR0_TS))
{
trigger_nm();
return false;
}
}
void task_switch_test_mmx()
{
if(*cr & (CR0_EM | CR0_TS))
{
if(*cr & CR0_TS)
{
trigger_nm();
}
else
{
trigger_ud();
}
}
return true;
}
void task_switch_test_void() { task_switch_test(); }
bool task_switch_test_mmx()
{
if(*cr & CR0_TS)
{
trigger_nm();
return false;
}
else if(*cr & CR0_EM)
{
trigger_ud_non_raising();
return false;
}
return true;
}
void task_switch_test_mmx_void() { task_switch_test_mmx(); }
// read 2 or 4 byte from ip, depending on address size attribute
int32_t read_moffs()

View file

@ -148,8 +148,10 @@ void write_xmm128(int32_t r, int32_t i0, int32_t i1, int32_t i2, int32_t i3);
void write_xmm_reg128(int32_t r, union reg128 data);
void clear_tlb(void);
void full_clear_tlb(void);
void task_switch_test(void);
void task_switch_test_mmx(void);
bool task_switch_test(void);
void task_switch_test_void(void);
bool task_switch_test_mmx(void);
void task_switch_test_mmx_void(void);
int32_t read_moffs(void);
int32_t get_real_eip(void);
int32_t get_stack_reg(void);

View file

@ -568,20 +568,13 @@ void instr_9B() {
// fwait: check for pending fpu exceptions
if((cr[0] & (CR0_MP | CR0_TS)) == (CR0_MP | CR0_TS))
{
// task switched and MP bit is set
// Note: Different from task_switch_test
// Triggers when TS and MP bits are set (EM bit is ignored)
trigger_nm();
}
else
{
//if(fpu)
{
fwait();
}
//else
//{
// // EM bit isn't checked
// // If there's no FPU, do nothing
//}
fwait();
}
}
void instr16_9C() {
@ -1016,16 +1009,15 @@ DEFINE_MODRM_INSTR_FPU_READ32(instr_D8_6, fpu_fdiv(0, ___))
DEFINE_MODRM_INSTR_FPU_READ32(instr_D8_7, fpu_fdivr(0, ___))
DEFINE_MODRM_INSTR_FPU_READ32(instr_D9_0, fpu_push(___))
void instr_D9_1_mem(int32_t addr) { task_switch_test(); dbg_log("d9/1"); trigger_ud(); }
void instr_D9_1_reg(int32_t r) { task_switch_test(); fpu_fxch(r); }
void instr_D9_2_mem(int32_t addr) { task_switch_test(); fpu_fstm32(addr); }
void instr_D9_2_reg(int32_t r) { task_switch_test(); if(r != 0) { trigger_ud(); } }
void instr_D9_3_mem(int32_t addr) { task_switch_test(); fpu_fstm32p(addr); }
void instr_D9_3_reg(int32_t r) { task_switch_test(); dbg_log("fstp1"); trigger_ud(); }
void instr_D9_4_mem(int32_t addr) { task_switch_test(); fpu_fldenv(addr); }
void instr_D9_1_mem(int32_t addr) { dbg_log("d9/1"); trigger_ud(); }
void instr_D9_1_reg(int32_t r) { fpu_fxch(r); }
void instr_D9_2_mem(int32_t addr) { fpu_fstm32(addr); }
void instr_D9_2_reg(int32_t r) { if(r != 0) { trigger_ud(); } }
void instr_D9_3_mem(int32_t addr) { fpu_fstm32p(addr); }
void instr_D9_3_reg(int32_t r) { dbg_log("fstp1"); trigger_ud(); }
void instr_D9_4_mem(int32_t addr) { fpu_fldenv(addr); }
void instr_D9_4_reg(int32_t r)
{
task_switch_test();
double_t st0 = fpu_get_st0();
switch(r)
{
@ -1048,11 +1040,10 @@ void instr_D9_4_reg(int32_t r)
trigger_ud();
}
}
void instr_D9_5_mem(int32_t addr) { task_switch_test(); fpu_fldcw(addr); }
void instr_D9_5_mem(int32_t addr) { fpu_fldcw(addr); }
void instr_D9_5_reg(int32_t r)
{
// fld1/fldl2t/fldl2e/fldpi/fldlg2/fldln2/fldz
task_switch_test();
switch(r)
{
case 0: fpu_push(1); break;
@ -1065,10 +1056,9 @@ void instr_D9_5_reg(int32_t r)
case 7: dbg_log("d9/5/7"); trigger_ud(); break;
}
}
void instr_D9_6_mem(int32_t addr) { task_switch_test(); fpu_fstenv(addr); }
void instr_D9_6_mem(int32_t addr) { fpu_fstenv(addr); }
void instr_D9_6_reg(int32_t r)
{
task_switch_test();
double_t st0 = fpu_get_st0();
switch(r)
@ -1113,10 +1103,9 @@ void instr_D9_6_reg(int32_t r)
dbg_assert(false);
}
}
void instr_D9_7_mem(int32_t addr) { task_switch_test(); fpu_fstcw(addr); }
void instr_D9_7_mem(int32_t addr) { fpu_fstcw(addr); }
void instr_D9_7_reg(int32_t r)
{
task_switch_test();
double_t st0 = fpu_get_st0();
switch(r)
@ -1155,40 +1144,39 @@ void instr_D9_7_reg(int32_t r)
}
}
void instr_DA_0_mem(int32_t addr) { task_switch_test(); fpu_fadd(0, safe_read32s(addr)); }
void instr_DA_1_mem(int32_t addr) { task_switch_test(); fpu_fmul(0, safe_read32s(addr)); }
void instr_DA_2_mem(int32_t addr) { task_switch_test(); fpu_fcom(safe_read32s(addr)); }
void instr_DA_3_mem(int32_t addr) { task_switch_test(); fpu_fcomp(safe_read32s(addr)); }
void instr_DA_4_mem(int32_t addr) { task_switch_test(); fpu_fsub(0, safe_read32s(addr)); }
void instr_DA_5_mem(int32_t addr) { task_switch_test(); fpu_fsubr(0, safe_read32s(addr)); }
void instr_DA_6_mem(int32_t addr) { task_switch_test(); fpu_fdiv(0, safe_read32s(addr)); }
void instr_DA_7_mem(int32_t addr) { task_switch_test(); fpu_fdivr(0, safe_read32s(addr)); }
void instr_DA_0_mem(int32_t addr) { fpu_fadd(0, safe_read32s(addr)); }
void instr_DA_1_mem(int32_t addr) { fpu_fmul(0, safe_read32s(addr)); }
void instr_DA_2_mem(int32_t addr) { fpu_fcom(safe_read32s(addr)); }
void instr_DA_3_mem(int32_t addr) { fpu_fcomp(safe_read32s(addr)); }
void instr_DA_4_mem(int32_t addr) { fpu_fsub(0, safe_read32s(addr)); }
void instr_DA_5_mem(int32_t addr) { fpu_fsubr(0, safe_read32s(addr)); }
void instr_DA_6_mem(int32_t addr) { fpu_fdiv(0, safe_read32s(addr)); }
void instr_DA_7_mem(int32_t addr) { fpu_fdivr(0, safe_read32s(addr)); }
void instr_DA_0_reg(int32_t r) { task_switch_test(); fpu_fcmovcc(test_b(), r); }
void instr_DA_1_reg(int32_t r) { task_switch_test(); fpu_fcmovcc(test_z(), r); }
void instr_DA_2_reg(int32_t r) { task_switch_test(); fpu_fcmovcc(test_be(), r); }
void instr_DA_3_reg(int32_t r) { task_switch_test(); fpu_fcmovcc(test_p(), r); }
void instr_DA_0_reg(int32_t r) { fpu_fcmovcc(test_b(), r); }
void instr_DA_1_reg(int32_t r) { fpu_fcmovcc(test_z(), r); }
void instr_DA_2_reg(int32_t r) { fpu_fcmovcc(test_be(), r); }
void instr_DA_3_reg(int32_t r) { fpu_fcmovcc(test_p(), r); }
void instr_DA_4_reg(int32_t r) { trigger_ud(); }
void instr_DA_5_reg(int32_t r) { task_switch_test(); if(r == 1) { fpu_fucompp(); } else { trigger_ud(); } }
void instr_DA_5_reg(int32_t r) { if(r == 1) { fpu_fucompp(); } else { trigger_ud(); } }
void instr_DA_6_reg(int32_t r) { trigger_ud(); }
void instr_DA_7_reg(int32_t r) { trigger_ud(); }
void instr_DB_0_mem(int32_t addr) { task_switch_test(); fpu_fldm32(addr); }
void instr_DB_0_mem(int32_t addr) { fpu_fldm32(addr); }
void instr_DB_1_mem(int32_t addr) { trigger_ud(); }
void instr_DB_2_mem(int32_t addr) { task_switch_test(); fpu_fistm32(addr); }
void instr_DB_3_mem(int32_t addr) { task_switch_test(); fpu_fistm32p(addr); }
void instr_DB_2_mem(int32_t addr) { fpu_fistm32(addr); }
void instr_DB_3_mem(int32_t addr) { fpu_fistm32p(addr); }
void instr_DB_4_mem(int32_t addr) { trigger_ud(); }
void instr_DB_5_mem(int32_t addr) { task_switch_test(); fpu_fldm80(addr); }
void instr_DB_5_mem(int32_t addr) { fpu_fldm80(addr); }
void instr_DB_6_mem(int32_t addr) { trigger_ud(); }
void instr_DB_7_mem(int32_t addr) { task_switch_test(); fpu_fst80p(addr); }
void instr_DB_7_mem(int32_t addr) { fpu_fst80p(addr); }
void instr_DB_0_reg(int32_t r) { task_switch_test(); fpu_fcmovcc(!test_b(), r); }
void instr_DB_1_reg(int32_t r) { task_switch_test(); fpu_fcmovcc(!test_z(), r); }
void instr_DB_2_reg(int32_t r) { task_switch_test(); fpu_fcmovcc(!test_be(), r); }
void instr_DB_3_reg(int32_t r) { task_switch_test(); fpu_fcmovcc(!test_p(), r); }
void instr_DB_0_reg(int32_t r) { fpu_fcmovcc(!test_b(), r); }
void instr_DB_1_reg(int32_t r) { fpu_fcmovcc(!test_z(), r); }
void instr_DB_2_reg(int32_t r) { fpu_fcmovcc(!test_be(), r); }
void instr_DB_3_reg(int32_t r) { fpu_fcmovcc(!test_p(), r); }
void instr_DB_4_reg(int32_t r)
{
task_switch_test();
if(r == 3)
{
fpu_finit();
@ -1206,80 +1194,80 @@ void instr_DB_4_reg(int32_t r)
trigger_ud();
}
}
void instr_DB_5_reg(int32_t r) { task_switch_test(); fpu_fucomi(r); }
void instr_DB_6_reg(int32_t r) { task_switch_test(); fpu_fcomi(r); }
void instr_DB_5_reg(int32_t r) { fpu_fucomi(r); }
void instr_DB_6_reg(int32_t r) { fpu_fcomi(r); }
void instr_DB_7_reg(int32_t r) { trigger_ud(); }
void instr_DC_0_mem(int32_t addr) { task_switch_test(); fpu_fadd(0, fpu_load_m64(addr)); }
void instr_DC_1_mem(int32_t addr) { task_switch_test(); fpu_fmul(0, fpu_load_m64(addr)); }
void instr_DC_2_mem(int32_t addr) { task_switch_test(); fpu_fcom(fpu_load_m64(addr)); }
void instr_DC_3_mem(int32_t addr) { task_switch_test(); fpu_fcomp(fpu_load_m64(addr)); }
void instr_DC_4_mem(int32_t addr) { task_switch_test(); fpu_fsub(0, fpu_load_m64(addr)); }
void instr_DC_5_mem(int32_t addr) { task_switch_test(); fpu_fsubr(0, fpu_load_m64(addr)); }
void instr_DC_6_mem(int32_t addr) { task_switch_test(); fpu_fdiv(0, fpu_load_m64(addr)); }
void instr_DC_7_mem(int32_t addr) { task_switch_test(); fpu_fdivr(0, fpu_load_m64(addr)); }
void instr_DC_0_mem(int32_t addr) { fpu_fadd(0, fpu_load_m64(addr)); }
void instr_DC_1_mem(int32_t addr) { fpu_fmul(0, fpu_load_m64(addr)); }
void instr_DC_2_mem(int32_t addr) { fpu_fcom(fpu_load_m64(addr)); }
void instr_DC_3_mem(int32_t addr) { fpu_fcomp(fpu_load_m64(addr)); }
void instr_DC_4_mem(int32_t addr) { fpu_fsub(0, fpu_load_m64(addr)); }
void instr_DC_5_mem(int32_t addr) { fpu_fsubr(0, fpu_load_m64(addr)); }
void instr_DC_6_mem(int32_t addr) { fpu_fdiv(0, fpu_load_m64(addr)); }
void instr_DC_7_mem(int32_t addr) { fpu_fdivr(0, fpu_load_m64(addr)); }
void instr_DC_0_reg(int32_t r) { task_switch_test(); fpu_fadd(r, fpu_get_sti(r)); }
void instr_DC_1_reg(int32_t r) { task_switch_test(); fpu_fmul(r, fpu_get_sti(r)); }
void instr_DC_2_reg(int32_t r) { task_switch_test(); fpu_fcom(fpu_get_sti(r)); }
void instr_DC_3_reg(int32_t r) { task_switch_test(); fpu_fcomp(fpu_get_sti(r)); }
void instr_DC_4_reg(int32_t r) { task_switch_test(); fpu_fsub(r, fpu_get_sti(r)); }
void instr_DC_5_reg(int32_t r) { task_switch_test(); fpu_fsubr(r, fpu_get_sti(r)); }
void instr_DC_6_reg(int32_t r) { task_switch_test(); fpu_fdiv(r, fpu_get_sti(r)); }
void instr_DC_7_reg(int32_t r) { task_switch_test(); fpu_fdivr(r, fpu_get_sti(r)); }
void instr_DC_0_reg(int32_t r) { fpu_fadd(r, fpu_get_sti(r)); }
void instr_DC_1_reg(int32_t r) { fpu_fmul(r, fpu_get_sti(r)); }
void instr_DC_2_reg(int32_t r) { fpu_fcom(fpu_get_sti(r)); }
void instr_DC_3_reg(int32_t r) { fpu_fcomp(fpu_get_sti(r)); }
void instr_DC_4_reg(int32_t r) { fpu_fsub(r, fpu_get_sti(r)); }
void instr_DC_5_reg(int32_t r) { fpu_fsubr(r, fpu_get_sti(r)); }
void instr_DC_6_reg(int32_t r) { fpu_fdiv(r, fpu_get_sti(r)); }
void instr_DC_7_reg(int32_t r) { fpu_fdivr(r, fpu_get_sti(r)); }
void instr_DD_0_mem(int32_t addr) { task_switch_test(); fpu_fldm64(addr); }
void instr_DD_0_mem(int32_t addr) { fpu_fldm64(addr); }
void instr_DD_1_mem(int32_t addr) { dbg_log("fisttp"); trigger_ud(); }
void instr_DD_2_mem(int32_t addr) { task_switch_test(); fpu_fstm64(addr); }
void instr_DD_3_mem(int32_t addr) { task_switch_test(); fpu_fstm64p(addr); }
void instr_DD_4_mem(int32_t addr) { task_switch_test(); fpu_frstor(addr); }
void instr_DD_2_mem(int32_t addr) { fpu_fstm64(addr); }
void instr_DD_3_mem(int32_t addr) { fpu_fstm64p(addr); }
void instr_DD_4_mem(int32_t addr) { fpu_frstor(addr); }
void instr_DD_5_mem(int32_t addr) { dbg_log("dd/5"); trigger_ud(); }
void instr_DD_6_mem(int32_t addr) { task_switch_test(); fpu_fsave(addr); }
void instr_DD_7_mem(int32_t addr) { task_switch_test(); fpu_fnstsw_mem(addr); }
void instr_DD_6_mem(int32_t addr) { fpu_fsave(addr); }
void instr_DD_7_mem(int32_t addr) { fpu_fnstsw_mem(addr); }
void instr_DD_0_reg(int32_t r) { task_switch_test(); fpu_ffree(r); }
void instr_DD_0_reg(int32_t r) { fpu_ffree(r); }
void instr_DD_1_reg(int32_t r) { trigger_ud(); }
void instr_DD_2_reg(int32_t r) { task_switch_test(); fpu_fst(r); }
void instr_DD_3_reg(int32_t r) { task_switch_test(); fpu_fstp(r); }
void instr_DD_4_reg(int32_t r) { task_switch_test(); fpu_fucom(r); }
void instr_DD_5_reg(int32_t r) { task_switch_test(); fpu_fucomp(r); }
void instr_DD_2_reg(int32_t r) { fpu_fst(r); }
void instr_DD_3_reg(int32_t r) { fpu_fstp(r); }
void instr_DD_4_reg(int32_t r) { fpu_fucom(r); }
void instr_DD_5_reg(int32_t r) { fpu_fucomp(r); }
void instr_DD_6_reg(int32_t r) { trigger_ud(); }
void instr_DD_7_reg(int32_t r) { trigger_ud(); }
void instr_DE_0_mem(int32_t addr) { task_switch_test(); fpu_fadd(0, (int16_t) safe_read16(addr)); }
void instr_DE_1_mem(int32_t addr) { task_switch_test(); fpu_fmul(0, (int16_t) safe_read16(addr)); }
void instr_DE_2_mem(int32_t addr) { task_switch_test(); fpu_fcom((int16_t) safe_read16(addr)); }
void instr_DE_3_mem(int32_t addr) { task_switch_test(); fpu_fcomp((int16_t) safe_read16(addr)); }
void instr_DE_4_mem(int32_t addr) { task_switch_test(); fpu_fsub(0, (int16_t) safe_read16(addr)); }
void instr_DE_5_mem(int32_t addr) { task_switch_test(); fpu_fsubr(0, (int16_t) safe_read16(addr)); }
void instr_DE_6_mem(int32_t addr) { task_switch_test(); fpu_fdiv(0, (int16_t) safe_read16(addr)); }
void instr_DE_7_mem(int32_t addr) { task_switch_test(); fpu_fdivr(0, (int16_t) safe_read16(addr)); }
void instr_DE_0_mem(int32_t addr) { fpu_fadd(0, (int16_t) safe_read16(addr)); }
void instr_DE_1_mem(int32_t addr) { fpu_fmul(0, (int16_t) safe_read16(addr)); }
void instr_DE_2_mem(int32_t addr) { fpu_fcom((int16_t) safe_read16(addr)); }
void instr_DE_3_mem(int32_t addr) { fpu_fcomp((int16_t) safe_read16(addr)); }
void instr_DE_4_mem(int32_t addr) { fpu_fsub(0, (int16_t) safe_read16(addr)); }
void instr_DE_5_mem(int32_t addr) { fpu_fsubr(0, (int16_t) safe_read16(addr)); }
void instr_DE_6_mem(int32_t addr) { fpu_fdiv(0, (int16_t) safe_read16(addr)); }
void instr_DE_7_mem(int32_t addr) { fpu_fdivr(0, (int16_t) safe_read16(addr)); }
void instr_DE_0_reg(int32_t r) { task_switch_test(); fpu_fadd(r, fpu_get_sti(r)); fpu_pop(); }
void instr_DE_1_reg(int32_t r) { task_switch_test(); fpu_fmul(r, fpu_get_sti(r)); fpu_pop(); }
void instr_DE_2_reg(int32_t r) { task_switch_test(); fpu_fcom(fpu_get_sti(r)); fpu_pop(); }
void instr_DE_3_reg(int32_t r) { task_switch_test(); fpu_fcomp(fpu_get_sti(r)); fpu_pop(); }
void instr_DE_4_reg(int32_t r) { task_switch_test(); fpu_fsub(r, fpu_get_sti(r)); fpu_pop(); }
void instr_DE_5_reg(int32_t r) { task_switch_test(); fpu_fsubr(r, fpu_get_sti(r)); fpu_pop(); }
void instr_DE_6_reg(int32_t r) { task_switch_test(); fpu_fdiv(r, fpu_get_sti(r)); fpu_pop(); }
void instr_DE_7_reg(int32_t r) { task_switch_test(); fpu_fdivr(r, fpu_get_sti(r)); fpu_pop(); }
void instr_DE_0_reg(int32_t r) { fpu_fadd(r, fpu_get_sti(r)); fpu_pop(); }
void instr_DE_1_reg(int32_t r) { fpu_fmul(r, fpu_get_sti(r)); fpu_pop(); }
void instr_DE_2_reg(int32_t r) { fpu_fcom(fpu_get_sti(r)); fpu_pop(); }
void instr_DE_3_reg(int32_t r) { fpu_fcomp(fpu_get_sti(r)); fpu_pop(); }
void instr_DE_4_reg(int32_t r) { fpu_fsub(r, fpu_get_sti(r)); fpu_pop(); }
void instr_DE_5_reg(int32_t r) { fpu_fsubr(r, fpu_get_sti(r)); fpu_pop(); }
void instr_DE_6_reg(int32_t r) { fpu_fdiv(r, fpu_get_sti(r)); fpu_pop(); }
void instr_DE_7_reg(int32_t r) { fpu_fdivr(r, fpu_get_sti(r)); fpu_pop(); }
void instr_DF_0_mem(int32_t addr) { task_switch_test(); fpu_push((int16_t) safe_read16(addr)); }
void instr_DF_0_mem(int32_t addr) { fpu_push((int16_t) safe_read16(addr)); }
void instr_DF_1_mem(int32_t addr) { dbg_log("df/fisttp"); trigger_ud(); }
void instr_DF_2_mem(int32_t addr) { task_switch_test(); fpu_fistm16(addr); }
void instr_DF_3_mem(int32_t addr) { task_switch_test(); fpu_fistm16p(addr); }
void instr_DF_2_mem(int32_t addr) { fpu_fistm16(addr); }
void instr_DF_3_mem(int32_t addr) { fpu_fistm16p(addr); }
void instr_DF_4_mem(int32_t addr) { dbg_log("fbld"); trigger_ud(); }
void instr_DF_5_mem(int32_t addr) { task_switch_test(); fpu_fildm64(addr); }
void instr_DF_5_mem(int32_t addr) { fpu_fildm64(addr); }
void instr_DF_6_mem(int32_t addr) { dbg_log("fbstp"); trigger_ud(); }
void instr_DF_7_mem(int32_t addr) { task_switch_test(); fpu_fistm64p(addr); }
void instr_DF_7_mem(int32_t addr) { fpu_fistm64p(addr); }
void instr_DF_0_reg(int32_t r) { trigger_ud(); }
void instr_DF_1_reg(int32_t r) { trigger_ud(); }
void instr_DF_2_reg(int32_t r) { trigger_ud(); }
void instr_DF_3_reg(int32_t r) { trigger_ud(); }
void instr_DF_4_reg(int32_t r) { task_switch_test(); if(r == 0) { fpu_fnstsw_reg(); } else { trigger_ud(); } }
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_4_reg(int32_t r) { if(r == 0) { fpu_fnstsw_reg(); } else { trigger_ud(); } }
void instr_DF_5_reg(int32_t r) { fpu_fucomip(r); }
void instr_DF_6_reg(int32_t r) { fpu_fcomip(r); }
void instr_DF_7_reg(int32_t r) { trigger_ud(); }
void instr16_E0(int32_t imm8s) { loopne16(imm8s); }

View file

@ -114,8 +114,8 @@
void name ## _reg(int32_t r1, int32_t r) { int32_t ___ = read_reg32(r1); fun; }
#define DEFINE_MODRM_INSTR_FPU_READ32(name, fun) \
void name ## _mem(int32_t addr) { task_switch_test(); double_t ___ = fpu_load_m32(addr); fun; } \
void name ## _reg(int32_t r) { task_switch_test(); double_t ___ = fpu_get_sti(r); fun; }
void name ## _mem(int32_t addr) { double_t ___ = fpu_load_m32(addr); fun; } \
void name ## _reg(int32_t r) { double_t ___ = fpu_get_sti(r); fun; }
void instr_00_mem(int32_t addr, int32_t r);
void instr_00_reg(int32_t r1, int32_t r);

View file

@ -217,14 +217,12 @@ DEFINE_SSE_SPLIT(instr_0F10, safe_read128s, read_xmm128s)
void instr_F30F10_reg(int32_t r1, int32_t r2) {
// movss xmm, xmm/m32
task_switch_test_mmx();
union reg128 data = read_xmm128s(r1);
union reg128 orig = read_xmm128s(r2);
write_xmm128(r2, data.u32[0], orig.u32[1], orig.u32[2], orig.u32[3]);
}
void instr_F30F10_mem(int32_t addr, int32_t r) {
// movss xmm, xmm/m32
task_switch_test_mmx();
int32_t data = safe_read32s(addr);
write_xmm128(r, data, 0, 0, 0);
}
@ -237,14 +235,12 @@ DEFINE_SSE_SPLIT(instr_660F10, safe_read128s, read_xmm128s)
void instr_F20F10_reg(int32_t r1, int32_t r2) {
// movsd xmm, xmm/m64
task_switch_test_mmx();
union reg128 data = read_xmm128s(r1);
union reg128 orig = read_xmm128s(r2);
write_xmm128(r2, data.u32[0], data.u32[1], orig.u32[2], orig.u32[3]);
}
void instr_F20F10_mem(int32_t addr, int32_t r) {
// movsd xmm, xmm/m64
task_switch_test_mmx();
union reg64 data = safe_read64s(addr);
write_xmm128(r, data.u32[0], data.u32[1], 0, 0);
}
@ -260,14 +256,12 @@ void instr_0F11_mem(int32_t addr, int32_t r) {
void instr_F30F11_reg(int32_t rm_dest, int32_t reg_src) {
// movss xmm/m32, xmm
task_switch_test_mmx();
union reg128 data = read_xmm128s(reg_src);
union reg128 orig = read_xmm128s(rm_dest);
write_xmm128(rm_dest, data.u32[0], orig.u32[1], orig.u32[2], orig.u32[3]);
}
void instr_F30F11_mem(int32_t addr, int32_t r) {
// movss xmm/m32, xmm
task_switch_test_mmx();
union reg128 data = read_xmm128s(r);
safe_write32(addr, data.u32[0]);
}
@ -283,28 +277,24 @@ void instr_660F11_mem(int32_t addr, int32_t r) {
void instr_F20F11_reg(int32_t r1, int32_t r2) {
// movsd xmm/m64, xmm
task_switch_test_mmx();
union reg128 data = read_xmm128s(r2);
union reg128 orig = read_xmm128s(r1);
write_xmm128(r1, data.u32[0], data.u32[1], orig.u32[2], orig.u32[3]);
}
void instr_F20F11_mem(int32_t addr, int32_t r) {
// movsd xmm/m64, xmm
task_switch_test_mmx();
union reg64 data = read_xmm64s(r);
safe_write64(addr, data.u64[0]);
}
void instr_0F12_mem(int32_t addr, int32_t r) {
// movlps xmm, m64
task_switch_test_mmx();
union reg64 data = safe_read64s(addr);
union reg128 orig = read_xmm128s(r);
write_xmm128(r, data.u32[0], data.u32[1], orig.u32[2], orig.u32[3]);
}
void instr_0F12_reg(int32_t r1, int32_t r2) {
// movhlps xmm, xmm
task_switch_test_mmx();
union reg128 data = read_xmm128s(r1);
union reg128 orig = read_xmm128s(r2);
write_xmm128(r2, data.u32[2], data.u32[3], orig.u32[2], orig.u32[3]);
@ -313,7 +303,6 @@ void instr_0F12_reg(int32_t r1, int32_t r2) {
void instr_660F12_reg(int32_t r1, int32_t r) { trigger_ud(); }
void instr_660F12_mem(int32_t addr, int32_t r) {
// movlpd xmm, m64
task_switch_test_mmx();
union reg64 data = safe_read64s(addr);
write_xmm64(r, data);
}
@ -338,7 +327,6 @@ void instr_660F13_mem(int32_t addr, int32_t r) {
void instr_0F14(union reg64 source, int32_t r) {
// unpcklps xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg64 destination = read_xmm64s(r);
write_xmm128(
@ -354,7 +342,6 @@ DEFINE_SSE_SPLIT(instr_0F14, safe_read64s, read_xmm64s)
void instr_660F14(union reg64 source, int32_t r) {
// unpcklpd xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg64 destination = read_xmm64s(r);
write_xmm128(
@ -370,7 +357,6 @@ DEFINE_SSE_SPLIT(instr_660F14, safe_read64s, read_xmm64s)
void instr_0F15(union reg128 source, int32_t r) {
// unpckhps xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
write_xmm128(
@ -386,7 +372,6 @@ DEFINE_SSE_SPLIT(instr_0F15, safe_read128s, read_xmm128s)
void instr_660F15(union reg128 source, int32_t r) {
// unpckhpd xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
write_xmm128(
@ -405,7 +390,6 @@ void instr_0F16_mem(int32_t addr, int32_t r) {
}
void instr_0F16_reg(int32_t r1, int32_t r2) {
// movlhps xmm, xmm
task_switch_test_mmx();
union reg128 data = read_xmm128s(r1);
union reg128 orig = read_xmm128s(r2);
write_xmm128(r2, orig.u32[0], orig.u32[1], data.u32[0], data.u32[1]);
@ -619,7 +603,6 @@ DEFINE_SSE_SPLIT(instr_660F28, safe_read128s, read_xmm128s)
void instr_0F29_mem(int32_t addr, int32_t r) {
// movaps m128, xmm
task_switch_test_mmx();
union reg128 data = read_xmm128s(r);
// XXX: Aligned write or #gp
safe_write128(addr, data);
@ -630,7 +613,6 @@ void instr_0F29_reg(int32_t r1, int32_t r2) {
}
void instr_660F29_mem(int32_t addr, int32_t r) {
// movapd m128, xmm
task_switch_test_mmx();
union reg128 data = read_xmm128s(r);
// XXX: Aligned write or #gp
safe_write128(addr, data);
@ -665,7 +647,6 @@ void instr_F20F2C(union reg64 source, int32_t r) {
// cvttsd2si r32, xmm/m64
// emscripten bug causes this ported instruction to throw "integer result unpresentable"
// https://github.com/kripken/emscripten/issues/5433
task_switch_test_mmx();
#if 0
union reg64 source = read_xmm_mem64s();
double f = source.f64[0];
@ -1008,7 +989,6 @@ DEFINE_MODRM_INSTR_READ32(instr32_0F4F, cmovcc32(!test_le(), ___, r))
void instr_0F50_reg(int32_t r1, int32_t r2) {
// movmskps r, xmm
task_switch_test_mmx();
union reg128 source = read_xmm128s(r1);
int32_t data = source.u32[0] >> 31 | (source.u32[1] >> 31) << 1 |
(source.u32[2] >> 31) << 2 | (source.u32[3] >> 31) << 3;
@ -1018,7 +998,6 @@ void instr_0F50_mem(int32_t addr, int32_t r1) { trigger_ud(); }
void instr_660F50_reg(int32_t r1, int32_t r2) {
// movmskpd r, xmm
task_switch_test_mmx();
union reg128 source = read_xmm128s(r1);
int32_t data = (source.u32[1] >> 31) | (source.u32[3] >> 31) << 1;
write_reg32(r2, data);
@ -1097,7 +1076,6 @@ void instr_0F5F() { unimplemented_sse(); }
void instr_0F60(int32_t source, int32_t r) {
// punpcklbw mm, mm/m32
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
int32_t byte0 = destination.u8[0];
@ -1119,7 +1097,6 @@ DEFINE_SSE_SPLIT(instr_0F60, safe_read32s, read_mmx32s)
void instr_660F60(union reg64 source, int32_t r) {
// punpcklbw xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg64 destination = read_xmm64s(r);
write_xmm128(
r,
@ -1133,7 +1110,6 @@ DEFINE_SSE_SPLIT(instr_660F60, safe_read64s, read_xmm64s)
void instr_0F61(int32_t source, int32_t r) {
// punpcklwd mm, mm/m32
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
int32_t word0 = destination.u16[0];
@ -1151,7 +1127,6 @@ DEFINE_SSE_SPLIT(instr_0F61, safe_read32s, read_mmx32s)
void instr_660F61(union reg64 source, int32_t r) {
// punpcklwd xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg64 destination = read_xmm64s(r);
write_xmm128(
r,
@ -1165,7 +1140,6 @@ DEFINE_SSE_SPLIT(instr_660F61, safe_read64s, read_xmm64s)
void instr_0F62(int32_t source, int32_t r) {
// punpckldq mm, mm/m32
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
write_mmx64(r, destination.u32[0], source);
}
@ -1174,7 +1148,6 @@ DEFINE_SSE_SPLIT(instr_0F62, safe_read32s, read_mmx32s)
void instr_660F62(union reg128 source, int32_t r) {
// punpckldq xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
write_xmm128(
r,
@ -1188,7 +1161,6 @@ DEFINE_SSE_SPLIT(instr_660F62, safe_read128s, read_xmm128s)
void instr_0F63(union reg64 source, int32_t r) {
// packsswb mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
int32_t low = saturate_sw_to_sb(destination.u16[0]) |
@ -1208,7 +1180,6 @@ DEFINE_SSE_SPLIT(instr_0F63, safe_read64s, read_mmx64s)
void instr_660F63(union reg128 source, int32_t r) {
// packsswb xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
int32_t dword0 = saturate_sw_to_sb(destination.u16[0]) |
@ -1237,7 +1208,6 @@ DEFINE_SSE_SPLIT(instr_660F63, safe_read128s, read_xmm128s)
void instr_0F64(union reg64 source, int32_t r) {
// pcmpgtb mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
union reg64 result = { { 0 } };
@ -1253,7 +1223,6 @@ DEFINE_SSE_SPLIT(instr_0F64, safe_read64s, read_mmx64s)
void instr_660F64(union reg128 source, int32_t r) {
// pcmpgtb xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
union reg128 result = { { 0 } };
@ -1268,7 +1237,6 @@ DEFINE_SSE_SPLIT(instr_660F64, safe_read128s, read_xmm128s)
void instr_0F65(union reg64 source, int32_t r) {
// pcmpgtw mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
int32_t word0 = destination.i16[0] > source.i16[0] ? 0xFFFF : 0;
@ -1286,7 +1254,6 @@ DEFINE_SSE_SPLIT(instr_0F65, safe_read64s, read_mmx64s)
void instr_660F65(union reg128 source, int32_t r) {
// pcmpgtw xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
union reg128 result = { { 0 } };
@ -1301,7 +1268,6 @@ DEFINE_SSE_SPLIT(instr_660F65, safe_read128s, read_xmm128s)
void instr_0F66(union reg64 source, int32_t r) {
// pcmpgtd mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
int32_t low = destination.i32[0] > source.i32[0] ? -1 : 0;
@ -1314,7 +1280,6 @@ DEFINE_SSE_SPLIT(instr_0F66, safe_read64s, read_mmx64s)
void instr_660F66(union reg128 source, int32_t r) {
// pcmpgtd xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
write_xmm128(
@ -1329,7 +1294,6 @@ DEFINE_SSE_SPLIT(instr_660F66, safe_read128s, read_xmm128s)
void instr_0F67(union reg64 source, int32_t r) {
// packuswb mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
uint32_t low = saturate_sw_to_ub(destination.u16[0]) |
@ -1349,7 +1313,6 @@ DEFINE_SSE_SPLIT(instr_0F67, safe_read64s, read_mmx64s)
void instr_660F67(union reg128 source, int32_t r) {
// packuswb xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
union reg128 result;
@ -1366,7 +1329,6 @@ DEFINE_SSE_SPLIT(instr_660F67, safe_read128s, read_xmm128s)
void instr_0F68(union reg64 source, int32_t r) {
// punpckhbw mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
int32_t byte0 = destination.u8[4];
@ -1388,7 +1350,6 @@ DEFINE_SSE_SPLIT(instr_0F68, safe_read64s, read_mmx64s)
void instr_660F68(union reg128 source, int32_t r) {
// punpckhbw xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
write_xmm128(
@ -1403,7 +1364,6 @@ DEFINE_SSE_SPLIT(instr_660F68, safe_read128s, read_xmm128s)
void instr_0F69(union reg64 source, int32_t r) {
// punpckhwd mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
int32_t word0 = destination.u16[2];
@ -1421,7 +1381,6 @@ DEFINE_SSE_SPLIT(instr_0F69, safe_read64s, read_mmx64s)
void instr_660F69(union reg128 source, int32_t r) {
// punpckhwd xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
int32_t dword0 = destination.u16[4] | source.u16[4] << 16;
@ -1435,7 +1394,6 @@ DEFINE_SSE_SPLIT(instr_660F69, safe_read128s, read_xmm128s)
void instr_0F6A(union reg64 source, int32_t r) {
// punpckhdq mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
write_mmx64(r, destination.u32[1], source.u32[1]);
}
@ -1444,7 +1402,6 @@ DEFINE_SSE_SPLIT(instr_0F6A, safe_read64s, read_mmx64s)
void instr_660F6A(union reg128 source, int32_t r) {
// punpckhdq xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
write_xmm128(r, destination.u32[2], source.u32[2], destination.u32[3], source.u32[3]);
}
@ -1452,7 +1409,6 @@ DEFINE_SSE_SPLIT(instr_660F6A, safe_read128s, read_xmm128s)
void instr_0F6B(union reg64 source, int32_t r) {
// packssdw mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
int32_t low = saturate_sd_to_sw(destination.u32[0]) |
@ -1467,7 +1423,6 @@ DEFINE_SSE_SPLIT(instr_0F6B, safe_read64s, read_mmx64s)
void instr_660F6B(union reg128 source, int32_t r) {
// packssdw xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
int32_t dword0 = saturate_sd_to_sw(destination.u32[0]) |
@ -1489,7 +1444,6 @@ void instr_0F6C_reg(int32_t r1, int32_t r2) { trigger_ud(); }
void instr_660F6C(union reg128 source, int32_t r) {
// punpcklqdq xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
write_xmm128(r, destination.u32[0], destination.u32[1], source.u32[0], source.u32[1]);
@ -1502,7 +1456,6 @@ void instr_0F6D_reg(int32_t r1, int32_t r2) { trigger_ud(); }
void instr_660F6D(union reg128 source, int32_t r) {
// punpckhqdq xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
write_xmm128(r, destination.u32[2], destination.u32[3], source.u32[2], source.u32[3]);
@ -1511,21 +1464,18 @@ DEFINE_SSE_SPLIT(instr_660F6D, safe_read128s, read_xmm128s)
void instr_0F6E(int32_t source, int32_t r) {
// movd mm, r/m32
task_switch_test_mmx();
write_mmx64(r, source, 0);
}
DEFINE_SSE_SPLIT(instr_0F6E, safe_read32s, read_reg32)
void instr_660F6E(int32_t source, int32_t r) {
// movd mm, r/m32
task_switch_test_mmx();
write_xmm128(r, source, 0, 0, 0);
}
DEFINE_SSE_SPLIT(instr_660F6E, safe_read32s, read_reg32)
void instr_0F6F(union reg64 source, int32_t r) {
// movq mm, mm/m64
task_switch_test_mmx();
write_mmx64(r, source.u32[0], source.u32[1]);
}
DEFINE_SSE_SPLIT(instr_0F6F, safe_read64s, read_mmx64s)
@ -1545,7 +1495,6 @@ DEFINE_SSE_SPLIT(instr_F30F6F, safe_read128s, read_xmm128s)
void instr_0F70(union reg64 source, int32_t r, int32_t imm8) {
// pshufw mm1, mm2/m64, imm8
task_switch_test_mmx();
int32_t word0_shift = imm8 & 0b11;
uint32_t word0 = source.u32[word0_shift >> 1] >> ((word0_shift & 1) << 4) & 0xFFFF;
@ -1566,7 +1515,6 @@ DEFINE_SSE_SPLIT_IMM(instr_0F70, safe_read64s, read_mmx64s)
void instr_660F70(union reg128 source, int32_t r, int32_t imm8) {
// pshufd xmm, xmm/mem128
// XXX: Aligned access or #gp
task_switch_test_mmx();
write_xmm128(
r,
source.u32[imm8 & 3],
@ -1580,7 +1528,6 @@ DEFINE_SSE_SPLIT_IMM(instr_660F70, safe_read128s, read_xmm128s)
void instr_F20F70(union reg128 source, int32_t r, int32_t imm8) {
// pshuflw xmm, xmm/m128, imm8
// XXX: Aligned access or #gp
task_switch_test_mmx();
write_xmm128(
r,
source.u16[imm8 & 3] | source.u16[imm8 >> 2 & 3] << 16,
@ -1594,7 +1541,6 @@ DEFINE_SSE_SPLIT_IMM(instr_F20F70, safe_read128s, read_xmm128s)
void instr_F30F70(union reg128 source, int32_t r, int32_t imm8) {
// pshufhw xmm, xmm/m128, imm8
// XXX: Aligned access or #gp
task_switch_test_mmx();
write_xmm128(
r,
source.u32[0],
@ -1710,7 +1656,6 @@ void instr_660F73_2_reg(int32_t r, int32_t imm8) {
void instr_660F73_3_reg(int32_t r, int32_t imm8) {
// psrldq xmm, imm8
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
if(imm8 == 0)
@ -1743,7 +1688,6 @@ void instr_660F73_6_reg(int32_t r, int32_t imm8) {
void instr_660F73_7_reg(int32_t r, int32_t imm8) {
// pslldq xmm, imm8
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
if(imm8 == 0)
@ -1770,7 +1714,6 @@ void instr_660F73_7_reg(int32_t r, int32_t imm8) {
void instr_0F74(union reg64 source, int32_t r) {
// pcmpeqb mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
union reg64 result = { { 0 } };
@ -1786,7 +1729,6 @@ DEFINE_SSE_SPLIT(instr_0F74, safe_read64s, read_mmx64s)
void instr_660F74(union reg128 source, int32_t r) {
// pcmpeqb xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
union reg128 result;
@ -1802,7 +1744,6 @@ DEFINE_SSE_SPLIT(instr_660F74, safe_read128s, read_xmm128s)
void instr_0F75(union reg64 source, int32_t r) {
// pcmpeqw mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
int32_t word0 = destination.u16[0] == source.u16[0] ? 0xFFFF : 0;
@ -1820,7 +1761,6 @@ DEFINE_SSE_SPLIT(instr_0F75, safe_read64s, read_mmx64s)
void instr_660F75(union reg128 source, int32_t r) {
// pcmpeqw xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
union reg128 result;
@ -1835,7 +1775,6 @@ DEFINE_SSE_SPLIT(instr_660F75, safe_read128s, read_xmm128s)
void instr_0F76(union reg64 source, int32_t r) {
// pcmpeqd mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
int32_t low = destination.u32[0] == source.u32[0] ? -1 : 0;
@ -1848,7 +1787,6 @@ DEFINE_SSE_SPLIT(instr_0F76, safe_read64s, read_mmx64s)
void instr_660F76(union reg128 source, int32_t r) {
// pcmpeqd xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
write_xmm128(
@ -1863,16 +1801,6 @@ DEFINE_SSE_SPLIT(instr_660F76, safe_read128s, read_xmm128s)
void instr_0F77() {
// emms
if(cr[0] & (CR0_EM | CR0_TS)) {
if(cr[0] & CR0_TS) {
trigger_nm();
}
else {
trigger_ud();
}
}
fpu_set_tag_word(0xFFFF);
}
@ -1885,27 +1813,23 @@ void instr_0F7D() { unimplemented_sse(); }
int32_t instr_0F7E(int32_t r) {
// movd r/m32, mm
task_switch_test_mmx();
union reg64 data = read_mmx64s(r);
return data.u32[0];
}
DEFINE_SSE_SPLIT_WRITE(instr_0F7E, safe_write32, write_reg32)
int32_t instr_660F7E(int32_t r) {
// movd r/m32, xmm
task_switch_test_mmx();
union reg64 data = read_xmm64s(r);
return data.u32[0];
}
DEFINE_SSE_SPLIT_WRITE(instr_660F7E, safe_write32, write_reg32)
void instr_F30F7E_mem(int32_t addr, int32_t r) {
// movq xmm, xmm/mem64
task_switch_test_mmx();
union reg64 data = safe_read64s(addr);
write_xmm128(r, data.u32[0], data.u32[1], 0, 0);
}
void instr_F30F7E_reg(int32_t r1, int32_t r2) {
// movq xmm, xmm/mem64
task_switch_test_mmx();
union reg64 data = read_xmm64s(r1);
write_xmm128(r2, data.u32[0], data.u32[1], 0, 0);
}
@ -1916,7 +1840,6 @@ void instr_0F7F_mem(int32_t addr, int32_t r) {
}
void instr_0F7F_reg(int32_t r1, int32_t r2) {
// movq mm/m64, mm
task_switch_test_mmx();
union reg64 data = read_mmx64s(r2);
write_mmx64(r1, data.u32[0], data.u32[1]);
}
@ -2349,7 +2272,6 @@ void instr_0FC3_mem(int32_t addr, int32_t r) {
void instr_0FC4(int32_t source, int32_t r, int32_t imm8) {
// pinsrw mm, r32/m16, imm8
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
uint32_t index = imm8 & 3;
@ -2361,7 +2283,6 @@ DEFINE_SSE_SPLIT_IMM(instr_0FC4, read16, read_reg32)
void instr_660FC4(int32_t source, int32_t r, int32_t imm8) {
// pinsrw xmm, r32/m16, imm8
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
uint32_t index = imm8 & 7;
@ -2374,7 +2295,6 @@ DEFINE_SSE_SPLIT_IMM(instr_660FC4, read16, read_reg32)
void instr_0FC5_mem(int32_t addr, int32_t r, int32_t imm8) { trigger_ud(); }
void instr_0FC5_reg(int32_t r1, int32_t r2, int32_t imm8) {
// pextrw r32, mm, imm8
task_switch_test_mmx();
union reg64 data = read_mmx64s(r1);
uint32_t index = imm8 & 3;
@ -2386,7 +2306,6 @@ void instr_0FC5_reg(int32_t r1, int32_t r2, int32_t imm8) {
void instr_660FC5_mem(int32_t addr, int32_t r, int32_t imm8) { trigger_ud(); }
void instr_660FC5_reg(int32_t r1, int32_t r2, int32_t imm8) {
// pextrw r32, xmm, imm8
task_switch_test_mmx();
union reg128 data = read_xmm128s(r1);
uint32_t index = imm8 & 7;
@ -2499,7 +2418,6 @@ DEFINE_SSE_SPLIT(instr_660FD3, safe_read128s, read_xmm128s)
void instr_0FD4(union reg64 source, int32_t r) {
// paddq mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
destination.u64[0] += source.u64[0];
write_mmx_reg64(r, destination);
@ -2509,7 +2427,6 @@ DEFINE_SSE_SPLIT(instr_0FD4, safe_read64s, read_mmx64s)
void instr_660FD4(union reg128 source, int32_t r) {
// paddq xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
destination.u64[0] += source.u64[0];
destination.u64[1] += source.u64[1];
@ -2519,7 +2436,6 @@ DEFINE_SSE_SPLIT(instr_660FD4, safe_read128s, read_xmm128s)
void instr_0FD5(union reg64 source, int32_t r) {
// pmullw mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
@ -2538,7 +2454,6 @@ DEFINE_SSE_SPLIT(instr_0FD5, safe_read64s, read_mmx64s)
void instr_660FD5(union reg128 source, int32_t r) {
// pmullw xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
write_xmm128(
@ -2560,7 +2475,6 @@ void instr_660FD6_mem(int32_t addr, int32_t r) {
}
void instr_660FD6_reg(int32_t r1, int32_t r2) {
// movq xmm/m64, xmm
task_switch_test_mmx();
union reg64 data = read_xmm64s(r2);
write_xmm128(r1, data.u32[0], data.u32[1], 0, 0);
}
@ -2568,7 +2482,6 @@ void instr_660FD6_reg(int32_t r1, int32_t r2) {
void instr_F20FD6_mem(int32_t addr, int32_t r) { trigger_ud(); }
void instr_F20FD6_reg(int32_t r1, int32_t r2) {
// movdq2q mm, xmm
task_switch_test_mmx();
union reg128 source = read_xmm128s(r1);
write_mmx64(r2, source.u32[0], source.u32[1]);
}
@ -2576,7 +2489,6 @@ void instr_F20FD6_reg(int32_t r1, int32_t r2) {
void instr_F30FD6_mem(int32_t addr, int32_t r) { trigger_ud(); }
void instr_F30FD6_reg(int32_t r1, int32_t r2) {
// movq2dq xmm, mm
task_switch_test_mmx();
union reg64 source = read_mmx64s(r1);
write_xmm128(r2, source.u32[0], source.u32[1], 0, 0);
}
@ -2584,7 +2496,6 @@ void instr_F30FD6_reg(int32_t r1, int32_t r2) {
void instr_0FD7_mem(int32_t addr, int32_t r) { trigger_ud(); }
void instr_0FD7_reg(int32_t r1, int32_t r2) {
// pmovmskb r, mm
task_switch_test_mmx();
union reg64 x = read_mmx64s(r1);
uint32_t result =
x.u8[0] >> 7 << 0 | x.u8[1] >> 7 << 1 | x.u8[2] >> 7 << 2 | x.u8[3] >> 7 << 3 |
@ -2595,7 +2506,6 @@ void instr_0FD7_reg(int32_t r1, int32_t r2) {
void instr_660FD7_mem(int32_t addr, int32_t r) { trigger_ud(); }
void instr_660FD7_reg(int32_t r1, int32_t r2) {
// pmovmskb reg, xmm
task_switch_test_mmx();
union reg128 x = read_xmm128s(r1);
int32_t result =
@ -2608,7 +2518,6 @@ void instr_660FD7_reg(int32_t r1, int32_t r2) {
void instr_0FD8(union reg64 source, int32_t r) {
// psubusb mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
union reg64 result = { { 0 } };
@ -2624,7 +2533,6 @@ DEFINE_SSE_SPLIT(instr_0FD8, safe_read64s, read_mmx64s)
void instr_660FD8(union reg128 source, int32_t r) {
// psubusb xmm, xmm/m128
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
union reg128 result;
@ -2640,7 +2548,6 @@ DEFINE_SSE_SPLIT(instr_660FD8, safe_read128s, read_xmm128s)
void instr_0FD9(union reg64 source, int32_t r) {
// psubusw mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
@ -2658,7 +2565,6 @@ DEFINE_SSE_SPLIT(instr_0FD9, safe_read64s, read_mmx64s)
void instr_660FD9(union reg128 source, int32_t r) {
// psubusw xmm, xmm/m128
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
union reg128 result;
@ -2674,7 +2580,6 @@ DEFINE_SSE_SPLIT(instr_660FD9, safe_read128s, read_xmm128s)
void instr_0FDA(union reg64 source, int32_t r) {
// pminub mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
union reg64 result;
@ -2691,7 +2596,6 @@ DEFINE_SSE_SPLIT(instr_0FDA, safe_read64s, read_mmx64s)
void instr_660FDA(union reg128 source, int32_t r) {
// pminub xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
union reg128 result;
@ -2707,7 +2611,6 @@ DEFINE_SSE_SPLIT(instr_660FDA, safe_read128s, read_xmm128s)
void instr_0FDB(union reg64 source, int32_t r) {
// pand mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
union reg64 result = { { 0 } };
@ -2727,7 +2630,6 @@ DEFINE_SSE_SPLIT(instr_660FDB, safe_read128s, read_xmm128s)
void instr_0FDC(union reg64 source, int32_t r) {
// paddusb mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
union reg64 result = { { 0 } };
@ -2744,7 +2646,6 @@ DEFINE_SSE_SPLIT(instr_0FDC, safe_read64s, read_mmx64s)
void instr_660FDC(union reg128 source, int32_t r) {
// paddusb xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
union reg128 result;
@ -2760,7 +2661,6 @@ DEFINE_SSE_SPLIT(instr_660FDC, safe_read128s, read_xmm128s)
void instr_0FDD(union reg64 source, int32_t r) {
// paddusw mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
@ -2779,7 +2679,6 @@ DEFINE_SSE_SPLIT(instr_0FDD, safe_read64s, read_mmx64s)
void instr_660FDD(union reg128 source, int32_t r) {
// paddusw xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
@ -2795,7 +2694,6 @@ DEFINE_SSE_SPLIT(instr_660FDD, safe_read128s, read_xmm128s)
void instr_0FDE(union reg64 source, int32_t r) {
// pmaxub mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
union reg64 result;
@ -2812,7 +2710,6 @@ DEFINE_SSE_SPLIT(instr_0FDE, safe_read64s, read_mmx64s)
void instr_660FDE(union reg128 source, int32_t r) {
// pmaxub xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
union reg128 result;
@ -2828,7 +2725,6 @@ DEFINE_SSE_SPLIT(instr_660FDE, safe_read128s, read_xmm128s)
void instr_0FDF(union reg64 source, int32_t r) {
// pandn mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
union reg64 result = { { 0 } };
@ -2848,7 +2744,6 @@ DEFINE_SSE_SPLIT(instr_660FDF, safe_read128s, read_xmm128s)
void instr_0FE0(union reg64 source, int32_t r) {
// pavgb mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
union reg64 result = { { 0 } };
@ -2864,7 +2759,6 @@ DEFINE_SSE_SPLIT(instr_0FE0, safe_read64s, read_mmx64s)
void instr_660FE0(union reg128 source, int32_t r) {
// pavgb xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
union reg128 result;
@ -2905,7 +2799,6 @@ DEFINE_SSE_SPLIT(instr_660FE2, safe_read128s, read_xmm128s)
void instr_0FE3(union reg64 source, int32_t r) {
// pavgw mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
destination.u16[0] = (destination.u16[0] + source.u16[0] + 1) >> 1;
@ -2920,7 +2813,6 @@ DEFINE_SSE_SPLIT(instr_0FE3, safe_read64s, read_mmx64s)
void instr_660FE3(union reg128 source, int32_t r) {
// pavgw xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
destination.u16[0] = (destination.u16[0] + source.u16[0] + 1) >> 1;
@ -2938,7 +2830,6 @@ DEFINE_SSE_SPLIT(instr_660FE3, safe_read128s, read_xmm128s)
void instr_0FE4(union reg64 source, int32_t r) {
// pmulhuw mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
@ -2953,7 +2844,6 @@ DEFINE_SSE_SPLIT(instr_0FE4, safe_read64s, read_mmx64s)
void instr_660FE4(union reg128 source, int32_t r) {
// pmulhuw xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
@ -2969,7 +2859,6 @@ DEFINE_SSE_SPLIT(instr_660FE4, safe_read128s, read_xmm128s)
void instr_0FE5(union reg64 source, int32_t r) {
// pmulhw mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
@ -2988,7 +2877,6 @@ DEFINE_SSE_SPLIT(instr_0FE5, safe_read64s, read_mmx64s)
void instr_660FE5(union reg128 source, int32_t r) {
// pmulhw xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
@ -3028,7 +2916,6 @@ void instr_660FE7_mem(int32_t addr, int32_t r) {
void instr_0FE8(union reg64 source, int32_t r) {
// psubsb mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
union reg64 result = { { 0 } };
@ -3045,7 +2932,6 @@ DEFINE_SSE_SPLIT(instr_0FE8, safe_read64s, read_mmx64s)
void instr_660FE8(union reg128 source, int32_t r) {
// psubsb xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
union reg128 result;
@ -3061,7 +2947,6 @@ DEFINE_SSE_SPLIT(instr_660FE8, safe_read128s, read_xmm128s)
void instr_0FE9(union reg64 source, int32_t r) {
// psubsw mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
@ -3080,7 +2965,6 @@ DEFINE_SSE_SPLIT(instr_0FE9, safe_read64s, read_mmx64s)
void instr_660FE9(union reg128 source, int32_t r) {
// psubsw xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
@ -3099,7 +2983,6 @@ DEFINE_SSE_SPLIT(instr_660FE9, safe_read128s, read_xmm128s)
void instr_0FEA(union reg64 source, int32_t r) {
// pminsw mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
union reg64 result;
@ -3116,7 +2999,6 @@ DEFINE_SSE_SPLIT(instr_0FEA, safe_read64s, read_mmx64s)
void instr_660FEA(union reg128 source, int32_t r) {
// pminsw xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
union reg128 result;
@ -3132,7 +3014,6 @@ DEFINE_SSE_SPLIT(instr_660FEA, safe_read128s, read_xmm128s)
void instr_0FEB(union reg64 source, int32_t r) {
// por mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
union reg64 result = { { 0 } };
@ -3152,7 +3033,6 @@ DEFINE_SSE_SPLIT(instr_660FEB, safe_read128s, read_xmm128s)
void instr_0FEC(union reg64 source, int32_t r) {
// paddsb mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
union reg64 result = { { 0 } };
@ -3169,7 +3049,6 @@ DEFINE_SSE_SPLIT(instr_0FEC, safe_read64s, read_mmx64s)
void instr_660FEC(union reg128 source, int32_t r) {
// paddsb xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
union reg128 result;
@ -3185,7 +3064,6 @@ DEFINE_SSE_SPLIT(instr_660FEC, safe_read128s, read_xmm128s)
void instr_0FED(union reg64 source, int32_t r) {
// paddsw mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
@ -3204,7 +3082,6 @@ DEFINE_SSE_SPLIT(instr_0FED, safe_read64s, read_mmx64s)
void instr_660FED(union reg128 source, int32_t r) {
// paddsw xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
@ -3223,7 +3100,6 @@ DEFINE_SSE_SPLIT(instr_660FED, safe_read128s, read_xmm128s)
void instr_0FEE(union reg64 source, int32_t r) {
// pmaxsw mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
union reg64 result;
@ -3240,7 +3116,6 @@ DEFINE_SSE_SPLIT(instr_0FEE, safe_read64s, read_mmx64s)
void instr_660FEE(union reg128 source, int32_t r) {
// pmaxsw xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
union reg128 result;
@ -3256,7 +3131,6 @@ DEFINE_SSE_SPLIT(instr_660FEE, safe_read128s, read_xmm128s)
void instr_0FEF(union reg64 source, int32_t r) {
// pxor mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
union reg64 result = { { 0 } };
@ -3316,7 +3190,6 @@ DEFINE_SSE_SPLIT(instr_660FF3, safe_read128s, read_xmm128s)
void instr_0FF4(union reg64 source, int32_t r) {
// pmuludq mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
destination.u64[0] = (uint64_t) source.u32[0] * (uint64_t) destination.u32[0];
@ -3327,7 +3200,6 @@ DEFINE_SSE_SPLIT(instr_0FF4, safe_read64s, read_mmx64s)
void instr_660FF4(union reg128 source, int32_t r) {
// pmuludq xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
destination.u64[0] = (uint64_t) source.u32[0] * (uint64_t) destination.u32[0];
@ -3338,7 +3210,6 @@ DEFINE_SSE_SPLIT(instr_660FF4, safe_read128s, read_xmm128s)
void instr_0FF5(union reg64 source, int32_t r) {
// pmaddwd mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
@ -3357,7 +3228,6 @@ DEFINE_SSE_SPLIT(instr_0FF5, safe_read64s, read_mmx64s)
void instr_660FF5(union reg128 source, int32_t r) {
// pmaddwd xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
@ -3376,7 +3246,6 @@ DEFINE_SSE_SPLIT(instr_660FF5, safe_read128s, read_xmm128s)
void instr_0FF6(union reg64 source, int32_t r) {
// psadbw mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
uint32_t sum = 0;
@ -3392,7 +3261,6 @@ DEFINE_SSE_SPLIT(instr_0FF6, safe_read64s, read_mmx64s)
void instr_660FF6(union reg128 source, int32_t r) {
// psadbw xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
uint32_t sum0 = 0;
uint32_t sum1 = 0;
@ -3410,7 +3278,6 @@ DEFINE_SSE_SPLIT(instr_660FF6, safe_read128s, read_xmm128s)
void instr_0FF7_mem(int32_t addr, int32_t r) { trigger_ud(); }
void instr_0FF7_reg(int32_t r1, int32_t r2) {
// maskmovq mm, mm
task_switch_test_mmx();
union reg64 source = read_mmx64s(r2);
union reg64 mask = read_mmx64s(r1);
int32_t addr = get_seg_prefix(DS) + get_reg_asize(EDI);
@ -3428,7 +3295,6 @@ void instr_0FF7_reg(int32_t r1, int32_t r2) {
void instr_660FF7_mem(int32_t addr, int32_t r) { trigger_ud(); }
void instr_660FF7_reg(int32_t r1, int32_t r2) {
// maskmovdqu xmm, xmm
task_switch_test_mmx();
union reg128 source = read_xmm128s(r2);
union reg128 mask = read_xmm128s(r1);
int32_t addr = get_seg_prefix(DS) + get_reg_asize(EDI);
@ -3445,7 +3311,6 @@ void instr_660FF7_reg(int32_t r1, int32_t r2) {
void instr_0FF8(union reg64 source, int32_t r) {
// psubb mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
union reg64 result = { { 0 } };
@ -3462,7 +3327,6 @@ DEFINE_SSE_SPLIT(instr_0FF8, safe_read64s, read_mmx64s)
void instr_660FF8(union reg128 source, int32_t r) {
// psubb xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
union reg128 result = { { 0 } };
@ -3478,7 +3342,6 @@ DEFINE_SSE_SPLIT(instr_660FF8, safe_read128s, read_xmm128s)
void instr_0FF9(union reg64 source, int32_t r) {
// psubw mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
@ -3497,7 +3360,6 @@ DEFINE_SSE_SPLIT(instr_0FF9, safe_read64s, read_mmx64s)
void instr_660FF9(union reg128 source, int32_t r) {
// psubw xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
union reg128 result = { { 0 } };
@ -3513,7 +3375,6 @@ DEFINE_SSE_SPLIT(instr_660FF9, safe_read128s, read_xmm128s)
void instr_0FFA(union reg64 source, int32_t r) {
// psubd mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
@ -3528,7 +3389,6 @@ DEFINE_SSE_SPLIT(instr_0FFA, safe_read64s, read_mmx64s)
void instr_660FFA(union reg128 source, int32_t r) {
// psubd xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
@ -3544,7 +3404,6 @@ DEFINE_SSE_SPLIT(instr_660FFA, safe_read128s, read_xmm128s)
void instr_0FFB(union reg64 source, int32_t r) {
// psubq mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
destination.u64[0] = destination.u64[0] - source.u64[0];
@ -3555,7 +3414,6 @@ DEFINE_SSE_SPLIT(instr_0FFB, safe_read64s, read_mmx64s)
void instr_660FFB(union reg128 source, int32_t r) {
// psubq xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
destination.u64[0] = destination.u64[0] - source.u64[0];
@ -3567,7 +3425,6 @@ DEFINE_SSE_SPLIT(instr_660FFB, safe_read128s, read_xmm128s)
void instr_0FFC(union reg64 source, int32_t r) {
// paddb mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
union reg64 result = { { 0 } };
@ -3584,7 +3441,6 @@ DEFINE_SSE_SPLIT(instr_0FFC, safe_read64s, read_mmx64s)
void instr_660FFC(union reg128 source, int32_t r) {
// paddb xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
union reg128 result = { { 0 } };
@ -3600,7 +3456,6 @@ DEFINE_SSE_SPLIT(instr_660FFC, safe_read128s, read_xmm128s)
void instr_0FFD(union reg64 source, int32_t r) {
// paddw mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
@ -3619,7 +3474,6 @@ DEFINE_SSE_SPLIT(instr_0FFD, safe_read64s, read_mmx64s)
void instr_660FFD(union reg128 source, int32_t r) {
// paddw xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
union reg128 result = { { 0 } };
@ -3635,7 +3489,6 @@ DEFINE_SSE_SPLIT(instr_660FFD, safe_read128s, read_xmm128s)
void instr_0FFE(union reg64 source, int32_t r) {
// paddd mm, mm/m64
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
@ -3649,7 +3502,6 @@ DEFINE_SSE_SPLIT(instr_0FFE, safe_read64s, read_mmx64s)
void instr_660FFE(union reg128 source, int32_t r) {
// paddd xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);

View file

@ -7,7 +7,6 @@
void mov_r_m64(int32_t addr, int32_t r)
{
// mov* m64, mm
task_switch_test_mmx();
union reg64 data = read_mmx64s(r);
safe_write64(addr, data.u64[0]);
}
@ -15,7 +14,6 @@ void mov_r_m64(int32_t addr, int32_t r)
void movl_r128_m64(int32_t addr, int32_t r)
{
// mov* m64, xmm
task_switch_test_mmx();
union reg64 data = read_xmm64s(r);
safe_write64(addr, data.u64[0]);
}
@ -23,7 +21,6 @@ void movl_r128_m64(int32_t addr, int32_t r)
void mov_r_r128(int32_t r1, int32_t r2)
{
// mov* xmm, xmm
task_switch_test_mmx();
union reg128 data = read_xmm128s(r2);
write_xmm_reg128(r1, data);
}
@ -31,7 +28,6 @@ void mov_r_r128(int32_t r1, int32_t r2)
void mov_r_m128(int32_t addr, int32_t r)
{
// mov* m128, xmm
task_switch_test_mmx();
union reg128 data = read_xmm128s(r);
safe_write128(addr, data);
}
@ -39,14 +35,12 @@ void mov_r_m128(int32_t addr, int32_t r)
void mov_rm_r128(union reg128 source, int32_t r)
{
// mov* xmm, xmm/m128
task_switch_test_mmx();
write_xmm_reg128(r, source);
}
void movh_m64_r128(int32_t addr, int32_t r)
{
// movhp* xmm, m64
task_switch_test_mmx();
union reg64 data = safe_read64s(addr);
union reg128 orig = read_xmm128s(r);
write_xmm128(r, orig.u32[0], orig.u32[1], data.u32[0], data.u32[1]);
@ -55,7 +49,6 @@ void movh_m64_r128(int32_t addr, int32_t r)
void movh_r128_m64(int32_t addr, int32_t r)
{
// movhp* m64, xmm
task_switch_test_mmx();
union reg128 data = read_xmm128s(r);
safe_write64(addr, data.u64[1]);
}
@ -64,7 +57,6 @@ void pand_r128(union reg128 source, int32_t r)
{
// pand xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
union reg128 result = { { 0 } };
@ -79,7 +71,6 @@ void pandn_r128(union reg128 source, int32_t r)
{
// pandn xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
union reg128 result = { { 0 } };
@ -94,7 +85,6 @@ void pxor_r128(union reg128 source, int32_t r)
{
// pxor xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
union reg128 result = { { 0 } };
@ -109,7 +99,6 @@ void por_r128(union reg128 source, int32_t r)
{
// por xmm, xmm/m128
// XXX: Aligned access or #gp
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
union reg128 result = { { 0 } };
@ -123,7 +112,6 @@ void por_r128(union reg128 source, int32_t r)
void psrlw_r64(int32_t r, uint32_t shift)
{
// psrlw mm, {shift}
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
int32_t dword0 = 0;
int32_t dword1 = 0;
@ -140,7 +128,6 @@ void psrlw_r64(int32_t r, uint32_t shift)
void psraw_r64(int32_t r, uint32_t shift)
{
// psraw mm, {shift}
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
int32_t shift_clamped = shift > 15 ? 16 : shift;
@ -154,7 +141,6 @@ void psraw_r64(int32_t r, uint32_t shift)
void psllw_r64(int32_t r, uint32_t shift)
{
// psllw mm, {shift}
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
int32_t dword0 = 0;
@ -174,7 +160,6 @@ void psllw_r64(int32_t r, uint32_t shift)
void psrld_r64(int32_t r, uint32_t shift)
{
// psrld mm, {shift}
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
int32_t dword0 = 0;
@ -192,7 +177,6 @@ void psrld_r64(int32_t r, uint32_t shift)
void psrad_r64(int32_t r, uint32_t shift)
{
// psrad mm, {shift}
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
int32_t shift_clamped = shift > 31 ? 31 : shift;
@ -205,7 +189,6 @@ void psrad_r64(int32_t r, uint32_t shift)
void pslld_r64(int32_t r, uint32_t shift)
{
// pslld mm, {shift}
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
int32_t dword0 = 0;
@ -223,7 +206,6 @@ void pslld_r64(int32_t r, uint32_t shift)
void psrlq_r64(int32_t r, uint32_t shift)
{
// psrlq mm, {shift}
task_switch_test_mmx();
if(shift == 0)
{
@ -244,7 +226,6 @@ void psrlq_r64(int32_t r, uint32_t shift)
void psllq_r64(int32_t r, uint32_t shift)
{
// psllq mm, {shift}
task_switch_test_mmx();
union reg64 destination = read_mmx64s(r);
if(shift == 0)
@ -265,7 +246,6 @@ void psllq_r64(int32_t r, uint32_t shift)
void psrlw_r128(int32_t r, uint32_t shift)
{
// psrlw xmm, {shift}
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
int32_t dword0 = 0;
int32_t dword1 = 0;
@ -286,7 +266,6 @@ void psrlw_r128(int32_t r, uint32_t shift)
void psraw_r128(int32_t r, uint32_t shift)
{
// psraw xmm, {shift}
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
int32_t shift_clamped = shift > 15 ? 16 : shift;
@ -304,7 +283,6 @@ void psraw_r128(int32_t r, uint32_t shift)
void psllw_r128(int32_t r, uint32_t shift)
{
// psllw xmm, {shift}
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
int32_t dword0 = 0;
@ -326,7 +304,6 @@ void psllw_r128(int32_t r, uint32_t shift)
void psrld_r128(int32_t r, uint32_t shift)
{
// psrld xmm, {shift}
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
int32_t dword0 = 0;
@ -348,7 +325,6 @@ void psrld_r128(int32_t r, uint32_t shift)
void psrad_r128(int32_t r, uint32_t shift)
{
// psrad xmm, {shift}
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
int32_t shift_clamped = shift > 31 ? 31 : shift;
@ -363,7 +339,6 @@ void psrad_r128(int32_t r, uint32_t shift)
void pslld_r128(int32_t r, uint32_t shift)
{
// pslld xmm, {shift}
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
int32_t dword0 = 0;
@ -385,7 +360,6 @@ void pslld_r128(int32_t r, uint32_t shift)
void psrlq_r128(int32_t r, uint32_t shift)
{
// psrlq xmm, {shift}
task_switch_test_mmx();
if(shift == 0)
{
@ -407,7 +381,6 @@ void psrlq_r128(int32_t r, uint32_t shift)
void psllq_r128(int32_t r, uint32_t shift)
{
// psllq xmm, {shift}
task_switch_test_mmx();
union reg128 destination = read_xmm128s(r);
if(shift == 0)

View file

@ -572,3 +572,42 @@ pub fn gen_pop32s(ctx: &mut JitContext) {
gen_pop32s_ss16(ctx);
}
}
pub fn gen_task_switch_test(ctx: &mut JitContext) {
// generate if(cr[0] & (CR0_EM | CR0_TS)) { task_switch_test_void(); return; }
let cr0_offset = global_pointers::get_creg_offset(0);
wasm_util::load_aligned_i32(&mut ctx.builder.instruction_body, cr0_offset);
wasm_util::push_i32(
&mut ctx.builder.instruction_body,
(regs::CR0_EM | regs::CR0_TS) as i32,
);
wasm_util::and_i32(&mut ctx.builder.instruction_body);
wasm_util::if_void(&mut ctx.builder.instruction_body);
gen_fn0_const(ctx, "task_switch_test_void");
wasm_util::return_(&mut ctx.builder.instruction_body);
wasm_util::block_end(&mut ctx.builder.instruction_body);
}
pub fn gen_task_switch_test_mmx(ctx: &mut JitContext) {
// generate if(cr[0] & (CR0_EM | CR0_TS)) { task_switch_test_mmx_void(); return; }
let cr0_offset = global_pointers::get_creg_offset(0);
wasm_util::load_aligned_i32(&mut ctx.builder.instruction_body, cr0_offset);
wasm_util::push_i32(
&mut ctx.builder.instruction_body,
(regs::CR0_EM | regs::CR0_TS) as i32,
);
wasm_util::and_i32(&mut ctx.builder.instruction_body);
wasm_util::if_void(&mut ctx.builder.instruction_body);
gen_fn0_const(ctx, "task_switch_test_mmx_void");
wasm_util::return_(&mut ctx.builder.instruction_body);
wasm_util::block_end(&mut ctx.builder.instruction_body);
}

View file

@ -1,6 +1,7 @@
pub const REG: u32 = 4;
pub const INSTRUCTION_POINTER: u32 = 556;
pub const PREVIOUS_IP: u32 = 560;
pub const CR: u32 = 580;
pub const PREFIXES: u32 = 648;
pub const TIMESTAMP_COUNTER: u32 = 664;
pub const SEGMENT_OFFSETS: u32 = 736;
@ -17,7 +18,13 @@ pub fn get_reg32_offset(r: u32) -> u32 {
dbg_assert!(r < 8);
REG + 4 * r
}
pub fn get_seg_offset(s: u32) -> u32 {
dbg_assert!(s < 8);
SEGMENT_OFFSETS + 4 * s
}
pub fn get_creg_offset(cr: u32) -> u32 {
dbg_assert!(cr < 8);
CR + 4 * cr
}

View file

@ -23,3 +23,6 @@ pub const SP: u32 = 4;
pub const BP: u32 = 5;
pub const SI: u32 = 6;
pub const DI: u32 = 7;
pub const CR0_EM: u32 = 1 << 2;
pub const CR0_TS: u32 = 1 << 3;