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    ldr     r3, .L${opcode}_max         @ (double)maxlong, hi
16    sub     sp, sp, #4                  @ align for EABI
17    mov     r2, #0                      @ (double)maxlong, lo
18    mov     r4, r0                      @ save r0
19    mov     r5, r1                      @  and r1
20    bl      __aeabi_dcmpge              @ is arg >= maxlong?
21    cmp     r0, #0                      @ nonzero == yes
22    mvnne   r0, #0                      @ return maxlong (7fffffffffffffff)
23    mvnne   r1, #0x80000000
24    bne     1f
25
26    mov     r0, r4                      @ recover arg
27    mov     r1, r5
28    ldr     r3, .L${opcode}_min         @ (double)minlong, hi
29    mov     r2, #0                      @ (double)minlong, lo
30    bl      __aeabi_dcmple              @ is arg <= minlong?
31    cmp     r0, #0                      @ nonzero == yes
32    movne   r0, #0                      @ return minlong (8000000000000000)
33    movne   r1, #0x80000000
34    bne     1f
35
36    mov     r0, r4                      @ recover arg
37    mov     r1, r5
38    mov     r2, r4                      @ compare against self
39    mov     r3, r5
40    bl      __aeabi_dcmpeq              @ is arg == self?
41    cmp     r0, #0                      @ zero == no
42    moveq   r1, #0                      @ return zero for NaN
43    beq     1f
44
45    mov     r0, r4                      @ recover arg
46    mov     r1, r5
47    bl      __aeabi_d2lz                @ convert double to long
48
491:
50    add     sp, sp, #4
51    ldmfd   sp!, {r4, r5, pc}
52
53.L${opcode}_max:
54    .word   0x43e00000                  @ maxlong, as a double (high word)
55.L${opcode}_min:
56    .word   0xc3e00000                  @ minlong, as a double (high word)
57
58