Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

224 lines
5.8 KiB

  1. /*++
  2. Copyright (c) 1995-1998 Microsoft Corporation
  3. Module Name:
  4. fpufragp.h
  5. Abstract:
  6. Private include file for the 487 emulator portion of the Fragment Library
  7. Author:
  8. 04-Oct-1995 BarryBo, Created
  9. Revision History:
  10. --*/
  11. #ifndef FPUFRAGP_H
  12. #define FPUFRAGP_H
  13. //
  14. // ALPHA, PPC and INTEL have the same bit-patterns for QNAN/SNAN/INDEFINITE.
  15. // MIPS has different representations. NATIVE_NAN_IS_INTEL_FORMAT
  16. // is used to distinguish between the different representations.
  17. //
  18. #if defined(_ALPHA_) || defined(_PPC_)
  19. #define NATIVE_NAN_IS_INTEL_FORMAT 1
  20. #elif defined(_MIPS_)
  21. #define NATIVE_NAN_IS_INTEL_FORMAT 0
  22. #else
  23. #error Unknown machine type
  24. #endif
  25. // Macros to access the register stack
  26. #define ST(i) ((cpu->FpTop+(i)) & 0x07)
  27. #define PUSHFLT(x) { \
  28. INT Top; \
  29. Top = (cpu->FpTop-1) & 0x07; \
  30. cpu->FpTop = Top; \
  31. x = cpu->FpST0 = &cpu->FpStack[Top];\
  32. }
  33. #define INCFLT { \
  34. INT Top; \
  35. Top = (cpu->FpTop+1) & 0x07; \
  36. cpu->FpTop = Top; \
  37. cpu->FpST0 = &cpu->FpStack[Top]; \
  38. }
  39. #define POPFLT { cpu->FpST0->Tag = TAG_EMPTY; INCFLT; }
  40. // Values for cpu->FpReg[].Tag
  41. #define TAG_VALID 0 // value specified by Intel
  42. #define TAG_ZERO 1 // value specified by Intel
  43. #define TAG_SPECIAL 2 // value specified by Intel, indicates SpecialTag is set
  44. #define TAG_EMPTY 3 // value specified by Intel
  45. #define TAG_MAX 4 // value after the highest legal tag value
  46. // Values for cpu->FpReg[].SpecialTag, valid only when Tag==TAG_SPECIAL
  47. #define TAG_SPECIAL_DENORM 0 // private value for NPX emulator
  48. #define TAG_SPECIAL_INFINITY 1 // private value for NPX emulator
  49. #define TAG_SPECIAL_SNAN 2 // private value for NPX emulator
  50. #define TAG_SPECIAL_QNAN 3 // private value for NPX emulator
  51. #define TAG_SPECIAL_INDEF 4 // private value for NPX emulator
  52. // Does a register hold a QNAN, SNAN, or INDEFINITE?
  53. #define IS_TAG_NAN(FpReg) \
  54. ((FpReg)->Tag == TAG_SPECIAL && (FpReg)->TagSpecial >= TAG_SPECIAL_SNAN)
  55. // Common types used for jump tables in the 487 emulator
  56. typedef VOID (*NpxFunc0)(PCPUDATA);
  57. typedef VOID (*NpxFunc1)(PCPUDATA, PFPREG Fp);
  58. typedef VOID (*NpxFunc2)(PCPUDATA cpu, PFPREG l, PFPREG r);
  59. typedef VOID (*NpxFunc3)(PCPUDATA cpu, PFPREG dest, PFPREG l, PFPREG r);
  60. typedef VOID (*NpxComFunc)(PCPUDATA cpu, PFPREG l, PFPREG r, BOOL fUnordered);
  61. typedef VOID (*NpxPutIntelR4)(FLOAT *pIntelReal, PFPREG Fp);
  62. typedef VOID (*NpxPutIntelR8)(DOUBLE *pIntelReal, PFPREG Fp);
  63. typedef VOID (*NpxPutIntelR10)(PBYTE r10, PFPREG Fp);
  64. typedef VOID (*NpxLoadIntelR10ToR8)(PCPUDATA cpu, PBYTE r10, PFPREG FpReg);
  65. typedef VOID (*NpxPutI2)(PCPUDATA cpu, SHORT *pop1, PFPREG Fp);
  66. typedef VOID (*NpxPutI4)(PCPUDATA cpu, LONG *pop1, PFPREG Fp);
  67. typedef VOID (*NpxPutI8)(PCPUDATA cpu, LONGLONG *pop1, PFPREG Fp);
  68. // Macros to declare functions for those common types
  69. #define NPXFUNC0(name) VOID name(PCPUDATA cpu)
  70. #define NPXFUNC1(name) VOID name(PCPUDATA cpu, PFPREG Fp)
  71. #define NPXFUNC2(name) VOID name(PCPUDATA cpu, PFPREG l, PFPREG r)
  72. #define NPXFUNC3(name) VOID name(PCPUDATA cpu, PFPREG dest, PFPREG l, PFPREG r)
  73. #define NPXCOMFUNC(name) VOID name(PCPUDATA cpu, PFPREG l, PFPREG r, BOOL fUnordered)
  74. #define NPXPUTINTELR4(name) VOID name(FLOAT *pIntelReal, PFPREG Fp)
  75. #define NPXPUTINTELR8(name) VOID name(DOUBLE *pIntelReal, PFPREG Fp)
  76. #define NPXPUTINTELR10(name) VOID name(PBYTE r10, PFPREG Fp)
  77. #define NPXLOADINTELR10TOR8(name) VOID name(PCPUDATA cpu, PBYTE r10, PFPREG Fp)
  78. #define NPXPUTI2(name) VOID name(PCPUDATA cpu, SHORT *pop1, PFPREG Fp)
  79. #define NPXPUTI4(name) VOID name(PCPUDATA cpu, LONG *pop1, PFPREG Fp)
  80. #define NPXPUTI8(name) VOID name(PCPUDATA cpu, LONGLONG *pop1, PFPREG Fp)
  81. extern const BYTE R8PositiveInfinityVal[8];
  82. extern const BYTE R8NegativeInfinityVal[8];
  83. #define R8PositiveInfinity *(DOUBLE *)R8PositiveInfinityVal
  84. #define R8NegativeInfinity *(DOUBLE *)R8NegativeInfinityVal
  85. VOID GetIntelR4(PFPREG Fp, FLOAT *pIntelReal);
  86. #if NATIVE_NAN_IS_INTEL_FORMAT
  87. #define GetIntelR8(Fp, pIntelReal) \
  88. (Fp)->r64 = *(UNALIGNED DOUBLE *)(pIntelReal); \
  89. SetTag(Fp);
  90. #define PutIntelR4(pIntelReal, Fp) \
  91. *(UNALIGNED FLOAT *)pIntelReal = (FLOAT)(Fp)->r64;
  92. #define PutIntelR8(pIntelReal, Fp) \
  93. *(UNALIGNED DOUBLE *)pIntelReal = (Fp)->r64;
  94. #else
  95. VOID GetIntelR8(
  96. PFPREG Fp,
  97. DOUBLE *pIntelReal
  98. );
  99. extern NpxPutIntelR4 PutIntelR4Table[TAG_MAX];
  100. extern NpxPutIntelR8 PutIntelR8Table[TAG_MAX];
  101. #define PutIntelR4(pIntelReal, Fp) \
  102. (*PutIntelR4Table[(Fp)->Tag])((pIntelReal), (Fp))
  103. #define PutIntelR8(pIntelReal, Fp) \
  104. (*PutIntelR8Table[(Fp)->Tag])((pIntelReal), (Fp))
  105. #endif
  106. extern const NpxPutIntelR10 PutIntelR10Table[TAG_MAX];
  107. #define PutIntelR10(pIntelReal, Fp) (*PutIntelR10Table[(Fp)->Tag])((pIntelReal), (Fp))
  108. VOID
  109. SetTag(
  110. PFPREG FpReg
  111. );
  112. VOID
  113. ComputeR10Tag(
  114. USHORT *r10,
  115. PFPREG FpReg
  116. );
  117. VOID
  118. ChopR10ToR8(
  119. PBYTE r10,
  120. PFPREG FpReg,
  121. USHORT R10Exponent
  122. );
  123. VOID
  124. LoadIntelR10ToR8(
  125. PCPUDATA cpu,
  126. PBYTE r10,
  127. PFPREG FpReg
  128. );
  129. BOOL
  130. HandleSnan(
  131. PCPUDATA cpu,
  132. PFPREG FpReg
  133. );
  134. BOOL
  135. HandleStackEmpty(
  136. PCPUDATA cpu,
  137. PFPREG FpReg
  138. );
  139. VOID
  140. UpdateFpExceptionFlags(
  141. PCPUDATA cpu
  142. );
  143. VOID
  144. SetIndefinite(
  145. PFPREG FpReg
  146. );
  147. BOOL
  148. HandleInvalidOp(
  149. PCPUDATA cpu
  150. );
  151. VOID
  152. FpControlPreamble(
  153. PCPUDATA cpu
  154. );
  155. VOID
  156. FpArithPreamble(
  157. PCPUDATA cpu
  158. );
  159. VOID
  160. FpArithDataPreamble(
  161. PCPUDATA cpu,
  162. PVOID FpData
  163. );
  164. VOID
  165. HandleStackFull(
  166. PCPUDATA cpu,
  167. PFPREG FpReg
  168. );
  169. #endif //FPUFRAGP_H