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.

165 lines
4.1 KiB

  1. page ,132
  2. subttl emnew - emulator new instruction support
  3. ;***
  4. ;emnew.asm - emulator new instruction support
  5. ;
  6. ; Copyright (c) 1985-89, Microsoft Corporation
  7. ;
  8. ;Purpose:
  9. ; Emulator new instruction support
  10. ;
  11. ; This Module contains Proprietary Information of Microsoft
  12. ; Corporation and should be treated as Confidential.
  13. ;
  14. ;Revision History:
  15. ; See emulator.hst
  16. ;
  17. ;*******************************************************************************
  18. ProfBegin NEW
  19. ;*** eFFREE - emulate FFREE ST(i)
  20. ;
  21. ; ARGUMENTS
  22. ; CX = |Op|r/m|MOD|esc|MF|Arith|
  23. ; r/m is register to free
  24. ;
  25. ; DESCRIPTION
  26. ; This routine assumes that the register being freed is
  27. ; either at the top or the bottom of the floating point
  28. ; stack. This is consistent with its use by the cmerge
  29. ; compiler. If ST(i) is valid, all registers from ST(0)
  30. ; to ST(i-1) are moved down one position in the stack,
  31. ; eliminating ST(i). [CURstk] is moved to the new location
  32. ; of ST(0).
  33. ;
  34. ; REGISTERS
  35. ; modifies si,di,dx
  36. pub eFFREE
  37. call RegAddr ; di <== address of ST(i)
  38. ; carry set if invalid register
  39. jnc short validSTi ; ok, continue
  40. pop edx ; toss return address
  41. jmp InvalidOperand ; set stack underflow/invalid and exit
  42. validSTi:
  43. mov esi,edi ; si <== address of ST(i)
  44. MovLoop:
  45. add esi,Reg87Len ; si <== address of ST(i-1)
  46. cmp esi,[CURstk] ; source addr <= top of stack?
  47. jg short SetCURstk ; set [CURstk] and exit
  48. call MOVRQQ ; ST(j) <== ST(j-1)
  49. add edi,Reg87Len ; move dest ptr to next stack entry
  50. jmp short MovLoop ; continue moving register entries
  51. SetCURstk:
  52. sub edi,Reg87Len ; di points to new location of ST(0)
  53. mov [CURstk],edi ; set new top of stack ptr
  54. ret
  55. ;*** eFXCHG - emulate FXCH ST(i)
  56. ;
  57. ; ARGUMENTS
  58. ; CX = |Op|r/m|MOD|esc|MF|Arith|
  59. ; r/m is the source register
  60. ;
  61. ; DESCRIPTION
  62. ; exchange ST(i) and ST(0) as follows:
  63. ; temp <== ST(0); ST(0) <== ST(i); ST(i) <== temp
  64. ; indicate stack underflow error if ST(i) does not exist
  65. ;
  66. ; REGISTERS
  67. ; modifies ax,es,si,di,dx,cx,bx
  68. pub eFXCHG
  69. test cx,01c00h ;test for ST(i) == ST(0)
  70. jz short fxchRet ;fxch ST(0),ST(0) is a nop
  71. mov ax,ds
  72. mov es,ax ;set es == ds
  73. call RegAddr ;di points to ST(i), si points to ST(0)
  74. ;carry set if invalid register
  75. jnc short okReg ;ok, continue
  76. pop edx ; toss return address
  77. jmp InvalidOperand ;give stack underflow/invalid error
  78. okReg:
  79. mov ecx,6 ;loop counter
  80. WordSwap: ;exchange a word of ST(0) and ST(i)
  81. mov ax,[esi] ;ax <== [si]
  82. mov bx,[edi] ;bx <== [di]
  83. stos word ptr es:[edi] ;[(di++)] <== ax
  84. mov [esi],bx ;[si] <== bx
  85. inc esi
  86. inc esi ;si++
  87. loop WordSwap ;exchange the six words of ST(0), ST(i)
  88. fxchRet:
  89. ret
  90. ;*** eFLDreg - emulate FLD ST(i)
  91. ;
  92. ; ARGUMENTS
  93. ; CX = |Op|r/m|MOD|esc|MF|Arith|
  94. ; r/m is the source register
  95. ;
  96. ; DESCRIPTION
  97. ; allocate new ST(0) and copy ST(i) into it
  98. ; indicate stack underflow error if ST(i) does not exist
  99. ;
  100. ; REGISTERS
  101. ; modifies ax,di,si
  102. pub eFLDreg
  103. call RegAddr ;di <== address of ST(i), si points to ST(0)
  104. ;carry set if invalid register
  105. jnc short okSTi ;yes, continue
  106. pop edx ; toss return address
  107. jmp InvalidOperand ;stack underflow, invalid operation
  108. okSTi:
  109. PUSHST ;allocate new TOS
  110. mov ax,ds
  111. mov es,ax ;set ES == DS
  112. xchg esi,edi ;si = source , di = destination
  113. call MOVRQQ ;move ST(i) to new ST(0)
  114. ret
  115. ;*** eFST_Preg - emulate FST ST(i) and FSTP ST(i)
  116. ;
  117. ; ARGUMENTS
  118. ; AX = 0 if FST ST(i)
  119. ; 1 if FSTP ST(i)
  120. ; CX = |Op|r/m|MOD|esc|MF|Arith|
  121. ; (except bit 2 of cl is toggled)
  122. ; r/m is the source register
  123. ;
  124. ; DESCRIPTION
  125. ; move contents of ST(0) to ST(i). If ax <> 0 pop stack
  126. ; after transfer.
  127. ;
  128. ; REGISTERS
  129. ; modifies si,di,dx
  130. pub eFST_Preg
  131. test cx,01c0h ;test for ST(i) == ST(0)
  132. jz short FSTRet ;pop stack and return
  133. call RegAddr ;di <== address of ST(i), si points to ST(0)
  134. ;carry set if invalid register
  135. jnc short ValidReg ;yes, continue
  136. pop edx ; toss return address
  137. jmp InvalidOperand ;no, indicate stack underflow/invalid
  138. ValidReg:
  139. mov dx,ds
  140. mov es,dx ;set es == ds
  141. call MOVRQQ ;ST(i) <== ST(0)
  142. FSTRet:
  143. or ax,ax ;FST ST(i) or FSTP ST(i)?
  144. jz short NoPOP ;FST ST(i) - don't pop the stack
  145. POPST ;pop the 8087 stack
  146. NoPOP:
  147. ret
  148. ProfEnd NEW