1%verify "executed"
2@include "armv5te/unopWide.S" {"instr":"bl      __aeabi_d2lz"}
3%include "armv5te/unopWide.S" {"instr":"bl      d2l_doconv"}
4
5%break
6/*
7 * Convert the double in r0/r1 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 */
13d2l_doconv:
14    stmfd   sp!, {r4, r5, lr}           @ save regs
15    mov     r3, #0x43000000             @ maxlong, as a double (high word)
16    add     r3, #0x00e00000             @  0x43e00000
17    mov     r2, #0                      @ maxlong, as a double (low word)
18    sub     sp, sp, #4                  @ align for EABI
19    mov     r4, r0                      @ save a copy of r0
20    mov     r5, r1                      @  and r1
21    bl      __aeabi_dcmpge              @ is arg >= maxlong?
22    cmp     r0, #0                      @ nonzero == yes
23    mvnne   r0, #0                      @ return maxlong (7fffffffffffffff)
24    mvnne   r1, #0x80000000
25    bne     1f
26
27    mov     r0, r4                      @ recover arg
28    mov     r1, r5
29    mov     r3, #0xc3000000             @ minlong, as a double (high word)
30    add     r3, #0x00e00000             @  0xc3e00000
31    mov     r2, #0                      @ minlong, as a double (low word)
32    bl      __aeabi_dcmple              @ is arg <= minlong?
33    cmp     r0, #0                      @ nonzero == yes
34    movne   r0, #0                      @ return minlong (8000000000000000)
35    movne   r1, #0x80000000
36    bne     1f
37
38    mov     r0, r4                      @ recover arg
39    mov     r1, r5
40    mov     r2, r4                      @ compare against self
41    mov     r3, r5
42    bl      __aeabi_dcmpeq              @ is arg == self?
43    cmp     r0, #0                      @ zero == no
44    moveq   r1, #0                      @ return zero for NaN
45    beq     1f
46
47    mov     r0, r4                      @ recover arg
48    mov     r1, r5
49    bl      __aeabi_d2lz                @ convert double to long
50
511:
52    add     sp, sp, #4
53    ldmfd   sp!, {r4, r5, pc}
54