summaryrefslogtreecommitdiff
path: root/components/external/espruino/libs/math/setprbor.asm
blob: 8aaf1f6d3f0c65dd678dc01b6e756c98a98ab04d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
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