OP_DOUBLE_TO_LONG.S revision a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647f
1a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden%verify "executed"
2a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden@include "armv6t2/unopWide.S" {"instr":"bl      __aeabi_d2lz"}
3a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden%include "armv6t2/unopWide.S" {"instr":"bl      d2l_doconv"}
4a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden
5a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden%break
6a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden/*
7a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden * Convert the double in r0/r1 to a long in r0/r1.
8a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden *
9a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden * We have to clip values to long min/max per the specification.  The
10a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden * expected common case is a "reasonable" value that converts directly
11a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden * to modest integer.  The EABI convert function isn't doing this for us.
12a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden */
13a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFaddend2l_doconv:
14a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    stmfd   sp!, {r4, r5, lr}           @ save regs
15a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    ldr     r3, .L${opcode}_max         @ (double)maxlong, hi
16a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    sub     sp, sp, #4                  @ align for EABI
17a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    mov     r2, #0                      @ (double)maxlong, lo
18a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    mov     r4, r0                      @ save r0
19a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    mov     r5, r1                      @  and r1
20a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    bl      __aeabi_dcmpge              @ is arg >= maxlong?
21a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    cmp     r0, #0                      @ nonzero == yes
22a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    mvnne   r0, #0                      @ return maxlong (7fffffffffffffff)
23a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    mvnne   r1, #0x80000000
24a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    bne     1f
25a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden
26a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    mov     r0, r4                      @ recover arg
27a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    mov     r1, r5
28a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    ldr     r3, .L${opcode}_min         @ (double)minlong, hi
29a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    mov     r2, #0                      @ (double)minlong, lo
30a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    bl      __aeabi_dcmple              @ is arg <= minlong?
31a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    cmp     r0, #0                      @ nonzero == yes
32a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    movne   r0, #0                      @ return minlong (8000000000000000)
33a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    movne   r1, #0x80000000
34a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    bne     1f
35a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden
36a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    mov     r0, r4                      @ recover arg
37a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    mov     r1, r5
38a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    mov     r2, r4                      @ compare against self
39a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    mov     r3, r5
40a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    bl      __aeabi_dcmpeq              @ is arg == self?
41a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    cmp     r0, #0                      @ zero == no
42a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    moveq   r1, #0                      @ return zero for NaN
43a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    beq     1f
44a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden
45a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    mov     r0, r4                      @ recover arg
46a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    mov     r1, r5
47a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    bl      __aeabi_d2lz                @ convert double to long
48a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden
49a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden1:
50a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    add     sp, sp, #4
51a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    ldmfd   sp!, {r4, r5, pc}
52a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden
53a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden.L${opcode}_max:
54a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    .word   0x43e00000                  @ maxlong, as a double (high word)
55a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden.L${opcode}_min:
56a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden    .word   0xc3e00000                  @ minlong, as a double (high word)
57a5069fb7eb2da846ff1fc2c903ebd8ce9fa3647fAndy McFadden
58