1@include "arm/unopWider.S" {"instr":"bl      __aeabi_f2lz"}
2%include "arm/unopWider.S" {"instr":"bl      f2l_doconv"}
3
4%break
5/*
6 * Convert the float in r0 to a long in r0/r1.
7 *
8 * We have to clip values to long min/max per the specification.  The
9 * expected common case is a "reasonable" value that converts directly
10 * to modest integer.  The EABI convert function isn't doing this for us.
11 */
12f2l_doconv:
13    stmfd   sp!, {r4, lr}
14    mov     r1, #0x5f000000             @ (float)maxlong
15    mov     r4, r0
16    bl      __aeabi_fcmpge              @ is arg >= maxlong?
17    cmp     r0, #0                      @ nonzero == yes
18    mvnne   r0, #0                      @ return maxlong (7fffffff)
19    mvnne   r1, #0x80000000
20    popne   {r4, pc}
21
22    mov     r0, r4                      @ recover arg
23    mov     r1, #0xdf000000             @ (float)minlong
24    bl      __aeabi_fcmple              @ is arg <= minlong?
25    cmp     r0, #0                      @ nonzero == yes
26    movne   r0, #0                      @ return minlong (80000000)
27    movne   r1, #0x80000000
28    popne   {r4, pc}
29
30    mov     r0, r4                      @ recover arg
31    mov     r1, r4
32    bl      __aeabi_fcmpeq              @ is arg == self?
33    cmp     r0, #0                      @ zero == no
34    moveq   r1, #0                      @ return zero for NaN
35    popeq   {r4, pc}
36
37    mov     r0, r4                      @ recover arg
38    bl      __aeabi_f2lz                @ convert float to long
39    ldmfd   sp!, {r4, pc}
40