summaryrefslogtreecommitdiff
path: root/vm/mterp/armv6t2/OP_FLOAT_TO_INT.S
blob: 4ba28e776bfe0a2321e41f5ec12b48fc142ad836 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
%verify "executed"
/* EABI appears to have Java-style conversions of +inf/-inf/NaN */
%include "armv6t2/unop.S" {"instr":"bl      __aeabi_f2iz"}

#if 0
@include "armv6t2/unop.S" {"instr":"bl      f2i_doconv"}
@break
/*
 * Convert the float in r0 to an int in r0.
 *
 * We have to clip values to int min/max per the specification.  The
 * expected common case is a "reasonable" value that converts directly
 * to modest integer.  The EABI convert function isn't doing this for us.
 */
f2i_doconv:
    stmfd   sp!, {r4, lr}
    mov     r1, #0x4f000000             @ (float)maxint
    mov     r4, r0
    bl      __aeabi_fcmpge              @ is arg >= maxint?
    cmp     r0, #0                      @ nonzero == yes
    mvnne   r0, #0x80000000             @ return maxint (7fffffff)
    ldmnefd sp!, {r4, pc}

    mov     r0, r4                      @ recover arg
    mov     r1, #0xcf000000             @ (float)minint
    bl      __aeabi_fcmple              @ is arg <= minint?
    cmp     r0, #0                      @ nonzero == yes
    movne   r0, #0x80000000             @ return minint (80000000)
    ldmnefd sp!, {r4, pc}

    mov     r0, r4                      @ recover arg
    mov     r1, r4
    bl      __aeabi_fcmpeq              @ is arg == self?
    cmp     r0, #0                      @ zero == no
    ldmeqfd sp!, {r4, pc}               @ return zero for NaN

    mov     r0, r4                      @ recover arg
    bl      __aeabi_f2iz                @ convert float to int
    ldmfd   sp!, {r4, pc}
#endif