ack/mach/powerpc/libem/fif4.s
George Koehler 66f93f08c5 Add fef 4, fif 4. Improve fef 8, fif 8. Other float changes.
When I wrote fef 8, I forgot to test denormalized numbers.  Oops.  Now
fix two of my mistakes:

 - When checking for zero, `extrwi r6, r3, 22, 12` needs to be
   `extrwi r6, r3, 20, 12`.  There are only 20 bits to extract.

 - After the multiplication by 2**64, I forgot to put the fraction in
   [0.5, 1) or (-1, 0.5] by setting IEEE exponent = 1022.

Teach fif 8 about signed zero and NaN.

In ncg/table, change cmf so NaN is not equal to any value, and comment
why ordered comparisons don't work with NaN.  Also add cost for
fctwiz, remove extra `uses REG`.

Edit comment in cfu8.s because the conditional branch might be before
or after fctwiz.
2018-01-22 14:04:15 -05:00

65 lines
1.8 KiB
ArmAsm

.sect .text
! Multiplies two single-precision floats, then splits the product into
! fraction and integer, both as floats, like modff(3) in C,
! http://en.cppreference.com/w/c/numeric/math/modf
!
! Stack: ( a b -- fraction integer )
.define .fif4
.fif4:
lfs f1, 4(sp)
lfs f2, 0(sp)
fmuls f1, f1, f2 ! f1 = a * b
stfs f1, 0(sp)
lwz r3, 0(sp) ! r3 = word of float bits
! IEEE single = sign * 1.fraction * 2**(exponent - 127)
! sign exponent fraction
! 0 1..8 9..31
!
! Subtract 127 from the IEEE exponent. If the result is from
! 0 to 23, then the IEEE fraction has that many integer bits.
extrwi r5, r3, 8, 1 ! r5 = IEEE exponent
addic. r5, r5, -127 ! r5 = nr of integer bits
blt 3f ! branch if no integer
cmpwi r5, 24
bge 4f ! branch if no fraction
! fall through if integer with fraction
! f1 has r5 = 0 to 23 integer bits in the IEEE fraction.
! There are 23 - r5 fraction bits.
li r6, 23
subf r6, r5, r6
srw r3, r3, r6
slw r3, r3, r6 ! clear fraction in word
! fall through
1: stw r3, 0(sp)
lfs f2, 0(sp) ! integer = high word, low word
fsubs f1, f1, f2 ! fraction = value - integer
2: stfs f1, 4(sp) ! push fraction
stfs f2, 0(sp) ! push integer
blr
! f1 is a fraction without integer (or zero).
! Then integer is zero with same sign.
3: extlwi r3, r3, 1, 0 ! extract sign bit
stfs f1, 4(sp) ! push fraction
stw r3, 0(sp) ! push integer = zero with sign
blr
! f1 is an integer without fraction (or infinity or NaN).
! Unless NaN, then fraction is zero with same sign.
4: fcmpu cr0, f1, f1
bun cr0, 5f
extlwi r3, r3, 1, 0 ! extract sign bit
stw r3, 4(sp) ! push fraction = zero with sign
stfs f1, 0(sp) ! push integer
blr
! f1 is NaN, so both fraction and integer are NaN.
5: fmr f2, f1
b 2b