rtt-f030/components/external/espruino/libs/math/setprec.87

209 lines
2.9 KiB
Plaintext

;
; Microsoft MASM subroutines for setting coprocessor precision
;
.286
.287
_TEXT SEGMENT BYTE PUBLIC 'CODE'
_TEXT ENDS
CONST SEGMENT WORD PUBLIC 'CONST'
CONST ENDS
_BSS SEGMENT WORD PUBLIC 'BSS'
_BSS ENDS
_DATA SEGMENT WORD PUBLIC 'DATA'
_DATA ENDS
DGROUP GROUP CONST, _BSS, _DATA
ASSUME CS: _TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP
EXTRN __fac:QWORD
_BSS SEGMENT
EXTRN __fltused:NEAR
_BSS ENDS
; exception masks (1 = masked)
; 1 invalid operation
; 2 denormalized operand
; 4 zero divide
; 8 overflow
; 10 underflow
; 20 precision
_DATA SEGMENT
; double precision setting
;;ctlwrd dw 01230h ; note this traps on denormal operands!
;;ctld dw 0133fh ; this doesn't trap
ctld dw 01230h
; single precision
ctls dw 01030h
; long double precision
ctlld dw 01320h
_DATA ENDS
ASSUME CS: _TEXT
_TEXT SEGMENT
; Set coprocessor to single precision float
PUBLIC _sprec
_sprec PROC NEAR
fclex
fwait
finit
fwait
fldcw word ptr ctls
fwait
ret
_sprec ENDP
; set coprocessor to long double precision
PUBLIC _ldprec
_ldprec PROC NEAR
fclex
fwait
finit
fwait
fldcw word ptr ctlld
fwait
ret
_ldprec ENDP
; set coprocessor to double precision
PUBLIC _dprec
_dprec PROC NEAR
fclex
fwait
finit
fwait
fldcw word ptr ctld
fwait
ret
_dprec ENDP
; get a double promoted to long double size
; getld( &doub, &ldoub );
PUBLIC _getld
_getld PROC NEAR
push bp
mov bp,sp
push bx
mov bx, word ptr [bp+4]
; fld st(0)
fld qword ptr [bx]
mov bx, word ptr [bp+6]
fstp tbyte ptr [bx]
mov bx, word ptr [bp+4]
fld qword ptr [bx]
mov bx, word ptr [bp+8]
fstp qword ptr [bx]
pop bx
pop bp
ret
_getld ENDP
PUBLIC _getprec
_getprec PROC NEAR
push bp
mov bp,sp
sub sp,4
fstcw [bp-4]
fwait
mov ax,[bp-4]
add sp,4
pop bp
ret
_getprec ENDP
PUBLIC _fpclear
_fpclear PROC NEAR
push bp
mov bp,sp
fnclex
fwait
pop bp
ret
_fpclear ENDP
PUBLIC _noexcept
_noexcept PROC NEAR
push bp
mov bp,sp
push ax
sub sp,4
fnclex
fwait
fstcw [bp-4]
fwait
mov ax,[bp-4]
and ax,0FFC0h
or ax,003fh
mov [bp-4],ax
fldcw [bp-4]
add sp,4
pop ax
pop bp
ret
_noexcept ENDP
;; single precision square root
;; assumes coprocessor precision already set up
;; return value in static __fac
; PUBLIC _sqrtf
;_sqrtf PROC NEAR
; push bp
; mov bp,sp
; fld DWORD PTR [bp+4]
; fsqrt
; fwait
; fstp DWORD PTR __fac
; mov ax,OFFSET __fac
; mov sp,bp
; pop bp
; ret
;_sqrtf ENDP
;
;
;; double precision square root
;; assumes coprocessor precision already set up
;; return value in static __fac
; PUBLIC _sqrt
;_sqrt PROC NEAR
; push bp
; mov bp,sp
; fld QWORD PTR [bp+4]
; fsqrt
; fwait
; fstp QWORD PTR __fac
; mov ax,OFFSET __fac
; mov sp,bp
; pop bp
; ret
;_sqrt ENDP
;
;
;; long double precision square root
;; assumes coprocessor precision already set up
;; return value in fp register
; PUBLIC _sqrtl
;_sqrtl PROC NEAR
; push bp
; mov bp,sp
; fld tbyte ptr [bp+4]
; fsqrt
; fwait
; mov sp,bp
; pop bp
; ret
;_sqrtl ENDP
;
_TEXT ENDS
END