From f3df799dc287792157b08d706c8e677924144e93 Mon Sep 17 00:00:00 2001 From: Aleksandar Andrejevic Date: Mon, 11 Nov 2013 03:14:18 +0000 Subject: [PATCH] [FAST486] Implement the LSS instruction. Fix a bug in LFS and LGS. svn path=/branches/ntvdm/; revision=60935 --- lib/fast486/extraops.c | 71 +++++++++++++++++++++++++++++++++++++++++- lib/fast486/extraops.h | 1 + 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/lib/fast486/extraops.c b/lib/fast486/extraops.c index 64ae8ba7310..ba2b5bd263f 100644 --- a/lib/fast486/extraops.c +++ b/lib/fast486/extraops.c @@ -215,7 +215,7 @@ Fast486ExtendedHandlers[FAST486_NUM_OPCODE_HANDLERS] = Fast486ExtOpcodeImul, Fast486ExtOpcodeCmpXchgByte, Fast486ExtOpcodeCmpXchg, - NULL, // TODO: OPCODE 0xB2 NOT IMPLEMENTED + Fast486ExtOpcodeLss, Fast486ExtOpcodeBtr, Fast486ExtOpcodeLfsLgs, Fast486ExtOpcodeLfsLgs, @@ -1102,6 +1102,74 @@ FAST486_OPCODE_HANDLER(Fast486ExtOpcodeCmpXchg) return TRUE; } +FAST486_OPCODE_HANDLER(Fast486ExtOpcodeLss) +{ + UCHAR FarPointer[6]; + BOOLEAN OperandSize, AddressSize; + FAST486_MOD_REG_RM ModRegRm; + + /* Make sure this is the right instruction */ + ASSERT(Opcode == 0xB2); + + OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size; + + TOGGLE_OPSIZE(OperandSize); + TOGGLE_ADSIZE(AddressSize); + + /* Get the operands */ + if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm)) + { + /* Exception occurred */ + return FALSE; + } + + if (!ModRegRm.Memory) + { + /* Invalid */ + Fast486Exception(State, FAST486_EXCEPTION_UD); + return FALSE; + } + + if (!Fast486ReadMemory(State, + (State->PrefixFlags & FAST486_PREFIX_SEG) + ? State->SegmentOverride : FAST486_REG_DS, + ModRegRm.MemoryAddress, + FALSE, + FarPointer, + OperandSize ? 6 : 4)) + { + /* Exception occurred */ + return FALSE; + } + + if (OperandSize) + { + ULONG Offset = *((PULONG)FarPointer); + USHORT Segment = *((PUSHORT)&FarPointer[sizeof(ULONG)]); + + /* Set the register to the offset */ + State->GeneralRegs[ModRegRm.Register].Long = Offset; + + /* Load the segment */ + return Fast486LoadSegment(State, + FAST486_REG_SS, + Segment); + } + else + { + USHORT Offset = *((PUSHORT)FarPointer); + USHORT Segment = *((PUSHORT)&FarPointer[sizeof(USHORT)]); + + /* Set the register to the offset */ + State->GeneralRegs[ModRegRm.Register].LowWord = Offset; + + /* Load the segment */ + return Fast486LoadSegment(State, + FAST486_REG_SS, + Segment); + } +} + FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBtr) { BOOLEAN OperandSize, AddressSize; @@ -1204,6 +1272,7 @@ FAST486_OPCODE_HANDLER(Fast486ExtOpcodeLfsLgs) OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size; + TOGGLE_OPSIZE(OperandSize); TOGGLE_ADSIZE(AddressSize); /* Get the operands */ diff --git a/lib/fast486/extraops.h b/lib/fast486/extraops.h index 0e6ff21b709..5996e811233 100644 --- a/lib/fast486/extraops.h +++ b/lib/fast486/extraops.h @@ -42,6 +42,7 @@ FAST486_OPCODE_HANDLER(Fast486ExtOpcodeShrd); FAST486_OPCODE_HANDLER(Fast486ExtOpcodeImul); FAST486_OPCODE_HANDLER(Fast486ExtOpcodeCmpXchgByte); FAST486_OPCODE_HANDLER(Fast486ExtOpcodeCmpXchg); +FAST486_OPCODE_HANDLER(Fast486ExtOpcodeLss); FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBtr); FAST486_OPCODE_HANDLER(Fast486ExtOpcodeLfsLgs); FAST486_OPCODE_HANDLER(Fast486ExtOpcodeMovzxByte);