Leaked source code of windows server 2003
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.

202 lines
4.6 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. mulops.c
  5. Abstract:
  6. This module implements the code to emulate the mul and imul opcodes.
  7. Author:
  8. David N. Cutler (davec) 21-Sep-1994
  9. Environment:
  10. Kernel mode only.
  11. Revision History:
  12. --*/
  13. #include "nthal.h"
  14. #include "emulate.h"
  15. VOID
  16. XmImulOp (
  17. IN PRXM_CONTEXT P
  18. )
  19. /*++
  20. Routine Description:
  21. This function emulates an imul opcode with a single destination.
  22. Arguments:
  23. P - Supplies a pointer to the emulation context structure.
  24. Return Value:
  25. None.
  26. --*/
  27. {
  28. LARGE_INTEGER Product;
  29. ULONG UpperEqual;
  30. //
  31. // Multiply the signed operands and store result.
  32. //
  33. if (P->DataType == BYTE_DATA) {
  34. Product.QuadPart = Int32x32To64((LONG)((SCHAR)P->DstValue.Byte),
  35. (LONG)((SCHAR)P->SrcValue.Byte));
  36. XmStoreResult(P, Product.LowPart & 0xff);
  37. UpperEqual = ((UCHAR)((Product.LowPart >> 8) & 0xff) !=
  38. (UCHAR)((SCHAR)Product.LowPart >> 7));
  39. } else if (P->DataType == LONG_DATA) {
  40. Product.QuadPart = Int32x32To64((LONG)P->DstValue.Long,
  41. (LONG)P->SrcValue.Long);
  42. XmStoreResult(P, Product.LowPart);
  43. UpperEqual = (Product.HighPart != (LONG)Product.LowPart >> 31);
  44. } else {
  45. Product.QuadPart = Int32x32To64((LONG)((SHORT)P->DstValue.Word),
  46. (LONG)((SHORT)P->SrcValue.Word));
  47. XmStoreResult(P, Product.LowPart & 0xffff);
  48. UpperEqual = ((USHORT)((Product.LowPart >> 16) & 0xffff) !=
  49. (USHORT)((SHORT)Product.LowPart >> 15));
  50. }
  51. P->Eflags.EFLAG_CF = UpperEqual;
  52. P->Eflags.EFLAG_OF = UpperEqual;
  53. return;
  54. }
  55. VOID
  56. XmImulxOp (
  57. IN PRXM_CONTEXT P
  58. )
  59. /*++
  60. Routine Description:
  61. This function emulates an imul opcode with an extended destination.
  62. Arguments:
  63. P - Supplies a pointer to the emulation context structure.
  64. Return Value:
  65. None.
  66. --*/
  67. {
  68. LARGE_INTEGER Product;
  69. ULONG UpperEqual;
  70. //
  71. // Multiply the signed operands and store the result and the extended
  72. // result.
  73. //
  74. if (P->DataType == BYTE_DATA) {
  75. Product.QuadPart = Int32x32To64((LONG)((SCHAR)P->DstValue.Byte),
  76. (LONG)((SCHAR)P->SrcValue.Byte));
  77. P->DataType = WORD_DATA;
  78. XmStoreResult(P, Product.LowPart & 0xffff);
  79. UpperEqual = (P->Gpr[AX].Xh != (UCHAR)((SCHAR)P->Gpr[AX].Xl >> 7));
  80. } else if (P->DataType == LONG_DATA) {
  81. Product.QuadPart = Int32x32To64((LONG)P->DstValue.Long,
  82. (LONG)P->SrcValue.Long);
  83. XmStoreResult(P, Product.LowPart);
  84. P->DstLong = (UNALIGNED ULONG *)(&P->Gpr[EDX].Exx);
  85. XmStoreResult(P, (ULONG)Product.HighPart);
  86. UpperEqual = (Product.HighPart != (LONG)Product.LowPart >> 31);
  87. } else {
  88. Product.QuadPart = Int32x32To64((LONG)((SHORT)P->DstValue.Word),
  89. (LONG)((SHORT)P->SrcValue.Word));
  90. XmStoreResult(P, Product.LowPart & 0xffff);
  91. P->DstLong = (UNALIGNED ULONG *)(&P->Gpr[DX].Exx);
  92. XmStoreResult(P, Product.LowPart >> 16);
  93. UpperEqual = (P->Gpr[DX].Xx != (USHORT)((SHORT)P->Gpr[AX].Xx >> 15));
  94. }
  95. P->Eflags.EFLAG_CF = UpperEqual;
  96. P->Eflags.EFLAG_OF = UpperEqual;
  97. return;
  98. }
  99. VOID
  100. XmMulOp (
  101. IN PRXM_CONTEXT P
  102. )
  103. /*++
  104. Routine Description:
  105. This function emulates a mul opcode.
  106. Arguments:
  107. P - Supplies a pointer to the emulation context structure.
  108. Return Value:
  109. None.
  110. --*/
  111. {
  112. ULARGE_INTEGER Product;
  113. ULONG UpperZero;
  114. //
  115. // Multiply the unsigned operands and store result.
  116. //
  117. Product.QuadPart = UInt32x32To64(P->DstValue.Long, P->SrcValue.Long);
  118. if (P->DataType == BYTE_DATA) {
  119. P->DataType = WORD_DATA;
  120. XmStoreResult(P, Product.LowPart);
  121. UpperZero = (P->Gpr[AX].Xh != 0);
  122. } else if (P->DataType == LONG_DATA) {
  123. XmStoreResult(P, Product.LowPart);
  124. P->DstLong = (UNALIGNED ULONG *)(&P->Gpr[EDX].Exx);
  125. XmStoreResult(P, Product.HighPart);
  126. UpperZero = (Product.HighPart != 0);
  127. } else {
  128. XmStoreResult(P, Product.LowPart & 0xffff);
  129. P->DstLong = (UNALIGNED ULONG *)(&P->Gpr[DX].Exx);
  130. XmStoreResult(P, Product.LowPart >> 16);
  131. UpperZero = (P->Gpr[DX].Xx != 0);
  132. }
  133. P->Eflags.EFLAG_CF = UpperZero;
  134. P->Eflags.EFLAG_OF = UpperZero;
  135. return;
  136. }