mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 10:58:12 +00:00
UserspaceEmulator: Add single-operand MUL and DIV instructions
These are the unsigned variants. Signed variants sold separately.
This commit is contained in:
parent
30d512144e
commit
02882d5345
1 changed files with 53 additions and 4 deletions
|
@ -1198,7 +1198,23 @@ void SoftCPU::DEC_reg32(const X86::Instruction& insn)
|
|||
gpr32(insn.reg32()) = op_dec(*this, gpr32(insn.reg32()));
|
||||
}
|
||||
|
||||
void SoftCPU::DIV_RM16(const X86::Instruction&) { TODO(); }
|
||||
void SoftCPU::DIV_RM16(const X86::Instruction& insn)
|
||||
{
|
||||
auto divisor = insn.modrm().read16(*this, insn);
|
||||
if (divisor == 0) {
|
||||
warn() << "Divide by zero";
|
||||
TODO();
|
||||
}
|
||||
u32 dividend = ((u32)dx() << 16) | ax();
|
||||
auto result = dividend / divisor;
|
||||
if (result > NumericLimits<u16>::max()) {
|
||||
warn() << "Divide overflow";
|
||||
TODO();
|
||||
}
|
||||
|
||||
set_ax(result);
|
||||
set_dx(dividend % divisor);
|
||||
}
|
||||
|
||||
void SoftCPU::DIV_RM32(const X86::Instruction& insn)
|
||||
{
|
||||
|
@ -1218,7 +1234,24 @@ void SoftCPU::DIV_RM32(const X86::Instruction& insn)
|
|||
set_edx(dividend % divisor);
|
||||
}
|
||||
|
||||
void SoftCPU::DIV_RM8(const X86::Instruction&) { TODO(); }
|
||||
void SoftCPU::DIV_RM8(const X86::Instruction& insn)
|
||||
{
|
||||
auto divisor = insn.modrm().read8(*this, insn);
|
||||
if (divisor == 0) {
|
||||
warn() << "Divide by zero";
|
||||
TODO();
|
||||
}
|
||||
u16 dividend = ax();
|
||||
auto result = dividend / divisor;
|
||||
if (result > NumericLimits<u8>::max()) {
|
||||
warn() << "Divide overflow";
|
||||
TODO();
|
||||
}
|
||||
|
||||
set_al(result);
|
||||
set_ah(dividend % divisor);
|
||||
}
|
||||
|
||||
void SoftCPU::ENTER16(const X86::Instruction&) { TODO(); }
|
||||
void SoftCPU::ENTER32(const X86::Instruction&) { TODO(); }
|
||||
|
||||
|
@ -1647,7 +1680,16 @@ void SoftCPU::MOV_reg8_imm8(const X86::Instruction& insn)
|
|||
|
||||
void SoftCPU::MOV_seg_RM16(const X86::Instruction&) { TODO(); }
|
||||
void SoftCPU::MOV_seg_RM32(const X86::Instruction&) { TODO(); }
|
||||
void SoftCPU::MUL_RM16(const X86::Instruction&) { TODO(); }
|
||||
|
||||
void SoftCPU::MUL_RM16(const X86::Instruction& insn)
|
||||
{
|
||||
u32 result = (u32)ax() * (u32)insn.modrm().read16(*this, insn);
|
||||
set_ax(result & 0xffff);
|
||||
set_dx(result >> 16);
|
||||
|
||||
set_cf(dx() != 0);
|
||||
set_of(dx() != 0);
|
||||
}
|
||||
|
||||
void SoftCPU::MUL_RM32(const X86::Instruction& insn)
|
||||
{
|
||||
|
@ -1659,7 +1701,14 @@ void SoftCPU::MUL_RM32(const X86::Instruction& insn)
|
|||
set_of(edx() != 0);
|
||||
}
|
||||
|
||||
void SoftCPU::MUL_RM8(const X86::Instruction&) { TODO(); }
|
||||
void SoftCPU::MUL_RM8(const X86::Instruction& insn)
|
||||
{
|
||||
u16 result = (u16)al() * insn.modrm().read8(*this, insn);
|
||||
set_ax(result);
|
||||
|
||||
set_cf((result & 0xff00) != 0);
|
||||
set_of((result & 0xff00) != 0);
|
||||
}
|
||||
|
||||
void SoftCPU::NEG_RM16(const X86::Instruction& insn)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue