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.

4448 lines
142 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Copyright (c) 1993 Digital Equipment Corporation
  4. Module Name:
  5. floatem.c
  6. Abstract:
  7. This module implements a software emulation of the IEEE single and
  8. double floating operations. It is required on Alpha processors since
  9. the hardware does not fully support all of the operations required
  10. by the IEEE standard. In particular, infinities and NaNs are not
  11. handled by the hardware, but rather cause an exception. On receipt
  12. of the exception, a software emulation of the floating operation
  13. is performed to determine the real result of the operation and if
  14. an exception will actually be raised.
  15. This code is also used to perform all floating operations on EV4
  16. processors when plus or minus infinity rounding is used.
  17. Since floating exceptions are rather rare events, this routine is
  18. written in C. Should a higher performance implementation be required,
  19. then the algorithms contained herein, can be used to guide a higher
  20. performance assembly language implementation.
  21. N.B. This routine does not emulate floating loads, floating stores,
  22. control to/from floating, or move to/from floating instructions.
  23. These instructions never require emulation.
  24. Floating point operations are carried out by unpacking the operands,
  25. normalizing denormalized numbers, checking for NaNs, interpreting
  26. infinities, and computing results.
  27. Floating operands are converted to a format that has a value with the
  28. appropriate number of leading zeros, an overflow bit, the mantissa, a
  29. guard bit, a round bit, and a set of sticky bits. The unpacked mantissa
  30. includes the hidden bit.
  31. The overflow bit is needed for addition and is also used for multiply.
  32. The mantissa is 24-bits for single operations and 53-bits for double
  33. operations. The guard bit and round bit are used to hold precise values
  34. for normalization and rounding.
  35. If the result of an operation is normalized, then the guard bit becomes
  36. the round bit and the round bit is accumulated with the sticky bits. If
  37. the result of an operation needs to be shifted left one bit for purposes
  38. of normalization, then the guard bit becomes part of the mantissa and the
  39. round bit is used for rounding.
  40. The round bit plus the sticky bits are used to determine how rounding is
  41. performed.
  42. Author:
  43. David N. Cutler (davec) 16-Jun-1991
  44. Environment:
  45. Kernel mode only.
  46. Revision History:
  47. Thomas Van Baak (tvb) 12-Sep-1992
  48. Adapted for Alpha AXP.
  49. Nigel Haslock (haslock) 20-Apr-1995
  50. Adjustments for additional EV4.5 and EV5 functionality
  51. Kim Peterson (peterson) 4-Feb-1998
  52. Corrections for denormal and double precision denormal processing.
  53. Rounds denormal after shifting it into denormal format.
  54. Preserves first operand NAN if second operand is not a NAN
  55. (single precision was already correct).
  56. --*/
  57. #include "ki.h"
  58. #pragma hdrstop
  59. #include "alphaops.h"
  60. #if DBG
  61. extern ULONG RtlDebugFlags;
  62. #define DBGPRINT ((RtlDebugFlags & 0x4) != 0) && DbgPrint
  63. #define DBGPRINT2 ((RtlDebugFlags & 0x8) != 0) && DbgPrint
  64. #else
  65. #define DBGPRINT 0 && DbgPrint
  66. #define DBGPRINT2 0 && DbgPrint
  67. #endif
  68. #define LOW_PART(Quad) ((ULONG)(Quad))
  69. #define HIGH_PART(Quad) ((ULONG)(Quad >> 32))
  70. #define MAKE_QUAD(Low, High) (((ULONGLONG)(High)) << 32 | ((ULONGLONG)(Low)))
  71. //
  72. // The hardware recognizes the new CVTST instruction by the kludged
  73. // opcode function 16.2ac instead of the proper 16.00e (per ECO #46).
  74. //
  75. #define CVTST_FUNC_PROPER 0x00E
  76. //
  77. // Define unpacked format NaN mask values and boolean macros.
  78. //
  79. // N.B. The NaN bit is set for a quiet NaN and reset for a signaling NaN.
  80. // This is the same as Intel, Sun, IBM and opposite of Mips, HP.
  81. //
  82. #define DOUBLE_NAN_BIT_HIGH (1 << (53 - 32))
  83. #define SINGLE_NAN_BIT (1 << 24)
  84. #define DoubleSignalNan(DoubleOperand) \
  85. (((DoubleOperand)->Nan != FALSE) && \
  86. (((DoubleOperand)->MantissaHigh & DOUBLE_NAN_BIT_HIGH) == 0))
  87. #define DoubleQuietNan(DoubleOperand) \
  88. (((DoubleOperand)->Nan != FALSE) && \
  89. (((DoubleOperand)->MantissaHigh & DOUBLE_NAN_BIT_HIGH) != 0))
  90. #define SingleSignalNan(SingleOperand) \
  91. (((SingleOperand)->Nan != FALSE) && \
  92. (((SingleOperand)->Mantissa & SINGLE_NAN_BIT) == 0))
  93. #define SingleQuietNan(SingleOperand) \
  94. (((SingleOperand)->Nan != FALSE) && \
  95. (((SingleOperand)->Mantissa & SINGLE_NAN_BIT) != 0))
  96. //
  97. // Define context block structure.
  98. //
  99. typedef struct _FP_CONTEXT_BLOCK {
  100. ULONG Fc;
  101. PEXCEPTION_RECORD ExceptionRecord;
  102. PKEXCEPTION_FRAME ExceptionFrame;
  103. PKTRAP_FRAME TrapFrame;
  104. PSW_FPCR SoftwareFpcr;
  105. ULONG Round;
  106. BOOLEAN IeeeMode;
  107. BOOLEAN UnderflowEnable;
  108. } FP_CONTEXT_BLOCK, *PFP_CONTEXT_BLOCK;
  109. //
  110. // Define single and double operand value structures.
  111. //
  112. typedef struct _FP_DOUBLE_OPERAND {
  113. LONG MantissaHigh;
  114. ULONG MantissaLow;
  115. LONGLONG Mantissa; // ## Not fully used yet
  116. LONG Exponent;
  117. LONG Sign;
  118. BOOLEAN Infinity;
  119. BOOLEAN Nan;
  120. BOOLEAN Normal;
  121. } FP_DOUBLE_OPERAND, *PFP_DOUBLE_OPERAND;
  122. typedef struct _FP_SINGLE_OPERAND {
  123. LONG Mantissa;
  124. LONG Exponent;
  125. LONG Sign;
  126. BOOLEAN Infinity;
  127. BOOLEAN Nan;
  128. BOOLEAN Normal;
  129. } FP_SINGLE_OPERAND, *PFP_SINGLE_OPERAND;
  130. //
  131. // Define single and double IEEE floating point memory formats.
  132. //
  133. typedef struct _DOUBLE_FORMAT {
  134. ULONGLONG Mantissa : 52;
  135. ULONGLONG Exponent : 11;
  136. ULONGLONG Sign : 1;
  137. } DOUBLE_FORMAT, *PDOUBLE_FORMAT;
  138. typedef struct _SINGLE_FORMAT {
  139. ULONG Mantissa : 23;
  140. ULONG Exponent : 8;
  141. ULONG Sign : 1;
  142. } SINGLE_FORMAT, *PSINGLE_FORMAT;
  143. //
  144. // Define forward referenced function prototypes.
  145. //
  146. ULONGLONG
  147. KiConvertSingleOperandToRegister (
  148. IN ULONG SingleValue
  149. );
  150. ULONG
  151. KiConvertRegisterToSingleOperand (
  152. IN ULONGLONG DoubleValue
  153. );
  154. BOOLEAN
  155. KiConvertQuadwordToLongword (
  156. IN PFP_CONTEXT_BLOCK ContextBlock,
  157. IN LONGLONG Quadword
  158. );
  159. BOOLEAN
  160. KiDivideByZeroDouble (
  161. IN PFP_CONTEXT_BLOCK ContextBlock,
  162. IN PFP_DOUBLE_OPERAND DoubleOperand1,
  163. IN PFP_DOUBLE_OPERAND DoubleOperand2
  164. );
  165. BOOLEAN
  166. KiDivideByZeroSingle (
  167. IN PFP_CONTEXT_BLOCK ContextBlock,
  168. IN PFP_SINGLE_OPERAND SingleOperand1,
  169. IN PFP_SINGLE_OPERAND SingleOperand2
  170. );
  171. PFP_IEEE_VALUE
  172. KiInitializeIeeeValue (
  173. IN PEXCEPTION_RECORD ExceptionRecord
  174. );
  175. BOOLEAN
  176. KiInvalidCompareDouble (
  177. IN PFP_CONTEXT_BLOCK ContextBlock,
  178. IN BOOLEAN CheckForSignalNan,
  179. IN PFP_DOUBLE_OPERAND DoubleOperand1,
  180. IN PFP_DOUBLE_OPERAND DoubleOperand2
  181. );
  182. BOOLEAN
  183. KiInvalidOperationDouble (
  184. IN PFP_CONTEXT_BLOCK ContextBlock,
  185. IN BOOLEAN CheckForSignalNan,
  186. IN PFP_DOUBLE_OPERAND DoubleOperand1,
  187. IN PFP_DOUBLE_OPERAND DoubleOperand2
  188. );
  189. BOOLEAN
  190. KiInvalidOperationQuadword (
  191. IN PFP_CONTEXT_BLOCK ContextBlock,
  192. IN ULONGLONG ResultValue
  193. );
  194. BOOLEAN
  195. KiInvalidOperationSingle (
  196. IN PFP_CONTEXT_BLOCK ContextBlock,
  197. IN BOOLEAN CheckForSignalNan,
  198. IN PFP_SINGLE_OPERAND SingleOperand1,
  199. IN PFP_SINGLE_OPERAND SingleOperand2
  200. );
  201. BOOLEAN
  202. KiNormalizeDouble (
  203. IN PFP_CONTEXT_BLOCK ContextBlock,
  204. IN PFP_DOUBLE_OPERAND ResultOperand,
  205. IN ULONGLONG StickyBits
  206. );
  207. BOOLEAN
  208. KiNormalizeQuadword (
  209. IN PFP_CONTEXT_BLOCK ContextBlock,
  210. IN PFP_DOUBLE_OPERAND ResultOperand
  211. );
  212. BOOLEAN
  213. KiNormalizeSingle (
  214. IN PFP_CONTEXT_BLOCK ContextBlock,
  215. IN PFP_SINGLE_OPERAND ResultOperand,
  216. IN ULONG StickyBits
  217. );
  218. VOID
  219. KiUnpackDouble (
  220. IN ULONG Source,
  221. IN PFP_CONTEXT_BLOCK ContextBlock,
  222. OUT PFP_DOUBLE_OPERAND DoubleOperand
  223. );
  224. VOID
  225. KiUnpackSingle (
  226. IN ULONG Source,
  227. IN PFP_CONTEXT_BLOCK ContextBlock,
  228. OUT PFP_SINGLE_OPERAND SingleOperand
  229. );
  230. BOOLEAN
  231. KiEmulateFloating (
  232. IN OUT PEXCEPTION_RECORD ExceptionRecord,
  233. IN OUT PKEXCEPTION_FRAME ExceptionFrame,
  234. IN OUT PKTRAP_FRAME TrapFrame,
  235. IN OUT PSW_FPCR SoftwareFpcr
  236. )
  237. /*++
  238. Routine Description:
  239. This function is called to emulate a floating operation and convert the
  240. exception status to the proper value. If the exception is an unimplemented
  241. operation, then the operation is emulated. Otherwise, the status code is
  242. just converted to its proper value.
  243. Arguments:
  244. ExceptionRecord - Supplies a pointer to an exception record.
  245. ExceptionFrame - Supplies a pointer to an exception frame.
  246. TrapFrame - Supplies a pointer to a trap frame.
  247. SoftwareFpcr - Supplies a pointer to a variable that contains a copy of
  248. the software FPCR.
  249. Return Value:
  250. A value of TRUE is returned if the floating exception is successfully
  251. emulated. Otherwise, a value of FALSE is returned.
  252. --*/
  253. {
  254. ULARGE_INTEGER AhighBhigh;
  255. ULARGE_INTEGER AhighBlow;
  256. ULARGE_INTEGER AlowBhigh;
  257. ULARGE_INTEGER AlowBlow;
  258. ULONG Carry1;
  259. ULONG Carry2;
  260. BOOLEAN CompareEqual;
  261. BOOLEAN CompareLess;
  262. BOOLEAN CompareResult;
  263. FP_CONTEXT_BLOCK ContextBlock;
  264. LARGE_INTEGER DoubleDividend;
  265. LARGE_INTEGER DoubleDivisor;
  266. ULONG DoubleMantissaLow;
  267. LONG DoubleMantissaHigh;
  268. FP_DOUBLE_OPERAND DoubleOperand1;
  269. FP_DOUBLE_OPERAND DoubleOperand2;
  270. FP_DOUBLE_OPERAND DoubleOperand3;
  271. LARGE_INTEGER DoubleQuotient;
  272. PVOID ExceptionAddress;
  273. ULONG ExponentDifference;
  274. ULONG Fa;
  275. ULONG Fb;
  276. ULONG Function;
  277. ULONG Index;
  278. ALPHA_INSTRUCTION Instruction;
  279. ULARGE_INTEGER LargeResult;
  280. LONG Negation;
  281. LONGLONG Quadword;
  282. LONG SingleMantissa;
  283. FP_SINGLE_OPERAND SingleOperand1;
  284. FP_SINGLE_OPERAND SingleOperand2;
  285. FP_SINGLE_OPERAND SingleOperand3;
  286. ULONG StickyBits;
  287. BOOLEAN ValidOperation;
  288. //
  289. // Save the original exception address in case another exception
  290. // occurs.
  291. //
  292. ExceptionAddress = ExceptionRecord->ExceptionAddress;
  293. //
  294. // Any exception that occurs during the attempted emulation of the
  295. // floating operation causes the emulation to be aborted. The new
  296. // exception code and information is copied to the original exception
  297. // record and a value of FALSE is returned.
  298. //
  299. try {
  300. //
  301. // Fetch the faulting or trapping instruction. Check the opcode and
  302. // function code (including the trap enable bits) for IEEE floating
  303. // point operations that are expected to be emulated.
  304. //
  305. // N.B. Only a subset of the 2048 possible combinations of 11 bits
  306. // in the function field are valid. A total of 88 functions
  307. // are affected by missing plus and minus infinity rounding
  308. // mode support in the EV4 chip.
  309. //
  310. Instruction = *((PALPHA_INSTRUCTION)ExceptionRecord->ExceptionAddress);
  311. DBGPRINT("KiEmulateFloating: Instruction = %.8lx, Fpcr = %.16Lx\n",
  312. Instruction.Long, TrapFrame->Fpcr);
  313. Function = Instruction.FpOp.Function;
  314. ValidOperation = FALSE;
  315. if (Instruction.FpOp.Opcode == IEEEFP_OP) {
  316. //
  317. // Adjust the function code if the instruction is CVTST.
  318. //
  319. if (Function == CVTST_FUNC) {
  320. Function = CVTST_FUNC_PROPER;
  321. } else if (Function == CVTST_S_FUNC) {
  322. Function = CVTST_FUNC_PROPER | FP_TRAP_ENABLE_S;
  323. }
  324. switch (Function & FP_FUNCTION_MASK) {
  325. case ADDS_FUNC :
  326. case SUBS_FUNC :
  327. case MULS_FUNC :
  328. case DIVS_FUNC :
  329. case ADDT_FUNC :
  330. case SUBT_FUNC :
  331. case MULT_FUNC :
  332. case DIVT_FUNC :
  333. case CVTTQ_FUNC :
  334. case CVTTS_FUNC :
  335. switch (Function & FP_TRAP_ENABLE_MASK) {
  336. case FP_TRAP_ENABLE_NONE :
  337. case FP_TRAP_ENABLE_U :
  338. case FP_TRAP_ENABLE_SU :
  339. case FP_TRAP_ENABLE_SUI :
  340. ValidOperation = TRUE;
  341. break;
  342. }
  343. break;
  344. case CVTQS_FUNC :
  345. case CVTQT_FUNC :
  346. switch (Function & FP_TRAP_ENABLE_MASK) {
  347. case FP_TRAP_ENABLE_NONE :
  348. case FP_TRAP_ENABLE_SUI :
  349. ValidOperation = TRUE;
  350. break;
  351. }
  352. break;
  353. case CVTST_FUNC_PROPER :
  354. switch (Function & FP_TRAP_ENABLE_MASK) {
  355. case FP_TRAP_ENABLE_NONE :
  356. case FP_TRAP_ENABLE_S :
  357. ValidOperation = TRUE;
  358. break;
  359. }
  360. break;
  361. case CMPTEQ_FUNC :
  362. case CMPTLE_FUNC :
  363. case CMPTLT_FUNC :
  364. case CMPTUN_FUNC :
  365. ValidOperation = TRUE;
  366. break;
  367. }
  368. } else if (Instruction.FpOp.Opcode == FPOP_OP) {
  369. switch (Function) {
  370. case CVTLQ_FUNC :
  371. case CVTQL_FUNC :
  372. case CVTQLV_FUNC :
  373. case CVTQLSV_FUNC :
  374. ValidOperation = TRUE;
  375. break;
  376. }
  377. }
  378. if (ValidOperation == FALSE) {
  379. //
  380. // An illegal instruction, function code, format value, or trap
  381. // enable value was encountered. Generate an illegal instruction
  382. // exception.
  383. //
  384. ExceptionRecord->ExceptionCode = STATUS_ILLEGAL_INSTRUCTION;
  385. DBGPRINT("KiEmulateFloating: Invalid Function or Format\n");
  386. return FALSE;
  387. }
  388. //
  389. // Increment the floating emulation count.
  390. //
  391. KeGetCurrentPrcb()->KeFloatingEmulationCount += 1;
  392. //
  393. // Initialize the address of the exception record, exception frame,
  394. // and trap frame in the context block used during the emulation of
  395. // the floating point operation.
  396. //
  397. // N.B. The SoftwareFpcr and IEEE exception records are only used
  398. // with IEEE mode instructions.
  399. //
  400. ContextBlock.ExceptionRecord = ExceptionRecord;
  401. ContextBlock.ExceptionFrame = ExceptionFrame;
  402. ContextBlock.TrapFrame = TrapFrame;
  403. ContextBlock.SoftwareFpcr = SoftwareFpcr;
  404. //
  405. // Check if the /S bit is set in the instruction. This bit is always
  406. // set in the case of a trigger instruction of an asynchronous trap
  407. // (assuming valid trap shadow) but not necessarily always set in the
  408. // case of an unimplemented floating instruction fault.
  409. //
  410. if ((Function & FP_TRAP_ENABLE_S) != 0) {
  411. ContextBlock.IeeeMode = TRUE;
  412. } else {
  413. ContextBlock.IeeeMode = FALSE;
  414. }
  415. if ((Function & FP_TRAP_ENABLE_U) != 0) {
  416. ContextBlock.UnderflowEnable = TRUE;
  417. } else {
  418. ContextBlock.UnderflowEnable = FALSE;
  419. }
  420. //
  421. // Set the current rounding mode from the rounding mode specified in
  422. // the instruction, or if dynamic rounding is specified, from the
  423. // rounding mode specified in the FPCR.
  424. // Set the emulation flag and emulate the floating point operation.
  425. // The return value is dependent on the results of the emulation.
  426. //
  427. ContextBlock.Fc = Instruction.FpOp.Fc;
  428. Fa = Instruction.FpOp.Fa;
  429. Fb = Instruction.FpOp.Fb;
  430. if ((Function & FP_ROUND_MASK) == FP_ROUND_D) {
  431. ContextBlock.Round = ((PFPCR)&TrapFrame->Fpcr)->DynamicRoundingMode;
  432. } else {
  433. ContextBlock.Round = (Function & FP_ROUND_MASK) >> FP_ROUND_SHIFT;
  434. }
  435. SoftwareFpcr->EmulationOccurred = 1;
  436. //
  437. // Unpack operands and dispense with NaNs.
  438. //
  439. switch (Function & FP_FUNCTION_MASK) {
  440. case ADDS_FUNC :
  441. case SUBS_FUNC :
  442. case MULS_FUNC :
  443. case DIVS_FUNC :
  444. //
  445. // The function has two single operand values.
  446. //
  447. KiUnpackSingle(Fa, &ContextBlock, &SingleOperand1);
  448. KiUnpackSingle(Fb, &ContextBlock, &SingleOperand2);
  449. //
  450. // Non-IEEE mode operate instructions trap on NaN, infinity, or
  451. // denormal operands.
  452. //
  453. if ((ContextBlock.IeeeMode == FALSE) &&
  454. ((SingleOperand1.Normal == FALSE) ||
  455. (SingleOperand2.Normal == FALSE))) {
  456. ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
  457. return FALSE;
  458. }
  459. if ((SingleOperand1.Nan != FALSE) || (SingleOperand2.Nan != FALSE)) {
  460. //
  461. // Store a quiet NaN if the invalid operation trap
  462. // is disabled, or raise an exception if the invalid
  463. // operation trap is enabled and either of the NaNs
  464. // is a signaling NaN.
  465. //
  466. return KiInvalidOperationSingle(&ContextBlock,
  467. TRUE,
  468. &SingleOperand1,
  469. &SingleOperand2);
  470. }
  471. break;
  472. case ADDT_FUNC :
  473. case SUBT_FUNC :
  474. case MULT_FUNC :
  475. case DIVT_FUNC :
  476. //
  477. // The function has two double operand values.
  478. //
  479. KiUnpackDouble(Fa, &ContextBlock, &DoubleOperand1);
  480. KiUnpackDouble(Fb, &ContextBlock, &DoubleOperand2);
  481. //
  482. // Non-IEEE mode operate instructions trap on NaN, infinity, or
  483. // denormal operands.
  484. //
  485. if ((ContextBlock.IeeeMode == FALSE) &&
  486. ((DoubleOperand1.Normal == FALSE) ||
  487. (DoubleOperand2.Normal == FALSE))) {
  488. ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
  489. return FALSE;
  490. }
  491. if ((DoubleOperand1.Nan != FALSE) || (DoubleOperand2.Nan != FALSE)) {
  492. //
  493. // Store a quiet NaN if the invalid operation trap
  494. // is disabled, or raise an exception if the invalid
  495. // operation trap is enabled and either of the NaNs
  496. // is a signaling NaN.
  497. //
  498. return KiInvalidOperationDouble(&ContextBlock,
  499. TRUE,
  500. &DoubleOperand1,
  501. &DoubleOperand2);
  502. }
  503. break;
  504. case CMPTEQ_FUNC :
  505. case CMPTLE_FUNC :
  506. case CMPTLT_FUNC :
  507. case CMPTUN_FUNC :
  508. //
  509. // The function has two double operand values.
  510. //
  511. KiUnpackDouble(Fa, &ContextBlock, &DoubleOperand1);
  512. KiUnpackDouble(Fb, &ContextBlock, &DoubleOperand2);
  513. //
  514. // Non-IEEE mode compare instructions trap on NaN or denormal
  515. // operands.
  516. //
  517. if ((ContextBlock.IeeeMode == FALSE) &&
  518. (((DoubleOperand1.Normal == FALSE) &&
  519. (DoubleOperand1.Infinity == FALSE)) ||
  520. ((DoubleOperand2.Normal == FALSE) &&
  521. (DoubleOperand2.Infinity == FALSE)))) {
  522. ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
  523. return FALSE;
  524. }
  525. //
  526. // Compare operation.
  527. //
  528. // If either operand is a NaN, then check the type of compare
  529. // operation to determine the result value and if an exception
  530. // should be raised. Otherwise, if the operation is a compare
  531. // unordered operation, store a false result.
  532. //
  533. if ((DoubleOperand1.Nan != FALSE) || (DoubleOperand2.Nan != FALSE)) {
  534. //
  535. // If the compare is an unordered compare, then store a true
  536. // result (a NaN compares unordered with everything, including
  537. // itself). Raise an exception if the invalid operation trap
  538. // is enabled and either of the NaNs is a signaling NaN.
  539. //
  540. // Otherwise, if the operation is compare equal, then store a
  541. // false result. Raise an exception if the invalid operation
  542. // trap is enabled and either of the NaNs is a signaling NaN.
  543. //
  544. // Otherwise store a false result and raise an exception if
  545. // the invalid operation trap is enabled.
  546. //
  547. if ((Function & FP_FUNCTION_MASK) == CMPTUN_FUNC) {
  548. KiSetRegisterValue(ContextBlock.Fc + 32,
  549. FP_COMPARE_TRUE,
  550. ExceptionFrame,
  551. TrapFrame);
  552. return KiInvalidCompareDouble(&ContextBlock,
  553. TRUE,
  554. &DoubleOperand1,
  555. &DoubleOperand2);
  556. } else if ((Function & FP_FUNCTION_MASK) == CMPTEQ_FUNC) {
  557. KiSetRegisterValue(ContextBlock.Fc + 32,
  558. FP_COMPARE_FALSE,
  559. ExceptionFrame,
  560. TrapFrame);
  561. return KiInvalidCompareDouble(&ContextBlock,
  562. TRUE,
  563. &DoubleOperand1,
  564. &DoubleOperand2);
  565. } else {
  566. KiSetRegisterValue(ContextBlock.Fc + 32,
  567. FP_COMPARE_FALSE,
  568. ExceptionFrame,
  569. TrapFrame);
  570. return KiInvalidCompareDouble(&ContextBlock,
  571. FALSE,
  572. &DoubleOperand1,
  573. &DoubleOperand2);
  574. }
  575. } else {
  576. if ((Function & FP_FUNCTION_MASK) == CMPTUN_FUNC) {
  577. KiSetRegisterValue(ContextBlock.Fc + 32,
  578. FP_COMPARE_FALSE,
  579. ExceptionFrame,
  580. TrapFrame);
  581. return TRUE;
  582. }
  583. }
  584. break;
  585. case CVTST_FUNC_PROPER :
  586. //
  587. // The function has one single operand value which is found in
  588. // the second operand.
  589. //
  590. KiUnpackSingle(Fb, &ContextBlock, &SingleOperand1);
  591. //
  592. // Non-IEEE mode convert instructions trap on NaN, infinity, or
  593. // denormal operands.
  594. //
  595. if ((ContextBlock.IeeeMode == FALSE) &&
  596. (SingleOperand1.Normal == FALSE)) {
  597. ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
  598. return FALSE;
  599. }
  600. break;
  601. case CVTTQ_FUNC :
  602. case CVTTS_FUNC :
  603. //
  604. // The function has one double operand value which is found in
  605. // the second operand.
  606. //
  607. KiUnpackDouble(Fb, &ContextBlock, &DoubleOperand1);
  608. //
  609. // Non-IEEE mode convert instructions trap on NaN, infinity, or
  610. // denormal operands.
  611. //
  612. if ((ContextBlock.IeeeMode == FALSE) &&
  613. (DoubleOperand1.Normal == FALSE)) {
  614. ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
  615. return FALSE;
  616. }
  617. break;
  618. case CVTLQ_FUNC :
  619. case CVTQL_FUNC :
  620. case CVTQS_FUNC :
  621. case CVTQT_FUNC :
  622. //
  623. // The function has one quadword operand value which is found in
  624. // the second operand.
  625. //
  626. Quadword = KiGetRegisterValue(Fb + 32,
  627. ContextBlock.ExceptionFrame,
  628. ContextBlock.TrapFrame);
  629. break;
  630. }
  631. //
  632. // Case to the proper function routine to emulate the operation.
  633. //
  634. Negation = 0;
  635. switch (Function & FP_FUNCTION_MASK) {
  636. //
  637. // Floating subtract operation.
  638. //
  639. // Floating subtract is accomplished by complementing the sign
  640. // of the second operand and then performing an add operation.
  641. //
  642. case SUBS_FUNC :
  643. DBGPRINT2("subs\n");
  644. Negation = 0x1;
  645. //
  646. // Floating add operation.
  647. //
  648. // Floating add is accomplished using signed magnitude addition.
  649. //
  650. // The exponent difference is calculated and the smaller number
  651. // is right shifted by the specified amount, but no more than
  652. // the width of the operand values (i.e., 26 for single and 55
  653. // for double). The shifted out value is saved for rounding.
  654. //
  655. // If the signs of the two operands are the same, then they
  656. // are added together after having performed the alignment
  657. // shift.
  658. //
  659. // If the signs of the two operands are different, then the
  660. // sign of the result is the sign of the larger operand and
  661. // the smaller operand is subtracted from the larger operand.
  662. // In order to avoid making a double level test (i.e., one on
  663. // the exponents, and one on the mantissas if the exponents
  664. // are equal), it is possible that the result of the subtract
  665. // could be negative (if the exponents are equal). If this
  666. // occurs, then the result sign and mantissa are complemented
  667. // to obtain the correct result.
  668. //
  669. case ADDS_FUNC :
  670. DBGPRINT2("adds\n");
  671. //
  672. // Complement the sign of the second operand if the operation
  673. // is subtraction.
  674. //
  675. SingleOperand2.Sign ^= Negation;
  676. //
  677. // Reorder the operands according to their exponent value
  678. // so that Operand1 exponent will be >= Operand2 exponent.
  679. //
  680. if (SingleOperand2.Exponent > SingleOperand1.Exponent) {
  681. SingleOperand3 = SingleOperand2;
  682. SingleOperand2 = SingleOperand1;
  683. SingleOperand1 = SingleOperand3;
  684. }
  685. //
  686. // Compute the exponent difference and shift the smaller
  687. // mantissa right by the difference value or 26 which ever
  688. // is smaller. The bits shifted out are termed the sticky
  689. // bits and are used later in the rounding operation.
  690. //
  691. ExponentDifference =
  692. SingleOperand1.Exponent - SingleOperand2.Exponent;
  693. if (ExponentDifference > 26) {
  694. ExponentDifference = 26;
  695. }
  696. StickyBits =
  697. SingleOperand2.Mantissa & ((1 << ExponentDifference) - 1);
  698. SingleMantissa = SingleOperand2.Mantissa >> ExponentDifference;
  699. //
  700. // If the operands both have the same sign, then perform the
  701. // operation by adding the values together. Otherwise, if the
  702. // operands are not infinity, perform the operation by
  703. // subtracting the second operand from the first operand.
  704. //
  705. if ((SingleOperand1.Sign ^ SingleOperand2.Sign) == 0) {
  706. SingleOperand1.Mantissa += SingleMantissa;
  707. } else {
  708. if ((SingleOperand1.Infinity != FALSE) &&
  709. (SingleOperand2.Infinity != FALSE)) {
  710. return KiInvalidOperationSingle(&ContextBlock,
  711. FALSE,
  712. &SingleOperand1,
  713. &SingleOperand2);
  714. } else if (SingleOperand1.Infinity == FALSE) {
  715. if (StickyBits != 0) {
  716. SingleOperand1.Mantissa -= 1;
  717. }
  718. SingleOperand1.Mantissa -= SingleMantissa;
  719. if (SingleOperand1.Mantissa < 0) {
  720. SingleOperand1.Mantissa = -SingleOperand1.Mantissa;
  721. SingleOperand1.Sign ^= 0x1;
  722. }
  723. //
  724. // If the result is exactly zero and the signs of the
  725. // operands differ, then the result is plus zero except
  726. // when the rounding mode is minus infinity.
  727. //
  728. if ((SingleOperand1.Mantissa == 0) && (StickyBits == 0)) {
  729. if (ContextBlock.Round == ROUND_TO_MINUS_INFINITY) {
  730. SingleOperand1.Sign = 0x1;
  731. } else {
  732. SingleOperand1.Sign = 0x0;
  733. }
  734. }
  735. }
  736. }
  737. //
  738. // Normalize and store the result value.
  739. //
  740. return KiNormalizeSingle(&ContextBlock,
  741. &SingleOperand1,
  742. StickyBits);
  743. case SUBT_FUNC :
  744. DBGPRINT2("subt\n");
  745. Negation = 0x1;
  746. case ADDT_FUNC :
  747. DBGPRINT2("addt\n");
  748. //
  749. // Complement the sign of the second operand if the operation
  750. // is subtraction.
  751. //
  752. DoubleOperand2.Sign ^= Negation;
  753. //
  754. // Reorder the operands according to their exponent value
  755. // so that Operand1 exponent will be >= Operand2 exponent.
  756. //
  757. if (DoubleOperand2.Exponent > DoubleOperand1.Exponent) {
  758. DoubleOperand3 = DoubleOperand2;
  759. DoubleOperand2 = DoubleOperand1;
  760. DoubleOperand1 = DoubleOperand3;
  761. }
  762. //
  763. // Compute the exponent difference and shift the smaller
  764. // mantissa right by the difference value or 55 which ever
  765. // is smaller. The bits shifted out are termed the sticky
  766. // bits and are used later in the rounding operation.
  767. //
  768. ExponentDifference =
  769. DoubleOperand1.Exponent - DoubleOperand2.Exponent;
  770. if (ExponentDifference > 55) {
  771. ExponentDifference = 55;
  772. }
  773. if (ExponentDifference >= 32) {
  774. ExponentDifference -= 32;
  775. StickyBits = (DoubleOperand2.MantissaLow) |
  776. (DoubleOperand2.MantissaHigh & ((1 << ExponentDifference) - 1));
  777. DoubleMantissaLow =
  778. DoubleOperand2.MantissaHigh >> ExponentDifference;
  779. DoubleMantissaHigh = 0;
  780. } else if (ExponentDifference > 0) {
  781. StickyBits =
  782. DoubleOperand2.MantissaLow & ((1 << ExponentDifference) - 1);
  783. DoubleMantissaLow =
  784. (DoubleOperand2.MantissaLow >> ExponentDifference) |
  785. (DoubleOperand2.MantissaHigh << (32 - ExponentDifference));
  786. DoubleMantissaHigh =
  787. DoubleOperand2.MantissaHigh >> ExponentDifference;
  788. } else {
  789. StickyBits = 0;
  790. DoubleMantissaLow = DoubleOperand2.MantissaLow;
  791. DoubleMantissaHigh = DoubleOperand2.MantissaHigh;
  792. }
  793. //
  794. // If the operands both have the same sign, then perform the
  795. // operation by adding the values together. Otherwise, if the
  796. // operands are not infinity, perform the operation by
  797. // subtracting the second operand from the first operand.
  798. //
  799. if ((DoubleOperand1.Sign ^ DoubleOperand2.Sign) == 0) {
  800. DoubleOperand1.MantissaLow += DoubleMantissaLow;
  801. DoubleOperand1.MantissaHigh += DoubleMantissaHigh;
  802. if (DoubleOperand1.MantissaLow < DoubleMantissaLow) {
  803. DoubleOperand1.MantissaHigh += 1;
  804. }
  805. } else {
  806. if ((DoubleOperand1.Infinity != FALSE) &&
  807. (DoubleOperand2.Infinity != FALSE)) {
  808. return KiInvalidOperationDouble(&ContextBlock,
  809. FALSE,
  810. &DoubleOperand1,
  811. &DoubleOperand2);
  812. } else if (DoubleOperand1.Infinity == FALSE) {
  813. if (StickyBits != 0) {
  814. if (DoubleOperand1.MantissaLow < 1) {
  815. DoubleOperand1.MantissaHigh -= 1;
  816. }
  817. DoubleOperand1.MantissaLow -= 1;
  818. }
  819. if (DoubleOperand1.MantissaLow < DoubleMantissaLow) {
  820. DoubleOperand1.MantissaHigh -= 1;
  821. }
  822. DoubleOperand1.MantissaLow -= DoubleMantissaLow;
  823. DoubleOperand1.MantissaHigh -= DoubleMantissaHigh;
  824. if (DoubleOperand1.MantissaHigh < 0) {
  825. DoubleOperand1.MantissaLow = -(LONG)DoubleOperand1.MantissaLow;
  826. DoubleOperand1.MantissaHigh = -DoubleOperand1.MantissaHigh;
  827. if (DoubleOperand1.MantissaLow != 0) {
  828. DoubleOperand1.MantissaHigh -= 1;
  829. }
  830. DoubleOperand1.Sign ^= 0x1;
  831. }
  832. //
  833. // If the result is exactly zero and the signs of the
  834. // operands differ, then the result is plus zero except
  835. // when the rounding mode is minus infinity.
  836. //
  837. if ((DoubleOperand1.MantissaHigh == 0) &&
  838. (DoubleOperand1.MantissaLow == 0) &&
  839. (StickyBits == 0)) {
  840. if (ContextBlock.Round == ROUND_TO_MINUS_INFINITY) {
  841. DoubleOperand1.Sign = 0x1;
  842. } else {
  843. DoubleOperand1.Sign = 0x0;
  844. }
  845. }
  846. }
  847. }
  848. //
  849. // Normalize and store the result value.
  850. //
  851. return KiNormalizeDouble(&ContextBlock,
  852. &DoubleOperand1,
  853. StickyBits);
  854. //
  855. // Floating multiply operation.
  856. //
  857. // Floating multiply is accomplished using unsigned multiplies
  858. // of the mantissa values, and adding the partial results together
  859. // to form the total product.
  860. //
  861. // The two mantissa values are preshifted such that the final
  862. // result is properly aligned.
  863. //
  864. case MULS_FUNC :
  865. DBGPRINT2("muls\n");
  866. //
  867. // Reorder the operands according to their exponent value
  868. // so that Operand1 exponent will be >= Operand2 exponent.
  869. //
  870. if (SingleOperand2.Exponent > SingleOperand1.Exponent) {
  871. SingleOperand3 = SingleOperand2;
  872. SingleOperand2 = SingleOperand1;
  873. SingleOperand1 = SingleOperand3;
  874. }
  875. //
  876. // If the first operand is infinite and the second operand is
  877. // zero, then an invalid operation is specified.
  878. //
  879. if ((SingleOperand1.Infinity != FALSE) &&
  880. (SingleOperand2.Infinity == FALSE) &&
  881. (SingleOperand2.Mantissa == 0)) {
  882. return KiInvalidOperationSingle(&ContextBlock,
  883. FALSE,
  884. &SingleOperand1,
  885. &SingleOperand2);
  886. }
  887. //
  888. // Preshift the operand mantissas so the result will be a
  889. // properly aligned 64-bit value and then unsigned multiply
  890. // the two mantissa values. The single result is the high part
  891. // of the 64-bit product and the sticky bits are the low part
  892. // of the 64-bit product.
  893. //
  894. // The size of the product will be (1+23+2)+(1+23+2) = 52 bits
  895. // of which the high (1+1+23+2) = 27 bits are result and the
  896. // remaining 25 bits are sticky. By preshifting the operands
  897. // left 7 bits, the number of sticky bits is 32. This alignment
  898. // is convenient.
  899. //
  900. // The 7 bit preshift amount must be applied in part to both
  901. // operands because 26 of 32 bits of the mantissa are used and
  902. // so neither operand can be safely shifted left by more than 6
  903. // bits. Thus one operand is shifted the maximum of 6 bits and
  904. // the other the remaining 1 bit.
  905. //
  906. LargeResult.QuadPart = ((ULONGLONG)((ULONG)(SingleOperand1.Mantissa << (32 - 26)))) *
  907. ((ULONGLONG)((ULONG)(SingleOperand2.Mantissa << 1)));
  908. SingleOperand1.Mantissa = LargeResult.HighPart;
  909. StickyBits = LargeResult.LowPart;
  910. //
  911. // Compute the sign and exponent of the result.
  912. //
  913. SingleOperand1.Sign ^= SingleOperand2.Sign;
  914. SingleOperand1.Exponent +=
  915. SingleOperand2.Exponent - SINGLE_EXPONENT_BIAS;
  916. //
  917. // Normalize and store the result value.
  918. //
  919. return KiNormalizeSingle(&ContextBlock,
  920. &SingleOperand1,
  921. StickyBits);
  922. case MULT_FUNC :
  923. DBGPRINT2("mult\n");
  924. //
  925. // Reorder the operands according to their exponent value
  926. // so that Operand1 exponent will be >= Operand2 exponent.
  927. //
  928. if (DoubleOperand2.Exponent > DoubleOperand1.Exponent) {
  929. DoubleOperand3 = DoubleOperand2;
  930. DoubleOperand2 = DoubleOperand1;
  931. DoubleOperand1 = DoubleOperand3;
  932. }
  933. //
  934. // If the first operand is infinite and the second operand is
  935. // zero, then an invalid operation is specified.
  936. //
  937. if ((DoubleOperand1.Infinity != FALSE) &&
  938. (DoubleOperand2.Infinity == FALSE) &&
  939. (DoubleOperand2.MantissaHigh == 0)) {
  940. return KiInvalidOperationDouble(&ContextBlock,
  941. FALSE,
  942. &DoubleOperand1,
  943. &DoubleOperand2);
  944. }
  945. //
  946. // Preshift the operand mantissas so the result will be a
  947. // properly aligned 128-bit value and then unsigned multiply
  948. // the two mantissa values. The double result is the high part
  949. // of the 128-bit product and the sticky bits are the low part
  950. // of the 128-bit product.
  951. //
  952. // The size of the product will be (1+52+2)+(1+52+2) = 110 bits
  953. // of which the high (1+1+52+2) = 56 bits are result and the
  954. // remaining 54 bits are sticky. By preshifting the operands
  955. // left 10 bits, the number of sticky bits is 64. This alignment
  956. // is convenient.
  957. //
  958. // The 10 bit preshift amount must be applied in part to both
  959. // operands because 55 of 64 bits of the mantissa are used and
  960. // so neither operand can be safely shifted left by more than 9
  961. // bits. Thus one operand is shifted the maximum of 9 bits and
  962. // the other the remaining 1 bit.
  963. //
  964. DoubleOperand1.MantissaHigh =
  965. (DoubleOperand1.MantissaHigh << 1) |
  966. (DoubleOperand1.MantissaLow >> 31);
  967. DoubleOperand1.MantissaLow <<= 1;
  968. DoubleOperand2.MantissaHigh =
  969. (DoubleOperand2.MantissaHigh << (64 - 55)) |
  970. (DoubleOperand2.MantissaLow >> (32 - (64 - 55)));
  971. DoubleOperand2.MantissaLow <<= (64 - 55);
  972. //
  973. // The 128-bit product is formed by multiplying and adding
  974. // all the cross product values.
  975. //
  976. // Consider the operands (A and B) as being composed of two
  977. // parts Ahigh, Alow, Bhigh, and Blow. The cross product sum
  978. // is then:
  979. //
  980. // Ahigh * Bhigh * 2^64 +
  981. // Ahigh * Blow * 2^32 +
  982. // Alow * Bhigh * 2^32 +
  983. // Alow * Blow
  984. //
  985. AhighBhigh.QuadPart = (ULONGLONG)(ULONG)DoubleOperand1.MantissaHigh *
  986. (ULONGLONG)(ULONG)DoubleOperand2.MantissaHigh;
  987. AhighBlow.QuadPart = (ULONGLONG)(ULONG)DoubleOperand1.MantissaHigh *
  988. (ULONGLONG)DoubleOperand2.MantissaLow;
  989. AlowBhigh.QuadPart = (ULONGLONG)DoubleOperand1.MantissaLow *
  990. (ULONGLONG)(ULONG)DoubleOperand2.MantissaHigh;
  991. AlowBlow.QuadPart = (ULONGLONG)DoubleOperand1.MantissaLow *
  992. (ULONGLONG)DoubleOperand2.MantissaLow;
  993. AlowBlow.HighPart += AhighBlow.LowPart;
  994. if (AlowBlow.HighPart < AhighBlow.LowPart) {
  995. Carry1 = 1;
  996. } else {
  997. Carry1 = 0;
  998. }
  999. AlowBlow.HighPart += AlowBhigh.LowPart;
  1000. if (AlowBlow.HighPart < AlowBhigh.LowPart) {
  1001. Carry1 += 1;
  1002. }
  1003. DoubleOperand1.MantissaLow = AhighBlow.HighPart + Carry1;
  1004. if (DoubleOperand1.MantissaLow < Carry1) {
  1005. Carry2 = 1;
  1006. } else {
  1007. Carry2 = 0;
  1008. }
  1009. DoubleOperand1.MantissaLow += AlowBhigh.HighPart;
  1010. if (DoubleOperand1.MantissaLow < AlowBhigh.HighPart) {
  1011. Carry2 += 1;
  1012. }
  1013. DoubleOperand1.MantissaLow += AhighBhigh.LowPart;
  1014. if (DoubleOperand1.MantissaLow < AhighBhigh.LowPart) {
  1015. Carry2 += 1;
  1016. }
  1017. DoubleOperand1.MantissaHigh = AhighBhigh.HighPart + Carry2;
  1018. StickyBits = AlowBlow.HighPart | AlowBlow.LowPart;
  1019. //
  1020. // Compute the sign and exponent of the result.
  1021. //
  1022. DoubleOperand1.Sign ^= DoubleOperand2.Sign;
  1023. DoubleOperand1.Exponent +=
  1024. DoubleOperand2.Exponent - DOUBLE_EXPONENT_BIAS;
  1025. //
  1026. // Normalize and store the result value.
  1027. //
  1028. return KiNormalizeDouble(&ContextBlock,
  1029. &DoubleOperand1,
  1030. StickyBits);
  1031. //
  1032. // Floating divide operation.
  1033. //
  1034. // Floating division is accomplished by repeated subtract using
  1035. // a single one-bit-at-a-time algorithm. The number of division
  1036. // steps performed is equal to the mantissa size plus one guard
  1037. // bit.
  1038. //
  1039. // The sticky bits are the remainder after the specified number
  1040. // of division steps.
  1041. //
  1042. case DIVS_FUNC :
  1043. DBGPRINT2("divs\n");
  1044. //
  1045. // If the first operand is infinite and the second operand
  1046. // is infinite, or both operands are zero, then an invalid
  1047. // operation is specified.
  1048. //
  1049. if (((SingleOperand1.Infinity != FALSE) &&
  1050. (SingleOperand2.Infinity != FALSE)) ||
  1051. ((SingleOperand1.Infinity == FALSE) &&
  1052. (SingleOperand1.Mantissa == 0) &&
  1053. (SingleOperand2.Infinity == FALSE) &&
  1054. (SingleOperand2.Mantissa == 0))) {
  1055. return KiInvalidOperationSingle(&ContextBlock,
  1056. FALSE,
  1057. &SingleOperand1,
  1058. &SingleOperand2);
  1059. }
  1060. //
  1061. // If the second operand is zero, then a divide by zero
  1062. // operation is specified.
  1063. //
  1064. if ((SingleOperand2.Infinity == FALSE) &&
  1065. (SingleOperand2.Mantissa == 0)) {
  1066. return KiDivideByZeroSingle(&ContextBlock,
  1067. &SingleOperand1,
  1068. &SingleOperand2);
  1069. }
  1070. //
  1071. // If the first operand is infinite, then the result is
  1072. // infinite. Otherwise, if the second operand is infinite,
  1073. // then the result is zero (note that both operands cannot
  1074. // be infinite).
  1075. //
  1076. if (SingleOperand1.Infinity != FALSE) {
  1077. SingleOperand1.Sign ^= SingleOperand2.Sign;
  1078. return KiNormalizeSingle(&ContextBlock,
  1079. &SingleOperand1,
  1080. 0);
  1081. } else if (SingleOperand2.Infinity != FALSE) {
  1082. SingleOperand1.Sign ^= SingleOperand2.Sign;
  1083. SingleOperand1.Exponent = 0;
  1084. SingleOperand1.Mantissa = 0;
  1085. return KiNormalizeSingle(&ContextBlock,
  1086. &SingleOperand1,
  1087. 0);
  1088. }
  1089. //
  1090. // Perform divide operation by repeating a single bit
  1091. // divide step 26 iterations.
  1092. //
  1093. SingleOperand3.Mantissa = 0;
  1094. for (Index = 0; Index < 26; Index += 1) {
  1095. SingleOperand3.Mantissa <<= 1;
  1096. if (SingleOperand1.Mantissa >= SingleOperand2.Mantissa) {
  1097. SingleOperand1.Mantissa -= SingleOperand2.Mantissa;
  1098. SingleOperand3.Mantissa |= 1;
  1099. }
  1100. SingleOperand1.Mantissa <<= 1;
  1101. }
  1102. //
  1103. // Compute the sign and exponent of the result.
  1104. //
  1105. SingleOperand3.Sign = SingleOperand1.Sign ^ SingleOperand2.Sign;
  1106. SingleOperand3.Exponent = SingleOperand1.Exponent -
  1107. SingleOperand2.Exponent + SINGLE_EXPONENT_BIAS;
  1108. //
  1109. // Normalize and store the result value.
  1110. //
  1111. SingleOperand3.Infinity = FALSE;
  1112. SingleOperand3.Nan = FALSE;
  1113. return KiNormalizeSingle(&ContextBlock,
  1114. &SingleOperand3,
  1115. SingleOperand1.Mantissa);
  1116. case DIVT_FUNC :
  1117. DBGPRINT2("divt\n");
  1118. //
  1119. // If the first operand is infinite and the second operand
  1120. // is infinite, or both operands are zero, then an invalid
  1121. // operation is specified.
  1122. //
  1123. if (((DoubleOperand1.Infinity != FALSE) &&
  1124. (DoubleOperand2.Infinity != FALSE)) ||
  1125. ((DoubleOperand1.Infinity == FALSE) &&
  1126. (DoubleOperand1.MantissaHigh == 0) &&
  1127. (DoubleOperand2.Infinity == FALSE) &&
  1128. (DoubleOperand2.MantissaHigh == 0))) {
  1129. return KiInvalidOperationDouble(&ContextBlock,
  1130. FALSE,
  1131. &DoubleOperand1,
  1132. &DoubleOperand2);
  1133. }
  1134. //
  1135. // If the second operand is zero, then a divide by zero
  1136. // operation is specified.
  1137. //
  1138. if ((DoubleOperand2.Infinity == FALSE) &&
  1139. (DoubleOperand2.MantissaHigh == 0)) {
  1140. return KiDivideByZeroDouble(&ContextBlock,
  1141. &DoubleOperand1,
  1142. &DoubleOperand2);
  1143. }
  1144. //
  1145. // If the first operand is infinite, then the result is
  1146. // infinite. Otherwise, if the second operand is infinite,
  1147. // then the result is zero (note that both operands cannot
  1148. // be infinite).
  1149. //
  1150. if (DoubleOperand1.Infinity != FALSE) {
  1151. DoubleOperand1.Sign ^= DoubleOperand2.Sign;
  1152. return KiNormalizeDouble(&ContextBlock,
  1153. &DoubleOperand1,
  1154. 0);
  1155. } else if (DoubleOperand2.Infinity != FALSE) {
  1156. DoubleOperand1.Sign ^= DoubleOperand2.Sign;
  1157. DoubleOperand1.Exponent = 0;
  1158. DoubleOperand1.MantissaHigh = 0;
  1159. DoubleOperand1.MantissaLow = 0;
  1160. return KiNormalizeDouble(&ContextBlock,
  1161. &DoubleOperand1,
  1162. 0);
  1163. }
  1164. //
  1165. // Perform divide operation by repeating a single bit
  1166. // divide step 55 iterations.
  1167. //
  1168. DoubleDividend.LowPart = DoubleOperand1.MantissaLow;
  1169. DoubleDividend.HighPart = DoubleOperand1.MantissaHigh;
  1170. DoubleDivisor.LowPart = DoubleOperand2.MantissaLow;
  1171. DoubleDivisor.HighPart = DoubleOperand2.MantissaHigh;
  1172. DoubleQuotient.LowPart = 0;
  1173. DoubleQuotient.HighPart = 0;
  1174. for (Index = 0; Index < 55; Index += 1) {
  1175. DoubleQuotient.HighPart =
  1176. (DoubleQuotient.HighPart << 1) |
  1177. DoubleQuotient.LowPart >> 31;
  1178. DoubleQuotient.LowPart <<= 1;
  1179. if (DoubleDividend.QuadPart >= DoubleDivisor.QuadPart) {
  1180. DoubleDividend.QuadPart = DoubleDividend.QuadPart - DoubleDivisor.QuadPart;
  1181. DoubleQuotient.LowPart |= 1;
  1182. }
  1183. DoubleDividend.HighPart =
  1184. (DoubleDividend.HighPart << 1) |
  1185. DoubleDividend.LowPart >> 31;
  1186. DoubleDividend.LowPart <<= 1;
  1187. }
  1188. DoubleOperand3.MantissaLow = DoubleQuotient.LowPart;
  1189. DoubleOperand3.MantissaHigh = DoubleQuotient.HighPart;
  1190. //
  1191. // Compute the sign and exponent of the result.
  1192. //
  1193. DoubleOperand3.Sign = DoubleOperand1.Sign ^ DoubleOperand2.Sign;
  1194. DoubleOperand3.Exponent = DoubleOperand1.Exponent -
  1195. DoubleOperand2.Exponent + DOUBLE_EXPONENT_BIAS;
  1196. //
  1197. // Normalize and store the result value.
  1198. //
  1199. DoubleOperand3.Infinity = FALSE;
  1200. DoubleOperand3.Nan = FALSE;
  1201. return KiNormalizeDouble(&ContextBlock,
  1202. &DoubleOperand3,
  1203. DoubleDividend.LowPart | DoubleDividend.HighPart);
  1204. //
  1205. // Floating compare double.
  1206. //
  1207. // This operation is performed after having separated out NaNs,
  1208. // and therefore the only comparison predicates left are equal
  1209. // and less.
  1210. //
  1211. // Floating compare double is accomplished by comparing signs,
  1212. // then exponents, and finally the mantissa if necessary.
  1213. //
  1214. // N.B. The sign of zero is ignored.
  1215. //
  1216. case CMPTEQ_FUNC :
  1217. case CMPTLE_FUNC :
  1218. case CMPTLT_FUNC :
  1219. //
  1220. // If either operand is zero, then set the sign of the operand
  1221. // positive and the exponent to a value less than the minimum
  1222. // denormal number.
  1223. //
  1224. if ((DoubleOperand1.Infinity == FALSE) &&
  1225. (DoubleOperand1.MantissaHigh == 0)) {
  1226. DoubleOperand1.Sign = 0;
  1227. DoubleOperand1.Exponent = -52;
  1228. }
  1229. if ((DoubleOperand2.Infinity == FALSE) &&
  1230. (DoubleOperand2.MantissaHigh == 0)) {
  1231. DoubleOperand2.Sign = 0;
  1232. DoubleOperand2.Exponent = -52;
  1233. }
  1234. //
  1235. // Compare signs first.
  1236. //
  1237. if (DoubleOperand1.Sign < DoubleOperand2.Sign) {
  1238. //
  1239. // The first operand is greater than the second operand.
  1240. //
  1241. CompareEqual = FALSE;
  1242. CompareLess = FALSE;
  1243. } else if (DoubleOperand1.Sign > DoubleOperand2.Sign) {
  1244. //
  1245. // The first operand is less than the second operand.
  1246. //
  1247. CompareEqual = FALSE;
  1248. CompareLess = TRUE;
  1249. } else {
  1250. //
  1251. // The operand signs are equal.
  1252. //
  1253. // If the sign of the operand is negative, then the sense of
  1254. // the comparison is reversed.
  1255. //
  1256. if (DoubleOperand1.Sign == 0) {
  1257. //
  1258. // Compare positive operand with positive operand.
  1259. //
  1260. if (DoubleOperand1.Exponent > DoubleOperand2.Exponent) {
  1261. CompareEqual = FALSE;
  1262. CompareLess = FALSE;
  1263. } else if (DoubleOperand1.Exponent < DoubleOperand2.Exponent) {
  1264. CompareEqual = FALSE;
  1265. CompareLess = TRUE;
  1266. } else {
  1267. if (DoubleOperand1.MantissaHigh >
  1268. DoubleOperand2.MantissaHigh) {
  1269. CompareEqual = FALSE;
  1270. CompareLess = FALSE;
  1271. } else if (DoubleOperand1.MantissaHigh <
  1272. DoubleOperand2.MantissaHigh) {
  1273. CompareEqual = FALSE;
  1274. CompareLess = TRUE;
  1275. } else {
  1276. if (DoubleOperand1.MantissaLow >
  1277. DoubleOperand2.MantissaLow) {
  1278. CompareEqual = FALSE;
  1279. CompareLess = FALSE;
  1280. } else if (DoubleOperand1.MantissaLow <
  1281. DoubleOperand2.MantissaLow) {
  1282. CompareEqual = FALSE;
  1283. CompareLess = TRUE;
  1284. } else {
  1285. CompareEqual = TRUE;
  1286. CompareLess = FALSE;
  1287. }
  1288. }
  1289. }
  1290. } else {
  1291. //
  1292. // Compare negative operand with negative operand.
  1293. //
  1294. if (DoubleOperand2.Exponent > DoubleOperand1.Exponent) {
  1295. CompareEqual = FALSE;
  1296. CompareLess = FALSE;
  1297. } else if (DoubleOperand2.Exponent < DoubleOperand1.Exponent) {
  1298. CompareEqual = FALSE;
  1299. CompareLess = TRUE;
  1300. } else {
  1301. if (DoubleOperand2.MantissaHigh >
  1302. DoubleOperand1.MantissaHigh) {
  1303. CompareEqual = FALSE;
  1304. CompareLess = FALSE;
  1305. } else if (DoubleOperand2.MantissaHigh <
  1306. DoubleOperand1.MantissaHigh) {
  1307. CompareEqual = FALSE;
  1308. CompareLess = TRUE;
  1309. } else {
  1310. if (DoubleOperand2.MantissaLow >
  1311. DoubleOperand1.MantissaLow) {
  1312. CompareEqual = FALSE;
  1313. CompareLess = FALSE;
  1314. } else if (DoubleOperand2.MantissaLow <
  1315. DoubleOperand1.MantissaLow) {
  1316. CompareEqual = FALSE;
  1317. CompareLess = TRUE;
  1318. } else {
  1319. CompareEqual = TRUE;
  1320. CompareLess = FALSE;
  1321. }
  1322. }
  1323. }
  1324. }
  1325. }
  1326. //
  1327. // Form the condition code result value using the comparison
  1328. // information and the compare function codes.
  1329. //
  1330. switch (Function & FP_FUNCTION_MASK) {
  1331. case CMPTEQ_FUNC :
  1332. CompareResult = CompareEqual;
  1333. DBGPRINT2("cmpteq\n");
  1334. break;
  1335. case CMPTLE_FUNC :
  1336. CompareResult = (CompareLess | CompareEqual);
  1337. DBGPRINT2("cmptle\n");
  1338. break;
  1339. case CMPTLT_FUNC :
  1340. CompareResult = CompareLess;
  1341. DBGPRINT2("cmptlt\n");
  1342. break;
  1343. }
  1344. //
  1345. // Set the result operand to 2.0 if the comparison is true,
  1346. // otherwise store 0.0.
  1347. //
  1348. if (CompareResult != FALSE) {
  1349. KiSetRegisterValue(ContextBlock.Fc + 32,
  1350. FP_COMPARE_TRUE,
  1351. ExceptionFrame,
  1352. TrapFrame);
  1353. } else {
  1354. KiSetRegisterValue(ContextBlock.Fc + 32,
  1355. FP_COMPARE_FALSE,
  1356. ExceptionFrame,
  1357. TrapFrame);
  1358. }
  1359. return TRUE;
  1360. //
  1361. // Floating convert single to double.
  1362. //
  1363. // Floating conversion to double is accomplished by forming a
  1364. // double floating operand and then normalizing and storing
  1365. // the result value.
  1366. //
  1367. case CVTST_FUNC_PROPER :
  1368. DBGPRINT2("cvtst\n");
  1369. //
  1370. // If the operand is a NaN, then store a quiet NaN if the
  1371. // invalid operation trap is disabled, or raise an exception
  1372. // if the invalid operation trap is enabled and the operand
  1373. // is a signaling NaN.
  1374. //
  1375. if (SingleOperand1.Nan != FALSE) {
  1376. DoubleOperand1.MantissaHigh =
  1377. SingleOperand1.Mantissa >> (26 - (55 - 32));
  1378. DoubleOperand1.MantissaLow =
  1379. SingleOperand1.Mantissa << (32 - (26 - (55 - 32)));
  1380. DoubleOperand1.Exponent = DOUBLE_MAXIMUM_EXPONENT;
  1381. DoubleOperand1.Sign = SingleOperand1.Sign;
  1382. DoubleOperand1.Infinity = FALSE;
  1383. DoubleOperand1.Nan = TRUE;
  1384. return KiInvalidOperationDouble(&ContextBlock,
  1385. TRUE,
  1386. &DoubleOperand1,
  1387. &DoubleOperand1);
  1388. }
  1389. //
  1390. // Transform the single operand to double format.
  1391. //
  1392. DoubleOperand1.MantissaHigh =
  1393. SingleOperand1.Mantissa >> (26 - (55 - 32));
  1394. DoubleOperand1.MantissaLow =
  1395. SingleOperand1.Mantissa << (32 - (26 - (55 - 32)));
  1396. DoubleOperand1.Exponent = SingleOperand1.Exponent +
  1397. DOUBLE_EXPONENT_BIAS - SINGLE_EXPONENT_BIAS;
  1398. DoubleOperand1.Sign = SingleOperand1.Sign;
  1399. DoubleOperand1.Infinity = SingleOperand1.Infinity;
  1400. DoubleOperand1.Nan = FALSE;
  1401. //
  1402. // Normalize and store the result value.
  1403. //
  1404. return KiNormalizeDouble(&ContextBlock,
  1405. &DoubleOperand1,
  1406. 0);
  1407. //
  1408. // Floating convert double to single.
  1409. //
  1410. // Floating conversion to single is accomplished by forming a
  1411. // single floating operand and then normalizing and storing the
  1412. // result value.
  1413. //
  1414. case CVTTS_FUNC :
  1415. DBGPRINT2("cvtts\n");
  1416. //
  1417. // If the operand is a NaN, then store a quiet NaN if the
  1418. // invalid operation trap is disabled, or raise an exception
  1419. // if the invalid operation trap is enabled and the operand
  1420. // is a signaling NaN.
  1421. //
  1422. if (DoubleOperand1.Nan != FALSE) {
  1423. SingleOperand1.Mantissa =
  1424. (DoubleOperand1.MantissaHigh << (26 - (55 - 32))) |
  1425. (DoubleOperand1.MantissaLow >> (32 - (26 - (55 - 32))));
  1426. SingleOperand1.Exponent = SINGLE_MAXIMUM_EXPONENT;
  1427. SingleOperand1.Sign = DoubleOperand1.Sign;
  1428. SingleOperand1.Infinity = FALSE;
  1429. SingleOperand1.Nan = TRUE;
  1430. return KiInvalidOperationSingle(&ContextBlock,
  1431. TRUE,
  1432. &SingleOperand1,
  1433. &SingleOperand1);
  1434. }
  1435. //
  1436. // Transform the double operand to single format.
  1437. //
  1438. SingleOperand1.Mantissa =
  1439. (DoubleOperand1.MantissaHigh << (26 - (55 - 32))) |
  1440. (DoubleOperand1.MantissaLow >> (32 - (26 - (55 - 32))));
  1441. StickyBits = DoubleOperand1.MantissaLow << (26 - (55 - 32));
  1442. SingleOperand1.Exponent = DoubleOperand1.Exponent +
  1443. SINGLE_EXPONENT_BIAS - DOUBLE_EXPONENT_BIAS;
  1444. SingleOperand1.Sign = DoubleOperand1.Sign;
  1445. SingleOperand1.Infinity = DoubleOperand1.Infinity;
  1446. SingleOperand1.Nan = FALSE;
  1447. //
  1448. // Normalize and store the result value.
  1449. //
  1450. return KiNormalizeSingle(&ContextBlock,
  1451. &SingleOperand1,
  1452. StickyBits);
  1453. //
  1454. // Floating convert longword to quadword.
  1455. //
  1456. // Floating conversion from longword to quadword is accomplished by
  1457. // a repositioning of 32 bits of the operand, with sign extension.
  1458. //
  1459. case CVTLQ_FUNC :
  1460. DBGPRINT2("cvtlq\n");
  1461. //
  1462. // Pack floating register longword format into upper 32-bits
  1463. // by keeping bits 63..62 and 58..29, eliminating unused bits
  1464. // 61..59. Then right justify and sign extend the 32 bits into
  1465. // 64 bits.
  1466. //
  1467. Quadword = ((Quadword >> 62) << 62) | ((ULONGLONG)(Quadword << 5) >> 2);
  1468. KiSetRegisterValue(ContextBlock.Fc + 32,
  1469. Quadword >> 32,
  1470. ExceptionFrame,
  1471. TrapFrame);
  1472. return TRUE;
  1473. //
  1474. // Floating convert quadword to longword.
  1475. //
  1476. // Floating conversion from quadword to longword is accomplished by
  1477. // truncating the high order 32 bits of the quadword after checking
  1478. // for overflow.
  1479. //
  1480. case CVTQL_FUNC :
  1481. DBGPRINT2("cvtql\n");
  1482. return KiConvertQuadwordToLongword(&ContextBlock, Quadword);
  1483. //
  1484. // Floating convert quadword to single.
  1485. //
  1486. // Floating conversion to single is accomplished by forming a
  1487. // single floating operand and then normalizing and storing the
  1488. // result value.
  1489. //
  1490. case CVTQS_FUNC :
  1491. DBGPRINT2("cvtqs\n");
  1492. //
  1493. // Compute the sign of the result.
  1494. //
  1495. if (Quadword < 0) {
  1496. SingleOperand1.Sign = 0x1;
  1497. Quadword = -Quadword;
  1498. } else {
  1499. SingleOperand1.Sign = 0;
  1500. }
  1501. //
  1502. // Initialize the infinity and NaN values.
  1503. //
  1504. SingleOperand1.Infinity = FALSE;
  1505. SingleOperand1.Nan = FALSE;
  1506. //
  1507. // Compute the exponent value and normalize the quadword
  1508. // value.
  1509. //
  1510. if (Quadword != 0) {
  1511. SingleOperand1.Exponent = SINGLE_EXPONENT_BIAS + 63;
  1512. while (Quadword > 0) {
  1513. Quadword <<= 1;
  1514. SingleOperand1.Exponent -= 1;
  1515. }
  1516. SingleOperand1.Mantissa = (LONG)((ULONGLONG)Quadword >> (64 - 26));
  1517. if (Quadword & (((ULONGLONG)1 << (64 - 26)) - 1)) {
  1518. StickyBits = 1;
  1519. } else {
  1520. StickyBits = 0;
  1521. }
  1522. } else {
  1523. SingleOperand1.Exponent = 0;
  1524. SingleOperand1.Mantissa = 0;
  1525. StickyBits = 0;
  1526. }
  1527. //
  1528. // Normalize and store the result value.
  1529. //
  1530. return KiNormalizeSingle(&ContextBlock,
  1531. &SingleOperand1,
  1532. StickyBits);
  1533. //
  1534. // Floating convert quadword to double.
  1535. //
  1536. // Floating conversion to double is accomplished by forming a
  1537. // double floating operand and then normalizing and storing the
  1538. // result value.
  1539. //
  1540. case CVTQT_FUNC :
  1541. DBGPRINT2("cvtqt\n");
  1542. //
  1543. // Compute the sign of the result.
  1544. //
  1545. if (Quadword < 0) {
  1546. DoubleOperand1.Sign = 0x1;
  1547. Quadword = -Quadword;
  1548. } else {
  1549. DoubleOperand1.Sign = 0;
  1550. }
  1551. //
  1552. // Initialize the infinity and NaN values.
  1553. //
  1554. DoubleOperand1.Infinity = FALSE;
  1555. DoubleOperand1.Nan = FALSE;
  1556. //
  1557. // Compute the exponent value and normalize the quadword
  1558. // value.
  1559. //
  1560. if (Quadword != 0) {
  1561. DoubleOperand1.Exponent = DOUBLE_EXPONENT_BIAS + 63;
  1562. while (Quadword > 0) {
  1563. Quadword <<= 1;
  1564. DoubleOperand1.Exponent -= 1;
  1565. }
  1566. DoubleOperand1.MantissaHigh = (LONG)((ULONGLONG)Quadword >> ((64 - 55) + 32));
  1567. DoubleOperand1.MantissaLow = (LONG)((ULONGLONG)Quadword >> (64 - 55));
  1568. if (Quadword & (((ULONGLONG)1 << (64 - 55)) - 1)) {
  1569. StickyBits = 1;
  1570. } else {
  1571. StickyBits = 0;
  1572. }
  1573. } else {
  1574. DoubleOperand1.MantissaHigh = 0;
  1575. DoubleOperand1.MantissaLow = 0;
  1576. DoubleOperand1.Exponent = 0;
  1577. StickyBits = 0;
  1578. }
  1579. //
  1580. // Normalize and store the result value.
  1581. //
  1582. return KiNormalizeDouble(&ContextBlock,
  1583. &DoubleOperand1,
  1584. StickyBits);
  1585. //
  1586. // Floating convert double to quadword.
  1587. //
  1588. // Floating conversion to quadword is accomplished by forming
  1589. // a quadword value from a double floating value.
  1590. //
  1591. case CVTTQ_FUNC :
  1592. DBGPRINT2("cvttq\n");
  1593. //
  1594. // If the operand is infinite or is a NaN, then store a
  1595. // quiet NaN or an appropriate infinity if the invalid
  1596. // operation trap is disabled, or raise an exception if
  1597. // the invalid trap is enabled.
  1598. //
  1599. if ((DoubleOperand1.Infinity != FALSE) ||
  1600. (DoubleOperand1.Nan != FALSE)) {
  1601. return KiInvalidOperationQuadword(&ContextBlock, 0);
  1602. }
  1603. //
  1604. // Convert double to quadword and store the result value.
  1605. //
  1606. return KiNormalizeQuadword(&ContextBlock, &DoubleOperand1);
  1607. }
  1608. //
  1609. // If an exception occurs, then copy the new exception information to the
  1610. // original exception record and handle the exception.
  1611. //
  1612. } except (KiCopyInformation(ExceptionRecord,
  1613. (GetExceptionInformation())->ExceptionRecord)) {
  1614. //
  1615. // Preserve the original exception address.
  1616. //
  1617. ExceptionRecord->ExceptionAddress = ExceptionAddress;
  1618. DBGPRINT("KiEmulateFloating: Exception\n");
  1619. return FALSE;
  1620. }
  1621. DBGPRINT("KiEmulateFloating: Invalid Instruction\n");
  1622. return FALSE;
  1623. }
  1624. ULONGLONG
  1625. KiConvertSingleOperandToRegister (
  1626. IN ULONG SingleValue
  1627. )
  1628. /*++
  1629. Routine Description:
  1630. This function converts a 32-bit single format floating point value to
  1631. the 64-bit, double format used within floating point registers. Alpha
  1632. floating point registers are 64-bits wide and single format values are
  1633. transformed to 64-bits when stored or loaded from memory.
  1634. Arguments:
  1635. SingleValue - Supplies the 32-bit single operand value as an integer.
  1636. Return Value:
  1637. The 64-bit register format operand value is returned as the function
  1638. value.
  1639. --*/
  1640. {
  1641. PDOUBLE_FORMAT DoubleFormat;
  1642. ULONGLONG Result;
  1643. PSINGLE_FORMAT SingleFormat;
  1644. SingleFormat = (PSINGLE_FORMAT)&SingleValue;
  1645. DoubleFormat = (PDOUBLE_FORMAT)&Result;
  1646. DoubleFormat->Sign = SingleFormat->Sign;
  1647. DoubleFormat->Mantissa = ((ULONGLONG)SingleFormat->Mantissa) << (52 - 23);
  1648. if (SingleFormat->Exponent == SINGLE_MAXIMUM_EXPONENT) {
  1649. DoubleFormat->Exponent = DOUBLE_MAXIMUM_EXPONENT;
  1650. } else if (SingleFormat->Exponent == SINGLE_MINIMUM_EXPONENT) {
  1651. DoubleFormat->Exponent = DOUBLE_MINIMUM_EXPONENT;
  1652. } else {
  1653. DoubleFormat->Exponent = SingleFormat->Exponent - SINGLE_EXPONENT_BIAS +
  1654. DOUBLE_EXPONENT_BIAS;
  1655. }
  1656. return Result;
  1657. }
  1658. ULONG
  1659. KiConvertRegisterToSingleOperand (
  1660. IN ULONGLONG DoubleValue
  1661. )
  1662. /*++
  1663. Routine Description:
  1664. This function converts the 64-bit, double format floating point value
  1665. used within the floating point registers to a 32-bit, single format
  1666. floating point value.
  1667. Arguments:
  1668. DoubleValue - Supplies the 64-bit double operand value as an integer.
  1669. Return Value:
  1670. The 32-bit register format operand value is returned as the function
  1671. value.
  1672. --*/
  1673. {
  1674. PDOUBLE_FORMAT DoubleFormat;
  1675. ULONG Result;
  1676. PSINGLE_FORMAT SingleFormat;
  1677. SingleFormat = (PSINGLE_FORMAT)&Result;
  1678. DoubleFormat = (PDOUBLE_FORMAT)&DoubleValue;
  1679. SingleFormat->Sign = (ULONG)DoubleFormat->Sign;
  1680. SingleFormat->Mantissa = (ULONG)(DoubleFormat->Mantissa >> (52 - 23));
  1681. if (DoubleFormat->Exponent == DOUBLE_MAXIMUM_EXPONENT) {
  1682. SingleFormat->Exponent = SINGLE_MAXIMUM_EXPONENT;
  1683. } else if (DoubleFormat->Exponent == DOUBLE_MINIMUM_EXPONENT) {
  1684. SingleFormat->Exponent = SINGLE_MINIMUM_EXPONENT;
  1685. } else {
  1686. SingleFormat->Exponent = (ULONG)(DoubleFormat->Exponent - DOUBLE_EXPONENT_BIAS +
  1687. SINGLE_EXPONENT_BIAS);
  1688. }
  1689. return Result;
  1690. }
  1691. BOOLEAN
  1692. KiConvertQuadwordToLongword (
  1693. IN PFP_CONTEXT_BLOCK ContextBlock,
  1694. IN LONGLONG Quadword
  1695. )
  1696. /*++
  1697. Routine Description:
  1698. This function is called to convert a quadword operand to a longword
  1699. result.
  1700. Arguments:
  1701. ContextBlock - Supplies a pointer to the emulation context block.
  1702. Operand - Supplies the quadword operand value.
  1703. Return Value:
  1704. If the quadword value would overflow the longword result and the invalid
  1705. trap is enabled then a value of FALSE is returned. Otherwise, the quadword
  1706. is truncated to a longword and a value of TRUE is returned.
  1707. --*/
  1708. {
  1709. PEXCEPTION_RECORD ExceptionRecord;
  1710. PFPCR Fpcr;
  1711. PFP_IEEE_VALUE IeeeValue;
  1712. ULONGLONG ResultValue;
  1713. PSW_FPCR SoftwareFpcr;
  1714. //
  1715. // Truncate the quadword to a longword and convert the longword integer
  1716. // to floating register longword integer format.
  1717. //
  1718. ResultValue = ((Quadword & (ULONGLONG)0xc0000000) << 32) |
  1719. ((Quadword & (ULONGLONG)0x3fffffff) << 29);
  1720. //
  1721. // Check to determine if an exception should be delivered or the result
  1722. // should be written to the destination register.
  1723. //
  1724. if ((Quadword < (LONG)0x80000000) || (Quadword > (LONG)0x7fffffff)) {
  1725. Fpcr = (PFPCR)&ContextBlock->TrapFrame->Fpcr;
  1726. Fpcr->InvalidOperation = 1;
  1727. Fpcr->SummaryBit = 1;
  1728. if (ContextBlock->IeeeMode == FALSE) {
  1729. ExceptionRecord = ContextBlock->ExceptionRecord;
  1730. ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
  1731. return FALSE;
  1732. }
  1733. SoftwareFpcr = ContextBlock->SoftwareFpcr;
  1734. SoftwareFpcr->StatusInvalid = 1;
  1735. if (SoftwareFpcr->EnableInvalid != 0) {
  1736. ExceptionRecord = ContextBlock->ExceptionRecord;
  1737. ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
  1738. IeeeValue = KiInitializeIeeeValue(ExceptionRecord);
  1739. IeeeValue->Value.U64Value.LowPart = LOW_PART(ResultValue);
  1740. IeeeValue->Value.U64Value.HighPart = HIGH_PART(ResultValue);
  1741. return FALSE;
  1742. }
  1743. Fpcr->DisableInvalid = 1;
  1744. }
  1745. //
  1746. // Set the destination register value and return a value of TRUE.
  1747. //
  1748. KiSetRegisterValue(ContextBlock->Fc + 32,
  1749. ResultValue,
  1750. ContextBlock->ExceptionFrame,
  1751. ContextBlock->TrapFrame);
  1752. return TRUE;
  1753. }
  1754. BOOLEAN
  1755. KiDivideByZeroDouble (
  1756. IN PFP_CONTEXT_BLOCK ContextBlock,
  1757. IN PFP_DOUBLE_OPERAND DoubleOperand1,
  1758. IN PFP_DOUBLE_OPERAND DoubleOperand2
  1759. )
  1760. /*++
  1761. Routine Description:
  1762. This function is called to either raise an exception or store a
  1763. quiet NaN or properly signed infinity for a divide by zero double
  1764. floating operation.
  1765. Arguments:
  1766. ContextBlock - Supplies a pointer to the emulation context block.
  1767. DoubleOperand1 - Supplies a pointer to the first operand value.
  1768. DoubleOperand2 - Supplies a pointer ot the second operand value.
  1769. Return Value:
  1770. If the divide by zero trap is enabled and the dividend is not infinite,
  1771. then a value of FALSE is returned. Otherwise, a quiet NaN or a properly
  1772. signed infinity is stored as the destination result and a value of TRUE
  1773. is returned.
  1774. --*/
  1775. {
  1776. PEXCEPTION_RECORD ExceptionRecord;
  1777. PFPCR Fpcr;
  1778. PFP_IEEE_VALUE IeeeValue;
  1779. ULONG ResultSign;
  1780. ULONG ResultValueHigh;
  1781. ULONG ResultValueLow;
  1782. PSW_FPCR SoftwareFpcr;
  1783. //
  1784. // The result value is a properly signed infinity.
  1785. //
  1786. ResultSign = DoubleOperand1->Sign ^ DoubleOperand2->Sign;
  1787. ResultValueHigh = DOUBLE_INFINITY_VALUE_HIGH | (ResultSign << 31);
  1788. ResultValueLow = DOUBLE_INFINITY_VALUE_LOW;
  1789. //
  1790. // If the first operand is not infinite and the divide by zero trap is
  1791. // enabled, then store the proper exception code and exception flags
  1792. // and return a value of FALSE. Otherwise, store the appropriately signed
  1793. // infinity and return a value of TRUE.
  1794. //
  1795. if (DoubleOperand1->Infinity == FALSE) {
  1796. Fpcr = (PFPCR)&ContextBlock->TrapFrame->Fpcr;
  1797. Fpcr->DivisionByZero = 1;
  1798. Fpcr->SummaryBit = 1;
  1799. if (ContextBlock->IeeeMode == FALSE) {
  1800. ExceptionRecord = ContextBlock->ExceptionRecord;
  1801. ExceptionRecord->ExceptionCode = STATUS_FLOAT_DIVIDE_BY_ZERO;
  1802. return FALSE;
  1803. }
  1804. SoftwareFpcr = ContextBlock->SoftwareFpcr;
  1805. SoftwareFpcr->StatusDivisionByZero = 1;
  1806. if (SoftwareFpcr->EnableDivisionByZero != 0) {
  1807. ExceptionRecord = ContextBlock->ExceptionRecord;
  1808. ExceptionRecord->ExceptionCode = STATUS_FLOAT_DIVIDE_BY_ZERO;
  1809. IeeeValue = KiInitializeIeeeValue(ExceptionRecord);
  1810. IeeeValue->Value.Fp64Value.W[0] = ResultValueLow;
  1811. IeeeValue->Value.Fp64Value.W[1] = ResultValueHigh;
  1812. return FALSE;
  1813. }
  1814. Fpcr->DisableDivisionByZero = 1;
  1815. }
  1816. KiSetRegisterValue(ContextBlock->Fc + 32,
  1817. MAKE_QUAD(ResultValueLow, ResultValueHigh),
  1818. ContextBlock->ExceptionFrame,
  1819. ContextBlock->TrapFrame);
  1820. return TRUE;
  1821. }
  1822. BOOLEAN
  1823. KiDivideByZeroSingle (
  1824. IN PFP_CONTEXT_BLOCK ContextBlock,
  1825. IN PFP_SINGLE_OPERAND SingleOperand1,
  1826. IN PFP_SINGLE_OPERAND SingleOperand2
  1827. )
  1828. /*++
  1829. Routine Description:
  1830. This function is called to either raise an exception or store a
  1831. quiet NaN or properly signed infinity for a divide by zero single
  1832. floating operation.
  1833. Arguments:
  1834. ContextBlock - Supplies a pointer to the emulation context block.
  1835. SingleOperand1 - Supplies a pointer to the first operand value.
  1836. SingleOperand2 - Supplies a pointer ot the second operand value.
  1837. Return Value:
  1838. If the divide by zero trap is enabled and the dividend is not infinite,
  1839. then a value of FALSE is returned. Otherwise, a quiet NaN or a properly
  1840. signed infinity is stored as the destination result and a value of TRUE
  1841. is returned.
  1842. --*/
  1843. {
  1844. PEXCEPTION_RECORD ExceptionRecord;
  1845. PFPCR Fpcr;
  1846. PFP_IEEE_VALUE IeeeValue;
  1847. ULONG ResultSign;
  1848. ULONG ResultValue;
  1849. PSW_FPCR SoftwareFpcr;
  1850. //
  1851. // The result value is a properly signed infinity.
  1852. //
  1853. ResultSign = SingleOperand1->Sign ^ SingleOperand2->Sign;
  1854. ResultValue = SINGLE_INFINITY_VALUE | (ResultSign << 31);
  1855. //
  1856. // If the first operand is not infinite and the divide by zero trap is
  1857. // enabled, then store the proper exception code and exception flags
  1858. // and return a value of FALSE. Otherwise, store the appropriately signed
  1859. // infinity and return a value of TRUE.
  1860. //
  1861. if (SingleOperand1->Infinity == FALSE) {
  1862. Fpcr = (PFPCR)&ContextBlock->TrapFrame->Fpcr;
  1863. Fpcr->DivisionByZero = 1;
  1864. Fpcr->SummaryBit = 1;
  1865. if (ContextBlock->IeeeMode == FALSE) {
  1866. ExceptionRecord = ContextBlock->ExceptionRecord;
  1867. ExceptionRecord->ExceptionCode = STATUS_FLOAT_DIVIDE_BY_ZERO;
  1868. return FALSE;
  1869. }
  1870. SoftwareFpcr = ContextBlock->SoftwareFpcr;
  1871. SoftwareFpcr->StatusDivisionByZero = 1;
  1872. if (SoftwareFpcr->EnableDivisionByZero != 0) {
  1873. ExceptionRecord = ContextBlock->ExceptionRecord;
  1874. ExceptionRecord->ExceptionCode = STATUS_FLOAT_DIVIDE_BY_ZERO;
  1875. IeeeValue = KiInitializeIeeeValue(ExceptionRecord);
  1876. IeeeValue->Value.Fp32Value.W[0] = ResultValue;
  1877. return FALSE;
  1878. }
  1879. Fpcr->DisableDivisionByZero = 1;
  1880. }
  1881. KiSetRegisterValue(ContextBlock->Fc + 32,
  1882. KiConvertSingleOperandToRegister(ResultValue),
  1883. ContextBlock->ExceptionFrame,
  1884. ContextBlock->TrapFrame);
  1885. return TRUE;
  1886. }
  1887. PFP_IEEE_VALUE
  1888. KiInitializeIeeeValue (
  1889. IN PEXCEPTION_RECORD ExceptionRecord
  1890. )
  1891. /*++
  1892. Routine Description:
  1893. This function is called to initialize an IEEE exception record.
  1894. N.B. The original hardware exception record should be overwritten with an
  1895. IEEE exception record only when it is known for certain that an IEEE
  1896. exception must be generated.
  1897. Arguments:
  1898. ExceptionRecord - Supplies a pointer to the exception record.
  1899. Return Value:
  1900. The address of the IEEE value portion of the exception record is returned
  1901. as the function value.
  1902. --*/
  1903. {
  1904. //
  1905. // Initialize the number of exception information parameters, zero
  1906. // the first parameter to indicate a hardware initiated exception,
  1907. // set the continuation address, and clear the IEEE exception value.
  1908. //
  1909. ExceptionRecord->NumberParameters = 6;
  1910. ExceptionRecord->ExceptionInformation[0] = 0;
  1911. ExceptionRecord->ExceptionInformation[1] =
  1912. ((ULONG_PTR)(ExceptionRecord)->ExceptionAddress) + 4;
  1913. ExceptionRecord->ExceptionInformation[2] = 0;
  1914. ExceptionRecord->ExceptionInformation[3] = 0;
  1915. ExceptionRecord->ExceptionInformation[4] = 0;
  1916. ExceptionRecord->ExceptionInformation[5] = 0;
  1917. //
  1918. // Return address of IEEE exception value.
  1919. //
  1920. return (PFP_IEEE_VALUE)&ExceptionRecord->ExceptionInformation[2];
  1921. }
  1922. BOOLEAN
  1923. KiInvalidCompareDouble (
  1924. IN PFP_CONTEXT_BLOCK ContextBlock,
  1925. IN BOOLEAN CheckForSignalNan,
  1926. IN PFP_DOUBLE_OPERAND DoubleOperand1,
  1927. IN PFP_DOUBLE_OPERAND DoubleOperand2
  1928. )
  1929. /*++
  1930. Routine Description:
  1931. This function is called to determine whether an invalid operation
  1932. exception should be raised for a double compare operation.
  1933. Arguments:
  1934. ContextBlock - Supplies a pointer to the emulation context block.
  1935. CheckForSignalNan - Supplies a boolean value that determines whether the
  1936. operand values should be checked for a signaling NaN.
  1937. DoubleOperand1 - Supplies a pointer to the first operand value.
  1938. DoubleOperand2 - Supplies a pointer ot the second operand value.
  1939. Return Value:
  1940. If the invalid operation trap is enabled and either the operation is
  1941. invalid or one of the operands in a signaling NaN, then a value of
  1942. FALSE is returned. Otherwise, no operation is performed and a value
  1943. of TRUE is returned.
  1944. --*/
  1945. {
  1946. PEXCEPTION_RECORD ExceptionRecord;
  1947. PFPCR Fpcr;
  1948. PFP_IEEE_VALUE IeeeValue;
  1949. PSW_FPCR SoftwareFpcr;
  1950. //
  1951. // If an invalid operation is specified or one of the operands is a
  1952. // signaling NaN and the invalid operation trap is enabled, then
  1953. // store the proper exception code and exception flags and return
  1954. // a value of FALSE. Otherwise, perform no operation and return a
  1955. // value of TRUE.
  1956. //
  1957. if ((CheckForSignalNan == FALSE) ||
  1958. (DoubleSignalNan(DoubleOperand1) != FALSE) ||
  1959. (DoubleSignalNan(DoubleOperand2) != FALSE)) {
  1960. Fpcr = (PFPCR)&ContextBlock->TrapFrame->Fpcr;
  1961. Fpcr->InvalidOperation = 1;
  1962. Fpcr->SummaryBit = 1;
  1963. if (ContextBlock->IeeeMode == FALSE) {
  1964. ExceptionRecord = ContextBlock->ExceptionRecord;
  1965. ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
  1966. return FALSE;
  1967. }
  1968. SoftwareFpcr = ContextBlock->SoftwareFpcr;
  1969. SoftwareFpcr->StatusInvalid = 1;
  1970. if (SoftwareFpcr->EnableInvalid != 0) {
  1971. ExceptionRecord = ContextBlock->ExceptionRecord;
  1972. ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
  1973. IeeeValue = KiInitializeIeeeValue(ExceptionRecord);
  1974. IeeeValue->Value.CompareValue = FpCompareUnordered;
  1975. return FALSE;
  1976. }
  1977. Fpcr->DisableInvalid = 1;
  1978. }
  1979. return TRUE;
  1980. }
  1981. BOOLEAN
  1982. KiInvalidOperationDouble (
  1983. IN PFP_CONTEXT_BLOCK ContextBlock,
  1984. IN BOOLEAN CheckForSignalNan,
  1985. IN PFP_DOUBLE_OPERAND DoubleOperand1,
  1986. IN PFP_DOUBLE_OPERAND DoubleOperand2
  1987. )
  1988. /*++
  1989. Routine Description:
  1990. This function is called to either raise an exception or store a
  1991. quiet NaN for an invalid double floating operation.
  1992. Arguments:
  1993. ContextBlock - Supplies a pointer to the emulation context block.
  1994. CheckForSignalNan - Supplies a boolean value that determines whether the
  1995. operand values should be checked for a signaling NaN.
  1996. DoubleOperand1 - Supplies a pointer to the first operand value.
  1997. DoubleOperand2 - Supplies a pointer ot the second operand value.
  1998. Return Value:
  1999. If the invalid operation trap is enabled and either the operation is
  2000. invalid or one of the operands in a signaling NaN, then a value of
  2001. FALSE is returned. Otherwise, a quiet NaN is stored as the destination
  2002. result and a value of TRUE is returned.
  2003. --*/
  2004. {
  2005. PEXCEPTION_RECORD ExceptionRecord;
  2006. PFPCR Fpcr;
  2007. PFP_IEEE_VALUE IeeeValue;
  2008. ULONG ResultValueHigh;
  2009. ULONG ResultValueLow;
  2010. PSW_FPCR SoftwareFpcr;
  2011. //
  2012. // If the second operand is a NaN, then compute a quiet NaN from its
  2013. // value. Otherwise, if the first operand is a NaN, then compute a
  2014. // quiet NaN from its value. Otherwise, the result value is a quiet
  2015. // (real indefinite) NaN.
  2016. //
  2017. DBGPRINT("Operand1: Inf=%d NaN=%d Sign=%d Exponent=%d Mantissa=%.8x%.8x\n",
  2018. DoubleOperand1->Infinity, DoubleOperand1->Nan,
  2019. DoubleOperand1->Sign,
  2020. DoubleOperand1->Exponent,
  2021. DoubleOperand1->MantissaHigh, DoubleOperand1->MantissaLow);
  2022. DBGPRINT("Operand2: Inf=%d NaN=%d Sign=%d Exponent=%d Mantissa=%.8x%.8x\n",
  2023. DoubleOperand2->Infinity, DoubleOperand2->Nan,
  2024. DoubleOperand2->Sign,
  2025. DoubleOperand2->Exponent,
  2026. DoubleOperand2->MantissaHigh, DoubleOperand2->MantissaLow);
  2027. if (DoubleOperand2->Nan != FALSE) {
  2028. ResultValueLow = DoubleOperand2->MantissaLow >> 2;
  2029. ResultValueLow |= DoubleOperand2->MantissaHigh << 30;
  2030. ResultValueHigh = DoubleOperand2->MantissaHigh >> 2;
  2031. ResultValueHigh |= DOUBLE_QUIET_NAN_PREFIX_HIGH;
  2032. ResultValueHigh |= DoubleOperand2->Sign << 31;
  2033. } else if (DoubleOperand1->Nan != FALSE) {
  2034. ResultValueLow = DoubleOperand1->MantissaLow >> 2;
  2035. ResultValueLow |= DoubleOperand1->MantissaHigh << 30;
  2036. ResultValueHigh = DoubleOperand1->MantissaHigh >> 2;
  2037. ResultValueHigh |= DOUBLE_QUIET_NAN_PREFIX_HIGH;
  2038. ResultValueHigh |= DoubleOperand1->Sign << 31;
  2039. } else {
  2040. ResultValueLow = DOUBLE_QUIET_NAN_VALUE_LOW;
  2041. ResultValueHigh = DOUBLE_QUIET_NAN_VALUE_HIGH;
  2042. }
  2043. //
  2044. // If an invalid operation is specified or one of the operands is a
  2045. // signaling NaN and the invalid operation trap is enabled, then
  2046. // store the proper exception code and exception flags and return
  2047. // a value of FALSE. Otherwise, store a quiet NaN as the destination
  2048. // result and return a value of TRUE.
  2049. //
  2050. if ((CheckForSignalNan == FALSE) ||
  2051. (DoubleSignalNan(DoubleOperand1) != FALSE) ||
  2052. (DoubleSignalNan(DoubleOperand2) != FALSE)) {
  2053. Fpcr = (PFPCR)&ContextBlock->TrapFrame->Fpcr;
  2054. Fpcr->InvalidOperation = 1;
  2055. Fpcr->SummaryBit = 1;
  2056. if (ContextBlock->IeeeMode == FALSE) {
  2057. ExceptionRecord = ContextBlock->ExceptionRecord;
  2058. ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
  2059. return FALSE;
  2060. }
  2061. SoftwareFpcr = ContextBlock->SoftwareFpcr;
  2062. SoftwareFpcr->StatusInvalid = 1;
  2063. if (SoftwareFpcr->EnableInvalid != 0) {
  2064. ExceptionRecord = ContextBlock->ExceptionRecord;
  2065. ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
  2066. IeeeValue = KiInitializeIeeeValue(ExceptionRecord);
  2067. IeeeValue->Value.Fp64Value.W[0] = ResultValueLow;
  2068. IeeeValue->Value.Fp64Value.W[1] = ResultValueHigh;
  2069. return FALSE;
  2070. }
  2071. Fpcr->DisableInvalid = 1;
  2072. }
  2073. KiSetRegisterValue(ContextBlock->Fc + 32,
  2074. MAKE_QUAD(ResultValueLow, ResultValueHigh),
  2075. ContextBlock->ExceptionFrame,
  2076. ContextBlock->TrapFrame);
  2077. return TRUE;
  2078. }
  2079. BOOLEAN
  2080. KiInvalidOperationQuadword (
  2081. IN PFP_CONTEXT_BLOCK ContextBlock,
  2082. IN ULONGLONG ResultValue
  2083. )
  2084. /*++
  2085. Routine Description:
  2086. This function is called to either raise an exception or store a
  2087. quiet NaN for an invalid conversion to quadword.
  2088. Arguments:
  2089. ContextBlock - Supplies a pointer to the emulation context block.
  2090. ResultValue - Suplies a quadword result value to be stored.
  2091. Return Value:
  2092. If the invalid operation trap is enabled, then a value of FALSE is
  2093. returned. Otherwise, an appropriate quadword value is stored as the
  2094. destination result and a value of TRUE is returned.
  2095. --*/
  2096. {
  2097. PEXCEPTION_RECORD ExceptionRecord;
  2098. PFPCR Fpcr;
  2099. PFP_IEEE_VALUE IeeeValue;
  2100. PSW_FPCR SoftwareFpcr;
  2101. //
  2102. // If the invalid operation trap is enabled then store the proper
  2103. // exception code and exception flags and return a value of FALSE.
  2104. // Otherwise, store a quiet NaN as the destination result and return
  2105. // a value of TRUE.
  2106. //
  2107. Fpcr = (PFPCR)&ContextBlock->TrapFrame->Fpcr;
  2108. Fpcr->InvalidOperation = 1;
  2109. Fpcr->SummaryBit = 1;
  2110. if (ContextBlock->IeeeMode == FALSE) {
  2111. ExceptionRecord = ContextBlock->ExceptionRecord;
  2112. ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
  2113. return FALSE;
  2114. }
  2115. SoftwareFpcr = ContextBlock->SoftwareFpcr;
  2116. SoftwareFpcr->StatusInvalid = 1;
  2117. if (SoftwareFpcr->EnableInvalid != 0) {
  2118. ExceptionRecord = ContextBlock->ExceptionRecord;
  2119. ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
  2120. IeeeValue = KiInitializeIeeeValue(ExceptionRecord);
  2121. IeeeValue->Value.U64Value.LowPart = LOW_PART(ResultValue);
  2122. IeeeValue->Value.U64Value.HighPart = HIGH_PART(ResultValue);
  2123. return FALSE;
  2124. }
  2125. Fpcr->DisableInvalid = 1;
  2126. KiSetRegisterValue(ContextBlock->Fc + 32,
  2127. ResultValue,
  2128. ContextBlock->ExceptionFrame,
  2129. ContextBlock->TrapFrame);
  2130. return TRUE;
  2131. }
  2132. BOOLEAN
  2133. KiInvalidOperationSingle (
  2134. IN PFP_CONTEXT_BLOCK ContextBlock,
  2135. IN BOOLEAN CheckForSignalNan,
  2136. IN PFP_SINGLE_OPERAND SingleOperand1,
  2137. IN PFP_SINGLE_OPERAND SingleOperand2
  2138. )
  2139. /*++
  2140. Routine Description:
  2141. This function is called to either raise an exception or store a
  2142. quiet NaN for an invalid single floating operation.
  2143. Arguments:
  2144. ContextBlock - Supplies a pointer to the emulation context block.
  2145. CheckForSignalNan - Supplies a boolean value that determines whether the
  2146. operand values should be checked for a signaling NaN.
  2147. SingleOperand1 - Supplies a pointer to the first operand value.
  2148. SingleOperand2 - Supplies a pointer ot the second operand value.
  2149. Return Value:
  2150. If the invalid operation trap is enabled and either the operation is
  2151. invalid or one of the operands in a signaling NaN, then a value of
  2152. FALSE is returned. Otherwise, a quiet NaN is stored as the destination
  2153. result and a value of TRUE is returned.
  2154. --*/
  2155. {
  2156. PEXCEPTION_RECORD ExceptionRecord;
  2157. PFPCR Fpcr;
  2158. PFP_IEEE_VALUE IeeeValue;
  2159. ULONG ResultValue;
  2160. PSW_FPCR SoftwareFpcr;
  2161. //
  2162. // If the second operand is a NaN, then compute a quiet NaN from its
  2163. // value. Otherwise, if the first operand is a NaN, then compute a
  2164. // quiet NaN from its value. Otherwise, the result value is a quiet
  2165. // (real indefinite) NaN.
  2166. //
  2167. if (SingleOperand2->Nan != FALSE) {
  2168. ResultValue = SingleOperand2->Mantissa >> 2;
  2169. ResultValue |= SINGLE_QUIET_NAN_PREFIX;
  2170. ResultValue |= SingleOperand2->Sign << 31;
  2171. } else if (SingleOperand1->Nan != FALSE) {
  2172. ResultValue = SingleOperand1->Mantissa >> 2;
  2173. ResultValue |= SINGLE_QUIET_NAN_PREFIX;
  2174. ResultValue |= SingleOperand1->Sign << 31;
  2175. } else {
  2176. ResultValue = SINGLE_QUIET_NAN_VALUE;
  2177. }
  2178. //
  2179. // If an invalid operation is specified or one of the operands is a
  2180. // signaling NaN and the invalid operation trap is enabled, then
  2181. // store the proper exception code and exception flags and return
  2182. // a value of FALSE. Otherwise, store a quiet NaN as the destination
  2183. // result and return a value of TRUE.
  2184. //
  2185. if ((CheckForSignalNan == FALSE) ||
  2186. (SingleSignalNan(SingleOperand1) != FALSE) ||
  2187. (SingleSignalNan(SingleOperand2) != FALSE)) {
  2188. Fpcr = (PFPCR)&ContextBlock->TrapFrame->Fpcr;
  2189. Fpcr->InvalidOperation = 1;
  2190. Fpcr->SummaryBit = 1;
  2191. if (ContextBlock->IeeeMode == FALSE) {
  2192. ExceptionRecord = ContextBlock->ExceptionRecord;
  2193. ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
  2194. return FALSE;
  2195. }
  2196. SoftwareFpcr = ContextBlock->SoftwareFpcr;
  2197. SoftwareFpcr->StatusInvalid = 1;
  2198. if (SoftwareFpcr->EnableInvalid != 0) {
  2199. ExceptionRecord = ContextBlock->ExceptionRecord;
  2200. ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
  2201. IeeeValue = KiInitializeIeeeValue(ExceptionRecord);
  2202. IeeeValue->Value.Fp32Value.W[0] = ResultValue;
  2203. return FALSE;
  2204. }
  2205. Fpcr->DisableInvalid = 1;
  2206. }
  2207. KiSetRegisterValue(ContextBlock->Fc + 32,
  2208. KiConvertSingleOperandToRegister(ResultValue),
  2209. ContextBlock->ExceptionFrame,
  2210. ContextBlock->TrapFrame);
  2211. return TRUE;
  2212. }
  2213. BOOLEAN
  2214. KiNormalizeDouble (
  2215. IN PFP_CONTEXT_BLOCK ContextBlock,
  2216. IN PFP_DOUBLE_OPERAND ResultOperand,
  2217. IN ULONGLONG StickyBits
  2218. )
  2219. /*++
  2220. Routine Description:
  2221. This function is called to normalize a double floating result.
  2222. N.B. The result value is specified with a guard bit on the right,
  2223. the hidden bit (if appropriate), and a possible overflow bit.
  2224. The result format is:
  2225. <63:56> - zero
  2226. <55> - overflow bit
  2227. <54> - hidden bit
  2228. <53:2> - mantissa
  2229. <1> - guard bit
  2230. <0> - round bit
  2231. The sticky bits specify bits that were lost during the computation.
  2232. Arguments:
  2233. ContextBlock - Supplies a pointer to the emulation context block.
  2234. ResultOperand - Supplies a pointer to the result operand value.
  2235. StickyBits - Supplies the value of the sticky bits.
  2236. Return Value:
  2237. If there is not an exception, or the exception is handled, then a proper
  2238. result is stored in the destination result, the continuation address is
  2239. set, and a value of TRUE is returned. Otherwise, a proper value is stored and
  2240. a value of FALSE is returned.
  2241. --*/
  2242. {
  2243. ULONGLONG DenormalizeShift;
  2244. PEXCEPTION_RECORD ExceptionRecord;
  2245. ULONGLONG ExceptionResult;
  2246. PFPCR Fpcr;
  2247. PFP_IEEE_VALUE IeeeValue;
  2248. BOOLEAN Inexact;
  2249. ULONGLONG Mantissa;
  2250. BOOLEAN Overflow;
  2251. ULONGLONG ResultValue;
  2252. ULONG RoundBit;
  2253. PSW_FPCR SoftwareFpcr;
  2254. BOOLEAN Underflow;
  2255. ULONGLONG ResultStickyBits;
  2256. ULONGLONG ResultMantissa;
  2257. ULONG ResultRoundBit;
  2258. LONG ResultExponent;
  2259. BOOLEAN ReturnValue = TRUE;
  2260. //
  2261. // If the result is infinite, then store a properly signed infinity
  2262. // in the destination register and return a value of TRUE. Otherwise,
  2263. // round and normalize the result and check for overflow and underflow.
  2264. //
  2265. DBGPRINT("KiNormalizeDouble: Inf=%d NaN=%d Sign=%d Exponent=%d Mantissa=%.8x%.8x\n",
  2266. ResultOperand->Infinity, ResultOperand->Nan, ResultOperand->Sign,
  2267. ResultOperand->Exponent,
  2268. ResultOperand->MantissaHigh, ResultOperand->MantissaLow);
  2269. DBGPRINT("KiNormalizeDouble: StickyBits=%.16Lx\n", StickyBits);
  2270. if (ResultOperand->Infinity != FALSE) {
  2271. KiSetRegisterValue(ContextBlock->Fc + 32,
  2272. MAKE_QUAD(DOUBLE_INFINITY_VALUE_LOW,
  2273. DOUBLE_INFINITY_VALUE_HIGH |
  2274. (ResultOperand->Sign << 31)),
  2275. ContextBlock->ExceptionFrame,
  2276. ContextBlock->TrapFrame);
  2277. return TRUE;
  2278. }
  2279. Mantissa = MAKE_QUAD(ResultOperand->MantissaLow,
  2280. ResultOperand->MantissaHigh);
  2281. Fpcr = (PFPCR)&ContextBlock->TrapFrame->Fpcr;
  2282. SoftwareFpcr = ContextBlock->SoftwareFpcr;
  2283. //
  2284. // If the overflow bit is set, then right shift the mantissa one bit,
  2285. // accumulate the lost bit with the sticky bits, and adjust the exponent
  2286. // value.
  2287. //
  2288. if ((Mantissa & ((ULONGLONG)1 << 55)) != 0) {
  2289. StickyBits |= (Mantissa & 0x1);
  2290. Mantissa >>= 1;
  2291. ResultOperand->Exponent += 1;
  2292. }
  2293. //
  2294. // If the mantissa is nonzero, then normalize the mantissa by left
  2295. // shifting one bit at a time until there is a one bit in bit 54.
  2296. //
  2297. if (Mantissa != 0) {
  2298. while ((Mantissa & ((ULONGLONG)1 << 54)) == 0) {
  2299. Mantissa <<= 1;
  2300. ResultOperand->Exponent -= 1;
  2301. }
  2302. }
  2303. //
  2304. // Right shift the mantissa two bits, set the round bit, and accumulate
  2305. // the other lost bit with the sticky bits.
  2306. //
  2307. StickyBits |= (Mantissa & 0x1);
  2308. RoundBit = (ULONG)(Mantissa & 0x2);
  2309. Mantissa >>= 2;
  2310. //
  2311. // Convert to denormal format before rounding to allow underflow to
  2312. // be detected on rounded result. Save context to calculate IEEE
  2313. // exception record, if needed.
  2314. //
  2315. if (ResultOperand->Exponent <= DOUBLE_MINIMUM_EXPONENT && Mantissa != 0) {
  2316. //
  2317. // Save everything needed for calculating IEEE exception record value
  2318. //
  2319. ResultMantissa = Mantissa;
  2320. ResultExponent = ResultOperand->Exponent;
  2321. ResultStickyBits = StickyBits;
  2322. ResultRoundBit = RoundBit;
  2323. //
  2324. // Right shift the mantissa to set the minimum exponent plus an extra
  2325. // bit for the denormal format
  2326. //
  2327. DenormalizeShift = 1 - ResultOperand->Exponent;
  2328. //
  2329. // The maximum denormal shift is 52 bits for the mantissa plus 1 bit for the round
  2330. // A denormal shift of 54 guarantees 0 mantissa and 0 round bit and preserves all sticky bits
  2331. //
  2332. if (DenormalizeShift > 54) {
  2333. DenormalizeShift = 54;
  2334. }
  2335. //
  2336. // The denormalized result will be rounded after it is
  2337. // shifted. Preserve existing Round and Sticky Bits.
  2338. //
  2339. StickyBits |= RoundBit;
  2340. StickyBits |= (Mantissa << 1) << (64 - DenormalizeShift);
  2341. RoundBit = (ULONG)(Mantissa >> (DenormalizeShift - 1)) & 1;
  2342. Mantissa = Mantissa >> DenormalizeShift;
  2343. ResultOperand->Exponent = DOUBLE_MINIMUM_EXPONENT;
  2344. }
  2345. //
  2346. // Round the result value using the mantissa, the round bit, and the sticky bits.
  2347. //
  2348. switch (ContextBlock->Round) {
  2349. //
  2350. // Round to nearest representable number.
  2351. //
  2352. case ROUND_TO_NEAREST:
  2353. if (RoundBit != 0) {
  2354. if ((StickyBits != 0) || ((Mantissa & 0x1) != 0)) {
  2355. Mantissa += 1;
  2356. }
  2357. }
  2358. break;
  2359. //
  2360. // Round toward zero.
  2361. //
  2362. case ROUND_TO_ZERO:
  2363. break;
  2364. //
  2365. // Round toward plus infinity.
  2366. //
  2367. case ROUND_TO_PLUS_INFINITY:
  2368. if ((ResultOperand->Sign == 0) &&
  2369. ((StickyBits != 0) || (RoundBit != 0))) {
  2370. Mantissa += 1;
  2371. }
  2372. break;
  2373. //
  2374. // Round toward minus infinity.
  2375. //
  2376. case ROUND_TO_MINUS_INFINITY:
  2377. if ((ResultOperand->Sign != 0) &&
  2378. ((StickyBits != 0) || (RoundBit != 0))) {
  2379. Mantissa += 1;
  2380. }
  2381. break;
  2382. }
  2383. //
  2384. // If rounding resulted in a carry into bit 53, then right shift the
  2385. // mantissa one bit and adjust the exponent.
  2386. //
  2387. if ((Mantissa & ((ULONGLONG)1 << 53)) != 0) {
  2388. Mantissa >>= 1;
  2389. ResultOperand->Exponent += 1;
  2390. }
  2391. //
  2392. // If rounding resulted in a carry into bit 52 in denormal format, then
  2393. // adjust the exponent.
  2394. //
  2395. if ((ResultOperand->Exponent == DOUBLE_MINIMUM_EXPONENT) &&
  2396. (Mantissa & ((ULONGLONG)1 << 52)) != 0) {
  2397. ResultOperand->Exponent += 1;
  2398. }
  2399. //
  2400. // If the exponent value is greater than or equal to the maximum
  2401. // exponent value, then overflow has occurred. This results in both
  2402. // the inexact and overflow sticky bits being set in the FPCR.
  2403. //
  2404. // If the exponent value is less than or equal to the minimum exponent
  2405. // value, the mantissa is nonzero, and the denormalized result is inexact,
  2406. // then underflow has occurred. This results in both the inexact and
  2407. // underflow sticky bits being set in the FPCR.
  2408. //
  2409. // Or if underflow exceptions are enabled, underflow occurs for all denormal
  2410. // numbers. This results in the underflow sticky bit always being set in the
  2411. // FPCR and the inexact sticky bit is set when the denormalized result is
  2412. // also inexact.
  2413. //
  2414. // Otherwise, a normal result can be delivered, but it may be inexact.
  2415. // If the result is inexact, then the inexact sticky bit is set in the
  2416. // FPCR.
  2417. //
  2418. if (ResultOperand->Exponent >= DOUBLE_MAXIMUM_EXPONENT) {
  2419. Inexact = TRUE;
  2420. Overflow = TRUE;
  2421. Underflow = FALSE;
  2422. //
  2423. // The overflow value is dependent on the rounding mode.
  2424. //
  2425. switch (ContextBlock->Round) {
  2426. //
  2427. // Round to nearest representable number.
  2428. //
  2429. // The result value is infinity with the sign of the result.
  2430. //
  2431. case ROUND_TO_NEAREST:
  2432. ResultValue = MAKE_QUAD(DOUBLE_INFINITY_VALUE_LOW,
  2433. DOUBLE_INFINITY_VALUE_HIGH |
  2434. (ResultOperand->Sign << 31));
  2435. break;
  2436. //
  2437. // Round toward zero.
  2438. //
  2439. // The result is the maximum number with the sign of the result.
  2440. //
  2441. case ROUND_TO_ZERO:
  2442. ResultValue = MAKE_QUAD(DOUBLE_MAXIMUM_VALUE_LOW,
  2443. DOUBLE_MAXIMUM_VALUE_HIGH |
  2444. (ResultOperand->Sign << 31));
  2445. break;
  2446. //
  2447. // Round toward plus infinity.
  2448. //
  2449. // If the sign of the result is positive, then the result is
  2450. // plus infinity. Otherwise, the result is the maximum negative
  2451. // number.
  2452. //
  2453. case ROUND_TO_PLUS_INFINITY:
  2454. if (ResultOperand->Sign == 0) {
  2455. ResultValue = MAKE_QUAD(DOUBLE_INFINITY_VALUE_LOW,
  2456. DOUBLE_INFINITY_VALUE_HIGH);
  2457. } else {
  2458. ResultValue = MAKE_QUAD(DOUBLE_MAXIMUM_VALUE_LOW,
  2459. DOUBLE_MAXIMUM_VALUE_HIGH |
  2460. (1 << 31));
  2461. }
  2462. break;
  2463. //
  2464. // Round toward minus infinity.
  2465. //
  2466. // If the sign of the result is negative, then the result is
  2467. // negative infinity. Otherwise, the result is the maximum
  2468. // positive number.
  2469. //
  2470. case ROUND_TO_MINUS_INFINITY:
  2471. if (ResultOperand->Sign != 0) {
  2472. ResultValue = MAKE_QUAD(DOUBLE_INFINITY_VALUE_LOW,
  2473. DOUBLE_INFINITY_VALUE_HIGH |
  2474. (1 << 31));
  2475. } else {
  2476. ResultValue = MAKE_QUAD(DOUBLE_MAXIMUM_VALUE_LOW,
  2477. DOUBLE_MAXIMUM_VALUE_HIGH);
  2478. }
  2479. break;
  2480. }
  2481. //
  2482. // Compute the overflow exception result value by subtracting 1536
  2483. // from the exponent.
  2484. //
  2485. ExceptionResult = Mantissa & (((ULONGLONG)1 << 52) - 1);
  2486. ExceptionResult |= (((ULONGLONG)ResultOperand->Exponent - 1536) << 52);
  2487. ExceptionResult |= ((ULONGLONG)ResultOperand->Sign << 63);
  2488. } else {
  2489. //
  2490. // After rounding if the exponent value is equal to
  2491. // the minimum exponent value and the result was nonzero, then
  2492. // underflow has occurred.
  2493. //
  2494. if ((ResultOperand->Exponent == DOUBLE_MINIMUM_EXPONENT) &&
  2495. (Mantissa != 0 || RoundBit != 00 || StickyBits != 0)) {
  2496. //
  2497. // If the FPCR underflow to zero (denormal enable) control bit
  2498. // is set, then flush the denormalized result to zero and do
  2499. // not set an underflow status or generate an exception.
  2500. //
  2501. if ((ContextBlock->IeeeMode == FALSE) ||
  2502. (SoftwareFpcr->DenormalResultEnable == 0)) {
  2503. DBGPRINT("SoftwareFpcr->DenormalResultEnable == 0\n");
  2504. ResultValue = 0;
  2505. Inexact = FALSE;
  2506. Overflow = FALSE;
  2507. Underflow = FALSE;
  2508. } else {
  2509. ResultValue = Mantissa;
  2510. ResultValue |= (ULONGLONG)ResultOperand->Sign << 63;
  2511. //
  2512. //
  2513. // Compute the underflow exception result value by recalculating the
  2514. // full precision answer and adding 1536 to the exponent.
  2515. //
  2516. //
  2517. // Round the result value using the mantissa, the round bit, and the sticky bits.
  2518. //
  2519. switch (ContextBlock->Round) {
  2520. //
  2521. // Round to nearest representable number.
  2522. //
  2523. case ROUND_TO_NEAREST:
  2524. if (ResultRoundBit != 0) {
  2525. if ((ResultStickyBits != 0) || ((ResultMantissa & 0x1) != 0)) {
  2526. ResultMantissa += 1;
  2527. }
  2528. }
  2529. break;
  2530. //
  2531. // Round toward zero.
  2532. //
  2533. case ROUND_TO_ZERO:
  2534. break;
  2535. //
  2536. // Round toward plus infinity.
  2537. //
  2538. case ROUND_TO_PLUS_INFINITY:
  2539. if ((ResultOperand->Sign == 0) &&
  2540. ((ResultStickyBits != 0) || (ResultRoundBit != 0))) {
  2541. ResultMantissa += 1;
  2542. }
  2543. break;
  2544. //
  2545. // Round toward minus infinity.
  2546. //
  2547. case ROUND_TO_MINUS_INFINITY:
  2548. if ((ResultOperand->Sign != 0) &&
  2549. ((ResultStickyBits != 0) || (ResultRoundBit != 0))) {
  2550. ResultMantissa += 1;
  2551. }
  2552. break;
  2553. }
  2554. //
  2555. // If rounding resulted in a carry into bit 53, then right shift the
  2556. // mantissa one bit and adjust the exponent.
  2557. //
  2558. if ((ResultMantissa & ((ULONGLONG)1 << 53)) != 0) {
  2559. ResultMantissa >>= 1;
  2560. ResultExponent += 1;
  2561. }
  2562. // Compute the underflow exception result value by adding
  2563. // 1536 to the exponent.
  2564. //
  2565. ExceptionResult = ResultMantissa & (((ULONGLONG)1 << 52) - 1);
  2566. ExceptionResult |= (((ULONGLONG)ResultExponent + 1536) << 52);
  2567. ExceptionResult |= ((ULONGLONG)ResultOperand->Sign << 63);
  2568. //
  2569. // If the denormalized result is inexact, then set underflow.
  2570. // Otherwise, for exact denormals do not set the underflow
  2571. // sticky bit unless underflow exception is enabled.
  2572. //
  2573. Overflow = FALSE;
  2574. Underflow = TRUE;
  2575. if ((StickyBits != 0) || (RoundBit != 0)) {
  2576. Inexact = TRUE;
  2577. } else {
  2578. Inexact = FALSE;
  2579. }
  2580. }
  2581. } else {
  2582. //
  2583. // If the result is zero, then set the proper sign for zero.
  2584. //
  2585. if (Mantissa == 0) {
  2586. ResultOperand->Exponent = 0;
  2587. }
  2588. ResultValue = Mantissa & (((ULONGLONG)1 << 52) - 1);
  2589. ResultValue |= (ULONGLONG)ResultOperand->Exponent << 52;
  2590. ResultValue |= (ULONGLONG)ResultOperand->Sign << 63;
  2591. if ((StickyBits != 0) || (RoundBit != 0)) {
  2592. Inexact = TRUE;
  2593. } else {
  2594. Inexact = FALSE;
  2595. }
  2596. Overflow = FALSE;
  2597. Underflow = FALSE;
  2598. }
  2599. }
  2600. //
  2601. // Check to determine if an exception should be delivered.
  2602. //
  2603. ExceptionRecord = ContextBlock->ExceptionRecord;
  2604. if (Overflow != FALSE) {
  2605. Fpcr->Overflow = 1;
  2606. Fpcr->InexactResult = 1;
  2607. Fpcr->SummaryBit = 1;
  2608. if (ContextBlock->IeeeMode == FALSE) {
  2609. ExceptionRecord->ExceptionCode = STATUS_FLOAT_OVERFLOW;
  2610. return FALSE;
  2611. }
  2612. IeeeValue = KiInitializeIeeeValue(ExceptionRecord);
  2613. SoftwareFpcr->StatusOverflow = 1;
  2614. SoftwareFpcr->StatusInexact = 1;
  2615. if (SoftwareFpcr->EnableOverflow != 0) {
  2616. ExceptionRecord->ExceptionCode = STATUS_FLOAT_OVERFLOW;
  2617. IeeeValue->Value.Fp64Value.W[0] = LOW_PART(ExceptionResult);
  2618. IeeeValue->Value.Fp64Value.W[1] = HIGH_PART(ExceptionResult);
  2619. ReturnValue = FALSE;
  2620. } else if (SoftwareFpcr->EnableInexact != 0) {
  2621. ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
  2622. IeeeValue->Value.Fp64Value.W[0] = LOW_PART(ExceptionResult);
  2623. IeeeValue->Value.Fp64Value.W[1] = HIGH_PART(ExceptionResult);
  2624. ReturnValue = FALSE;
  2625. } else {
  2626. Fpcr->DisableOverflow = 1;
  2627. Fpcr->DisableInexact = 1;
  2628. }
  2629. } else if (Underflow != FALSE) {
  2630. //
  2631. // Non-IEEE instruction always forces underflow to zero
  2632. //
  2633. if (ContextBlock->IeeeMode == FALSE) {
  2634. Fpcr->Underflow = 1;
  2635. Fpcr->SummaryBit = 1;
  2636. Fpcr->InexactResult = 1;
  2637. if (ContextBlock->UnderflowEnable != FALSE) {
  2638. ExceptionRecord->ExceptionCode = STATUS_FLOAT_UNDERFLOW;
  2639. return FALSE;
  2640. }
  2641. //
  2642. // IEEE instructions don't report underflow unless the results are
  2643. // inexact or underflow exceptions are enabled
  2644. //
  2645. } else {
  2646. IeeeValue = KiInitializeIeeeValue(ExceptionRecord);
  2647. if (Inexact != FALSE) {
  2648. Fpcr->Underflow = 1;
  2649. Fpcr->SummaryBit = 1;
  2650. Fpcr->InexactResult = 1;
  2651. SoftwareFpcr->StatusUnderflow = 1;
  2652. SoftwareFpcr->StatusInexact = 1;
  2653. }
  2654. if (SoftwareFpcr->EnableUnderflow != 0) {
  2655. Fpcr->Underflow = 1;
  2656. Fpcr->SummaryBit = 1;
  2657. SoftwareFpcr->StatusUnderflow = 1;
  2658. ExceptionRecord->ExceptionCode = STATUS_FLOAT_UNDERFLOW;
  2659. IeeeValue->Value.Fp64Value.W[0] = LOW_PART(ExceptionResult);
  2660. IeeeValue->Value.Fp64Value.W[1] = HIGH_PART(ExceptionResult);
  2661. ReturnValue = FALSE;
  2662. } else if (Inexact != FALSE && SoftwareFpcr->EnableInexact != 0) {
  2663. ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
  2664. IeeeValue->Value.Fp64Value.W[0] = LOW_PART(ExceptionResult);
  2665. IeeeValue->Value.Fp64Value.W[1] = HIGH_PART(ExceptionResult);
  2666. ReturnValue = FALSE;
  2667. } else if (Inexact != FALSE) {
  2668. Fpcr->DisableUnderflow = 1;
  2669. Fpcr->DisableInexact = 1;
  2670. }
  2671. }
  2672. } else if (Inexact != FALSE) {
  2673. Fpcr->InexactResult = 1;
  2674. Fpcr->SummaryBit = 1;
  2675. if (ContextBlock->IeeeMode != FALSE) {
  2676. IeeeValue = KiInitializeIeeeValue(ExceptionRecord);
  2677. SoftwareFpcr->StatusInexact = 1;
  2678. if (SoftwareFpcr->EnableInexact != 0) {
  2679. ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
  2680. IeeeValue->Value.Fp64Value.W[0] = LOW_PART(ResultValue);
  2681. IeeeValue->Value.Fp64Value.W[1] = HIGH_PART(ResultValue);
  2682. ReturnValue = FALSE;
  2683. } else {
  2684. Fpcr->DisableInexact = 1;
  2685. }
  2686. }
  2687. }
  2688. //
  2689. // Always write the destination register. If an exception is delivered, and
  2690. // then dismissed, the correct value must be in the register.
  2691. //
  2692. KiSetRegisterValue(ContextBlock->Fc + 32,
  2693. ResultValue,
  2694. ContextBlock->ExceptionFrame,
  2695. ContextBlock->TrapFrame);
  2696. //
  2697. // Return a value of TRUE.unless an exception should be generated
  2698. //
  2699. return ReturnValue;
  2700. }
  2701. BOOLEAN
  2702. KiNormalizeQuadword (
  2703. IN PFP_CONTEXT_BLOCK ContextBlock,
  2704. IN PFP_DOUBLE_OPERAND ResultOperand
  2705. )
  2706. /*++
  2707. Routine Description:
  2708. This function is called to convert a result value to a quadword result.
  2709. N.B. The result value is specified with a guard bit on the right,
  2710. the hidden bit (if appropriate), and an overflow bit of zero.
  2711. As called above, the guard bit and the round bit are also zero.
  2712. The result format is:
  2713. <63:55> - zero
  2714. <54 - hidden bit
  2715. <53:2> - mantissa
  2716. <1> - guard bit
  2717. <0> - round bit
  2718. There are no sticky bits.
  2719. Arguments:
  2720. ContextBlock - Supplies a pointer to the emulation context block.
  2721. ResultOperand - Supplies a pointer to the result operand value.
  2722. Return Value:
  2723. If there is not an exception, or the exception is handled, then a proper
  2724. result is stored in the destination result, the continuation address is
  2725. set, and a value of TRUE is returned. Otherwise, no value is stored and
  2726. a value of FALSE is returned.
  2727. --*/
  2728. {
  2729. PEXCEPTION_RECORD ExceptionRecord;
  2730. LONGLONG ExponentShift;
  2731. PFPCR Fpcr;
  2732. PFP_IEEE_VALUE IeeeValue;
  2733. ULONGLONG Mantissa;
  2734. BOOLEAN Overflow;
  2735. ULONGLONG ResultValue;
  2736. ULONG RoundBit;
  2737. ULONGLONG StickyBits;
  2738. PSW_FPCR SoftwareFpcr;
  2739. //
  2740. // Subtract out the exponent bias and divide the cases into right
  2741. // and left shifts.
  2742. //
  2743. ExponentShift = ResultOperand->Exponent - DOUBLE_EXPONENT_BIAS;
  2744. DBGPRINT("KiNormalizeQuadword: Inf=%d NaN=%d Sign=%d Exponent=%d Mantissa=%.8x%.8x\n",
  2745. ResultOperand->Infinity, ResultOperand->Nan, ResultOperand->Sign,
  2746. ResultOperand->Exponent,
  2747. ResultOperand->MantissaHigh, ResultOperand->MantissaLow);
  2748. DBGPRINT(".. ExponentShift = %d\n", ExponentShift);
  2749. Mantissa = MAKE_QUAD(ResultOperand->MantissaLow,
  2750. ResultOperand->MantissaHigh);
  2751. if (ExponentShift < 54) {
  2752. //
  2753. // The integer result value is less than 2**54 and so a right shift
  2754. // must be performed.
  2755. //
  2756. ExponentShift = 54 - ExponentShift;
  2757. if (ExponentShift < 64) {
  2758. StickyBits = Mantissa << (64 - ExponentShift);
  2759. ResultValue = Mantissa >> ExponentShift;
  2760. } else {
  2761. StickyBits = Mantissa;
  2762. ResultValue = 0;
  2763. }
  2764. Overflow = FALSE;
  2765. } else if (ExponentShift > 54) {
  2766. ExponentShift -= 54;
  2767. //
  2768. // The integer result value is 2**54 or greater and so a left shift
  2769. // must be performed. If the unsigned integer result value is 2**64
  2770. // or greater, then overflow has occurred and store the low order 64
  2771. // bits of the true result.
  2772. //
  2773. if (ExponentShift < (64 - 54)) {
  2774. StickyBits = Mantissa >> (64 - ExponentShift);
  2775. ResultValue = Mantissa << ExponentShift;
  2776. Overflow = FALSE;
  2777. } else {
  2778. StickyBits = 0;
  2779. if (ExponentShift < 64) {
  2780. ResultValue = Mantissa << ExponentShift;
  2781. } else {
  2782. ResultValue = 0;
  2783. }
  2784. Overflow = TRUE;
  2785. }
  2786. } else {
  2787. StickyBits = 0;
  2788. ResultValue = Mantissa;
  2789. Overflow = FALSE;
  2790. }
  2791. DBGPRINT(".. ResultValue = %.16Lx, StickyBits = %.16Lx\n",
  2792. ResultValue, StickyBits);
  2793. //
  2794. // Round the result value using the mantissa, the round bit, and the
  2795. // sticky bits.
  2796. //
  2797. RoundBit = (ULONG)(StickyBits >> 63);
  2798. StickyBits <<= 1;
  2799. DBGPRINT(".. ResultValue = %.16Lx, StickyBits = %.16Lx, RoundBit = %lx\n",
  2800. ResultValue, StickyBits, RoundBit);
  2801. switch (ContextBlock->Round) {
  2802. //
  2803. // Round to nearest representable number.
  2804. //
  2805. case ROUND_TO_NEAREST:
  2806. if (RoundBit != 0) {
  2807. if ((StickyBits != 0) || ((ResultValue & 0x1) != 0)) {
  2808. ResultValue += 1;
  2809. if (ResultValue == 0) {
  2810. Overflow = TRUE;
  2811. }
  2812. }
  2813. }
  2814. break;
  2815. //
  2816. // Round toward zero.
  2817. //
  2818. case ROUND_TO_ZERO:
  2819. break;
  2820. //
  2821. // Round toward plus infinity.
  2822. //
  2823. case ROUND_TO_PLUS_INFINITY:
  2824. if ((ResultOperand->Sign == 0) &&
  2825. ((StickyBits != 0) || (RoundBit != 0))) {
  2826. ResultValue += 1;
  2827. if (ResultValue == 0) {
  2828. Overflow = TRUE;
  2829. }
  2830. }
  2831. break;
  2832. //
  2833. // Round toward minus infinity.
  2834. //
  2835. case ROUND_TO_MINUS_INFINITY:
  2836. if ((ResultOperand->Sign != 0) &&
  2837. ((StickyBits != 0) || (RoundBit != 0))) {
  2838. ResultValue += 1;
  2839. if (ResultValue == 0) {
  2840. Overflow = TRUE;
  2841. }
  2842. }
  2843. break;
  2844. }
  2845. //
  2846. // If the result value is positive and the result is negative, then
  2847. // overflow has occurred. Otherwise, negate the result value and
  2848. // check if the result is negative. If the result is positive, then
  2849. // overflow has occurred.
  2850. //
  2851. if (ResultOperand->Sign == 0) {
  2852. if ((LONGLONG)ResultValue < 0) {
  2853. Overflow = TRUE;
  2854. }
  2855. } else {
  2856. ResultValue = -(LONGLONG)ResultValue;
  2857. if ((LONGLONG)ResultValue > 0) {
  2858. Overflow = TRUE;
  2859. }
  2860. }
  2861. DBGPRINT(".. ResultValue = %.16Lx, StickyBits = %.16Lx\n",
  2862. ResultValue, StickyBits);
  2863. //
  2864. // Check to determine if an exception should be delivered or the result
  2865. // should be written to the destination register.
  2866. //
  2867. if (Overflow != FALSE) {
  2868. return KiInvalidOperationQuadword(ContextBlock, ResultValue);
  2869. } else if ((StickyBits | RoundBit) != 0) {
  2870. Fpcr = (PFPCR)&ContextBlock->TrapFrame->Fpcr;
  2871. Fpcr->InexactResult = 1;
  2872. Fpcr->SummaryBit = 1;
  2873. if (ContextBlock->IeeeMode != FALSE) {
  2874. SoftwareFpcr = ContextBlock->SoftwareFpcr;
  2875. SoftwareFpcr->StatusInexact = 1;
  2876. if (SoftwareFpcr->EnableInexact != 0) {
  2877. ExceptionRecord = ContextBlock->ExceptionRecord;
  2878. ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
  2879. IeeeValue = KiInitializeIeeeValue(ExceptionRecord);
  2880. IeeeValue->Value.U64Value.LowPart = LOW_PART(ResultValue);
  2881. IeeeValue->Value.U64Value.HighPart = HIGH_PART(ResultValue);
  2882. return FALSE;
  2883. }
  2884. Fpcr->DisableInexact = 1;
  2885. }
  2886. }
  2887. //
  2888. // Set the destination register value and return a value of TRUE.
  2889. //
  2890. KiSetRegisterValue(ContextBlock->Fc + 32,
  2891. ResultValue,
  2892. ContextBlock->ExceptionFrame,
  2893. ContextBlock->TrapFrame);
  2894. return TRUE;
  2895. }
  2896. BOOLEAN
  2897. KiNormalizeSingle (
  2898. IN PFP_CONTEXT_BLOCK ContextBlock,
  2899. IN PFP_SINGLE_OPERAND ResultOperand,
  2900. IN ULONG StickyBits
  2901. )
  2902. /*++
  2903. Routine Description:
  2904. This function is called to normalize a single floating result.
  2905. N.B. The result value is specified with a guard bit on the right,
  2906. the hidden bit (if appropriate), and a possible overflow bit.
  2907. The result format is:
  2908. <31:27> - zero
  2909. <26> - overflow bit
  2910. <25> - hidden bit
  2911. <24:2> - mantissa
  2912. <1> - guard bit
  2913. <0> - round bit
  2914. The sticky bits specify bits that were lost during the computation.
  2915. Arguments:
  2916. ContextBlock - Supplies a pointer to the emulation context block.
  2917. ResultOperand - Supplies a pointer to the result operand value.
  2918. StickyBits - Supplies the value of the sticky bits.
  2919. Return Value:
  2920. If there is not an exception, or the exception is handled, then a proper
  2921. result is stored in the destination result, the continuation address is
  2922. set, and a value of TRUE is returned. Otherwise, a proper value is stored and
  2923. a value of FALSE is returned.
  2924. --*/
  2925. {
  2926. ULONG DenormalizeShift;
  2927. PEXCEPTION_RECORD ExceptionRecord;
  2928. ULONG ExceptionResult;
  2929. PFPCR Fpcr;
  2930. PFP_IEEE_VALUE IeeeValue;
  2931. BOOLEAN Inexact;
  2932. ULONG Mantissa;
  2933. BOOLEAN Overflow;
  2934. ULONG ResultValue;
  2935. ULONG RoundBit;
  2936. PSW_FPCR SoftwareFpcr;
  2937. BOOLEAN Underflow;
  2938. ULONG ResultStickyBits;
  2939. ULONG ResultMantissa;
  2940. ULONG ResultRoundBit;
  2941. LONG ResultExponent;
  2942. BOOLEAN ReturnValue = TRUE;
  2943. //
  2944. // If the result is infinite, then store a properly signed infinity
  2945. // in the destination register and return a value of TRUE. Otherwise,
  2946. // round and normalize the result and check for overflow and underflow.
  2947. //
  2948. DBGPRINT("KiNormalizeSingle: Inf=%d NaN=%d Sign=%d Exponent=%d Mantissa=%.8x\n",
  2949. ResultOperand->Infinity, ResultOperand->Nan, ResultOperand->Sign,
  2950. ResultOperand->Exponent, ResultOperand->Mantissa);
  2951. DBGPRINT("KiNormalizeSingle: StickyBits=%.8lx\n", StickyBits);
  2952. if (ResultOperand->Infinity != FALSE) {
  2953. ResultValue = SINGLE_INFINITY_VALUE | (ResultOperand->Sign << 31);
  2954. KiSetRegisterValue(ContextBlock->Fc + 32,
  2955. KiConvertSingleOperandToRegister(ResultValue),
  2956. ContextBlock->ExceptionFrame,
  2957. ContextBlock->TrapFrame);
  2958. return TRUE;
  2959. }
  2960. Mantissa = ResultOperand->Mantissa;
  2961. Fpcr = (PFPCR)&ContextBlock->TrapFrame->Fpcr;
  2962. SoftwareFpcr = ContextBlock->SoftwareFpcr;
  2963. //
  2964. // If the overflow bit is set, then right shift the mantissa one bit,
  2965. // accumulate the lost bit with the sticky bits, and adjust the exponent
  2966. // value.
  2967. //
  2968. if ((Mantissa & (1 << 26)) != 0) {
  2969. StickyBits |= (Mantissa & 0x1);
  2970. Mantissa >>= 1;
  2971. ResultOperand->Exponent += 1;
  2972. }
  2973. //
  2974. // If the mantissa is nonzero, then normalize the mantissa by left
  2975. // shifting one bit at a time until there is a one bit in bit 25.
  2976. //
  2977. if (Mantissa != 0) {
  2978. while ((Mantissa & (1 << 25)) == 0) {
  2979. Mantissa <<= 1;
  2980. ResultOperand->Exponent -= 1;
  2981. }
  2982. }
  2983. //
  2984. // Right shift the mantissa two bits, set the round bit, and accumulate
  2985. // the other lost bit with the sticky bits.
  2986. //
  2987. StickyBits |= (Mantissa & 0x1);
  2988. RoundBit = (Mantissa & 0x2);
  2989. Mantissa >>= 2;
  2990. //
  2991. // Convert to denormal format before rounding to allow underflow to
  2992. // be detected on rounded result. Save context to calculate IEEE
  2993. // exception record, if needed.
  2994. //
  2995. if (ResultOperand->Exponent <= SINGLE_MINIMUM_EXPONENT && Mantissa != 0) {
  2996. //
  2997. // Save everything needed for calculating IEEE exception record value
  2998. //
  2999. ResultMantissa = Mantissa;
  3000. ResultExponent = ResultOperand->Exponent;
  3001. ResultStickyBits = StickyBits;
  3002. ResultRoundBit = RoundBit;
  3003. //
  3004. // Right shift the mantissa to set the minimum exponent plus an extra
  3005. // bit for the denormal format
  3006. //
  3007. DenormalizeShift = 1 - ResultOperand->Exponent;
  3008. //
  3009. // The maximum denormal shift is 23 bits for the mantissa plus 1 bit for the round
  3010. // A denormal shift of 25 guarantees 0 mantissa and 0 round bit and preserves all sticky bits
  3011. //
  3012. if (DenormalizeShift > 25) {
  3013. DenormalizeShift = 25;
  3014. }
  3015. //
  3016. // The denormalized result will be rounded after it is
  3017. // shifted. Preserve existing Round and Sticky Bits.
  3018. //
  3019. StickyBits |= RoundBit;
  3020. StickyBits |= (Mantissa << 1) << (32 - DenormalizeShift);
  3021. RoundBit = (Mantissa >> (DenormalizeShift - 1)) & 1;
  3022. Mantissa = Mantissa >> DenormalizeShift;
  3023. ResultOperand->Exponent = SINGLE_MINIMUM_EXPONENT;
  3024. }
  3025. //
  3026. // Round the result value using the mantissa, the round bit, and the sticky bits.
  3027. //
  3028. switch (ContextBlock->Round) {
  3029. //
  3030. // Round to nearest representable number.
  3031. //
  3032. case ROUND_TO_NEAREST:
  3033. if (RoundBit != 0) {
  3034. if ((StickyBits != 0) || ((Mantissa & 0x1) != 0)) {
  3035. Mantissa += 1;
  3036. }
  3037. }
  3038. break;
  3039. //
  3040. // Round toward zero.
  3041. //
  3042. case ROUND_TO_ZERO:
  3043. break;
  3044. //
  3045. // Round toward plus infinity.
  3046. //
  3047. case ROUND_TO_PLUS_INFINITY:
  3048. if ((ResultOperand->Sign == 0) &&
  3049. ((StickyBits != 0) || (RoundBit != 0))) {
  3050. Mantissa += 1;
  3051. }
  3052. break;
  3053. //
  3054. // Round toward minus infinity.
  3055. //
  3056. case ROUND_TO_MINUS_INFINITY:
  3057. if ((ResultOperand->Sign != 0) &&
  3058. ((StickyBits != 0) || (RoundBit != 0))) {
  3059. Mantissa += 1;
  3060. }
  3061. break;
  3062. }
  3063. //
  3064. // If rounding resulted in a carry into bit 24, then right shift the
  3065. // mantissa one bit and adjust the exponent.
  3066. //
  3067. if ((Mantissa & (1 << 24)) != 0) {
  3068. Mantissa >>= 1;
  3069. ResultOperand->Exponent += 1;
  3070. }
  3071. //
  3072. // If rounding resulted in a carry into bit 23 in denormal format, then
  3073. // adjust the exponent.
  3074. //
  3075. if ((ResultOperand->Exponent == SINGLE_MINIMUM_EXPONENT) &&
  3076. (Mantissa & (1 << 23)) != 0) {
  3077. ResultOperand->Exponent += 1;
  3078. }
  3079. //
  3080. // If the exponent value is greater than or equal to the maximum
  3081. // exponent value, then overflow has occurred. This results in both
  3082. // the inexact and overflow sticky bits being set in the FPCR.
  3083. //
  3084. // If the exponent value is less than or equal to the minimum exponent
  3085. // value, the mantissa is nonzero, and the denormalized result is inexact,
  3086. // then underflow has occurred. This results in both the inexact and
  3087. // underflow sticky bits being set in the FPCR.
  3088. //
  3089. // Or if underflow exceptions are enabled, underflow occurs for all denormal
  3090. // numbers. This results in the underflow sticky bit always being set in the
  3091. // FPCR and the inexact sticky bit is set when the denormalized result is
  3092. // also inexact.
  3093. //
  3094. // Otherwise, a normal result can be delivered, but it may be inexact.
  3095. // If the result is inexact, then the inexact sticky bit is set in the
  3096. // FPCR.
  3097. //
  3098. if (ResultOperand->Exponent >= SINGLE_MAXIMUM_EXPONENT) {
  3099. Inexact = TRUE;
  3100. Overflow = TRUE;
  3101. Underflow = FALSE;
  3102. //
  3103. // The overflow value is dependent on the rounding mode.
  3104. //
  3105. switch (ContextBlock->Round) {
  3106. //
  3107. // Round to nearest representable number.
  3108. //
  3109. // The result value is infinity with the sign of the result.
  3110. //
  3111. case ROUND_TO_NEAREST:
  3112. ResultValue = SINGLE_INFINITY_VALUE | (ResultOperand->Sign << 31);
  3113. break;
  3114. //
  3115. // Round toward zero.
  3116. //
  3117. // The result is the maximum number with the sign of the result.
  3118. //
  3119. case ROUND_TO_ZERO:
  3120. ResultValue = SINGLE_MAXIMUM_VALUE | (ResultOperand->Sign << 31);
  3121. break;
  3122. //
  3123. // Round toward plus infinity.
  3124. //
  3125. // If the sign of the result is positive, then the result is
  3126. // plus infinity. Otherwise, the result is the maximum negative
  3127. // number.
  3128. //
  3129. case ROUND_TO_PLUS_INFINITY:
  3130. if (ResultOperand->Sign == 0) {
  3131. ResultValue = SINGLE_INFINITY_VALUE;
  3132. } else {
  3133. ResultValue = (ULONG)(SINGLE_MAXIMUM_VALUE | (1 << 31));
  3134. }
  3135. break;
  3136. //
  3137. // Round toward minus infinity.
  3138. //
  3139. // If the sign of the result is negative, then the result is
  3140. // negative infinity. Otherwise, the result is the maximum
  3141. // positive number.
  3142. //
  3143. case ROUND_TO_MINUS_INFINITY:
  3144. if (ResultOperand->Sign != 0) {
  3145. ResultValue = (ULONG)(SINGLE_INFINITY_VALUE | (1 << 31));
  3146. } else {
  3147. ResultValue = SINGLE_MAXIMUM_VALUE;
  3148. }
  3149. break;
  3150. }
  3151. //
  3152. // Compute the overflow exception result value by subtracting 192
  3153. // from the exponent.
  3154. //
  3155. ExceptionResult = Mantissa & ((1 << 23) - 1);
  3156. ExceptionResult |= ((ResultOperand->Exponent - 192) << 23);
  3157. ExceptionResult |= (ResultOperand->Sign << 31);
  3158. } else {
  3159. //
  3160. // After rounding if the exponent value is equal to
  3161. // the minimum exponent value and the result was nonzero, then
  3162. // underflow has occurred.
  3163. //
  3164. if ((ResultOperand->Exponent == SINGLE_MINIMUM_EXPONENT) &&
  3165. (Mantissa != 0 || RoundBit != 00 || StickyBits != 0)) {
  3166. //
  3167. // If the FPCR underflow to zero (denormal enable) control bit
  3168. // is set, then flush the denormalized result to zero and do
  3169. // not set an underflow status or generate an exception.
  3170. //
  3171. if ((ContextBlock->IeeeMode == FALSE) ||
  3172. (SoftwareFpcr->DenormalResultEnable == 0)) {
  3173. DBGPRINT("SoftwareFpcr->DenormalResultEnable == 0\n");
  3174. ResultValue = 0;
  3175. Inexact = FALSE;
  3176. Overflow = FALSE;
  3177. Underflow = FALSE;
  3178. } else {
  3179. ResultValue = Mantissa;
  3180. ResultValue |= ResultOperand->Sign << 31;
  3181. //
  3182. //
  3183. // Compute the underflow exception result value by first recalculating the
  3184. // full precision answer.
  3185. //
  3186. //
  3187. // Round the result value using the mantissa, the round bit, and the sticky bits.
  3188. //
  3189. switch (ContextBlock->Round) {
  3190. //
  3191. // Round to nearest representable number.
  3192. //
  3193. case ROUND_TO_NEAREST:
  3194. if (ResultRoundBit != 0) {
  3195. if ((ResultStickyBits != 0) || ((ResultMantissa & 0x1) != 0)) {
  3196. ResultMantissa += 1;
  3197. }
  3198. }
  3199. break;
  3200. //
  3201. // Round toward zero.
  3202. //
  3203. case ROUND_TO_ZERO:
  3204. break;
  3205. //
  3206. // Round toward plus infinity.
  3207. //
  3208. case ROUND_TO_PLUS_INFINITY:
  3209. if ((ResultOperand->Sign == 0) &&
  3210. ((ResultStickyBits != 0) || (ResultRoundBit != 0))) {
  3211. ResultMantissa += 1;
  3212. }
  3213. break;
  3214. //
  3215. // Round toward minus infinity.
  3216. //
  3217. case ROUND_TO_MINUS_INFINITY:
  3218. if ((ResultOperand->Sign != 0) &&
  3219. ((ResultStickyBits != 0) || (ResultRoundBit != 0))) {
  3220. ResultMantissa += 1;
  3221. }
  3222. break;
  3223. }
  3224. //
  3225. // If rounding resulted in a carry into bit 24, then right shift the
  3226. // mantissa one bit and adjust the exponent.
  3227. //
  3228. if ((ResultMantissa & (1 << 24)) != 0) {
  3229. ResultMantissa >>= 1;
  3230. ResultExponent += 1;
  3231. }
  3232. //
  3233. // Compute the underflow exception result value by adding
  3234. // 192 to the exponent.
  3235. //
  3236. ExceptionResult = ResultMantissa & ((1 << 23) - 1);
  3237. ExceptionResult |= ((ResultExponent + 192) << 23);
  3238. ExceptionResult |= (ResultOperand->Sign << 31);
  3239. //
  3240. // If the denormalized result is inexact, then set underflow.
  3241. // Otherwise, for exact denormals do not set the underflow
  3242. // sticky bit unless underflow exception is enabled.
  3243. //
  3244. Overflow = FALSE;
  3245. Underflow = TRUE;
  3246. if ((StickyBits != 0) || (RoundBit != 0)) {
  3247. Inexact = TRUE;
  3248. } else {
  3249. Inexact = FALSE;
  3250. }
  3251. }
  3252. } else {
  3253. //
  3254. // If the result is zero, then set the proper sign for zero.
  3255. //
  3256. if (Mantissa == 0) {
  3257. ResultOperand->Exponent = 0;
  3258. }
  3259. ResultValue = Mantissa & ((1 << 23) - 1);
  3260. ResultValue |= (ResultOperand->Exponent << 23);
  3261. ResultValue |= (ResultOperand->Sign << 31);
  3262. if ((StickyBits != 0) || (RoundBit != 0)) {
  3263. Inexact = TRUE;
  3264. } else {
  3265. Inexact = FALSE;
  3266. }
  3267. Overflow = FALSE;
  3268. Underflow = FALSE;
  3269. }
  3270. }
  3271. //
  3272. // Check to determine if an exception should be delivered.
  3273. //
  3274. ExceptionRecord = ContextBlock->ExceptionRecord;
  3275. if (Overflow != FALSE) {
  3276. Fpcr->Overflow = 1;
  3277. Fpcr->InexactResult = 1;
  3278. Fpcr->SummaryBit = 1;
  3279. if (ContextBlock->IeeeMode == FALSE) {
  3280. ExceptionRecord->ExceptionCode = STATUS_FLOAT_OVERFLOW;
  3281. return FALSE;
  3282. }
  3283. IeeeValue = KiInitializeIeeeValue(ExceptionRecord);
  3284. SoftwareFpcr->StatusOverflow = 1;
  3285. SoftwareFpcr->StatusInexact = 1;
  3286. if (SoftwareFpcr->EnableOverflow != 0) {
  3287. ExceptionRecord->ExceptionCode = STATUS_FLOAT_OVERFLOW;
  3288. IeeeValue->Value.Fp32Value.W[0] = ExceptionResult;
  3289. ReturnValue = FALSE;
  3290. } else if (SoftwareFpcr->EnableInexact != 0) {
  3291. ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
  3292. IeeeValue->Value.Fp32Value.W[0] = ExceptionResult;
  3293. ReturnValue = FALSE;
  3294. } else {
  3295. Fpcr->DisableOverflow = 1;
  3296. Fpcr->DisableInexact = 1;
  3297. }
  3298. } else if (Underflow != FALSE) {
  3299. //
  3300. // Non-IEEE instruction always forces underflow to zero
  3301. //
  3302. if (ContextBlock->IeeeMode == FALSE) {
  3303. Fpcr->Underflow = 1;
  3304. Fpcr->SummaryBit = 1;
  3305. Fpcr->InexactResult = 1;
  3306. if (ContextBlock->UnderflowEnable != FALSE) {
  3307. ExceptionRecord->ExceptionCode = STATUS_FLOAT_UNDERFLOW;
  3308. return FALSE;
  3309. }
  3310. //
  3311. // IEEE instructions don't report underflow unless the results are
  3312. // inexact or underflow exceptions are enabled
  3313. //
  3314. } else {
  3315. IeeeValue = KiInitializeIeeeValue(ExceptionRecord);
  3316. if (Inexact != FALSE) {
  3317. Fpcr->Underflow = 1;
  3318. Fpcr->InexactResult = 1;
  3319. Fpcr->SummaryBit = 1;
  3320. SoftwareFpcr->StatusUnderflow = 1;
  3321. SoftwareFpcr->StatusInexact = 1;
  3322. }
  3323. if (SoftwareFpcr->EnableUnderflow != 0) {
  3324. Fpcr->Underflow = 1;
  3325. Fpcr->SummaryBit = 1;
  3326. SoftwareFpcr->StatusUnderflow = 1;
  3327. ExceptionRecord->ExceptionCode = STATUS_FLOAT_UNDERFLOW;
  3328. IeeeValue->Value.Fp32Value.W[0] = ExceptionResult;
  3329. ReturnValue = FALSE;
  3330. } else if (Inexact != FALSE && SoftwareFpcr->EnableInexact != 0) {
  3331. ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
  3332. IeeeValue->Value.Fp32Value.W[0] = ExceptionResult;
  3333. ReturnValue = FALSE;
  3334. } else if (Inexact != FALSE) {
  3335. Fpcr->DisableUnderflow = 1;
  3336. Fpcr->DisableInexact = 1;
  3337. }
  3338. }
  3339. } else if (Inexact != FALSE) {
  3340. Fpcr->InexactResult = 1;
  3341. Fpcr->SummaryBit = 1;
  3342. if (ContextBlock->IeeeMode != FALSE) {
  3343. IeeeValue = KiInitializeIeeeValue(ExceptionRecord);
  3344. SoftwareFpcr->StatusInexact = 1;
  3345. if (SoftwareFpcr->EnableInexact != 0) {
  3346. ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
  3347. IeeeValue->Value.Fp32Value.W[0] = ResultValue;
  3348. ReturnValue = FALSE;
  3349. } else {
  3350. Fpcr->DisableInexact = 1;
  3351. }
  3352. }
  3353. }
  3354. //
  3355. // Always write the destination register. If an exception is delivered, and
  3356. // then dismissed, the correct value must be in the register.
  3357. //
  3358. KiSetRegisterValue(ContextBlock->Fc + 32,
  3359. KiConvertSingleOperandToRegister(ResultValue),
  3360. ContextBlock->ExceptionFrame,
  3361. ContextBlock->TrapFrame);
  3362. //
  3363. // Return a value of TRUE.unless an exception should be generated
  3364. //
  3365. return ReturnValue;
  3366. }
  3367. VOID
  3368. KiUnpackDouble (
  3369. IN ULONG Source,
  3370. IN PFP_CONTEXT_BLOCK ContextBlock,
  3371. OUT PFP_DOUBLE_OPERAND DoubleOperand
  3372. )
  3373. /*++
  3374. Routine Description:
  3375. This function is called to unpack a double floating value from the
  3376. specified source register.
  3377. N.B. The unpacked mantissa value is returned with a guard bit and a
  3378. round bit on the right and the hidden bit inserted if appropriate.
  3379. The format of the returned value is:
  3380. <63:55> - zero
  3381. <54> - hidden bit
  3382. <53:2> - mantissa
  3383. <1> - guard bit
  3384. <0> - round bit
  3385. Arguments:
  3386. Source - Supplies the number of the register that contains the operand.
  3387. ContextBlock - Supplies a pointer to the emulation context block.
  3388. DoubleOperand - Supplies a pointer to a structure that is to receive the
  3389. operand value.
  3390. Return Value:
  3391. None.
  3392. --*/
  3393. {
  3394. ULONGLONG Value;
  3395. ULONG Value1;
  3396. ULONG Value2;
  3397. //
  3398. // Get the source register value and unpack the sign, exponent, and
  3399. // mantissa value.
  3400. //
  3401. Value = KiGetRegisterValue(Source + 32,
  3402. ContextBlock->ExceptionFrame,
  3403. ContextBlock->TrapFrame);
  3404. Value1 = (ULONG)Value;
  3405. Value2 = (ULONG)(Value >> 32);
  3406. DoubleOperand->Sign = Value2 >> 31;
  3407. DoubleOperand->Exponent = (Value2 >> (52 - 32)) & 0x7ff;
  3408. DoubleOperand->MantissaHigh = Value2 & 0xfffff;
  3409. DoubleOperand->MantissaLow = Value1;
  3410. //
  3411. // If the exponent is the largest possible value, then the number is
  3412. // either a NaN or an infinity. Otherwise if the exponent is the smallest
  3413. // possible value and the mantissa is nonzero, then the number is
  3414. // denormalized. Otherwise the number is finite and normal.
  3415. //
  3416. if (DoubleOperand->Exponent == DOUBLE_MAXIMUM_EXPONENT) {
  3417. DoubleOperand->Normal = FALSE;
  3418. if ((DoubleOperand->MantissaLow | DoubleOperand->MantissaHigh) != 0) {
  3419. DoubleOperand->Infinity = FALSE;
  3420. DoubleOperand->Nan = TRUE;
  3421. } else {
  3422. DoubleOperand->Infinity = TRUE;
  3423. DoubleOperand->Nan = FALSE;
  3424. }
  3425. } else {
  3426. DoubleOperand->Infinity = FALSE;
  3427. DoubleOperand->Nan = FALSE;
  3428. DoubleOperand->Normal = TRUE;
  3429. if (DoubleOperand->Exponent == DOUBLE_MINIMUM_EXPONENT) {
  3430. if ((DoubleOperand->MantissaHigh | DoubleOperand->MantissaLow) != 0) {
  3431. if (ContextBlock->SoftwareFpcr->DenormalOperandsEnable == 0) {
  3432. DBGPRINT("SoftwareFpcr->DenormalOperandsEnable == 0\n");
  3433. DoubleOperand->MantissaHigh = 0;
  3434. DoubleOperand->MantissaLow = 0;
  3435. DoubleOperand->Exponent = 0;
  3436. } else {
  3437. DoubleOperand->Normal = FALSE;
  3438. DoubleOperand->Exponent += 1;
  3439. while ((DoubleOperand->MantissaHigh & (1 << 20)) == 0) {
  3440. DoubleOperand->MantissaHigh =
  3441. (DoubleOperand->MantissaHigh << 1) |
  3442. (DoubleOperand->MantissaLow >> 31);
  3443. DoubleOperand->MantissaLow <<= 1;
  3444. DoubleOperand->Exponent -= 1;
  3445. }
  3446. }
  3447. }
  3448. } else {
  3449. DoubleOperand->MantissaHigh |= (1 << 20);
  3450. }
  3451. }
  3452. //
  3453. // Left shift the mantissa 2-bits to provide for a guard bit and a round
  3454. // bit.
  3455. //
  3456. DoubleOperand->MantissaHigh =
  3457. (DoubleOperand->MantissaHigh << 2) | (DoubleOperand->MantissaLow >> 30);
  3458. DoubleOperand->MantissaLow <<= 2;
  3459. DBGPRINT("KiUnpackDouble: Inf=%d NaN=%d Sign=%d Exponent=%d Mantissa=%.8x%.8x\n",
  3460. DoubleOperand->Infinity, DoubleOperand->Nan, DoubleOperand->Sign,
  3461. DoubleOperand->Exponent,
  3462. DoubleOperand->MantissaHigh, DoubleOperand->MantissaLow);
  3463. return;
  3464. }
  3465. VOID
  3466. KiUnpackSingle (
  3467. IN ULONG Source,
  3468. IN PFP_CONTEXT_BLOCK ContextBlock,
  3469. OUT PFP_SINGLE_OPERAND SingleOperand
  3470. )
  3471. /*++
  3472. Routine Description:
  3473. This function is called to unpack a single floating value from the
  3474. specified source register.
  3475. N.B. The unpacked mantissa value is returned with a guard bit and a
  3476. round bit on the right and the hidden bit inserted if appropriate.
  3477. The format of the returned value is:
  3478. <31:26> - zero
  3479. <25> - hidden bit
  3480. <24:2> - mantissa
  3481. <1> - guard bit
  3482. <0> - round bit
  3483. Arguments:
  3484. Source - Supplies the number of the register that contains the operand.
  3485. ContextBlock - Supplies a pointer to the emulation context block.
  3486. SingleOperand - Supplies a pointer to a structure that is to receive the
  3487. operand value.
  3488. Return Value:
  3489. None.
  3490. --*/
  3491. {
  3492. ULONG Value;
  3493. //
  3494. // Get the source register value and unpack the sign, exponent, and
  3495. // mantissa value.
  3496. //
  3497. Value = KiConvertRegisterToSingleOperand(
  3498. KiGetRegisterValue(Source + 32,
  3499. ContextBlock->ExceptionFrame,
  3500. ContextBlock->TrapFrame));
  3501. SingleOperand->Sign = Value >> 31;
  3502. SingleOperand->Exponent = (Value >> 23) & 0xff;
  3503. SingleOperand->Mantissa = Value & 0x7fffff;
  3504. //
  3505. // If the exponent is the largest possible value, then the number is
  3506. // either a NaN or an infinity. Otherwise if the exponent is the smallest
  3507. // possible value and the mantissa is nonzero, then the number is
  3508. // denormalized. Otherwise the number is finite and normal.
  3509. //
  3510. if (SingleOperand->Exponent == SINGLE_MAXIMUM_EXPONENT) {
  3511. SingleOperand->Normal = FALSE;
  3512. if (SingleOperand->Mantissa != 0) {
  3513. SingleOperand->Infinity = FALSE;
  3514. SingleOperand->Nan = TRUE;
  3515. } else {
  3516. SingleOperand->Infinity = TRUE;
  3517. SingleOperand->Nan = FALSE;
  3518. }
  3519. } else {
  3520. SingleOperand->Infinity = FALSE;
  3521. SingleOperand->Nan = FALSE;
  3522. SingleOperand->Normal = TRUE;
  3523. if (SingleOperand->Exponent == SINGLE_MINIMUM_EXPONENT) {
  3524. if (SingleOperand->Mantissa != 0) {
  3525. if (ContextBlock->SoftwareFpcr->DenormalOperandsEnable == 0) {
  3526. DBGPRINT("SoftwareFpcr->DenormalOperandsEnable == 0\n");
  3527. SingleOperand->Mantissa = 0;
  3528. SingleOperand->Exponent = 0;
  3529. } else {
  3530. SingleOperand->Normal = FALSE;
  3531. SingleOperand->Exponent += 1;
  3532. while ((SingleOperand->Mantissa & (1 << 23)) == 0) {
  3533. SingleOperand->Mantissa <<= 1;
  3534. SingleOperand->Exponent -= 1;
  3535. }
  3536. }
  3537. }
  3538. } else {
  3539. SingleOperand->Mantissa |= (1 << 23);
  3540. }
  3541. }
  3542. //
  3543. // Left shift the mantissa 2-bits to provide for a guard bit and a round
  3544. // bit.
  3545. //
  3546. SingleOperand->Mantissa <<= 2;
  3547. DBGPRINT("KiUnpackSingle: Inf=%d NaN=%d Sign=%d Exponent=%d Mantissa=%.8x\n",
  3548. SingleOperand->Infinity, SingleOperand->Nan, SingleOperand->Sign,
  3549. SingleOperand->Exponent, SingleOperand->Mantissa);
  3550. return;
  3551. }