65 lines
1.8 KiB
ArmAsm
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
|