Mercurial > hg > index.cgi
diff src/fps.s @ 82:9a4e2364a966
Fix logic in int32_mul and overflow integer multiply to floating point
It seems logical to allow integer multiplication to overflow to floating
point. If this turns out to be unfortunate, it can be changed. In this
update, 32 bit integer multiplication will overflow to floating point.
author | William Astle <lost@l-w.ca> |
---|---|
date | Sat, 07 Oct 2023 13:39:25 -0600 |
parents | bb50ac9fdf37 |
children | a492441bfc56 |
line wrap: on
line diff
--- a/src/fps.s Sat Oct 07 12:59:43 2023 -0600 +++ b/src/fps.s Sat Oct 07 13:39:25 2023 -0600 @@ -42,6 +42,35 @@ clr fpa0extra ; clear extra precision jmp fps_add10 ; go normalize the result and return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Convert 64 bit unsigned value at (X) to single precision floating point in value accumulator at (Y) +; +; Cases: +; * byte 0 is first nonzero - exponent at 64 bits right, use upper 0 to 4 +; * byte 1 is first nonzero - exponent at 56 bits right, use bytes 1 to 5 +; * byte 2 is first nonzero - exponent at 48 bits right, use bytes 2 to 6 +; * otherwise - exponent at 40 bits right, use bytes 3 to 7 +fps_fromuint64 clra ; set sign to positive +fps_fromuint64s sta fpa0+fps.sign ; save sign of result + ldb #0xc0 ; exponent if binary point is 64 bits to the right + lda ,x+ ; is the first byte zero? + bne fps_fromuint64a ; brif not + subb #8 ; lose a byte off exponent + lda ,x+ ; is the second byte zero? + bne fps_fromuint64a ; brif not + subb #8 ; lose another byte off exponent + lda ,x+ ; is third byte zero? + bne fps_fromuint64a ; brif not + subb #8 ; lose another byte + lda ,x+ ; get first byte to copy +fps_fromuint64a stb fpa0+fps.exp ; save exponent + sta fpa0+fps.sig ; save high byte of significand + ldd ,x ; copy next two bytes to significand + std fpa0+fps.sig+1 + ldd 2,x ; and the final byte and extra precision + sta fpa0+fps.sig+3 + stb fpa0extra + jmp fps_add10 ; go normalize the result and return +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Unary negation - negate (X) to (Y) fps_neg ldd 2,x ; copy to output and keep exponent in A std 2,y