OSDN Git Service

Dalvik fast interpreter support and JIT implementation
[android-x86/dalvik.git] / vm / compiler / template / mips / TEMPLATE_DOUBLE_TO_INT_VFP.S
1 %verify "executed"
2 %include "mips/funopNarrower.S" {"instr":"b    d2i_doconv","instr_f":"b    d2i_doconv"}
3
4 /*
5  * Convert the double in a0/a1 to an int in a0.
6  *
7  * We have to clip values to int min/max per the specification.  The
8  * expected common case is a "reasonable" value that converts directly
9  * to modest integer.  The EABI convert function isn't doing this for us.
10  * Use rBIX / rOBJ as global to hold arguments (they are not bound to a global var)
11  */
12
13 d2i_doconv:
14 #ifdef SOFT_FLOAT
15     la          t0, .LDOUBLE_TO_INT_max
16     LOAD64(rARG2, rARG3, t0)
17     move        rBIX, rARG0                       # save a0
18     move        rOBJ, rARG1                       #  and a1
19     JAL(__gedf2)                               # is arg >= maxint?
20
21     move        t0, v0
22     li          v0, ~0x80000000                # return maxint (7fffffff)
23     bgez        t0, .L${opcode}_set_vreg       # nonzero == yes
24
25     move        rARG0, rBIX                       # recover arg
26     move        rARG1, rOBJ
27     la          t0, .LDOUBLE_TO_INT_min
28     LOAD64(rARG2, rARG3, t0)
29     JAL(__ledf2)                               # is arg <= minint?
30
31     move        t0, v0
32     li          v0, 0x80000000                 # return minint (80000000)
33     blez        t0, .L${opcode}_set_vreg       # nonzero == yes
34
35     move        rARG0, rBIX                  # recover arg
36     move        rARG1, rOBJ
37     move        rARG2, rBIX                  # compare against self
38     move        rARG3, rOBJ
39     JAL(__nedf2)                        # is arg == self?
40
41     move        t0, v0                  # zero == no
42     li          v0, 0
43     bnez        t0, .L${opcode}_set_vreg        # return zero for NaN
44
45     move        rARG0, rBIX                  # recover arg
46     move        rARG1, rOBJ
47     JAL(__fixdfsi)                      # convert double to int
48     b           .L${opcode}_set_vreg
49 #else
50     la          t0, .LDOUBLE_TO_INT_max
51     LOAD64_F(fa1, fa1f, t0)
52     c.ole.d     fcc0, fa1, fa0
53     l.s         fv0, .LDOUBLE_TO_INT_maxret
54     bc1t        .L${opcode}_set_vreg_f
55
56     la          t0, .LDOUBLE_TO_INT_min
57     LOAD64_F(fa1, fa1f, t0)
58     c.ole.d     fcc0, fa0, fa1
59     l.s         fv0, .LDOUBLE_TO_INT_minret
60     bc1t        .L${opcode}_set_vreg_f
61
62     mov.d       fa1, fa0
63     c.un.d      fcc0, fa0, fa1
64     li.s        fv0, 0
65     bc1t        .L${opcode}_set_vreg_f
66
67     trunc.w.d   fv0, fa0
68     b           .L${opcode}_set_vreg_f
69 #endif
70
71
72 .LDOUBLE_TO_INT_max:
73     .dword   0x41dfffffffc00000
74 .LDOUBLE_TO_INT_min:
75     .dword   0xc1e0000000000000                  # minint, as a double (high word)
76 .LDOUBLE_TO_INT_maxret:
77     .word   0x7fffffff
78 .LDOUBLE_TO_INT_minret:
79     .word   0x80000000