blob: 19ff7235e03b5d246c03baf8ef3696d5988d05e7 [file] [log] [blame]
%include "arm/unopWide.S" {"instr":"bl d2l_doconv"}
%break
/*
* Convert the double in r0/r1 to a long in r0/r1.
*
* We have to clip values to long min/max per the specification. The
* expected common case is a "reasonable" value that converts directly
* to modest integer. The EABI convert function isn't doing this for us.
*/
d2l_doconv:
ubfx r2, r1, #20, #11 @ grab the exponent
movw r3, #0x43e
cmp r2, r3 @ MINLONG < x > MAXLONG?
bhs d2l_special_cases
b __aeabi_d2lz @ tail call to convert double to long
d2l_special_cases:
movw r3, #0x7ff
cmp r2, r3
beq d2l_maybeNaN @ NaN?
d2l_notNaN:
adds r1, r1, r1 @ sign bit to carry
mov r0, #0xffffffff @ assume maxlong for lsw
mov r1, #0x7fffffff @ assume maxlong for msw
adc r0, r0, #0
adc r1, r1, #0 @ convert maxlong to minlong if exp negative
bx lr @ return
d2l_maybeNaN:
orrs r3, r0, r1, lsl #12
beq d2l_notNaN @ if fraction is non-zero, it's a NaN
mov r0, #0
mov r1, #0
bx lr @ return 0 for NaN