66f93f08c5
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.
62 lines
1.5 KiB
ArmAsm
62 lines
1.5 KiB
ArmAsm
.sect .text; .sect .rom; .sect .data; .sect .bss
|
|
|
|
.sect .text
|
|
|
|
! Split a double-precision float into fraction and exponent, like
|
|
! frexp(3) in C, http://en.cppreference.com/w/c/numeric/math/frexp
|
|
!
|
|
! Stack: ( double -- fraction exponent )
|
|
|
|
.define .fef8
|
|
.fef8:
|
|
lwz r3, 0(sp) ! r3 = high word (bits 0..31)
|
|
lwz r4, 4(sp) ! r4 = low word (bits 32..63)
|
|
|
|
! IEEE double = sign * 1.fraction * 2**(exponent - 1023)
|
|
! sign exponent fraction
|
|
! 0 1..11 12..63
|
|
!
|
|
! IEEE exponent = 1022 in [0.5, 1) or (-1, -0.5].
|
|
|
|
extrwi. r6, r3, 11, 1 ! r6 = IEEE exponent
|
|
beq 3f ! jump if zero or denormalized
|
|
cmpwi r6, 2047
|
|
addi r5, r6, -1022 ! 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, 1022
|
|
insrwi r3, r6, 11, 1 ! IEEE exponent = 1022
|
|
! fall through
|
|
|
|
2: stw r3, 0(sp)
|
|
stw r4, 4(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, 20, 12
|
|
or. r6, r6, r4 ! r6 = high|low fraction
|
|
bne 4f ! jump if not zero
|
|
li r5, 0 ! exponent = 0
|
|
b 2b
|
|
|
|
! Got denormalized number = 0.fraction * 2**-1022
|
|
4: lfd f0, 0(sp)
|
|
lis r6, ha16[.fs_2_64]
|
|
lfs f1, lo16[.fs_2_64](r6)
|
|
fmul f0, f0, f1 ! multiply it by 2**64
|
|
stfd f0, 0(sp)
|
|
lwz r3, 0(sp)
|
|
lwz r4, 4(sp)
|
|
extrwi r6, r3, 11, 1 ! r6 = IEEE exponent
|
|
addi r5, r6, -1022 - 64 ! r5 = our exponent
|
|
b 1b
|
|
|
|
.sect .rom
|
|
.fs_2_64:
|
|
!float 1.84467440737095516e+19 sz 4
|
|
.data1 0137,0200,00,00
|