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