summaryrefslogtreecommitdiff
path: root/components/external/espruino/libs/math/setprbor.asm
diff options
context:
space:
mode:
Diffstat (limited to 'components/external/espruino/libs/math/setprbor.asm')
-rw-r--r--components/external/espruino/libs/math/setprbor.asm207
1 files changed, 207 insertions, 0 deletions
diff --git a/components/external/espruino/libs/math/setprbor.asm b/components/external/espruino/libs/math/setprbor.asm
new file mode 100644
index 0000000000..8aaf1f6d3f
--- /dev/null
+++ b/components/external/espruino/libs/math/setprbor.asm
@@ -0,0 +1,207 @@
+;
+; Borland assembler header
+;
+; Microsoft MASM subroutines for setting coprocessor precision
+;
+.286
+.287
+PREC_TEXT SEGMENT BYTE PUBLIC 'CODE'
+PREC_TEXT ENDS
+DGROUP group _DATA,_BSS
+ assume cs:PREC_TEXT,ds:DGROUP
+_DATA segment word public 'DATA'
+d@ label byte
+d@w label word
+_DATA ends
+_BSS segment word public 'BSS'
+b@ label byte
+b@w label word
+_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
+
+PREC_TEXT segment byte public 'CODE'
+ assume cs:PREC_TEXT,ds:DGROUP
+; Set coprocessor to single precision float
+ PUBLIC _sprec
+_sprec PROC FAR
+ fclex
+ fwait
+ finit
+ fwait
+ fldcw word ptr ctls
+ fwait
+ ret
+_sprec ENDP
+
+; set coprocessor to long double precision
+ PUBLIC _ldprec
+_ldprec PROC far
+ fclex
+ fwait
+ finit
+ fwait
+ fldcw word ptr ctlld
+ fwait
+ ret
+_ldprec ENDP
+
+; set coprocessor to double precision
+ PUBLIC _dprec
+_dprec PROC far
+ 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 far
+ 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 far
+ 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 far
+ push bp
+ mov bp,sp
+ fnclex
+ fwait
+ pop bp
+ ret
+_fpclear ENDP
+
+
+ PUBLIC _noexcept
+_noexcept PROC far
+ 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 FAR
+ push bp
+ mov bp,sp
+ fld DWORD PTR [bp+6]
+ fsqrt
+ fwait
+ 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 FAR
+ push bp
+ mov bp,sp
+ fld QWORD PTR [bp+6]
+ fsqrt
+ fwait
+ 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 FAR
+ push bp
+ mov bp,sp
+ fld tbyte ptr [bp+6]
+ fsqrt
+ fwait
+ mov sp,bp
+ pop bp
+ ret
+_sqrtl ENDP
+
+
+PREC_TEXT ends
+_DATA segment word public 'DATA'
+s@ label byte
+_DATA ends
+PREC_TEXT segment byte public 'CODE'
+PREC_TEXT ends
+_s@ equ s@
+ public _sprec
+ public _dprec
+ public _ldprec
+ end