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
|