Author: aandrejevic Date: Fri Nov 1 02:48:28 2013 New Revision: 60819
URL: http://svn.reactos.org/svn/reactos?rev=60819&view=rev Log: [FAST486] Implement the XADD instruction.
Modified: branches/ntvdm/lib/fast486/extraops.c branches/ntvdm/lib/fast486/extraops.h
Modified: branches/ntvdm/lib/fast486/extraops.c URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/fast486/extraops.c?rev... ============================================================================== --- branches/ntvdm/lib/fast486/extraops.c [iso-8859-1] (original) +++ branches/ntvdm/lib/fast486/extraops.c [iso-8859-1] Fri Nov 1 02:48:28 2013 @@ -229,8 +229,8 @@ NULL, // TODO: OPCODE 0xBD NOT IMPLEMENTED NULL, // TODO: OPCODE 0xBE NOT IMPLEMENTED NULL, // TODO: OPCODE 0xBF NOT IMPLEMENTED - NULL, // TODO: OPCODE 0xC0 NOT IMPLEMENTED - NULL, // TODO: OPCODE 0xC1 NOT IMPLEMENTED + Fast486ExtOpcodeXaddByte, + Fast486ExtOpcodeXadd, NULL, // Invalid NULL, // Invalid NULL, // Invalid @@ -1233,6 +1233,165 @@ return Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, Value); }
+FAST486_OPCODE_HANDLER(Fast486ExtOpcodeXaddByte) +{ + UCHAR Source, Destination, Result; + FAST486_MOD_REG_RM ModRegRm; + BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size; + + /* Make sure this is the right instruction */ + ASSERT(Opcode == 0xC0); + + TOGGLE_ADSIZE(AddressSize); + + /* Get the operands */ + if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm)) + { + /* Exception occurred */ + return FALSE; + } + + if (!Fast486ReadModrmByteOperands(State, + &ModRegRm, + &Source, + &Destination)) + { + /* Exception occurred */ + return FALSE; + } + + /* Calculate the result */ + Result = Source + Destination; + + /* Update the flags */ + State->Flags.Cf = (Result < Source) && (Result < Destination); + State->Flags.Of = ((Source & SIGN_FLAG_BYTE) == (Destination & SIGN_FLAG_BYTE)) + && ((Source & SIGN_FLAG_BYTE) != (Result & SIGN_FLAG_BYTE)); + State->Flags.Af = (((Source & 0x0F) + (Destination & 0x0F)) & 0x10) ? TRUE : FALSE; + State->Flags.Zf = (Result == 0) ? TRUE : FALSE; + State->Flags.Sf = (Result & SIGN_FLAG_BYTE) ? TRUE : FALSE; + State->Flags.Pf = Fast486CalculateParity(Result); + + /* Write the sum to the destination */ + if (!Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, Result)) + { + /* Exception occurred */ + return FALSE; + } + + /* Write the old value of the destination to the source */ + if (!Fast486WriteModrmByteOperands(State, &ModRegRm, TRUE, Destination)) + { + /* Exception occurred */ + return FALSE; + } + + return TRUE; +} + +FAST486_OPCODE_HANDLER(Fast486ExtOpcodeXadd) +{ + FAST486_MOD_REG_RM ModRegRm; + BOOLEAN OperandSize, AddressSize; + + /* Make sure this is the right instruction */ + ASSERT(Opcode == 0xC1); + + OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size; + + TOGGLE_ADSIZE(AddressSize); + TOGGLE_OPSIZE(OperandSize); + + /* Get the operands */ + if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm)) + { + /* Exception occurred */ + return FALSE; + } + + /* Check the operand size */ + if (OperandSize) + { + ULONG Source, Destination, Result; + + if (!Fast486ReadModrmDwordOperands(State, + &ModRegRm, + &Source, + &Destination)) + { + /* Exception occurred */ + return FALSE; + } + + /* Calculate the result */ + Result = Source + Destination; + + /* Update the flags */ + State->Flags.Cf = (Result < Source) && (Result < Destination); + State->Flags.Of = ((Source & SIGN_FLAG_LONG) == (Destination & SIGN_FLAG_LONG)) + && ((Source & SIGN_FLAG_LONG) != (Result & SIGN_FLAG_LONG)); + State->Flags.Af = (((Source & 0x0F) + (Destination & 0x0F)) & 0x10) ? TRUE : FALSE; + State->Flags.Zf = (Result == 0) ? TRUE : FALSE; + State->Flags.Sf = (Result & SIGN_FLAG_LONG) ? TRUE : FALSE; + State->Flags.Pf = Fast486CalculateParity(Result); + + /* Write the sum to the destination */ + if (!Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Result)) + { + /* Exception occurred */ + return FALSE; + } + + /* Write the old value of the destination to the source */ + if (!Fast486WriteModrmDwordOperands(State, &ModRegRm, TRUE, Destination)) + { + /* Exception occurred */ + return FALSE; + } + } + else + { + USHORT Source, Destination, Result; + + if (!Fast486ReadModrmWordOperands(State, + &ModRegRm, + &Source, + &Destination)) + { + /* Exception occurred */ + return FALSE; + } + + /* Calculate the result */ + Result = Source + Destination; + + /* Update the flags */ + State->Flags.Cf = (Result < Source) && (Result < Destination); + State->Flags.Of = ((Source & SIGN_FLAG_WORD) == (Destination & SIGN_FLAG_WORD)) + && ((Source & SIGN_FLAG_WORD) != (Result & SIGN_FLAG_WORD)); + State->Flags.Af = (((Source & 0x0F) + (Destination & 0x0F)) & 0x10) ? TRUE : FALSE; + State->Flags.Zf = (Result == 0) ? TRUE : FALSE; + State->Flags.Sf = (Result & SIGN_FLAG_WORD) ? TRUE : FALSE; + State->Flags.Pf = Fast486CalculateParity(Result); + + /* Write the sum to the destination */ + if (!Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Result)) + { + /* Exception occurred */ + return FALSE; + } + + /* Write the old value of the destination to the source */ + if (!Fast486WriteModrmWordOperands(State, &ModRegRm, TRUE, Destination)) + { + /* Exception occurred */ + return FALSE; + } + } + + return TRUE; +} + FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBswap) { PUCHAR Pointer;
Modified: branches/ntvdm/lib/fast486/extraops.h URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/fast486/extraops.h?rev... ============================================================================== --- branches/ntvdm/lib/fast486/extraops.h [iso-8859-1] (original) +++ branches/ntvdm/lib/fast486/extraops.h [iso-8859-1] Fri Nov 1 02:48:28 2013 @@ -43,6 +43,8 @@ FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBtc); FAST486_OPCODE_HANDLER(Fast486ExtOpcodeConditionalJmp); FAST486_OPCODE_HANDLER(Fast486ExtOpcodeConditionalSet); +FAST486_OPCODE_HANDLER(Fast486ExtOpcodeXaddByte); +FAST486_OPCODE_HANDLER(Fast486ExtOpcodeXadd); FAST486_OPCODE_HANDLER(Fast486ExtOpcodeBswap); FAST486_OPCODE_HANDLER(Fast486OpcodeExtended);