Author: aandrejevic
Date: Thu Jan 1 18:05:45 2015
New Revision: 65933
URL:
http://svn.reactos.org/svn/reactos?rev=65933&view=rev
Log:
[FAST486]
Implement opcode 0xDA (FIADD, FIMUL, FICOM, FICOMP, FISUB, FISUBR, FIDIV, FIDIVR and
FUCOMPP).
Modified:
trunk/reactos/lib/fast486/fpu.c
Modified: trunk/reactos/lib/fast486/fpu.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/fpu.c?rev=6593…
==============================================================================
--- trunk/reactos/lib/fast486/fpu.c [iso-8859-1] (original)
+++ trunk/reactos/lib/fast486/fpu.c [iso-8859-1] Thu Jan 1 18:05:45 2015
@@ -569,6 +569,9 @@
{
FAST486_MOD_REG_RM ModRegRm;
BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
+ PFAST486_FPU_DATA_REG SourceOperand, DestOperand;
+ LONG Value;
+ FAST486_FPU_DATA_REG MemoryData;
/* Get the operands */
if (!Fast486ParseModRegRm(State, AddressSize, &ModRegRm))
@@ -580,10 +583,110 @@
FPU_CHECK();
#ifndef FAST486_NO_FPU
- // TODO: NOT IMPLEMENTED
- UNIMPLEMENTED;
-#else
- /* Do nothing */
+
+ if (!ModRegRm.Memory)
+ {
+ /* The only valid opcode in this case is FUCOMPP (0xDA 0xE9) */
+ if ((ModRegRm.Register != 5) && (ModRegRm.SecondRegister != 1))
+ {
+ Fast486Exception(State, FAST486_EXCEPTION_UD);
+ return;
+ }
+
+ if ((FPU_GET_TAG(0) == FPU_TAG_EMPTY) || (FPU_GET_TAG(1) == FPU_TAG_EMPTY))
+ {
+ /* FPU Exception */
+ State->FpuStatus.Ie = TRUE;
+ return;
+ }
+
+ /* Compare */
+ Fast486FpuCompare(State, &FPU_ST(0), &FPU_ST(1));
+
+ /* Pop twice */
+ Fast486FpuPop(State);
+ Fast486FpuPop(State);
+
+ return;
+ }
+
+ /* Load the source operand from memory */
+ if (!Fast486ReadModrmDwordOperands(State, &ModRegRm, NULL, (PULONG)&Value))
+ {
+ /* Exception occurred */
+ return;
+ }
+
+ Fast486FpuFromInteger(State, (LONGLONG)Value, &MemoryData);
+ SourceOperand = &MemoryData;
+
+ /* The destination operand is always ST0 */
+ DestOperand = &FPU_ST(0);
+
+ if (FPU_GET_TAG(0) == FPU_TAG_EMPTY)
+ {
+ /* Invalid operation */
+ State->FpuStatus.Ie = TRUE;
+ return;
+ }
+
+ /* Check the operation */
+ switch (ModRegRm.Register)
+ {
+ /* FIADD */
+ case 0:
+ {
+ Fast486FpuAdd(State, DestOperand, SourceOperand, DestOperand);
+ break;
+ }
+
+ /* FIMUL */
+ case 1:
+ {
+ Fast486FpuMultiply(State, DestOperand, SourceOperand, DestOperand);
+ break;
+ }
+
+ /* FICOM */
+ case 2:
+ /* FICOMP */
+ case 3:
+ {
+ Fast486FpuCompare(State, DestOperand, SourceOperand);
+ if (ModRegRm.Register == 3) Fast486FpuPop(State);
+
+ break;
+ }
+
+ /* FISUB */
+ case 4:
+ {
+ Fast486FpuSubtract(State, DestOperand, SourceOperand, DestOperand);
+ break;
+ }
+
+ /* FISUBR */
+ case 5:
+ {
+ Fast486FpuSubtract(State, SourceOperand, DestOperand, DestOperand);
+ break;
+ }
+
+ /* FIDIV */
+ case 6:
+ {
+ Fast486FpuDivide(State, DestOperand, SourceOperand, DestOperand);
+ break;
+ }
+
+ /* FIDIVR */
+ case 7:
+ {
+ Fast486FpuDivide(State, SourceOperand, DestOperand, DestOperand);
+ break;
+ }
+ }
+
#endif
}