ack/mach/xr17032/libem/fef8.s

57 lines
1.3 KiB
ArmAsm

#
.sect .text; .sect .rom; .sect .data; .sect .bss
/* 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 DBL_EXPBITS 11
#define DBL_FRACHBITS 20
#define DBL_FRACLBITS 32
#define DBL_FRACBITS 52
#define DBL_EXP_INFNAN 2047
#define DBL_EXP_BIAS 1023
.sect .text
.define .fef8
.fef8:
lw r4, 0(sp) ! r4 = low word (bits 0..31)
lw r5, 4(sp) ! r5 = high word (bits 32..63)
! IEEE double = sign * 1.fraction * 2**(exponent - 1023)
! sign exponent fraction
! 31 30..19 18..0, 31..0
!
! IEEE exponent = 1022 in [0.5, 1) or (-1, -0.5].
ext r7, r5, DBL_FRACHBITS, DBL_EXPBITS ! r7 = IEEE exponent
beq r7, zero, zeroexp ! this number is zero or denormalised, treat specially
nop
li at, DBL_EXP_INFNAN
beq r7, at, return ! just return if infinity or NaN
nop
addiu r7, r7, -[DBL_EXP_BIAS-1] ! undo exponent bias
li at, DBL_EXP_BIAS-1
ins r5, at, DBL_FRACHBITS, DBL_EXPBITS ! replace exponent
return:
addiu sp, sp, -4 ! returning one more quad than we got
sw r5, 8(sp)
sw r6, 4(sp)
sw r7, 0(sp)
jr ra
nop
/* We received a denormalised number or zero. */
zeroexp:
/* TODO: we just assume that the number is zero here. */
mov r5, zero
mov r6, zero
mov r7, zero
b return
nop