Split modrm functions by reg/mem
This commit is contained in:
parent
c61e668f61
commit
75ae9fe420
|
@ -4296,12 +4296,17 @@ CPU.prototype.load_ldt = function(selector)
|
|||
|
||||
CPU.prototype.arpl = function(seg, r16)
|
||||
{
|
||||
if(!this.protected_mode[0] || this.vm86_mode())
|
||||
{
|
||||
this.trigger_ud();
|
||||
}
|
||||
|
||||
this.flags_changed[0] &= ~flag_zero;
|
||||
|
||||
if((seg & 3) < (this.reg16[r16] & 3))
|
||||
if((seg & 3) < (r16 & 3))
|
||||
{
|
||||
this.flags[0] |= flag_zero;
|
||||
return seg & ~3 | this.reg16[r16] & 3;
|
||||
return seg & ~3 | r16 & 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
58
src/fpu.js
58
src/fpu.js
|
@ -657,7 +657,7 @@ FPU.prototype.dbg_log_fpu_op = function(op, imm8)
|
|||
}
|
||||
else
|
||||
{
|
||||
dbg_log(h(op, 2) + " /" + (imm8 >> 3 & 7) +
|
||||
dbg_log(h(op, 2) + " /" + imm8 +
|
||||
" @" + h(this.cpu.instruction_pointer[0] >>> 0, 8) + " sp=" + this.stack_ptr + " st=" + h(this.stack_empty[0], 2), LOG_FPU);
|
||||
}
|
||||
}
|
||||
|
@ -718,13 +718,11 @@ FPU.prototype.op_D8_reg = function(imm8)
|
|||
}
|
||||
};
|
||||
|
||||
FPU.prototype.op_D8_mem = function(imm8, addr)
|
||||
FPU.prototype.op_D8_mem = function(mod, addr)
|
||||
{
|
||||
this.dbg_log_fpu_op(0xD8, imm8);
|
||||
|
||||
var mod = imm8 >> 3 & 7,
|
||||
m32 = this.load_m32(addr);
|
||||
this.dbg_log_fpu_op(0xD8, mod);
|
||||
|
||||
var m32 = this.load_m32(addr);
|
||||
var st0 = this.get_st0();
|
||||
|
||||
switch(mod)
|
||||
|
@ -934,11 +932,9 @@ FPU.prototype.op_D9_reg = function(imm8)
|
|||
}
|
||||
};
|
||||
|
||||
FPU.prototype.op_D9_mem = function(imm8, addr)
|
||||
FPU.prototype.op_D9_mem = function(mod, addr)
|
||||
{
|
||||
this.dbg_log_fpu_op(0xD9, imm8);
|
||||
|
||||
var mod = imm8 >> 3 & 7;
|
||||
this.dbg_log_fpu_op(0xD9, mod);
|
||||
|
||||
switch(mod)
|
||||
{
|
||||
|
@ -1040,13 +1036,11 @@ FPU.prototype.op_DA_reg = function(imm8)
|
|||
}
|
||||
};
|
||||
|
||||
FPU.prototype.op_DA_mem = function(imm8, addr)
|
||||
FPU.prototype.op_DA_mem = function(mod, addr)
|
||||
{
|
||||
this.dbg_log_fpu_op(0xDA, imm8);
|
||||
|
||||
var mod = imm8 >> 3 & 7,
|
||||
m32 = this.cpu.safe_read32s(addr);
|
||||
this.dbg_log_fpu_op(0xDA, mod);
|
||||
|
||||
var m32 = this.cpu.safe_read32s(addr);
|
||||
var st0 = this.get_st0();
|
||||
|
||||
switch(mod)
|
||||
|
@ -1168,11 +1162,9 @@ FPU.prototype.op_DB_reg = function(imm8)
|
|||
}
|
||||
};
|
||||
|
||||
FPU.prototype.op_DB_mem = function(imm8, addr)
|
||||
FPU.prototype.op_DB_mem = function(mod, addr)
|
||||
{
|
||||
this.dbg_log_fpu_op(0xDB, imm8);
|
||||
|
||||
var mod = imm8 >> 3 & 7;
|
||||
this.dbg_log_fpu_op(0xDB, mod);
|
||||
|
||||
switch(mod)
|
||||
{
|
||||
|
@ -1275,13 +1267,11 @@ FPU.prototype.op_DC_reg = function(imm8)
|
|||
}
|
||||
};
|
||||
|
||||
FPU.prototype.op_DC_mem = function(imm8, addr)
|
||||
FPU.prototype.op_DC_mem = function(mod, addr)
|
||||
{
|
||||
this.dbg_log_fpu_op(0xDC, imm8);
|
||||
this.dbg_log_fpu_op(0xDC, mod);
|
||||
|
||||
var
|
||||
mod = imm8 >> 3 & 7,
|
||||
m64 = this.load_m64(addr);
|
||||
var m64 = this.load_m64(addr);
|
||||
|
||||
var st0 = this.get_st0();
|
||||
|
||||
|
@ -1368,11 +1358,9 @@ FPU.prototype.op_DD_reg = function(imm8)
|
|||
}
|
||||
};
|
||||
|
||||
FPU.prototype.op_DD_mem = function(imm8, addr)
|
||||
FPU.prototype.op_DD_mem = function(mod, addr)
|
||||
{
|
||||
this.dbg_log_fpu_op(0xDD, imm8);
|
||||
|
||||
var mod = imm8 >> 3 & 7;
|
||||
this.dbg_log_fpu_op(0xDD, mod);
|
||||
|
||||
switch(mod)
|
||||
{
|
||||
|
@ -1476,13 +1464,11 @@ FPU.prototype.op_DE_reg = function(imm8)
|
|||
this.pop();
|
||||
};
|
||||
|
||||
FPU.prototype.op_DE_mem = function(imm8, addr)
|
||||
FPU.prototype.op_DE_mem = function(mod, addr)
|
||||
{
|
||||
this.dbg_log_fpu_op(0xDE, imm8);
|
||||
|
||||
var mod = imm8 >> 3 & 7,
|
||||
m16 = this.cpu.safe_read16(addr) << 16 >> 16;
|
||||
this.dbg_log_fpu_op(0xDE, mod);
|
||||
|
||||
var m16 = this.cpu.safe_read16(addr) << 16 >> 16;
|
||||
var st0 = this.get_st0();
|
||||
|
||||
switch(mod)
|
||||
|
@ -1562,11 +1548,9 @@ FPU.prototype.op_DF_reg = function(imm8)
|
|||
}
|
||||
};
|
||||
|
||||
FPU.prototype.op_DF_mem = function(imm8, addr)
|
||||
FPU.prototype.op_DF_mem = function(mod, addr)
|
||||
{
|
||||
this.dbg_log_fpu_op(0xDF, imm8);
|
||||
|
||||
var mod = imm8 >> 3 & 7;
|
||||
this.dbg_log_fpu_op(0xDF, mod);
|
||||
|
||||
switch(mod)
|
||||
{
|
||||
|
|
|
@ -354,20 +354,18 @@ CPU.prototype.popa32 = function()
|
|||
this.reg32s[reg_eax] = this.pop32s();
|
||||
}
|
||||
|
||||
CPU.prototype.xchg8 = function(memory_data, modrm_byte)
|
||||
CPU.prototype.xchg8 = function(memory_data, mod)
|
||||
{
|
||||
var mod = modrm_byte >> 1 & 0xC | modrm_byte >> 5 & 1,
|
||||
tmp = this.reg8[mod];
|
||||
var tmp = this.reg8[mod];
|
||||
|
||||
this.reg8[mod] = memory_data;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
CPU.prototype.xchg16 = function(memory_data, modrm_byte)
|
||||
CPU.prototype.xchg16 = function(memory_data, mod)
|
||||
{
|
||||
var mod = modrm_byte >> 2 & 14,
|
||||
tmp = this.reg16[mod];
|
||||
var tmp = this.reg16[mod];
|
||||
|
||||
this.reg16[mod] = memory_data;
|
||||
|
||||
|
@ -381,10 +379,9 @@ CPU.prototype.xchg16r = function(operand)
|
|||
this.reg16[operand] = temp;
|
||||
}
|
||||
|
||||
CPU.prototype.xchg32 = function(memory_data, modrm_byte)
|
||||
CPU.prototype.xchg32 = function(memory_data, mod)
|
||||
{
|
||||
var mod = modrm_byte >> 3 & 7,
|
||||
tmp = this.reg32s[mod];
|
||||
var tmp = this.reg32s[mod];
|
||||
|
||||
this.reg32s[mod] = memory_data;
|
||||
|
||||
|
@ -398,39 +395,24 @@ CPU.prototype.xchg32r = function(operand)
|
|||
this.reg32s[operand] = temp;
|
||||
}
|
||||
|
||||
CPU.prototype.lss16 = function(seg)
|
||||
CPU.prototype.lss16 = function(addr, reg, seg)
|
||||
{
|
||||
if(this.modrm_byte[0] >= 0xC0)
|
||||
{
|
||||
// 0xc4c4 #ud (EMULATOR_BOP) is used by reactos and windows to exit vm86 mode
|
||||
this.trigger_ud();
|
||||
}
|
||||
|
||||
var addr = this.modrm_resolve(this.modrm_byte[0]);
|
||||
|
||||
var new_reg = this.safe_read16(addr),
|
||||
new_seg = this.safe_read16(addr + 2 | 0);
|
||||
|
||||
this.switch_seg(seg, new_seg);
|
||||
|
||||
this.reg16[this.modrm_byte[0] >> 2 & 14] = new_reg;
|
||||
this.reg16[reg] = new_reg;
|
||||
}
|
||||
|
||||
CPU.prototype.lss32 = function(seg)
|
||||
CPU.prototype.lss32 = function(addr, reg, seg)
|
||||
{
|
||||
if(this.modrm_byte[0] >= 0xC0)
|
||||
{
|
||||
this.trigger_ud();
|
||||
}
|
||||
|
||||
var addr = this.modrm_resolve(this.modrm_byte[0]);
|
||||
|
||||
var new_reg = this.safe_read32s(addr),
|
||||
new_seg = this.safe_read16(addr + 4 | 0);
|
||||
|
||||
this.switch_seg(seg, new_seg);
|
||||
|
||||
this.reg32s[this.modrm_byte[0] >> 3 & 7] = new_reg;
|
||||
this.reg32s[reg] = new_reg;
|
||||
}
|
||||
|
||||
CPU.prototype.enter16 = function(size, nesting_level)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -496,7 +496,7 @@ static void instr_0F22() { read_modrm_byte();
|
|||
assert(false);
|
||||
}
|
||||
|
||||
//dbg_log("cr4=" + h(cr[4]));
|
||||
//dbg_log("cr4=%d", cr[4]);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1357,10 +1357,12 @@ static void instr32_0FB1() { read_modrm_byte();
|
|||
|
||||
// lss
|
||||
static void instr16_0FB2() { read_modrm_byte();
|
||||
lss16(SS);
|
||||
if(modrm_byte[0] >= 0xC0) trigger_ud();
|
||||
lss16(modrm_resolve(*modrm_byte), *modrm_byte >> 2 & 14, SS);
|
||||
}
|
||||
static void instr32_0FB2() { read_modrm_byte();
|
||||
lss32(SS);
|
||||
if(modrm_byte[0] >= 0xC0) trigger_ud();
|
||||
lss32(modrm_resolve(*modrm_byte), *modrm_byte >> 3 & 7, SS);
|
||||
}
|
||||
|
||||
static void instr16_0FB3() { read_modrm_byte();
|
||||
|
@ -1380,16 +1382,20 @@ static void instr32_0FB3() { read_modrm_byte();
|
|||
|
||||
// lfs, lgs
|
||||
static void instr16_0FB4() { read_modrm_byte();
|
||||
lss16(FS);
|
||||
if(modrm_byte[0] >= 0xC0) trigger_ud();
|
||||
lss16(modrm_resolve(*modrm_byte), *modrm_byte >> 2 & 14, FS);
|
||||
}
|
||||
static void instr32_0FB4() { read_modrm_byte();
|
||||
lss32(FS);
|
||||
if(modrm_byte[0] >= 0xC0) trigger_ud();
|
||||
lss32(modrm_resolve(*modrm_byte), *modrm_byte >> 3 & 7, FS);
|
||||
}
|
||||
static void instr16_0FB5() { read_modrm_byte();
|
||||
lss16(GS);
|
||||
if(modrm_byte[0] >= 0xC0) trigger_ud();
|
||||
lss16(modrm_resolve(*modrm_byte), *modrm_byte >> 2 & 14, GS);
|
||||
}
|
||||
static void instr32_0FB5() { read_modrm_byte();
|
||||
lss32(GS);
|
||||
if(modrm_byte[0] >= 0xC0) trigger_ud();
|
||||
lss32(modrm_resolve(*modrm_byte), *modrm_byte >> 3 & 7, GS);
|
||||
}
|
||||
|
||||
static void instr16_0FB6() { read_modrm_byte();
|
||||
|
|
|
@ -106,7 +106,7 @@ const encodings = [
|
|||
{ opcode: 0x8C, os: 1, e: 1, g: 1, skip: 1, },
|
||||
{ opcode: 0x8D, os: 1, e: 1, g: 1, skip: 1, }, // lea
|
||||
{ opcode: 0x8E, e: 1, g: 1, skip: 1, },
|
||||
{ opcode: 0x8F, os: 1, e: 1, g: 1, },
|
||||
{ opcode: 0x8F, os: 1, e: 1, fixed_g: 0, },
|
||||
|
||||
{ opcode: 0x90, },
|
||||
{ opcode: 0x91, os: 1, },
|
||||
|
@ -152,8 +152,8 @@ const encodings = [
|
|||
{ opcode: 0xC4, os: 1, e: 1, g: 1, skip: 1, },
|
||||
{ opcode: 0xC5, os: 1, e: 1, g: 1, skip: 1, },
|
||||
|
||||
{ opcode: 0xC6, e: 1, g: 1, imm: 1, },
|
||||
{ opcode: 0xC7, os: 1, e: 1, g: 1, imm: 1, },
|
||||
{ opcode: 0xC6, e: 1, fixed_g: 0, imm: 1, },
|
||||
{ opcode: 0xC7, os: 1, e: 1, fixed_g: 0, imm: 1, },
|
||||
|
||||
{ opcode: 0xC8, os: 1, imm24: 1, skip: 1, }, // enter
|
||||
{ opcode: 0xC9, os: 1, skip: 1, },
|
||||
|
@ -690,17 +690,25 @@ function gen_instruction_body(encoding, variant)
|
|||
let opcode = encoding[0].opcode & 0xFF;
|
||||
let opcode_hex = hex_byte(opcode);
|
||||
|
||||
//if(opcode === 0 || opcode === 1 || opcode === 2 || opcode === 3)
|
||||
//{
|
||||
// return [
|
||||
// `int32_t modrm_byte = read_imm8();`,
|
||||
// `modrm_byte < 0xC0 ?`,
|
||||
// ` instr${suffix}_${opcode_hex}_mem(modrm_resolve(modrm_byte), modrm_byte >> 3 & 7) :`,
|
||||
// ` instr${suffix}_${opcode_hex}_reg(modrm_byte & 7, modrm_byte >> 3 & 7);`,
|
||||
// ];
|
||||
//}
|
||||
//else
|
||||
if(encoding.length > 1)
|
||||
if(encoding[0].fixed_g === undefined && encoding[0].e)
|
||||
{
|
||||
let prefix_call = [];
|
||||
|
||||
if(opcode === 0x8D)
|
||||
{
|
||||
// special case
|
||||
prefix_call = [`if(modrm_byte < 0xC0) { instr${suffix}_${opcode_hex}_mem_pre(); };`];
|
||||
}
|
||||
|
||||
return [].concat(
|
||||
`int32_t modrm_byte = read_imm8();`,
|
||||
prefix_call,
|
||||
`modrm_byte < 0xC0 ?`,
|
||||
` instr${suffix}_${opcode_hex}_mem(modrm_resolve(modrm_byte), modrm_byte >> 3 & 7) :`,
|
||||
` instr${suffix}_${opcode_hex}_reg(modrm_byte & 7, modrm_byte >> 3 & 7);`
|
||||
);
|
||||
}
|
||||
else if(encoding[0].fixed_g !== undefined)
|
||||
{
|
||||
let cases = encoding.slice().sort((e1, e2) => e1.fixed_g - e2.fixed_g);
|
||||
|
||||
|
@ -710,15 +718,27 @@ function gen_instruction_body(encoding, variant)
|
|||
}
|
||||
|
||||
return [
|
||||
"read_modrm_byte();",
|
||||
"int32_t modrm_byte = read_imm8();",
|
||||
{
|
||||
type: "switch",
|
||||
condition: "*modrm_byte >> 3 & 7",
|
||||
condition: "modrm_byte >> 3 & 7",
|
||||
body: cases.map(case_ => {
|
||||
let prefix_call = [];
|
||||
|
||||
if(opcode === 0x8F)
|
||||
{
|
||||
// special case
|
||||
prefix_call = [`if(modrm_byte < 0xC0) { instr${suffix}_${opcode_hex}_${case_.fixed_g}_mem_pre(); };`];
|
||||
}
|
||||
|
||||
return {
|
||||
type: "case",
|
||||
cases: [case_.fixed_g],
|
||||
body: [`instr${suffix}_${opcode_hex}_${case_.fixed_g}();`]
|
||||
body: prefix_call.concat([
|
||||
`modrm_byte < 0xC0 ?`,
|
||||
` instr${suffix}_${opcode_hex}_${case_.fixed_g}_mem(modrm_resolve(modrm_byte)) :`,
|
||||
` instr${suffix}_${opcode_hex}_${case_.fixed_g}_reg(modrm_byte & 7);`,
|
||||
]),
|
||||
};
|
||||
}).concat([
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue