Split modrm functions by reg/mem

This commit is contained in:
Fabian 2017-07-18 15:17:56 -05:00
parent c61e668f61
commit 75ae9fe420
6 changed files with 1497 additions and 863 deletions

View file

@ -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
{

View file

@ -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)
{

View file

@ -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

View file

@ -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();

View file

@ -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([
{