1%include "arm/unopWider.S" {"instr":"bl      f2l_doconv"}
2
3%break
4/*
5 * Convert the float in r0 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 */
11f2l_doconv:
12    ubfx    r2, r0, #23, #8             @ grab the exponent
13    cmp     r2, #0xbe                   @ MININT < x > MAXINT?
14    bhs     f2l_special_cases
15    b       __aeabi_f2lz                @ tail call to convert float to long
16f2l_special_cases:
17    cmp     r2, #0xff                   @ NaN or infinity?
18    beq     f2l_maybeNaN
19f2l_notNaN:
20    adds    r0, r0, r0                  @ sign bit to carry
21    mov     r0, #0xffffffff             @ assume maxlong for lsw
22    mov     r1, #0x7fffffff             @ assume maxlong for msw
23    adc     r0, r0, #0
24    adc     r1, r1, #0                  @ convert maxlong to minlong if exp negative
25    bx      lr                          @ return
26f2l_maybeNaN:
27    lsls    r3, r0, #9
28    beq     f2l_notNaN                  @ if fraction is non-zero, it's a NaN
29    mov     r0, #0
30    mov     r1, #0
31    bx      lr                          @ return 0 for NaN
32