ReactOS 0.4.15-dev-7842-g558ab78
extraops.c File Reference
#include <windef.h>
#include <debug.h>
#include <fast486.h>
#include "opcodes.h"
#include "common.h"
#include "opgroups.h"
#include "extraops.h"
Include dependency graph for extraops.c:

Go to the source code of this file.

Functions

 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeInvalid)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeUnimplemented)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcode0F0B)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeLar)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeLsl)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeClts)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeStoreControlReg)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeStoreDebugReg)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeLoadControlReg)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeLoadDebugReg)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodePushFs)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodePopFs)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeBitTest)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeShld)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodePushGs)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodePopGs)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeBts)
 
 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)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeMovzxWord)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeBtc)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeBsf)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeBsr)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeMovsxByte)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeMovsxWord)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeConditionalJmp)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeConditionalSet)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeXaddByte)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeXadd)
 
 FAST486_OPCODE_HANDLER (Fast486ExtOpcodeBswap)
 
 FAST486_OPCODE_HANDLER (Fast486OpcodeExtended)
 

Variables

FAST486_OPCODE_HANDLER_PROC Fast486ExtendedHandlers [FAST486_NUM_OPCODE_HANDLERS]
 

Function Documentation

◆ FAST486_OPCODE_HANDLER() [1/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcode0F0B  )

Definition at line 313 of file extraops.c.

314{
315 /* Reserved opcode (UD2) */
316 Fast486Exception(State, FAST486_EXCEPTION_UD);
317}

◆ FAST486_OPCODE_HANDLER() [2/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeBitTest  )

Definition at line 723 of file extraops.c.

724{
725 BOOLEAN OperandSize, AddressSize;
726 FAST486_MOD_REG_RM ModRegRm;
728 ULONG BitNumber;
729
730 OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
731 TOGGLE_OPSIZE(OperandSize);
732 TOGGLE_ADSIZE(AddressSize);
733
734 /* Get the number of bits */
735 if (OperandSize) DataSize = 32;
736 else DataSize = 16;
737
738 /* Get the operands */
739 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
740 {
741 /* Exception occurred */
742 return;
743 }
744
745 /* Get the bit number */
746 BitNumber = OperandSize ? State->GeneralRegs[ModRegRm.Register].Long
747 : (ULONG)State->GeneralRegs[ModRegRm.Register].LowWord;
748
749 if (ModRegRm.Memory)
750 {
751 /*
752 * For memory operands, add the bit offset divided by
753 * the data size to the address
754 */
755 ModRegRm.MemoryAddress += (BitNumber / DataSize) * (DataSize / 8);
756 }
757
758 /* Normalize the bit number */
759 BitNumber %= DataSize;
760
761 if (OperandSize)
762 {
763 ULONG Value;
764
765 /* Read the value */
766 if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Value))
767 {
768 /* Exception occurred */
769 return;
770 }
771
772 /* Set CF to the bit value */
773 State->Flags.Cf = (Value >> BitNumber) & 1;
774 }
775 else
776 {
778
779 /* Read the value */
780 if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &Value))
781 {
782 /* Exception occurred */
783 return;
784 }
785
786 /* Set CF to the bit value */
787 State->Flags.Cf = (Value >> BitNumber) & 1;
788 }
789}
unsigned char BOOLEAN
#define NULL
Definition: types.h:112
if(dx< 0)
Definition: linetemp.h:194
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4755
unsigned int UINT
Definition: ndis.h:50
unsigned short USHORT
Definition: pedump.c:61
#define TOGGLE_ADSIZE(x)
Definition: common.h:53
#define TOGGLE_OPSIZE(x)
Definition: common.h:50
ULONG MemoryAddress
Definition: common.h:81
BOOLEAN Memory
Definition: common.h:77
FAST486_GEN_REGS Register
Definition: common.h:76
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

◆ FAST486_OPCODE_HANDLER() [3/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeBsf  )

Definition at line 1643 of file extraops.c.

1644{
1645 UINT i;
1646 ULONG Value = 0;
1647 BOOLEAN OperandSize, AddressSize;
1648 FAST486_MOD_REG_RM ModRegRm;
1649 ULONG BitNumber;
1650 UINT DataSize;
1651
1652 OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
1653 TOGGLE_OPSIZE(OperandSize);
1654 TOGGLE_ADSIZE(AddressSize);
1655
1656 /* Make sure this is the right instruction */
1657 ASSERT(Opcode == 0xBC);
1658
1659 /* Get the number of bits */
1660 if (OperandSize) DataSize = 32;
1661 else DataSize = 16;
1662
1663 /* Get the operands */
1664 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
1665 {
1666 /* Exception occurred */
1667 return;
1668 }
1669
1670 /* Read the value */
1671 if (OperandSize)
1672 {
1673 if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Value))
1674 {
1675 /* Exception occurred */
1676 return;
1677 }
1678 }
1679 else
1680 {
1681 if (!Fast486ReadModrmWordOperands(State,
1682 &ModRegRm,
1683 (PUSHORT)NULL,
1684 (PUSHORT)&Value))
1685 {
1686 /* Exception occurred */
1687 return;
1688 }
1689 }
1690
1691 /* Set ZF */
1692 State->Flags.Zf = (Value == 0);
1693 if (State->Flags.Zf) return;
1694
1695 for (i = 0; i < DataSize; i++)
1696 {
1697 if (Value & (1 << i))
1698 {
1699 /* Save the bit number */
1700 BitNumber = i;
1701
1702 /* Exit the loop */
1703 break;
1704 }
1705 }
1706
1707 /* Write back the result */
1708 if (OperandSize) Fast486WriteModrmDwordOperands(State, &ModRegRm, TRUE, BitNumber);
1709 else Fast486WriteModrmWordOperands(State, &ModRegRm, TRUE, LOWORD(BitNumber));
1710}
#define TRUE
Definition: types.h:120
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_In_ PVOID _In_ ULONG Opcode
Definition: hubbusif.h:331
#define ASSERT(a)
Definition: mode.c:44
#define LOWORD(l)
Definition: pedump.c:82
uint16_t * PUSHORT
Definition: typedefs.h:56

◆ FAST486_OPCODE_HANDLER() [4/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeBsr  )

Definition at line 1712 of file extraops.c.

1713{
1714 INT i;
1715 ULONG Value = 0;
1716 BOOLEAN OperandSize, AddressSize;
1717 FAST486_MOD_REG_RM ModRegRm;
1718 ULONG BitNumber;
1719 UINT DataSize;
1720
1721 OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
1722 TOGGLE_OPSIZE(OperandSize);
1723 TOGGLE_ADSIZE(AddressSize);
1724
1725 /* Make sure this is the right instruction */
1726 ASSERT(Opcode == 0xBD);
1727
1728 /* Get the number of bits */
1729 if (OperandSize) DataSize = 32;
1730 else DataSize = 16;
1731
1732 /* Get the operands */
1733 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
1734 {
1735 /* Exception occurred */
1736 return;
1737 }
1738
1739 /* Read the value */
1740 if (OperandSize)
1741 {
1742 if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Value))
1743 {
1744 /* Exception occurred */
1745 return;
1746 }
1747 }
1748 else
1749 {
1750 if (!Fast486ReadModrmWordOperands(State,
1751 &ModRegRm,
1752 (PUSHORT)NULL,
1753 (PUSHORT)&Value))
1754 {
1755 /* Exception occurred */
1756 return;
1757 }
1758 }
1759
1760 /* Set ZF according to the value */
1761 State->Flags.Zf = (Value == 0);
1762 if (State->Flags.Zf) return;
1763
1764 for (i = DataSize - 1; i >= 0; i--)
1765 {
1766 if (Value & (1 << i))
1767 {
1768 /* Save the bit number */
1769 BitNumber = i;
1770
1771 /* Exit the loop */
1772 break;
1773 }
1774 }
1775
1776 /* Write back the result */
1777 if (OperandSize) Fast486WriteModrmDwordOperands(State, &ModRegRm, TRUE, BitNumber);
1778 else Fast486WriteModrmWordOperands(State, &ModRegRm, TRUE, LOWORD(BitNumber));
1779}
int32_t INT
Definition: typedefs.h:58

◆ FAST486_OPCODE_HANDLER() [5/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeBswap  )

Definition at line 2182 of file extraops.c.

2183{
2184 PUCHAR Pointer;
2185
2187
2188 /* Get a pointer to the value */
2189 Pointer = (PUCHAR)&State->GeneralRegs[Opcode & 0x07].Long;
2190
2191 /* Swap the byte order */
2192 SWAP(Pointer[0], Pointer[3]);
2193 SWAP(Pointer[1], Pointer[2]);
2194}
#define SWAP()
Definition: pattern.c:1185
#define NO_LOCK_PREFIX()
Definition: common.h:43
unsigned char * PUCHAR
Definition: typedefs.h:53

◆ FAST486_OPCODE_HANDLER() [6/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeBtc  )

Definition at line 1563 of file extraops.c.

1564{
1565 BOOLEAN OperandSize, AddressSize;
1566 FAST486_MOD_REG_RM ModRegRm;
1567 UINT DataSize;
1568 ULONG BitNumber;
1569
1570 OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
1571 TOGGLE_OPSIZE(OperandSize);
1572 TOGGLE_ADSIZE(AddressSize);
1573
1574 /* Get the number of bits */
1575 if (OperandSize) DataSize = 32;
1576 else DataSize = 16;
1577
1578 /* Get the operands */
1579 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
1580 {
1581 /* Exception occurred */
1582 return;
1583 }
1584
1585 /* Get the bit number */
1586 BitNumber = OperandSize ? State->GeneralRegs[ModRegRm.Register].Long
1587 : (ULONG)State->GeneralRegs[ModRegRm.Register].LowWord;
1588
1589 if (ModRegRm.Memory)
1590 {
1591 /*
1592 * For memory operands, add the bit offset divided by
1593 * the data size to the address
1594 */
1595 ModRegRm.MemoryAddress += (BitNumber / DataSize) * (DataSize / 8);
1596 }
1597
1598 /* Normalize the bit number */
1599 BitNumber %= DataSize;
1600
1601 if (OperandSize)
1602 {
1603 ULONG Value;
1604
1605 /* Read the value */
1606 if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Value))
1607 {
1608 /* Exception occurred */
1609 return;
1610 }
1611
1612 /* Set CF to the bit value */
1613 State->Flags.Cf = (Value >> BitNumber) & 1;
1614
1615 /* Toggle the bit */
1616 Value ^= 1 << BitNumber;
1617
1618 /* Write back the result */
1619 Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Value);
1620 }
1621 else
1622 {
1623 USHORT Value;
1624
1625 /* Read the value */
1626 if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &Value))
1627 {
1628 /* Exception occurred */
1629 return;
1630 }
1631
1632 /* Set CF to the bit value */
1633 State->Flags.Cf = (Value >> BitNumber) & 1;
1634
1635 /* Toggle the bit */
1636 Value ^= 1 << BitNumber;
1637
1638 /* Write back the result */
1639 Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value);
1640 }
1641}
#define FALSE
Definition: types.h:117

◆ FAST486_OPCODE_HANDLER() [7/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeBtr  )

Definition at line 1349 of file extraops.c.

1350{
1351 BOOLEAN OperandSize, AddressSize;
1352 FAST486_MOD_REG_RM ModRegRm;
1353 UINT DataSize;
1354 ULONG BitNumber;
1355
1356 OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
1357 TOGGLE_OPSIZE(OperandSize);
1358 TOGGLE_ADSIZE(AddressSize);
1359
1360 /* Get the number of bits */
1361 if (OperandSize) DataSize = 32;
1362 else DataSize = 16;
1363
1364 /* Get the operands */
1365 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
1366 {
1367 /* Exception occurred */
1368 return;
1369 }
1370
1371 /* Get the bit number */
1372 BitNumber = OperandSize ? State->GeneralRegs[ModRegRm.Register].Long
1373 : (ULONG)State->GeneralRegs[ModRegRm.Register].LowWord;
1374
1375 if (ModRegRm.Memory)
1376 {
1377 /*
1378 * For memory operands, add the bit offset divided by
1379 * the data size to the address
1380 */
1381 ModRegRm.MemoryAddress += (BitNumber / DataSize) * (DataSize / 8);
1382 }
1383
1384 /* Normalize the bit number */
1385 BitNumber %= DataSize;
1386
1387 if (OperandSize)
1388 {
1389 ULONG Value;
1390
1391 /* Read the value */
1392 if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Value))
1393 {
1394 /* Exception occurred */
1395 return;
1396 }
1397
1398 /* Set CF to the bit value */
1399 State->Flags.Cf = (Value >> BitNumber) & 1;
1400
1401 /* Clear the bit */
1402 Value &= ~(1 << BitNumber);
1403
1404 /* Write back the result */
1405 Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Value);
1406 }
1407 else
1408 {
1409 USHORT Value;
1410
1411 /* Read the value */
1412 if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &Value))
1413 {
1414 /* Exception occurred */
1415 return;
1416 }
1417
1418 /* Set CF to the bit value */
1419 State->Flags.Cf = (Value >> BitNumber) & 1;
1420
1421 /* Clear the bit */
1422 Value &= ~(1 << BitNumber);
1423
1424 /* Write back the result */
1425 Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value);
1426 }
1427}

◆ FAST486_OPCODE_HANDLER() [8/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeBts  )

Definition at line 907 of file extraops.c.

908{
909 BOOLEAN OperandSize, AddressSize;
910 FAST486_MOD_REG_RM ModRegRm;
912 ULONG BitNumber;
913
914 OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
915 TOGGLE_OPSIZE(OperandSize);
916 TOGGLE_ADSIZE(AddressSize);
917
918 /* Get the number of bits */
919 if (OperandSize) DataSize = 32;
920 else DataSize = 16;
921
922 /* Get the operands */
923 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
924 {
925 /* Exception occurred */
926 return;
927 }
928
929 /* Get the bit number */
930 BitNumber = OperandSize ? State->GeneralRegs[ModRegRm.Register].Long
931 : (ULONG)State->GeneralRegs[ModRegRm.Register].LowWord;
932
933 if (ModRegRm.Memory)
934 {
935 /*
936 * For memory operands, add the bit offset divided by
937 * the data size to the address
938 */
939 ModRegRm.MemoryAddress += (BitNumber / DataSize) * (DataSize / 8);
940 }
941
942 /* Normalize the bit number */
943 BitNumber %= DataSize;
944
945 if (OperandSize)
946 {
947 ULONG Value;
948
949 /* Read the value */
950 if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Value))
951 {
952 /* Exception occurred */
953 return;
954 }
955
956 /* Set CF to the bit value */
957 State->Flags.Cf = (Value >> BitNumber) & 1;
958
959 /* Set the bit */
960 Value |= 1 << BitNumber;
961
962 /* Write back the result */
963 Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Value);
964 }
965 else
966 {
968
969 /* Read the value */
970 if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &Value))
971 {
972 /* Exception occurred */
973 return;
974 }
975
976 /* Set CF to the bit value */
977 State->Flags.Cf = (Value >> BitNumber) & 1;
978
979 /* Set the bit */
980 Value |= 1 << BitNumber;
981
982 /* Write back the result */
983 Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Value);
984 }
985}

◆ FAST486_OPCODE_HANDLER() [9/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeClts  )

Definition at line 493 of file extraops.c.

494{
496
497 /* The current privilege level must be zero */
498 if (Fast486GetCurrentPrivLevel(State) != 0)
499 {
500 Fast486Exception(State, FAST486_EXCEPTION_GP);
501 return;
502 }
503
504 /* Clear the task switch bit */
505 State->ControlRegisters[FAST486_REG_CR0] &= ~FAST486_CR0_TS;
506}

◆ FAST486_OPCODE_HANDLER() [10/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeCmpXchg  )

Definition at line 1196 of file extraops.c.

1197{
1198 FAST486_MOD_REG_RM ModRegRm;
1199 BOOLEAN OperandSize, AddressSize;
1200
1201 OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
1202
1203 TOGGLE_OPSIZE(OperandSize);
1204 TOGGLE_ADSIZE(AddressSize);
1205
1206 /* Get the operands */
1207 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
1208 {
1209 /* Exception occurred */
1210 return;
1211 }
1212
1213 if (OperandSize)
1214 {
1216 ULONG Accumulator = State->GeneralRegs[FAST486_REG_EAX].Long;
1217
1218 /* Read the operands */
1219 if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, &Source, &Destination))
1220 {
1221 /* Exception occurred */
1222 return;
1223 }
1224
1225 /* Compare EAX with the destination */
1226 Result = Accumulator - Destination;
1227
1228 /* Update the flags */
1229 State->Flags.Cf = (Accumulator < Destination);
1230 State->Flags.Of = ((Accumulator & SIGN_FLAG_LONG) != (Destination & SIGN_FLAG_LONG))
1231 && ((Accumulator & SIGN_FLAG_LONG) != (Result & SIGN_FLAG_LONG));
1232 State->Flags.Af = (Accumulator & 0x0F) < (Destination & 0x0F);
1233 State->Flags.Zf = (Result == 0);
1234 State->Flags.Sf = ((Result & SIGN_FLAG_LONG) != 0);
1235 State->Flags.Pf = Fast486CalculateParity(Result);
1236
1237 if (State->Flags.Zf)
1238 {
1239 /* Load the source operand into the destination */
1240 Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Source);
1241 }
1242 else
1243 {
1244 /* Load the destination into EAX */
1245 State->GeneralRegs[FAST486_REG_EAX].Long = Destination;
1246 }
1247 }
1248 else
1249 {
1251 USHORT Accumulator = State->GeneralRegs[FAST486_REG_EAX].LowWord;
1252
1253 /* Read the operands */
1254 if (!Fast486ReadModrmWordOperands(State, &ModRegRm, &Source, &Destination))
1255 {
1256 /* Exception occurred */
1257 return;
1258 }
1259
1260 /* Compare AX with the destination */
1261 Result = Accumulator - Destination;
1262
1263 /* Update the flags */
1264 State->Flags.Cf = (Accumulator < Destination);
1265 State->Flags.Of = ((Accumulator & SIGN_FLAG_WORD) != (Destination & SIGN_FLAG_WORD))
1266 && ((Accumulator & SIGN_FLAG_WORD) != (Result & SIGN_FLAG_WORD));
1267 State->Flags.Af = (Accumulator & 0x0F) < (Destination & 0x0F);
1268 State->Flags.Zf = (Result == 0);
1269 State->Flags.Sf = ((Result & SIGN_FLAG_WORD) != 0);
1270 State->Flags.Pf = Fast486CalculateParity(Result);
1271
1272 if (State->Flags.Zf)
1273 {
1274 /* Load the source operand into the destination */
1275 Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Source);
1276 }
1277 else
1278 {
1279 /* Load the destination into AX */
1280 State->GeneralRegs[FAST486_REG_EAX].LowWord = Destination;
1281 }
1282 }
1283}
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:3004
#define SIGN_FLAG_WORD
Definition: common.h:30
#define SIGN_FLAG_LONG
Definition: common.h:31
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409

◆ FAST486_OPCODE_HANDLER() [11/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeCmpXchgByte  )

Definition at line 1149 of file extraops.c.

1150{
1151 FAST486_MOD_REG_RM ModRegRm;
1152 UCHAR Accumulator = State->GeneralRegs[FAST486_REG_EAX].LowByte;
1154 BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
1155
1156 TOGGLE_ADSIZE(AddressSize);
1157
1158 /* Get the operands */
1159 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
1160 {
1161 /* Exception occurred */
1162 return;
1163 }
1164
1165 /* Read the operands */
1166 if (!Fast486ReadModrmByteOperands(State, &ModRegRm, &Source, &Destination))
1167 {
1168 /* Exception occurred */
1169 return;
1170 }
1171
1172 /* Compare AL with the destination */
1173 Result = Accumulator - Destination;
1174
1175 /* Update the flags */
1176 State->Flags.Cf = (Accumulator < Destination);
1177 State->Flags.Of = ((Accumulator & SIGN_FLAG_BYTE) != (Destination & SIGN_FLAG_BYTE))
1178 && ((Accumulator & SIGN_FLAG_BYTE) != (Result & SIGN_FLAG_BYTE));
1179 State->Flags.Af = (Accumulator & 0x0F) < (Destination & 0x0F);
1180 State->Flags.Zf = (Result == 0);
1181 State->Flags.Sf = ((Result & SIGN_FLAG_BYTE) != 0);
1182 State->Flags.Pf = Fast486CalculateParity(Result);
1183
1184 if (State->Flags.Zf)
1185 {
1186 /* Load the source operand into the destination */
1187 Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, Source);
1188 }
1189 else
1190 {
1191 /* Load the destination into AL */
1192 State->GeneralRegs[FAST486_REG_EAX].LowByte = Destination;
1193 }
1194}
#define SIGN_FLAG_BYTE
Definition: common.h:29
unsigned char UCHAR
Definition: xmlstorage.h:181

◆ FAST486_OPCODE_HANDLER() [12/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeConditionalJmp  )

Definition at line 1845 of file extraops.c.

1846{
1847 BOOLEAN Jump = FALSE;
1848 LONG Offset = 0;
1849 BOOLEAN Size = State->SegmentRegs[FAST486_REG_CS].Size;
1850
1853
1854 /* Make sure this is the right instruction */
1855 ASSERT((Opcode & 0xF0) == 0x80);
1856
1857 /* Fetch the offset */
1858 if (Size)
1859 {
1860 if (!Fast486FetchDword(State, (PULONG)&Offset))
1861 {
1862 /* Exception occurred */
1863 return;
1864 }
1865 }
1866 else
1867 {
1868 SHORT Value;
1869
1870 if (!Fast486FetchWord(State, (PUSHORT)&Value))
1871 {
1872 /* Exception occurred */
1873 return;
1874 }
1875
1876 /* Sign-extend */
1877 Offset = (LONG)Value;
1878 }
1879
1880 switch ((Opcode & 0x0F) >> 1)
1881 {
1882 /* JO / JNO */
1883 case 0:
1884 {
1885 Jump = State->Flags.Of;
1886 break;
1887 }
1888
1889 /* JC / JNC */
1890 case 1:
1891 {
1892 Jump = State->Flags.Cf;
1893 break;
1894 }
1895
1896 /* JZ / JNZ */
1897 case 2:
1898 {
1899 Jump = State->Flags.Zf;
1900 break;
1901 }
1902
1903 /* JBE / JNBE */
1904 case 3:
1905 {
1906 Jump = State->Flags.Cf || State->Flags.Zf;
1907 break;
1908 }
1909
1910 /* JS / JNS */
1911 case 4:
1912 {
1913 Jump = State->Flags.Sf;
1914 break;
1915 }
1916
1917 /* JP / JNP */
1918 case 5:
1919 {
1920 Jump = State->Flags.Pf;
1921 break;
1922 }
1923
1924 /* JL / JNL */
1925 case 6:
1926 {
1927 Jump = State->Flags.Sf != State->Flags.Of;
1928 break;
1929 }
1930
1931 /* JLE / JNLE */
1932 case 7:
1933 {
1934 Jump = (State->Flags.Sf != State->Flags.Of) || State->Flags.Zf;
1935 break;
1936 }
1937 }
1938
1939 if (Opcode & 1)
1940 {
1941 /* Invert the result */
1942 Jump = !Jump;
1943 }
1944
1945 if (Jump)
1946 {
1947 /* Move the instruction pointer */
1948 State->InstPtr.Long += Offset;
1949 }
1950}
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
uint32_t * PULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533

◆ FAST486_OPCODE_HANDLER() [13/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeConditionalSet  )

Definition at line 1952 of file extraops.c.

1953{
1955 BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
1956 FAST486_MOD_REG_RM ModRegRm;
1957
1958 TOGGLE_ADSIZE(AddressSize);
1959
1960 /* Get the operands */
1961 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
1962 {
1963 /* Exception occurred */
1964 return;
1965 }
1966
1967 /* Make sure this is the right instruction */
1968 ASSERT((Opcode & 0xF0) == 0x90);
1969
1970 switch ((Opcode & 0x0F) >> 1)
1971 {
1972 /* SETO / SETNO */
1973 case 0:
1974 {
1975 Value = State->Flags.Of;
1976 break;
1977 }
1978
1979 /* SETC / SETNC */
1980 case 1:
1981 {
1982 Value = State->Flags.Cf;
1983 break;
1984 }
1985
1986 /* SETZ / SETNZ */
1987 case 2:
1988 {
1989 Value = State->Flags.Zf;
1990 break;
1991 }
1992
1993 /* SETBE / SETNBE */
1994 case 3:
1995 {
1996 Value = State->Flags.Cf || State->Flags.Zf;
1997 break;
1998 }
1999
2000 /* SETS / SETNS */
2001 case 4:
2002 {
2003 Value = State->Flags.Sf;
2004 break;
2005 }
2006
2007 /* SETP / SETNP */
2008 case 5:
2009 {
2010 Value = State->Flags.Pf;
2011 break;
2012 }
2013
2014 /* SETL / SETNL */
2015 case 6:
2016 {
2017 Value = State->Flags.Sf != State->Flags.Of;
2018 break;
2019 }
2020
2021 /* SETLE / SETNLE */
2022 case 7:
2023 {
2024 Value = (State->Flags.Sf != State->Flags.Of) || State->Flags.Zf;
2025 break;
2026 }
2027 }
2028
2029 if (Opcode & 1)
2030 {
2031 /* Invert the result */
2032 Value = !Value;
2033 }
2034
2035 /* Write back the result */
2036 Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, Value);
2037}

◆ FAST486_OPCODE_HANDLER() [14/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeImul  )

Definition at line 1082 of file extraops.c.

1083{
1084 BOOLEAN OperandSize, AddressSize;
1085 FAST486_MOD_REG_RM ModRegRm;
1086
1087 OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
1088
1089 TOGGLE_OPSIZE(OperandSize);
1090 TOGGLE_ADSIZE(AddressSize);
1091
1092 /* Get the operands */
1093 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
1094 {
1095 /* Exception occurred */
1096 return;
1097 }
1098
1099 if (OperandSize)
1100 {
1103
1104 /* Read the operands */
1105 if (!Fast486ReadModrmDwordOperands(State,
1106 &ModRegRm,
1108 (PULONG)&Source))
1109 {
1110 /* Exception occurred */
1111 return;
1112 }
1113
1114 /* Calculate the result */
1116
1117 /* Update the flags */
1118 State->Flags.Cf = State->Flags.Of = ((Result < -2147483648LL) || (Result > 2147483647LL));
1119
1120 /* Write back the result */
1121 Fast486WriteModrmDwordOperands(State, &ModRegRm, TRUE, (ULONG)((LONG)Result));
1122 }
1123 else
1124 {
1126 LONG Result;
1127
1128 /* Read the operands */
1129 if (!Fast486ReadModrmWordOperands(State,
1130 &ModRegRm,
1132 (PUSHORT)&Source))
1133 {
1134 /* Exception occurred */
1135 return;
1136 }
1137
1138 /* Calculate the result */
1140
1141 /* Update the flags */
1142 State->Flags.Cf = State->Flags.Of = ((Result < -32768) || (Result > 32767));
1143
1144 /* Write back the result */
1145 Fast486WriteModrmWordOperands(State, &ModRegRm, TRUE, (USHORT)((SHORT)Result));
1146 }
1147}
int64_t LONGLONG
Definition: typedefs.h:68

◆ FAST486_OPCODE_HANDLER() [15/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeInvalid  )

Definition at line 300 of file extraops.c.

301{
302 DPRINT1("FAST486 -- Extended opcode 0x%02X is INVALID!\n", Opcode);
303 Fast486Exception(State, FAST486_EXCEPTION_UD);
304 return;
305}
#define DPRINT1
Definition: precomp.h:8

◆ FAST486_OPCODE_HANDLER() [16/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeLar  )

Definition at line 319 of file extraops.c.

320{
321 BOOLEAN OperandSize, AddressSize;
322 FAST486_MOD_REG_RM ModRegRm;
323 BOOLEAN Valid;
324 USHORT Selector;
325 FAST486_GDT_ENTRY GdtEntry;
326 DWORD AccessRights;
327
328 OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
329
330 if (!(State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
331 || State->Flags.Vm)
332 {
333 /* Not recognized */
334 Fast486Exception(State, FAST486_EXCEPTION_UD);
335 return;
336 }
337
339 TOGGLE_OPSIZE(OperandSize);
340 TOGGLE_ADSIZE(AddressSize);
341
342 /* Get the operands */
343 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
344 {
345 /* Exception occurred */
346 return;
347 }
348
349 if (OperandSize)
350 {
351 ULONG Value;
352
353 /* Read the value */
354 if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Value))
355 {
356 /* Exception occurred */
357 return;
358 }
359
360 Selector = LOWORD(Value);
361 }
362 else
363 {
364 /* Read the value */
365 if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &Selector))
366 {
367 /* Exception occurred */
368 return;
369 }
370 }
371
372 if (!Fast486ReadDescriptorEntry(State, Selector, &Valid, &GdtEntry))
373 {
374 /* Exception occurred */
375 return;
376 }
377
378 if (!Valid)
379 {
380 State->Flags.Zf = FALSE;
381 return;
382 }
383
384 /* Privilege check */
385 if (((GET_SEGMENT_RPL(Selector) > GdtEntry.Dpl))
386 || (Fast486GetCurrentPrivLevel(State) > GdtEntry.Dpl))
387 {
388 State->Flags.Zf = FALSE;
389 return;
390 }
391
392 /* Set ZF */
393 State->Flags.Zf = TRUE;
394
395 /* Get the access rights */
396 AccessRights = ((PDWORD)&GdtEntry)[1] & 0x00F0FF00;
397
398 /* Return the access rights */
399 if (OperandSize) Fast486WriteModrmDwordOperands(State, &ModRegRm, TRUE, AccessRights);
400 else Fast486WriteModrmWordOperands(State, &ModRegRm, TRUE, LOWORD(AccessRights));
401}
#define FAST486_CR0_PE
Definition: fast486.h:46
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD * PDWORD
Definition: pedump.c:68
#define GET_SEGMENT_RPL(s)
Definition: common.h:38

◆ FAST486_OPCODE_HANDLER() [17/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeLfsLgs  )

Definition at line 1429 of file extraops.c.

1430{
1431 UCHAR FarPointer[6];
1432 BOOLEAN OperandSize, AddressSize;
1433 FAST486_MOD_REG_RM ModRegRm;
1434
1435 /* Make sure this is the right instruction */
1436 ASSERT((Opcode & 0xFE) == 0xB4);
1437
1438 OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
1439
1440 TOGGLE_OPSIZE(OperandSize);
1441 TOGGLE_ADSIZE(AddressSize);
1442
1443 /* Get the operands */
1444 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
1445 {
1446 /* Exception occurred */
1447 return;
1448 }
1449
1450 if (!ModRegRm.Memory)
1451 {
1452 /* Invalid */
1453 Fast486Exception(State, FAST486_EXCEPTION_UD);
1454 return;
1455 }
1456
1458 (State->PrefixFlags & FAST486_PREFIX_SEG)
1459 ? State->SegmentOverride : FAST486_REG_DS,
1460 ModRegRm.MemoryAddress,
1461 FALSE,
1462 FarPointer,
1463 OperandSize ? 6 : 4))
1464 {
1465 /* Exception occurred */
1466 return;
1467 }
1468
1469 if (OperandSize)
1470 {
1471 ULONG Offset = *((PULONG)FarPointer);
1472 USHORT Segment = *((PUSHORT)&FarPointer[sizeof(ULONG)]);
1473
1474 /* Set the register to the offset */
1475 State->GeneralRegs[ModRegRm.Register].Long = Offset;
1476
1477 /* Load the segment */
1478 Fast486LoadSegment(State,
1479 (Opcode == 0xB4)
1480 ? FAST486_REG_FS : FAST486_REG_GS,
1481 Segment);
1482 }
1483 else
1484 {
1485 USHORT Offset = *((PUSHORT)FarPointer);
1486 USHORT Segment = *((PUSHORT)&FarPointer[sizeof(USHORT)]);
1487
1488 /* Set the register to the offset */
1489 State->GeneralRegs[ModRegRm.Register].LowWord = Offset;
1490
1491 /* Load the segment */
1492 Fast486LoadSegment(State,
1493 (Opcode == 0xB4)
1494 ? FAST486_REG_FS : FAST486_REG_GS,
1495 Segment);
1496 }
1497}
#define FAST486_PREFIX_SEG
Definition: fast486.h:98
BOOLEAN FASTCALL Fast486ReadMemory(PFAST486_STATE State, FAST486_SEG_REGS SegmentReg, ULONG Offset, BOOLEAN InstFetch, PVOID Buffer, ULONG Size)
Definition: common.c:36
_Inout_ PVOID Segment
Definition: exfuncs.h:1101

◆ FAST486_OPCODE_HANDLER() [18/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeLoadControlReg  )

Definition at line 586 of file extraops.c.

587{
588 ULONG Value;
589 BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
590 FAST486_MOD_REG_RM ModRegRm;
591
593 TOGGLE_ADSIZE(AddressSize);
594
595 /* Get the operands */
596 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
597 {
598 /* Exception occurred */
599 return;
600 }
601
602 /* The current privilege level must be zero */
603 if (Fast486GetCurrentPrivLevel(State) != 0)
604 {
605 Fast486Exception(State, FAST486_EXCEPTION_GP);
606 return;
607 }
608
609 if ((ModRegRm.Register == 1) || (ModRegRm.Register > 3))
610 {
611 /* CR1, CR4, CR5, CR6 and CR7 don't exist */
612 Fast486Exception(State, FAST486_EXCEPTION_UD);
613 return;
614 }
615
616 if (ModRegRm.Register != 0)
617 {
618 /* CR2 and CR3 and are stored in array indexes 1 and 2 */
619 ModRegRm.Register--;
620 }
621
622 /* Get the value */
623 Value = State->GeneralRegs[ModRegRm.SecondRegister].Long;
624
625 if (ModRegRm.Register == (INT)FAST486_REG_CR0)
626 {
627 /* CR0 checks */
628
631 {
632 /* Invalid value */
633 Fast486Exception(State, FAST486_EXCEPTION_GP);
634 return;
635 }
636 }
637
638#ifndef FAST486_NO_PREFETCH
639 /* Changing CR0 or CR3 can interfere with prefetching (because of paging) */
640 State->PrefetchValid = FALSE;
641#endif
642
643 if (ModRegRm.Register == (INT)FAST486_REG_CR3)
644 {
645 /* Flush the TLB */
646 Fast486FlushTlb(State);
647 }
648
649 /* Load a value to the control register */
650 State->ControlRegisters[ModRegRm.Register] = Value;
651}
#define FAST486_CR0_CD
Definition: fast486.h:55
#define FAST486_CR0_NW
Definition: fast486.h:54
#define FAST486_CR0_PG
Definition: fast486.h:56
FAST486_GEN_REGS SecondRegister
Definition: common.h:80

◆ FAST486_OPCODE_HANDLER() [19/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeLoadDebugReg  )

Definition at line 653 of file extraops.c.

654{
655 BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
656 FAST486_MOD_REG_RM ModRegRm;
657
659 TOGGLE_ADSIZE(AddressSize);
660
661 /* Get the operands */
662 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
663 {
664 /* Exception occurred */
665 return;
666 }
667
668 /* The current privilege level must be zero */
669 if (Fast486GetCurrentPrivLevel(State) != 0)
670 {
671 Fast486Exception(State, FAST486_EXCEPTION_GP);
672 return;
673 }
674
675 if ((ModRegRm.Register == 6) || (ModRegRm.Register == 7))
676 {
677 /* DR6 and DR7 are aliases to DR4 and DR5 */
678 ModRegRm.Register -= 2;
679 }
680
681 if (State->DebugRegisters[FAST486_REG_DR5] & FAST486_DR5_GD)
682 {
683 /* Disallow access to debug registers */
684 Fast486Exception(State, FAST486_EXCEPTION_GP);
685 return;
686 }
687
688 /* Load a value to the debug register */
689 State->DebugRegisters[ModRegRm.Register] = State->GeneralRegs[ModRegRm.SecondRegister].Long;
690
691 if (ModRegRm.Register == (INT)FAST486_REG_DR4)
692 {
693 /* The reserved bits are 1 */
694 State->DebugRegisters[ModRegRm.Register] |= FAST486_DR4_RESERVED;
695 }
696 else if (ModRegRm.Register == (INT)FAST486_REG_DR5)
697 {
698 /* The reserved bits are 0 */
699 State->DebugRegisters[ModRegRm.Register] &= ~FAST486_DR5_RESERVED;
700 }
701}
#define FAST486_DR5_GD
Definition: fast486.h:76
#define FAST486_DR4_RESERVED
Definition: fast486.h:82

◆ FAST486_OPCODE_HANDLER() [20/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeLsl  )

Definition at line 403 of file extraops.c.

404{
405 BOOLEAN OperandSize, AddressSize;
406 FAST486_MOD_REG_RM ModRegRm;
407 BOOLEAN Valid;
408 USHORT Selector;
409 ULONG Limit;
410 FAST486_GDT_ENTRY GdtEntry;
411
412 OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
413
414 if (!(State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
415 || State->Flags.Vm)
416 {
417 /* Not recognized */
418 Fast486Exception(State, FAST486_EXCEPTION_UD);
419 return;
420 }
421
423 TOGGLE_OPSIZE(OperandSize);
424 TOGGLE_ADSIZE(AddressSize);
425
426 /* Get the operands */
427 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
428 {
429 /* Exception occurred */
430 return;
431 }
432
433 if (OperandSize)
434 {
435 ULONG Value;
436
437 /* Read the value */
438 if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Value))
439 {
440 /* Exception occurred */
441 return;
442 }
443
444 Selector = LOWORD(Value);
445 }
446 else
447 {
448 /* Read the value */
449 if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &Selector))
450 {
451 /* Exception occurred */
452 return;
453 }
454 }
455
456 if (!Fast486ReadDescriptorEntry(State, Selector, &Valid, &GdtEntry))
457 {
458 /* Exception occurred */
459 return;
460 }
461
462 if (!Valid)
463 {
464 State->Flags.Zf = FALSE;
465 return;
466 }
467
468 /* Privilege check */
469 if (((GET_SEGMENT_RPL(Selector) > GdtEntry.Dpl))
470 || (Fast486GetCurrentPrivLevel(State) > GdtEntry.Dpl))
471 {
472 State->Flags.Zf = FALSE;
473 return;
474 }
475
476 /* Calculate the limit */
477 Limit = GdtEntry.Limit | (GdtEntry.LimitHigh << 16);
478
479 if (GdtEntry.Granularity)
480 {
481 Limit <<= 12;
482 Limit |= 0x00000FFF;
483 }
484
485 /* Set ZF */
486 State->Flags.Zf = TRUE;
487
488 /* Return the limit */
489 if (OperandSize) Fast486WriteModrmDwordOperands(State, &ModRegRm, TRUE, Limit);
490 else Fast486WriteModrmWordOperands(State, &ModRegRm, TRUE, LOWORD(Limit));
491}
_In_ LONG _In_ LONG Limit
Definition: kefuncs.h:304

◆ FAST486_OPCODE_HANDLER() [21/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeLss  )

Definition at line 1285 of file extraops.c.

1286{
1287 UCHAR FarPointer[6];
1288 BOOLEAN OperandSize, AddressSize;
1289 FAST486_MOD_REG_RM ModRegRm;
1290
1291 /* Make sure this is the right instruction */
1292 ASSERT(Opcode == 0xB2);
1293
1294 OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
1295
1296 TOGGLE_OPSIZE(OperandSize);
1297 TOGGLE_ADSIZE(AddressSize);
1298
1299 /* Get the operands */
1300 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
1301 {
1302 /* Exception occurred */
1303 return;
1304 }
1305
1306 if (!ModRegRm.Memory)
1307 {
1308 /* Invalid */
1309 Fast486Exception(State, FAST486_EXCEPTION_UD);
1310 return;
1311 }
1312
1314 (State->PrefixFlags & FAST486_PREFIX_SEG)
1315 ? State->SegmentOverride : FAST486_REG_DS,
1316 ModRegRm.MemoryAddress,
1317 FALSE,
1318 FarPointer,
1319 OperandSize ? 6 : 4))
1320 {
1321 /* Exception occurred */
1322 return;
1323 }
1324
1325 if (OperandSize)
1326 {
1327 ULONG Offset = *((PULONG)FarPointer);
1328 USHORT Segment = *((PUSHORT)&FarPointer[sizeof(ULONG)]);
1329
1330 /* Set the register to the offset */
1331 State->GeneralRegs[ModRegRm.Register].Long = Offset;
1332
1333 /* Load the segment */
1334 Fast486LoadSegment(State, FAST486_REG_SS, Segment);
1335 }
1336 else
1337 {
1338 USHORT Offset = *((PUSHORT)FarPointer);
1339 USHORT Segment = *((PUSHORT)&FarPointer[sizeof(USHORT)]);
1340
1341 /* Set the register to the offset */
1342 State->GeneralRegs[ModRegRm.Register].LowWord = Offset;
1343
1344 /* Load the segment */
1345 Fast486LoadSegment(State, FAST486_REG_SS, Segment);
1346 }
1347}

◆ FAST486_OPCODE_HANDLER() [22/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeMovsxByte  )

Definition at line 1781 of file extraops.c.

1782{
1783 CHAR Value;
1784 BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
1785 FAST486_MOD_REG_RM ModRegRm;
1786
1787 TOGGLE_ADSIZE(AddressSize);
1788
1789 /* Make sure this is the right instruction */
1790 ASSERT(Opcode == 0xBE);
1791
1792 /* Get the operands */
1793 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
1794 {
1795 /* Exception occurred */
1796 return;
1797 }
1798
1799 /* Read the operands */
1800 if (!Fast486ReadModrmByteOperands(State, &ModRegRm, NULL, (PUCHAR)&Value))
1801 {
1802 /* Exception occurred */
1803 return;
1804 }
1805
1806 /* Write back the sign-extended value */
1807 Fast486WriteModrmDwordOperands(State,
1808 &ModRegRm,
1809 TRUE,
1810 (ULONG)((LONG)Value));
1811}
char CHAR
Definition: xmlstorage.h:175

◆ FAST486_OPCODE_HANDLER() [23/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeMovsxWord  )

Definition at line 1813 of file extraops.c.

1814{
1815 SHORT Value;
1816 BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
1817 FAST486_MOD_REG_RM ModRegRm;
1818
1819 TOGGLE_ADSIZE(AddressSize);
1820
1821 /* Make sure this is the right instruction */
1822 ASSERT(Opcode == 0xBF);
1823
1824 /* Get the operands */
1825 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
1826 {
1827 /* Exception occurred */
1828 return;
1829 }
1830
1831 /* Read the operands */
1832 if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, (PUSHORT)&Value))
1833 {
1834 /* Exception occurred */
1835 return;
1836 }
1837
1838 /* Write back the sign-extended value */
1839 Fast486WriteModrmDwordOperands(State,
1840 &ModRegRm,
1841 TRUE,
1842 (ULONG)((LONG)Value));
1843}

◆ FAST486_OPCODE_HANDLER() [24/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeMovzxByte  )

Definition at line 1499 of file extraops.c.

1500{
1501 UCHAR Value;
1502 BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
1503 FAST486_MOD_REG_RM ModRegRm;
1504
1505 TOGGLE_ADSIZE(AddressSize);
1506
1507 /* Make sure this is the right instruction */
1508 ASSERT(Opcode == 0xB6);
1509
1510 /* Get the operands */
1511 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
1512 {
1513 /* Exception occurred */
1514 return;
1515 }
1516
1517 /* Read the operands */
1518 if (!Fast486ReadModrmByteOperands(State, &ModRegRm, NULL, &Value))
1519 {
1520 /* Exception occurred */
1521 return;
1522 }
1523
1524 /* Write back the zero-extended value */
1525 Fast486WriteModrmDwordOperands(State,
1526 &ModRegRm,
1527 TRUE,
1528 (ULONG)Value);
1529}

◆ FAST486_OPCODE_HANDLER() [25/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeMovzxWord  )

Definition at line 1531 of file extraops.c.

1532{
1533 USHORT Value;
1534 BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
1535 FAST486_MOD_REG_RM ModRegRm;
1536
1537 TOGGLE_ADSIZE(AddressSize);
1538
1539 /* Make sure this is the right instruction */
1540 ASSERT(Opcode == 0xB7);
1541
1542 /* Get the operands */
1543 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
1544 {
1545 /* Exception occurred */
1546 return;
1547 }
1548
1549 /* Read the operands */
1550 if (!Fast486ReadModrmWordOperands(State, &ModRegRm, NULL, &Value))
1551 {
1552 /* Exception occurred */
1553 return;
1554 }
1555
1556 /* Write back the zero-extended value */
1557 Fast486WriteModrmDwordOperands(State,
1558 &ModRegRm,
1559 TRUE,
1560 (ULONG)Value);
1561}

◆ FAST486_OPCODE_HANDLER() [26/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodePopFs  )

Definition at line 709 of file extraops.c.

710{
711 ULONG NewSelector;
712
713 if (!Fast486StackPop(State, &NewSelector))
714 {
715 /* Exception occurred */
716 return;
717 }
718
719 /* Call the internal API */
720 Fast486LoadSegment(State, FAST486_REG_FS, LOWORD(NewSelector));
721}

◆ FAST486_OPCODE_HANDLER() [27/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodePopGs  )

Definition at line 893 of file extraops.c.

894{
895 ULONG NewSelector;
896
897 if (!Fast486StackPop(State, &NewSelector))
898 {
899 /* Exception occurred */
900 return;
901 }
902
903 /* Call the internal API */
904 Fast486LoadSegment(State, FAST486_REG_GS, LOWORD(NewSelector));
905}

◆ FAST486_OPCODE_HANDLER() [28/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodePushFs  )

Definition at line 703 of file extraops.c.

704{
705 /* Call the internal API */
706 Fast486StackPush(State, State->SegmentRegs[FAST486_REG_FS].Selector);
707}

◆ FAST486_OPCODE_HANDLER() [29/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodePushGs  )

Definition at line 887 of file extraops.c.

888{
889 /* Call the internal API */
890 Fast486StackPush(State, State->SegmentRegs[FAST486_REG_GS].Selector);
891}

◆ FAST486_OPCODE_HANDLER() [30/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeShld  )

Definition at line 791 of file extraops.c.

792{
793 BOOLEAN OperandSize, AddressSize;
794 FAST486_MOD_REG_RM ModRegRm;
795 UCHAR Count;
796
797 OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
798 TOGGLE_OPSIZE(OperandSize);
799 TOGGLE_ADSIZE(AddressSize);
800
801 /* Make sure this is the right instruction */
802 ASSERT((Opcode & 0xFE) == 0xA4);
803
804 /* Get the operands */
805 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
806 {
807 /* Exception occurred */
808 return;
809 }
810
811 if (Opcode == 0xA4)
812 {
813 /* Fetch the count */
814 if (!Fast486FetchByte(State, &Count))
815 {
816 /* Exception occurred */
817 return;
818 }
819 }
820 else
821 {
822 /* The count is in CL */
823 Count = State->GeneralRegs[FAST486_REG_ECX].LowByte;
824 }
825
826 /* Normalize the count */
827 Count &= 0x1F;
828
829 /* Do nothing if the count is zero */
830 if (Count == 0) return;
831
832 if (OperandSize)
833 {
835
836 if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, &Source, &Destination))
837 {
838 /* Exception occurred */
839 return;
840 }
841
842 /* Calculate the result */
843 Result = (Destination << Count) | (Source >> (32 - Count));
844
845 /* Update flags */
846 State->Flags.Cf = (Destination >> (32 - Count)) & 1;
847 if (Count == 1) State->Flags.Of = (Result & SIGN_FLAG_LONG)
849 State->Flags.Zf = (Result == 0);
850 State->Flags.Sf = ((Result & SIGN_FLAG_LONG) != 0);
851 State->Flags.Pf = Fast486CalculateParity(Result);
852
853 /* Write back the result */
854 Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Result);
855 }
856 else
857 {
859 ULONG DoubleSource;
860
861 if (!Fast486ReadModrmWordOperands(State, &ModRegRm, &Source, &Destination))
862 {
863 /* Exception occurred */
864 return;
865 }
866
867 DoubleSource = Source | (Source << 16);
868
869 /* Calculate the result */
870 Result = (Destination << Count) | (DoubleSource >> (32 - Count));
871
872 /* Update flags */
873 if (Count <= 16) State->Flags.Cf = (Destination >> (16 - Count)) & 1;
874 else State->Flags.Cf = (Source >> (32 - Count)) & 1;
875
876 if (Count == 1) State->Flags.Of = (Result & SIGN_FLAG_WORD)
878 State->Flags.Zf = (Result == 0);
879 State->Flags.Sf = ((Result & SIGN_FLAG_WORD) != 0);
880 State->Flags.Pf = Fast486CalculateParity(Result);
881
882 /* Write back the result */
883 Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Result);
884 }
885}
int Count
Definition: noreturn.cpp:7

◆ FAST486_OPCODE_HANDLER() [31/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeShrd  )

Definition at line 987 of file extraops.c.

988{
989 BOOLEAN OperandSize, AddressSize;
990 FAST486_MOD_REG_RM ModRegRm;
991 UCHAR Count;
992
993 OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
994 TOGGLE_OPSIZE(OperandSize);
995 TOGGLE_ADSIZE(AddressSize);
996
997 /* Make sure this is the right instruction */
998 ASSERT((Opcode & 0xFE) == 0xAC);
999
1000 /* Get the operands */
1001 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
1002 {
1003 /* Exception occurred */
1004 return;
1005 }
1006
1007 if (Opcode == 0xAC)
1008 {
1009 /* Fetch the count */
1010 if (!Fast486FetchByte(State, &Count))
1011 {
1012 /* Exception occurred */
1013 return;
1014 }
1015 }
1016 else
1017 {
1018 /* The count is in CL */
1019 Count = State->GeneralRegs[FAST486_REG_ECX].LowByte;
1020 }
1021
1022 /* Normalize the count */
1023 Count &= 0x1F;
1024
1025 /* Do nothing if the count is zero */
1026 if (Count == 0) return;
1027
1028 if (OperandSize)
1029 {
1031
1032 if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, &Source, &Destination))
1033 {
1034 /* Exception occurred */
1035 return;
1036 }
1037
1038 /* Calculate the result */
1039 Result = (Destination >> Count) | (Source << (32 - Count));
1040
1041 /* Update flags */
1042 State->Flags.Cf = (Destination >> (Count - 1)) & 1;
1043 if (Count == 1) State->Flags.Of = (Result & SIGN_FLAG_LONG)
1045 State->Flags.Zf = (Result == 0);
1046 State->Flags.Sf = ((Result & SIGN_FLAG_LONG) != 0);
1047 State->Flags.Pf = Fast486CalculateParity(Result);
1048
1049 /* Write back the result */
1050 Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Result);
1051 }
1052 else
1053 {
1055
1056 if (!Fast486ReadModrmWordOperands(State, &ModRegRm, &Source, &Destination))
1057 {
1058 /* Exception occurred */
1059 return;
1060 }
1061
1062 /* Calculate the result */
1063 Result = (Destination >> Count) | (Source << (16 - Count));
1064
1065 if (Count >= 16) Result |= (ULONG)(Source | (Source << 16)) >> (Count - 16);
1066
1067 /* Update flags */
1068 if (Count <= 16) State->Flags.Cf = (Destination >> (Count - 1)) & 1;
1069 else State->Flags.Cf = (Source >> (Count - 17)) & 1;
1070
1071 if (Count == 1) State->Flags.Of = (Result & SIGN_FLAG_WORD)
1073 State->Flags.Zf = (Result == 0);
1074 State->Flags.Sf = ((Result & SIGN_FLAG_WORD) != 0);
1075 State->Flags.Pf = Fast486CalculateParity(Result);
1076
1077 /* Write back the result */
1078 Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Result);
1079 }
1080}

◆ FAST486_OPCODE_HANDLER() [32/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeStoreControlReg  )

Definition at line 508 of file extraops.c.

509{
510 BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
511 FAST486_MOD_REG_RM ModRegRm;
512
514 TOGGLE_ADSIZE(AddressSize);
515
516 /* Get the operands */
517 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
518 {
519 /* Exception occurred */
520 return;
521 }
522
523 /* The current privilege level must be zero */
524 if (Fast486GetCurrentPrivLevel(State) != 0)
525 {
526 Fast486Exception(State, FAST486_EXCEPTION_GP);
527 return;
528 }
529
530 if ((ModRegRm.Register == 1) || (ModRegRm.Register > 3))
531 {
532 /* CR1, CR4, CR5, CR6 and CR7 don't exist */
533 Fast486Exception(State, FAST486_EXCEPTION_UD);
534 return;
535 }
536
537 if (ModRegRm.Register != 0)
538 {
539 /* CR2 and CR3 and are stored in array indexes 1 and 2 */
540 ModRegRm.Register--;
541 }
542
543 /* Store the value of the control register */
544 State->GeneralRegs[ModRegRm.SecondRegister].Long = State->ControlRegisters[ModRegRm.Register];
545}

◆ FAST486_OPCODE_HANDLER() [33/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeStoreDebugReg  )

Definition at line 547 of file extraops.c.

548{
549 BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
550 FAST486_MOD_REG_RM ModRegRm;
551
553 TOGGLE_ADSIZE(AddressSize);
554
555 /* Get the operands */
556 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
557 {
558 /* Exception occurred */
559 return;
560 }
561
562 /* The current privilege level must be zero */
563 if (Fast486GetCurrentPrivLevel(State) != 0)
564 {
565 Fast486Exception(State, FAST486_EXCEPTION_GP);
566 return;
567 }
568
569 if ((ModRegRm.Register == 6) || (ModRegRm.Register == 7))
570 {
571 /* DR6 and DR7 are aliases to DR4 and DR5 */
572 ModRegRm.Register -= 2;
573 }
574
575 if (State->DebugRegisters[FAST486_REG_DR5] & FAST486_DR5_GD)
576 {
577 /* Disallow access to debug registers */
578 Fast486Exception(State, FAST486_EXCEPTION_GP);
579 return;
580 }
581
582 /* Store the value of the debug register */
583 State->GeneralRegs[ModRegRm.SecondRegister].Long = State->DebugRegisters[ModRegRm.Register];
584}

◆ FAST486_OPCODE_HANDLER() [34/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeUnimplemented  )

Definition at line 307 of file extraops.c.

308{
309 DPRINT1("FAST486 -- Extended opcode 0x%02X is UNIMPLEMENTED\n", Opcode);
310 // Fast486Exception(State, FAST486_EXCEPTION_UD);
311}

◆ FAST486_OPCODE_HANDLER() [35/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeXadd  )

Definition at line 2089 of file extraops.c.

2090{
2091 FAST486_MOD_REG_RM ModRegRm;
2092 BOOLEAN OperandSize, AddressSize;
2093
2094 /* Make sure this is the right instruction */
2095 ASSERT(Opcode == 0xC1);
2096
2097 OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
2098
2099 TOGGLE_ADSIZE(AddressSize);
2100 TOGGLE_OPSIZE(OperandSize);
2101
2102 /* Get the operands */
2103 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
2104 {
2105 /* Exception occurred */
2106 return;
2107 }
2108
2109 /* Check the operand size */
2110 if (OperandSize)
2111 {
2113
2114 if (!Fast486ReadModrmDwordOperands(State,
2115 &ModRegRm,
2116 &Source,
2117 &Destination))
2118 {
2119 /* Exception occurred */
2120 return;
2121 }
2122
2123 /* Calculate the result */
2125
2126 /* Update the flags */
2127 State->Flags.Cf = (Result < Source) && (Result < Destination);
2128 State->Flags.Of = ((Source & SIGN_FLAG_LONG) == (Destination & SIGN_FLAG_LONG))
2130 State->Flags.Af = ((((Source & 0x0F) + (Destination & 0x0F)) & 0x10) != 0);
2131 State->Flags.Zf = (Result == 0);
2132 State->Flags.Sf = ((Result & SIGN_FLAG_LONG) != 0);
2133 State->Flags.Pf = Fast486CalculateParity(Result);
2134
2135 /* Write the old value of the destination to the source */
2136 if (!Fast486WriteModrmDwordOperands(State, &ModRegRm, TRUE, Destination))
2137 {
2138 /* Exception occurred */
2139 return;
2140 }
2141
2142 /* Write the sum to the destination */
2143 Fast486WriteModrmDwordOperands(State, &ModRegRm, FALSE, Result);
2144 }
2145 else
2146 {
2148
2149 if (!Fast486ReadModrmWordOperands(State,
2150 &ModRegRm,
2151 &Source,
2152 &Destination))
2153 {
2154 /* Exception occurred */
2155 return;
2156 }
2157
2158 /* Calculate the result */
2160
2161 /* Update the flags */
2162 State->Flags.Cf = (Result < Source) && (Result < Destination);
2163 State->Flags.Of = ((Source & SIGN_FLAG_WORD) == (Destination & SIGN_FLAG_WORD))
2165 State->Flags.Af = ((((Source & 0x0F) + (Destination & 0x0F)) & 0x10) != 0);
2166 State->Flags.Zf = (Result == 0);
2167 State->Flags.Sf = ((Result & SIGN_FLAG_WORD) != 0);
2168 State->Flags.Pf = Fast486CalculateParity(Result);
2169
2170 /* Write the old value of the destination to the source */
2171 if (!Fast486WriteModrmWordOperands(State, &ModRegRm, TRUE, Destination))
2172 {
2173 /* Exception occurred */
2174 return;
2175 }
2176
2177 /* Write the sum to the destination */
2178 Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, Result);
2179 }
2180}

◆ FAST486_OPCODE_HANDLER() [36/37]

FAST486_OPCODE_HANDLER ( Fast486ExtOpcodeXaddByte  )

Definition at line 2039 of file extraops.c.

2040{
2042 FAST486_MOD_REG_RM ModRegRm;
2043 BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
2044
2045 /* Make sure this is the right instruction */
2046 ASSERT(Opcode == 0xC0);
2047
2048 TOGGLE_ADSIZE(AddressSize);
2049
2050 /* Get the operands */
2051 if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
2052 {
2053 /* Exception occurred */
2054 return;
2055 }
2056
2057 if (!Fast486ReadModrmByteOperands(State,
2058 &ModRegRm,
2059 &Source,
2060 &Destination))
2061 {
2062 /* Exception occurred */
2063 return;
2064 }
2065
2066 /* Calculate the result */
2068
2069 /* Update the flags */
2070 State->Flags.Cf = (Result < Source) && (Result < Destination);
2071 State->Flags.Of = ((Source & SIGN_FLAG_BYTE) == (Destination & SIGN_FLAG_BYTE))
2073 State->Flags.Af = ((((Source & 0x0F) + (Destination & 0x0F)) & 0x10) != 0);
2074 State->Flags.Zf = (Result == 0);
2075 State->Flags.Sf = ((Result & SIGN_FLAG_BYTE) != 0);
2076 State->Flags.Pf = Fast486CalculateParity(Result);
2077
2078 /* Write the sum to the destination */
2079 if (!Fast486WriteModrmByteOperands(State, &ModRegRm, FALSE, Result))
2080 {
2081 /* Exception occurred */
2082 return;
2083 }
2084
2085 /* Write the old value of the destination to the source */
2086 Fast486WriteModrmByteOperands(State, &ModRegRm, TRUE, Destination);
2087}

◆ FAST486_OPCODE_HANDLER() [37/37]

FAST486_OPCODE_HANDLER ( Fast486OpcodeExtended  )

Definition at line 2196 of file extraops.c.

2197{
2198 UCHAR SecondOpcode;
2199
2200 /* Fetch the second operation code */
2201 if (!Fast486FetchByte(State, &SecondOpcode))
2202 {
2203 /* Exception occurred */
2204 return;
2205 }
2206
2207 /* Call the extended opcode handler */
2208 Fast486ExtendedHandlers[SecondOpcode](State, SecondOpcode);
2209}
FAST486_OPCODE_HANDLER_PROC Fast486ExtendedHandlers[FAST486_NUM_OPCODE_HANDLERS]
Definition: extraops.c:38

Variable Documentation

◆ Fast486ExtendedHandlers

Definition at line 38 of file extraops.c.

Referenced by FAST486_OPCODE_HANDLER().