mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
[FAST486]
Implement FSTENV and FSAVE. Keep track of the last FPU instruction and operand. svn path=/trunk/; revision=66131
This commit is contained in:
parent
2369d5c3db
commit
8c1b044a8c
3 changed files with 246 additions and 103 deletions
|
@ -508,6 +508,10 @@ struct _FAST486_STATE
|
|||
FAST486_FPU_STATUS_REG FpuStatus;
|
||||
FAST486_FPU_CONTROL_REG FpuControl;
|
||||
USHORT FpuTag;
|
||||
FAST486_REG FpuLastInstPtr;
|
||||
USHORT FpuLastCodeSel;
|
||||
FAST486_REG FpuLastOpPtr;
|
||||
USHORT FpuLastDataSel;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -919,6 +919,43 @@ Fast486FpuArithmeticOperation(PFAST486_STATE State,
|
|||
}
|
||||
}
|
||||
|
||||
static inline BOOLEAN FASTCALL
|
||||
Fast486FpuSaveEnvironment(PFAST486_STATE State,
|
||||
INT Segment,
|
||||
ULONG Address,
|
||||
BOOLEAN Size)
|
||||
{
|
||||
UCHAR Buffer[28];
|
||||
|
||||
/* Check if this is a 32-bit save or a 16-bit save */
|
||||
if (Size)
|
||||
{
|
||||
PULONG Data = (PULONG)Buffer;
|
||||
|
||||
Data[0] = (ULONG)State->FpuControl.Value;
|
||||
Data[1] = (ULONG)State->FpuStatus.Value;
|
||||
Data[2] = (ULONG)State->FpuTag;
|
||||
Data[3] = State->FpuLastInstPtr.Long;
|
||||
Data[4] = (ULONG)State->FpuLastCodeSel;
|
||||
Data[5] = State->FpuLastOpPtr.Long;
|
||||
Data[6] = (ULONG)State->FpuLastDataSel;
|
||||
}
|
||||
else
|
||||
{
|
||||
PUSHORT Data = (PUSHORT)Buffer;
|
||||
|
||||
Data[0] = State->FpuControl.Value;
|
||||
Data[1] = State->FpuStatus.Value;
|
||||
Data[2] = State->FpuTag;
|
||||
Data[3] = State->FpuLastInstPtr.LowWord;
|
||||
Data[4] = State->FpuLastCodeSel;
|
||||
Data[5] = State->FpuLastOpPtr.LowWord;
|
||||
Data[6] = State->FpuLastDataSel;
|
||||
}
|
||||
|
||||
return Fast486WriteMemory(State, Segment, Address, Buffer, (Size + 1) * 14);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
@ -930,6 +967,8 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeD8)
|
|||
PFAST486_FPU_DATA_REG SourceOperand, DestOperand;
|
||||
FAST486_FPU_DATA_REG MemoryData;
|
||||
|
||||
TOGGLE_ADSIZE(AddressSize);
|
||||
|
||||
/* Get the operands */
|
||||
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
{
|
||||
|
@ -941,6 +980,8 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeD8)
|
|||
|
||||
#ifndef FAST486_NO_FPU
|
||||
|
||||
FPU_SAVE_LAST_INST();
|
||||
|
||||
/* The destination operand is ST0 */
|
||||
DestOperand = &FPU_ST(0);
|
||||
|
||||
|
@ -976,6 +1017,8 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeD8)
|
|||
|
||||
Fast486FpuFromSingleReal(State, Value, &MemoryData);
|
||||
SourceOperand = &MemoryData;
|
||||
|
||||
FPU_SAVE_LAST_OPERAND();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1008,106 +1051,14 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeD8)
|
|||
#endif
|
||||
}
|
||||
|
||||
FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDC)
|
||||
{
|
||||
FAST486_MOD_REG_RM ModRegRm;
|
||||
BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
|
||||
PFAST486_FPU_DATA_REG SourceOperand, DestOperand;
|
||||
FAST486_FPU_DATA_REG MemoryData;
|
||||
|
||||
/* Get the operands */
|
||||
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return;
|
||||
}
|
||||
|
||||
FPU_CHECK();
|
||||
|
||||
#ifndef FAST486_NO_FPU
|
||||
|
||||
if (ModRegRm.Memory)
|
||||
{
|
||||
ULONGLONG Value;
|
||||
|
||||
/* The destination operand is ST0 */
|
||||
DestOperand = &FPU_ST(0);
|
||||
|
||||
if (FPU_GET_TAG(0) == FPU_TAG_EMPTY)
|
||||
{
|
||||
/* Raise the invalid operation exception */
|
||||
State->FpuStatus.Ie = TRUE;
|
||||
|
||||
if (State->FpuControl.Im)
|
||||
{
|
||||
/* Return the indefinite NaN */
|
||||
DestOperand->Sign = TRUE;
|
||||
DestOperand->Exponent = FPU_MAX_EXPONENT + 1;
|
||||
DestOperand->Mantissa = FPU_INDEFINITE_MANTISSA;
|
||||
|
||||
FPU_SET_TAG(0, FPU_TAG_SPECIAL);
|
||||
}
|
||||
else Fast486FpuException(State);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Load the source operand from memory */
|
||||
if (!Fast486ReadMemory(State,
|
||||
(State->PrefixFlags & FAST486_PREFIX_SEG)
|
||||
? State->SegmentOverride : FAST486_REG_DS,
|
||||
ModRegRm.MemoryAddress,
|
||||
FALSE,
|
||||
&Value,
|
||||
sizeof(ULONGLONG)))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return;
|
||||
}
|
||||
|
||||
Fast486FpuFromDoubleReal(State, Value, &MemoryData);
|
||||
SourceOperand = &MemoryData;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The source operand is ST0 */
|
||||
SourceOperand = &FPU_ST(0);
|
||||
|
||||
/* Load the destination operand from an FPU register */
|
||||
DestOperand = &FPU_ST(ModRegRm.SecondRegister);
|
||||
|
||||
if ((FPU_GET_TAG(0) == FPU_TAG_EMPTY)
|
||||
|| (FPU_GET_TAG(ModRegRm.SecondRegister) == FPU_TAG_EMPTY))
|
||||
{
|
||||
/* Raise the invalid operation exception */
|
||||
State->FpuStatus.Ie = TRUE;
|
||||
|
||||
if (State->FpuControl.Im)
|
||||
{
|
||||
/* Return the indefinite NaN */
|
||||
DestOperand->Sign = TRUE;
|
||||
DestOperand->Exponent = FPU_MAX_EXPONENT + 1;
|
||||
DestOperand->Mantissa = FPU_INDEFINITE_MANTISSA;
|
||||
|
||||
FPU_SET_TAG(ModRegRm.SecondRegister, FPU_TAG_SPECIAL);
|
||||
}
|
||||
else Fast486FpuException(State);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform the requested operation */
|
||||
Fast486FpuArithmeticOperation(State, ModRegRm.Register, SourceOperand, DestOperand);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
FAST486_OPCODE_HANDLER(Fast486FpuOpcodeD9)
|
||||
{
|
||||
FAST486_MOD_REG_RM ModRegRm;
|
||||
BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
|
||||
BOOLEAN OperandSize, AddressSize;
|
||||
|
||||
OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
|
||||
TOGGLE_OPSIZE(OperandSize);
|
||||
TOGGLE_ADSIZE(AddressSize);
|
||||
|
||||
/* Get the operands */
|
||||
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
|
@ -1130,6 +1081,9 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeD9)
|
|||
ULONG Value;
|
||||
FAST486_FPU_DATA_REG MemoryData;
|
||||
|
||||
FPU_SAVE_LAST_INST();
|
||||
FPU_SAVE_LAST_OPERAND();
|
||||
|
||||
if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, &Value))
|
||||
{
|
||||
/* Exception occurred */
|
||||
|
@ -1149,6 +1103,9 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeD9)
|
|||
{
|
||||
ULONG Value = FPU_REAL4_INDEFINITE;
|
||||
|
||||
FPU_SAVE_LAST_INST();
|
||||
FPU_SAVE_LAST_OPERAND();
|
||||
|
||||
if (FPU_GET_TAG(0) == FPU_TAG_EMPTY)
|
||||
{
|
||||
/* Raise the invalid operation exception */
|
||||
|
@ -1195,9 +1152,11 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeD9)
|
|||
/* FSTENV */
|
||||
case 6:
|
||||
{
|
||||
// TODO: NOT IMPLEMENTED
|
||||
UNIMPLEMENTED;
|
||||
|
||||
Fast486FpuSaveEnvironment(State,
|
||||
(State->PrefixFlags & FAST486_PREFIX_SEG)
|
||||
? FAST486_REG_DS : State->SegmentOverride,
|
||||
ModRegRm.MemoryAddress,
|
||||
OperandSize);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1233,6 +1192,8 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDA)
|
|||
LONG Value;
|
||||
FAST486_FPU_DATA_REG MemoryData;
|
||||
|
||||
TOGGLE_ADSIZE(AddressSize);
|
||||
|
||||
/* Get the operands */
|
||||
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
{
|
||||
|
@ -1244,6 +1205,8 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDA)
|
|||
|
||||
#ifndef FAST486_NO_FPU
|
||||
|
||||
FPU_SAVE_LAST_INST();
|
||||
|
||||
if (!ModRegRm.Memory)
|
||||
{
|
||||
/* The only valid opcode in this case is FUCOMPP (0xDA 0xE9) */
|
||||
|
@ -1272,6 +1235,8 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDA)
|
|||
return;
|
||||
}
|
||||
|
||||
FPU_SAVE_LAST_OPERAND();
|
||||
|
||||
/* Load the source operand from memory */
|
||||
if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, (PULONG)&Value))
|
||||
{
|
||||
|
@ -1315,6 +1280,8 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDB)
|
|||
FAST486_MOD_REG_RM ModRegRm;
|
||||
BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
|
||||
|
||||
TOGGLE_ADSIZE(AddressSize);
|
||||
|
||||
/* Get the operands */
|
||||
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
{
|
||||
|
@ -1328,6 +1295,9 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDB)
|
|||
|
||||
if (ModRegRm.Memory)
|
||||
{
|
||||
FPU_SAVE_LAST_INST();
|
||||
FPU_SAVE_LAST_OPERAND();
|
||||
|
||||
switch (ModRegRm.Register)
|
||||
{
|
||||
/* FILD */
|
||||
|
@ -1531,10 +1501,115 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDB)
|
|||
#endif
|
||||
}
|
||||
|
||||
FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDD)
|
||||
FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDC)
|
||||
{
|
||||
FAST486_MOD_REG_RM ModRegRm;
|
||||
BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
|
||||
PFAST486_FPU_DATA_REG SourceOperand, DestOperand;
|
||||
FAST486_FPU_DATA_REG MemoryData;
|
||||
|
||||
TOGGLE_ADSIZE(AddressSize);
|
||||
|
||||
/* Get the operands */
|
||||
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return;
|
||||
}
|
||||
|
||||
FPU_CHECK();
|
||||
|
||||
#ifndef FAST486_NO_FPU
|
||||
|
||||
FPU_SAVE_LAST_INST();
|
||||
|
||||
if (ModRegRm.Memory)
|
||||
{
|
||||
ULONGLONG Value;
|
||||
|
||||
/* The destination operand is ST0 */
|
||||
DestOperand = &FPU_ST(0);
|
||||
|
||||
if (FPU_GET_TAG(0) == FPU_TAG_EMPTY)
|
||||
{
|
||||
/* Raise the invalid operation exception */
|
||||
State->FpuStatus.Ie = TRUE;
|
||||
|
||||
if (State->FpuControl.Im)
|
||||
{
|
||||
/* Return the indefinite NaN */
|
||||
DestOperand->Sign = TRUE;
|
||||
DestOperand->Exponent = FPU_MAX_EXPONENT + 1;
|
||||
DestOperand->Mantissa = FPU_INDEFINITE_MANTISSA;
|
||||
|
||||
FPU_SET_TAG(0, FPU_TAG_SPECIAL);
|
||||
}
|
||||
else Fast486FpuException(State);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Load the source operand from memory */
|
||||
if (!Fast486ReadMemory(State,
|
||||
(State->PrefixFlags & FAST486_PREFIX_SEG)
|
||||
? State->SegmentOverride : FAST486_REG_DS,
|
||||
ModRegRm.MemoryAddress,
|
||||
FALSE,
|
||||
&Value,
|
||||
sizeof(ULONGLONG)))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return;
|
||||
}
|
||||
|
||||
Fast486FpuFromDoubleReal(State, Value, &MemoryData);
|
||||
SourceOperand = &MemoryData;
|
||||
|
||||
FPU_SAVE_LAST_OPERAND();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The source operand is ST0 */
|
||||
SourceOperand = &FPU_ST(0);
|
||||
|
||||
/* Load the destination operand from an FPU register */
|
||||
DestOperand = &FPU_ST(ModRegRm.SecondRegister);
|
||||
|
||||
if ((FPU_GET_TAG(0) == FPU_TAG_EMPTY)
|
||||
|| (FPU_GET_TAG(ModRegRm.SecondRegister) == FPU_TAG_EMPTY))
|
||||
{
|
||||
/* Raise the invalid operation exception */
|
||||
State->FpuStatus.Ie = TRUE;
|
||||
|
||||
if (State->FpuControl.Im)
|
||||
{
|
||||
/* Return the indefinite NaN */
|
||||
DestOperand->Sign = TRUE;
|
||||
DestOperand->Exponent = FPU_MAX_EXPONENT + 1;
|
||||
DestOperand->Mantissa = FPU_INDEFINITE_MANTISSA;
|
||||
|
||||
FPU_SET_TAG(ModRegRm.SecondRegister, FPU_TAG_SPECIAL);
|
||||
}
|
||||
else Fast486FpuException(State);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform the requested operation */
|
||||
Fast486FpuArithmeticOperation(State, ModRegRm.Register, SourceOperand, DestOperand);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDD)
|
||||
{
|
||||
FAST486_MOD_REG_RM ModRegRm;
|
||||
BOOLEAN OperandSize, AddressSize;
|
||||
|
||||
OperandSize = AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
|
||||
TOGGLE_OPSIZE(OperandSize);
|
||||
TOGGLE_ADSIZE(AddressSize);
|
||||
|
||||
/* Get the operands */
|
||||
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
|
@ -1557,6 +1632,9 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDD)
|
|||
ULONGLONG Value;
|
||||
FAST486_FPU_DATA_REG MemoryData;
|
||||
|
||||
FPU_SAVE_LAST_INST();
|
||||
FPU_SAVE_LAST_OPERAND();
|
||||
|
||||
if (!Fast486ReadMemory(State,
|
||||
(State->PrefixFlags & FAST486_PREFIX_SEG)
|
||||
? State->SegmentOverride : FAST486_REG_DS,
|
||||
|
@ -1582,6 +1660,9 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDD)
|
|||
{
|
||||
ULONGLONG Value = FPU_REAL8_INDEFINITE;
|
||||
|
||||
FPU_SAVE_LAST_INST();
|
||||
FPU_SAVE_LAST_OPERAND();
|
||||
|
||||
if (FPU_GET_TAG(0) == FPU_TAG_EMPTY)
|
||||
{
|
||||
/* Raise the invalid operation exception */
|
||||
|
@ -1626,8 +1707,40 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDD)
|
|||
/* FSAVE */
|
||||
case 6:
|
||||
{
|
||||
// TODO: NOT IMPLEMENTED
|
||||
UNIMPLEMENTED;
|
||||
INT i;
|
||||
UCHAR AllRegs[80];
|
||||
|
||||
FPU_SAVE_LAST_INST();
|
||||
|
||||
/* Save the environment */
|
||||
if (!Fast486FpuSaveEnvironment(State,
|
||||
(State->PrefixFlags & FAST486_PREFIX_SEG)
|
||||
? FAST486_REG_DS : State->SegmentOverride,
|
||||
ModRegRm.MemoryAddress,
|
||||
OperandSize))
|
||||
{
|
||||
/* Exception occurred */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Save the registers */
|
||||
for (i = 0; i < FAST486_NUM_FPU_REGS; i++)
|
||||
{
|
||||
*((PULONGLONG)&AllRegs[i * 10]) = State->FpuRegisters[i].Mantissa;
|
||||
*((PUSHORT)&AllRegs[(i * 10) + sizeof(ULONGLONG)]) = State->FpuRegisters[i].Exponent;
|
||||
|
||||
if (State->FpuRegisters[i].Sign)
|
||||
{
|
||||
*((PUSHORT)&AllRegs[(i * 10) + sizeof(ULONGLONG)]) |= 0x8000;
|
||||
}
|
||||
}
|
||||
|
||||
Fast486WriteMemory(State,
|
||||
(State->PrefixFlags & FAST486_PREFIX_SEG)
|
||||
? FAST486_REG_DS : State->SegmentOverride,
|
||||
ModRegRm.MemoryAddress + (OperandSize + 1) * 14,
|
||||
AllRegs,
|
||||
sizeof(AllRegs));
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -1635,6 +1748,9 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDD)
|
|||
/* FSTSW */
|
||||
case 7:
|
||||
{
|
||||
FPU_SAVE_LAST_INST();
|
||||
FPU_SAVE_LAST_OPERAND();
|
||||
|
||||
Fast486WriteModrmWordOperands(State, &ModRegRm, FALSE, State->FpuStatus.Value);
|
||||
break;
|
||||
}
|
||||
|
@ -1648,6 +1764,8 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDD)
|
|||
}
|
||||
else
|
||||
{
|
||||
FPU_SAVE_LAST_INST();
|
||||
|
||||
switch (ModRegRm.Register)
|
||||
{
|
||||
/* FFREE */
|
||||
|
@ -1731,6 +1849,8 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDE)
|
|||
BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
|
||||
PFAST486_FPU_DATA_REG SourceOperand, DestOperand;
|
||||
|
||||
TOGGLE_ADSIZE(AddressSize);
|
||||
|
||||
/* Get the operands */
|
||||
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
{
|
||||
|
@ -1742,6 +1862,8 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDE)
|
|||
|
||||
#ifndef FAST486_NO_FPU
|
||||
|
||||
FPU_SAVE_LAST_INST();
|
||||
|
||||
if (ModRegRm.Memory)
|
||||
{
|
||||
SHORT Value;
|
||||
|
@ -1778,6 +1900,8 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDE)
|
|||
|
||||
Fast486FpuFromInteger(State, (LONGLONG)Value, &MemoryData);
|
||||
SourceOperand = &MemoryData;
|
||||
|
||||
FPU_SAVE_LAST_OPERAND();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1818,6 +1942,8 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDF)
|
|||
FAST486_MOD_REG_RM ModRegRm;
|
||||
BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
|
||||
|
||||
TOGGLE_ADSIZE(AddressSize);
|
||||
|
||||
/* Get the operands */
|
||||
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
|
||||
{
|
||||
|
@ -1829,8 +1955,12 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeDF)
|
|||
|
||||
#ifndef FAST486_NO_FPU
|
||||
|
||||
FPU_SAVE_LAST_INST();
|
||||
|
||||
if (ModRegRm.Memory)
|
||||
{
|
||||
FPU_SAVE_LAST_OPERAND();
|
||||
|
||||
switch (ModRegRm.Register)
|
||||
{
|
||||
/* FILD */
|
||||
|
|
|
@ -42,6 +42,15 @@
|
|||
State->FpuTag |= ((t) & 3) << (FPU_INDEX(i) * 2); \
|
||||
}
|
||||
#define FPU_UPDATE_TAG(i) FPU_SET_TAG((i), Fast486FpuGetValueTag(&FPU_ST(i)))
|
||||
#define FPU_SAVE_LAST_INST() { \
|
||||
State->FpuLastInstPtr = State->SavedInstPtr; \
|
||||
State->FpuLastCodeSel = State->SegmentRegs[FAST486_REG_CS].Selector; \
|
||||
}
|
||||
#define FPU_SAVE_LAST_OPERAND() { \
|
||||
State->FpuLastOpPtr.Long = ModRegRm.MemoryAddress; \
|
||||
State->FpuLastDataSel = (State->PrefixFlags & FAST486_PREFIX_SEG) \
|
||||
? State->SegmentOverride : FAST486_REG_DS; \
|
||||
}
|
||||
|
||||
#define FPU_REAL4_BIAS 0x7F
|
||||
#define FPU_REAL8_BIAS 0x3FF
|
||||
|
|
Loading…
Reference in a new issue