mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 01:57:44 +00:00
UserspaceEmulator: Fix buggy IDIV instructions
These were not doing mashing together the signed double-size results correctly and lost bits in the signed/unsigned casting process.
This commit is contained in:
parent
9e6d002660
commit
e4b068aec5
1 changed files with 24 additions and 7 deletions
|
@ -1257,18 +1257,35 @@ void SoftCPU::ESCAPE(const X86::Instruction&)
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftCPU::HLT(const X86::Instruction&) { TODO(); }
|
void SoftCPU::HLT(const X86::Instruction&) { TODO(); }
|
||||||
void SoftCPU::IDIV_RM16(const X86::Instruction&) { TODO(); }
|
|
||||||
|
|
||||||
void SoftCPU::IDIV_RM32(const X86::Instruction& insn)
|
void SoftCPU::IDIV_RM16(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto divisor = insn.modrm().read32(*this, insn);
|
auto divisor = (i16)insn.modrm().read16(*this, insn);
|
||||||
if (divisor == 0) {
|
if (divisor == 0) {
|
||||||
warn() << "Divide by zero";
|
warn() << "Divide by zero";
|
||||||
TODO();
|
TODO();
|
||||||
}
|
}
|
||||||
i64 dividend = ((i64)edx() << 32) | eax();
|
i32 dividend = (i32)(((u32)dx() << 16) | (u32)ax());
|
||||||
auto result = dividend / divisor;
|
i32 result = dividend / divisor;
|
||||||
if (result > NumericLimits<i32>::max()) {
|
if (result > NumericLimits<i16>::max() || result < NumericLimits<i16>::min()) {
|
||||||
|
warn() << "Divide overflow";
|
||||||
|
TODO();
|
||||||
|
}
|
||||||
|
|
||||||
|
set_ax(result);
|
||||||
|
set_dx(dividend % divisor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoftCPU::IDIV_RM32(const X86::Instruction& insn)
|
||||||
|
{
|
||||||
|
auto divisor = (i32)insn.modrm().read32(*this, insn);
|
||||||
|
if (divisor == 0) {
|
||||||
|
warn() << "Divide by zero";
|
||||||
|
TODO();
|
||||||
|
}
|
||||||
|
i64 dividend = (i64)(((u64)edx() << 32) | (u64)eax());
|
||||||
|
i64 result = dividend / divisor;
|
||||||
|
if (result > NumericLimits<i32>::max() || result < NumericLimits<i32>::min()) {
|
||||||
warn() << "Divide overflow";
|
warn() << "Divide overflow";
|
||||||
TODO();
|
TODO();
|
||||||
}
|
}
|
||||||
|
@ -1279,7 +1296,7 @@ void SoftCPU::IDIV_RM32(const X86::Instruction& insn)
|
||||||
|
|
||||||
void SoftCPU::IDIV_RM8(const X86::Instruction& insn)
|
void SoftCPU::IDIV_RM8(const X86::Instruction& insn)
|
||||||
{
|
{
|
||||||
auto divisor = (i16)insn.modrm().read8(*this, insn);
|
auto divisor = (i8)insn.modrm().read8(*this, insn);
|
||||||
if (divisor == 0) {
|
if (divisor == 0) {
|
||||||
warn() << "Divide by zero";
|
warn() << "Divide by zero";
|
||||||
TODO();
|
TODO();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue