032bcffef6
The new features are the hi16/lo16 and ha16/lo16 syntax for relocations, and the extended mnemonics like "blr". Use ha16/lo16 to load some double floats with 2 instructions (lis/lfd) instead of 3 (lis/ori/lfd). Use the extended names for branches, comparisons, and bit rotations, so I can more easily read the code. The new names often encode the same machine instructions as the old names, except in a few places where I changed the instructions. Stop using andi. when we don't need to set cr0. In inn.s, I change andi. to extrwi to extract the same bits. In los.s and sts.s, I change "andi. r3, r3, ~3" to "clrrwi r3, r3, 2". This avoids setting cr0 and also stops clearing the high 16 bits of r3. In csa.s, los.s, sts.s, I change some comparisons and right shifts from signed to unsigned (cmplw, cmplwi, srwi), because the sizes are unsigned. In inn.s, the right shift can be signed (sraw) or unsigned (srw), but I use srw because we don't need the carry bit. In fef8.s, I save an instruction by using rlwinm instead of addis/andc to rlwinm to clear a field. The code no longer kills r7. In both fef8.s and fif8.s, I remove the list of killed registers. Also remove some whitespace from ends of lines.
68 lines
1.6 KiB
ArmAsm
68 lines
1.6 KiB
ArmAsm
.sect .text
|
|
|
|
! Multiplies two double-precision floats, then splits the product into
|
|
! integer and fraction, like modf(3) in C. On entry:
|
|
! f1 = float
|
|
! f2 = other float
|
|
! Yields:
|
|
! f1 = fraction
|
|
! f2 = integer
|
|
|
|
.define .fif8
|
|
.fif8:
|
|
fmul f1, f1, f2
|
|
stfdu f1, -8(sp) ! push f1 = product
|
|
lwz r3, 0(sp) ! r3 = high word
|
|
lwz r4, 4(sp) ! r4 = low word
|
|
|
|
! IEEE double-precision format:
|
|
! sign exponent fraction
|
|
! 0 1..11 12..63
|
|
! Subtract 1023 from the IEEE exponent. If the result is from
|
|
! 0 to 51, then the IEEE fraction has that many integer bits.
|
|
! (IEEE has an implicit 1 before its fraction. If the IEEE
|
|
! fraction has 0 integer bits, we still have an integer.)
|
|
extrwi r5, r3, 11, 1 ! r5 = IEEE exponent
|
|
addic. r5, r5, -1023 ! r5 = nr of integer bits
|
|
blt no_int
|
|
cmpwi r5, 21
|
|
blt small_int
|
|
cmpwi r5, 52
|
|
blt big_int
|
|
|
|
! f1 is an integer without fraction (or infinity or NaN).
|
|
fmr f2, f1 ! integer = f1
|
|
b subtract
|
|
|
|
no_int:
|
|
! f1 is a fraction without integer.
|
|
fsub f2, f1, f1 ! integer = zero
|
|
b done
|
|
|
|
small_int:
|
|
! f1 has r5 = 0 to 20 integer bits in the IEEE fraction.
|
|
! High word has 20 - r5 fraction bits.
|
|
li r6, 20
|
|
subf r6, r5, r6
|
|
srw r3, r3, r6
|
|
li r4, 0 ! clear low word
|
|
slw r3, r3, r6 ! clear fraction in high word
|
|
b move_int
|
|
|
|
big_int:
|
|
! f1 has r5 = 21 to 51 to integer bits.
|
|
! Low word has 52 - r5 fraction bits.
|
|
li r6, 52
|
|
subf r6, r5, r6
|
|
srw r4, r4, r6
|
|
slw r4, r4, r6 ! clear fraction in low word
|
|
move_int:
|
|
stw r3, 0(sp)
|
|
stw r4, 4(sp)
|
|
lfd f2, 0(sp) ! f2 = integer
|
|
subtract:
|
|
fsub f1, f1, f2 ! fraction = value - integer
|
|
done:
|
|
addi sp, sp, 8 ! restore stack pointer
|
|
blr
|