1%include "arm/unopWide.S" {"instr":"bl d2l_doconv"} 2 3%break 4/* 5 * Convert the double in r0/r1 to a long in r0/r1. 6 * 7 * We have to clip values to long min/max per the specification. The 8 * expected common case is a "reasonable" value that converts directly 9 * to modest integer. The EABI convert function isn't doing this for us. 10 */ 11d2l_doconv: 12 ubfx r2, r1, #20, #11 @ grab the exponent 13 movw r3, #0x43e 14 cmp r2, r3 @ MINLONG < x > MAXLONG? 15 bhs d2l_special_cases 16 b __aeabi_d2lz @ tail call to convert double to long 17d2l_special_cases: 18 movw r3, #0x7ff 19 cmp r2, r3 20 beq d2l_maybeNaN @ NaN? 21d2l_notNaN: 22 adds r1, r1, r1 @ sign bit to carry 23 mov r0, #0xffffffff @ assume maxlong for lsw 24 mov r1, #0x7fffffff @ assume maxlong for msw 25 adc r0, r0, #0 26 adc r1, r1, #0 @ convert maxlong to minlong if exp negative 27 bx lr @ return 28d2l_maybeNaN: 29 orrs r3, r0, r1, lsl #12 30 beq d2l_notNaN @ if fraction is non-zero, it's a NaN 31 mov r0, #0 32 mov r1, #0 33 bx lr @ return 0 for NaN 34