ack/mach/powerpc/libem/fef4.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

49 lines
1.2 KiB
ArmAsm

.sect .text
! Split a single-precision float into fraction and exponent, like
! frexpf(3) in C, http://en.cppreference.com/w/c/numeric/math/frexp
!
! Stack: ( single -- fraction exponent )
.define .fef4
.fef4:
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
!
! IEEE exponent = 126 in [0.5, 1) or (-1, -0.5].
extrwi. r6, r3, 8, 1 ! r6 = IEEE exponent
beq 3f ! jump if zero or denormalized
cmpwi r6, 255
addi r5, r6, -126 ! r5 = our exponent
beq 2f ! jump if infinity or NaN
! fall through if normalized
! Put fraction in [0.5, 1) or (-1, -0.5].
1: li r6, 126
insrwi r3, r6, 8, 1 ! IEEE exponent = 126
! fall through
2: stw r3, 0(sp) ! push fraction
stwu r5, -4(sp) ! push exponent
blr
! Got denormalized number or zero, probably zero.
! If zero, then exponent must also be zero.
3: extrwi. r6, r3, 23, 9 ! r6 = fraction
bne 4f ! jump if not zero
li r5, 0 ! exponent = 0
b 2b
! Got denormalized number = 0.fraction * 2**-126
4: cntlzw r5, r6
addi r5, r5, -8
slw r6, r6, r5 ! shift left to make 1.fraction
insrwi r3, r6, 23, 9 ! set new fraction
li r6, -126 + 1
subf r5, r5, r6 ! r5 = our exponent
b 1b