386fpemu.inc
来自「开放源码的编译器open watcom 1.6.0版的源代码」· INC 代码 · 共 1,702 行 · 第 1/5 页
INC
1,702 行
mov ecx,8 ; do 8 times
fslup: lea esi,[ebx+ebp].fpstack ; - point source to stack top
movsd ; - save the value
movsd ; - ...
movsw ; - ...
movzx ebx,TENTBL[ebx].t_next ; - 'pop' the stack
loop fslup ; end do
ENDIF
mov edi,ebx
endm
rest87 macro size ; put user memory into the 87
mov ecx,ENV_SIZE / 4 ; set up size reg
push ds ; save registers
push es ; and xchg ds,es
mov ax,es ; ...
mov dx,ds ; ...
mov es,dx ; ...
mov ds,ax ; ...
mov edi,ebp ; ...
rep movsd ; put into 8087
IFDIF <size>,<ENV_SIZE>
ifdef SEGMENTED
mov ebx,dword ptr es:[ebp].status;- ebx gets index of top of stack
else
mov ebx,dword ptr [ebp].status;- ebx gets index of top of stack
endif
and ebx,SW_ST ; - ...
shr ebx,SW_ST_SHIFT ; - ...
lea ebx,[ebx+ebx*4] ; - ... times 5
add ebx,ebx ; - ... ... times 2
ifdef SEGMENTED
mov dword ptr es:[ebp].stktop,ebx;- save index of top of stack
else
mov dword ptr [ebp].stktop,ebx;- save index of top of stack
endif
mov ecx,8 ; do 8 times
frlup: lea edi,[ebp+ebx].fpstack ; - point to st(0)
movsd ; - restore st(0)
movsd ; - ...
movsw ; - ...
movzx ebx,TENTBL[ebx].t_next ;- 'pop' the stack
loop frlup ; end do
ENDIF
pop es ; ...
pop ds ; ...
endm
load macro where,what ; load up hi:lo
IFIDN <what>,<double> ; - then
ifdef SEGMENTED
mov eax,es:[esi] ; - load up double
mov edx,es:4[esi] ; - ...
else
mov eax, [esi] ; - load up double
mov edx, 4[esi] ; - ...
endif
_lea ebx,where ; - ...
call __EmuFDLD ; - convert to tbyte
ELSE ; else if long
IFIDN <what>,<long> ; - then
ifdef SEGMENTED
mov eax,es:[esi] ; - load long integer
else
mov eax, [esi] ; - load long integer
endif
_lea edx,where ; - ...
call __I4LD ; - convert to tbyte
ELSE ; else if int
IFIDN <what>,<integer> ; - then
ifdef SEGMENTED
mov ax,es:[esi] ; - load an int
else
mov ax, [esi] ; - load an int
endif
cwde ; - convert to long
_lea edx,where ; - ...
call __I4LD ; - convert to tbyte
ELSE ; else if double long (8 bytes)
IFIDN <what>,<dlong> ; - then
ifdef SEGMENTED
mov eax,es:[esi] ; - load up unsigned long
else
mov eax, [esi] ; - load up unsigned long
endif
_lea edx,where ; - ...
call __U4LD ; - convert to tbyte
ELSE ; else if float
IFIDN <what>,<float> ; - then
ifdef SEGMENTED
mov eax,es:[esi] ; - load a float
else
mov eax, [esi] ; - load a float
endif
_lea edx,where ; - ...
call __EmuFSLD ; - convert to double
ELSE ; else if st(i)
IFIDN <what>,<st(i)> ; - then
IFIDN <where>,<temp> ; - if going to temp
mov10 ds,[esi+ebp].fpstack,ds,[ebp].fptemp
ELSE ; - else going to st
mov10 ds,[esi+ebp].fpstack,ds,[edi+ebp].fpstack
ENDIF ; - endif
ELSE ; else if st
IFIDN <what>,<st> ; - then
.ERRDIF <where>,<temp> ; - if going to temp
mov10 ds,[edi+ebp].fpstack,ds,[ebp].fptemp
ELSE ; else if treal
IFIDN <what>,<treal> ; - then
IFIDN <where>,<st> ; - if load to st
mov10 es,[esi],ds,[edi+ebp].fpstack ; - - move 10 bytes
ELSE ; - else load to temp
.ERRDIF <where>,<temp> ; - - ...
mov10 es,[esi],ds,[ebp].fptemp ; - - move 10 bytes
ENDIF ; - endif
ELSE ; else if temp
IFIDN <what>,<temp> ; - then
.ERRDIF <where>,<st> ; - loading into st
mov10 ds,[ebp].fptemp,ds,[ebp+edi].fpstack; - move 10 bytes
ELSE ; else
.ERR ; - I can't use my own macro's
%OUT bad load macro ; - ...
ENDIF ; endif
ENDIF ; ...
ENDIF ; ...
ENDIF ; ...
ENDIF ; ...
ENDIF ; ... oh for an elseif
ENDIF ; ...
ENDIF ; ...
ENDIF ; ...
endm
store macro what ; store st somewhere
IFIDN <what>,<double> ; - then it
_lea eax,st ; - point to top of stack
call __EmuLDFD ; - convert to double
ifdef SEGMENTED
mov es:[esi],eax ; - store it
mov es:4[esi],edx ; - ...
else
mov [esi],eax ; - store it
mov 4[esi],edx ; - ...
endif
ELSE ; - ...
IFIDN <what>,<long> ; else if long
_lea eax,st ; - point to top of stack
call __LDI4 ; - convert to long
ifdef SEGMENTED
mov es:[esi],eax ; - store it
else
mov [esi],eax ; - store it
endif
ELSE ; else if float
IFIDN <what>,<float> ; - then
_lea eax,st ; - point to top of stack
call __EmuLDFS ; - convert to float
ifdef SEGMENTED
mov es:[esi],eax ; - store it
else
mov [esi],eax ; - store it
endif
ELSE ; else if integer
IFIDN <what>,<integer> ; - then
_lea eax,st ; - point to top of stack
call __LDI4 ; - convert to long
mov edx,eax ; - save value
cwde ; - sign extend ax to eax
cmp eax,edx ; - if not equal
_if ne ; - then
mov ax,8000h ; - - indicate overflow
_endif ; - endif
ifdef SEGMENTED
mov es:[esi],ax ; - store it
else
mov [esi],ax ; - store it
endif
ELSE ; else if double long (8 bytes)
IFIDN <what>,<dlong> ; - then
_lea eax,st ; - point to top of stack
call __LDU4 ; - convert to unsigned long
ifdef SEGMENTED
mov es:[esi],eax ; - store it
else
mov [esi],eax ; - store it
endif
ELSE ; else if st(i)
IFIDN <what>,<st(i)> ; - then
mov10 ds,[edi+ebp].fpstack,ds,[esi+ebp].fpstack
ELSE ; else if st(i)
IFIDN <what>,<treal> ; - then
mov10 ds,[edi+ebp].fpstack,es,[esi] ; - move 10 bytes
ELSE ; else
.ERR ; - I cant use my own macro
%OUT bad store macro ; - ...
ENDIF ; endif
ENDIF ; ...
ENDIF ; ...
ENDIF ; ...
ENDIF ; ...
ENDIF ; ...
ENDIF ; ...
endm
;;;;;;;;;;;;;;;;;;;;;;;;;;;; memory instruction emulation ;;;;;;;;;;;;;;;;;;;;;
;;
;; AT THIS POINT
;; ES:ESI - pointer to the memory operand
;; DS:[EDI+EBP].fpstack - pointer to the top of stack
;; ON EXIT
;; EDI - will be updated to reflect top of stack pointer
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include memops.inc
;;;;;;;;;;;;;;;;;;;;;;;;;;; stack instruction emulation ;;;;;;;;;;;;;;;;;;;;;;;;
;; AT THIS POINT
;; DS:[EDI+EBP].fpstack - pointer to ST(0)
;; DS:[ESI+EBP].fpstack - pointer to ST(i)
;; EBX is the bottom 3 bits of modrm byte
;; ON EXIT
;; EDI - will have been updated to reflect top of stack pointer
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include stkops.inc
; here are some 386 specific stack ops
s613:; fpatan
;===================================================================
_lea edx,st ; X
popstk
_lea eax,st ; Y
mov ebx,eax ; destination
call __fpatan
donearith
s614:; fxtract
;===================================================================
_lea esi,st
pushstk ; push stack pointer
_lea ebx,st
mov eax,[esi]
mov [ebx],eax
mov eax,4[esi]
mov 4[ebx],eax
mov ax,8[esi]
mov dx,ax
and dx,8000h
or dx,3fffh
mov 8[ebx],dx
and ax,7fffh ; remove sign
sub ax,3fffh ; remove bias
cwde ; sign extend
mov edx,esi ; st(1)
call __I4LD ; load exponent
done
s615:; fprem1
s710:; fprem
;===================================================================
_lea EAX,st ; point to st(0)
movzx ESI,TENTBL[EDI].t_next ; get index for st(1)
_lea EDX,st(i) ; point to st(1)
call __fprem ; do remainder
savecc ; save condition codes
donearith
s714:; frndint
;===================================================================
rndint ; round top of stack
done
s715:; fscale
;===================================================================
mov esi,edi ; save top of stack index
;;; incstp ; point to st(1)
movzx edi,TENTBL[edi].t_next ; inc stack pointer
_lea EAX,st ; point to scale factor
mov CX,8[EAX] ; save exponent and sign
call __LDI4 ; convert scale factor to integer
mov edi,esi ; restore pointer to st(0)
_lea EBX,st ; point to number to be scaled
;
; check to see if scale factor is too large; 29-mar-91
;
mov EDX,EAX ; get integer scale factor
cwde ; sign extend low order 16 bits
cmp EAX,EDX ; if exponent doesn't fit in 16 bits
_if ne ; then
or CH,CH ; - if negative scale factor
_if s ; - then
sub DX,DX ; - - underflow
sub CX,CX ; - - clear the sign
_else ; - else
mov DX,7FFFh ; - - overflow
mov CX,8[EBX] ; - - get exponent and sign
and CX,8000h ; - - isolate sign
_endif ; - endif
_else ; else
mov DX,8[EBX] ; - get current exponent
mov CX,DX ; - get sign
and CX,8000h ; - ...
and DX,7FFFh ; - isolate exponent
add DX,AX ; - calc. new exponent
_if s ; - if overflow/underflow
or AH,AH ; - - if negative
_if s ; - - then
sub DX,DX ; - - - underflow
sub CX,CX ; - - - clear the sign
_else ; - - else
mov DX,7FFFh ; - - - overflow
_endif ; - - endif
_endif ; - endif
_endif ; endif
or DX,CX ; put in the sign
mov 8[EBX],DX ; store new exponent
done
s470:; fstsw ax
;===================================================================
getword ax,status ; get status word
ifdef __WIN387__
mov ebp,[esp] ; get access to saved registers
mov word ptr S_EAX[ebp],ax ; update user's AX
else
mov ebp,esp ; get access to saved registers
mov S_EAX[ebp],ax ; update user's AX
endif
done
ifdef __WIN387__
__Win387_emulator endp
else
__int7 endp
endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?