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
|
! bcc 386 floating point routines (version 2)
! -- dtoi, dtol, dtoui, dtoul, ftoi, ftol (todo: ftoui, ftoul)
! authors: Timothy Murphy (tim@maths.tcd.ie), Bruce Evans
#include "fplib.h"
.extern fpoverflow
.extern Fpushf
! Convert double x at [ebx] to int and return in eax
.globl dtoi
.globl dtol
.align ALIGNMENT
dtoi:
dtol:
mov eax,D_HIGH[ebx]
mov ecx,eax
and ecx,#D_EXP_MASK ! extract exponent
jz retz ! if 0 return 0
test eax,#D_SIGN_MASK
jnz negative
call into_dtoui
cmp eax,#INT_MAX
ja overflow_int_max
ret
.align ALIGNMENT
negative:
and eax,#~D_SIGN_MASK
call into_dtoui
cmp eax,#INT_MIN
ja overflow_int_min
neg eax
ret
.align ALIGNMENT
overflow_int_max:
call fpoverflow
mov eax,#INT_MAX
ret
.align ALIGNMENT
overflow_int_min:
js return ! actually INT_MIN is OK
call fpoverflow
mov eax,#INT_MIN
return:
ret
.align ALIGNMENT
retz:
sub eax,eax ! clear return value
ret
! Convert double x at [ebx] to unsigned and return in eax
.globl dtoui
.globl dtoul
.align ALIGNMENT
dtoui:
dtoul:
mov eax,D_HIGH[ebx]
mov ecx,eax
and ecx,#D_EXP_MASK ! extract exponent
jz retz ! if 0 return 0
test eax,#D_SIGN_MASK
jnz overflow_0
into_dtoui:
mov edx,D_LOW[ebx]
and eax,#D_FRAC_MASK ! extract fraction
or eax,#D_NORM_MASK ! restore normalization bit
shr ecx,#D_EXP_SHIFT ! convert exponent to number
sub ecx,#D_EXP_BIAS+D_NORM_BIT ! adjust radix point
jl dtoui_rightshift ! should we shift left or right?
cmp ecx,#D_BIT-D_FRAC_BIT ! can shift left by at most this
ja overflow_uint_max ! if more, overflow
shld eax,edx,cl
ret
.align ALIGNMENT
dtoui_rightshift:
neg ecx ! make shift count > 0
cmp ecx,#REG_BIT ! big shifts would be taken mod REG_BIT ...
jae retz ! ... no good
shr eax,cl ! otherwise it is faster to do the shift ...
ret ! ... then to jump for the slightly smaller
! ... shift counts that shift out all bits
.align ALIGNMENT
overflow_0:
call fpoverflow
sub eax,eax
ret
.align ALIGNMENT
overflow_uint_max:
call fpoverflow
mov eax,#UINT_MAX
ret
! ftoi is like dtoi except ebx points to a float instead of a double.
! This is a quickly-written slowish version that does not take advantage
! of the float being smaller.
.globl ftoi
.globl ftol
.align ALIGNMENT
ftoi:
ftol:
call Fpushf
mov ebx,esp
call dtoi
add esp,#D_SIZE
ret
|