From 4f4d9fe5d23929648646254a54c604b84ccbc2e1 Mon Sep 17 00:00:00 2001 From: Aleksandar Andrejevic Date: Thu, 7 Nov 2013 01:06:39 +0000 Subject: [PATCH] [FAST486] Implement LFS, LGS and MOVZX. svn path=/branches/ntvdm/; revision=60878 --- lib/fast486/extraops.c | 141 +++++++++++++++++++++++++++++++++++++++-- lib/fast486/extraops.h | 3 + 2 files changed, 140 insertions(+), 4 deletions(-) diff --git a/lib/fast486/extraops.c b/lib/fast486/extraops.c index a36bea1e841..582de71c9b6 100644 --- a/lib/fast486/extraops.c +++ b/lib/fast486/extraops.c @@ -217,10 +217,10 @@ Fast486ExtendedHandlers[FAST486_NUM_OPCODE_HANDLERS] = Fast486ExtOpcodeCmpXchg, NULL, // TODO: OPCODE 0xB2 NOT IMPLEMENTED Fast486ExtOpcodeBtr, - NULL, // TODO: OPCODE 0xB4 NOT IMPLEMENTED - NULL, // TODO: OPCODE 0xB5 NOT IMPLEMENTED - NULL, // TODO: OPCODE 0xB6 NOT IMPLEMENTED - NULL, // TODO: OPCODE 0xB7 NOT IMPLEMENTED + Fast486ExtOpcodeLfsLgs, + Fast486ExtOpcodeLfsLgs, + Fast486ExtOpcodeMovzxByte, + Fast486ExtOpcodeMovzxWord, NULL, // TODO: OPCODE 0xB8 NOT IMPLEMENTED Fast486OpcodeGroup0FB9, Fast486OpcodeGroup0FBA, @@ -945,6 +945,139 @@ FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBtr) return TRUE; } +FAST486_OPCODE_HANDLER(Fast486ExtOpcodeLfsLgs) +{ + UCHAR FarPointer[6]; + BOOLEAN OperandSize, AddressSize; + FAST486_MOD_REG_RM ModRegRm; + + /* Make sure this is the right instruction */ + ASSERT((Opcode & 0xFE) == 0xB4); + + OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size; + + 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, + (Opcode == 0xB4) + ? FAST486_REG_FS : FAST486_REG_GS, + 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, + (Opcode == 0xB4) + ? FAST486_REG_FS : FAST486_REG_GS, + Segment); + } +} + +FAST486_OPCODE_HANDLER(Fast486ExtOpcodeMovzxByte) +{ + UCHAR Dummy, Value; + BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size; + FAST486_MOD_REG_RM ModRegRm; + + TOGGLE_ADSIZE(AddressSize); + + /* Make sure this is the right instruction */ + ASSERT(Opcode == 0xB6); + + /* Get the operands */ + if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm)) + { + /* Exception occurred */ + return FALSE; + } + + /* Read the operands */ + if (!Fast486ReadModrmByteOperands(State, &ModRegRm, &Dummy, &Value)) + { + /* Exception occurred */ + return FALSE; + } + + /* Write back the zero-extended value */ + return Fast486WriteModrmDwordOperands(State, + &ModRegRm, + TRUE, + (ULONG)Value); +} + +FAST486_OPCODE_HANDLER(Fast486ExtOpcodeMovzxWord) +{ + USHORT Dummy, Value; + BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size; + FAST486_MOD_REG_RM ModRegRm; + + TOGGLE_ADSIZE(AddressSize); + + /* Make sure this is the right instruction */ + ASSERT(Opcode == 0xB7); + + /* Get the operands */ + if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm)) + { + /* Exception occurred */ + return FALSE; + } + + /* Read the operands */ + if (!Fast486ReadModrmWordOperands(State, &ModRegRm, &Dummy, &Value)) + { + /* Exception occurred */ + return FALSE; + } + + /* Write back the zero-extended value */ + return Fast486WriteModrmDwordOperands(State, + &ModRegRm, + TRUE, + (ULONG)Value); +} + FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBtc) { BOOLEAN OperandSize, AddressSize; diff --git a/lib/fast486/extraops.h b/lib/fast486/extraops.h index 8d6924f5699..9b5a3e416a4 100644 --- a/lib/fast486/extraops.h +++ b/lib/fast486/extraops.h @@ -40,6 +40,9 @@ FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBts); FAST486_OPCODE_HANDLER(Fast486ExtOpcodeCmpXchgByte); FAST486_OPCODE_HANDLER(Fast486ExtOpcodeCmpXchg); FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBtr); +FAST486_OPCODE_HANDLER(Fast486ExtOpcodeLfsLgs); +FAST486_OPCODE_HANDLER(Fast486ExtOpcodeMovzxByte); +FAST486_OPCODE_HANDLER(Fast486ExtOpcodeMovzxWord); FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBtc); FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBsf); FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBsr); -- 2.17.1