blob: b1792ec56515e4fe0cf90b2e92e41376c3b15285 [file] [log] [blame]
Douglas Leung200f0402016-02-25 20:05:47 -08001%include "mips/unopNarrower.S" {"instr":"b d2i_doconv"}
2/*
3 * Convert the double in a0/a1 to an int in a0.
4 *
5 * We have to clip values to int min/max per the specification. The
6 * expected common case is a "reasonable" value that converts directly
7 * to modest integer. The EABI convert function isn't doing this for us.
8 */
9%break
10
11d2i_doconv:
12#ifdef MIPS32REVGE6
13 la t0, .LDOUBLE_TO_INT_max
14 LOAD64_F(fa1, fa1f, t0)
Alexey Frunze28d06c12016-10-20 21:50:05 -070015 cmp.le.d ft2, fa1, fa0
Douglas Leung200f0402016-02-25 20:05:47 -080016 l.s fv0, .LDOUBLE_TO_INT_maxret
17 bc1nez ft2, .L${opcode}_set_vreg_f
18
19 la t0, .LDOUBLE_TO_INT_min
20 LOAD64_F(fa1, fa1f, t0)
Alexey Frunze28d06c12016-10-20 21:50:05 -070021 cmp.le.d ft2, fa0, fa1
Douglas Leung200f0402016-02-25 20:05:47 -080022 l.s fv0, .LDOUBLE_TO_INT_minret
23 bc1nez ft2, .L${opcode}_set_vreg_f
24
25 mov.d fa1, fa0
26 cmp.un.d ft2, fa0, fa1
27 li.s fv0, 0
28 bc1nez ft2, .L${opcode}_set_vreg_f
29#else
30 la t0, .LDOUBLE_TO_INT_max
31 LOAD64_F(fa1, fa1f, t0)
32 c.ole.d fcc0, fa1, fa0
33 l.s fv0, .LDOUBLE_TO_INT_maxret
34 bc1t .L${opcode}_set_vreg_f
35
36 la t0, .LDOUBLE_TO_INT_min
37 LOAD64_F(fa1, fa1f, t0)
38 c.ole.d fcc0, fa0, fa1
39 l.s fv0, .LDOUBLE_TO_INT_minret
40 bc1t .L${opcode}_set_vreg_f
41
42 mov.d fa1, fa0
43 c.un.d fcc0, fa0, fa1
44 li.s fv0, 0
45 bc1t .L${opcode}_set_vreg_f
46#endif
47
48 trunc.w.d fv0, fa0
49 b .L${opcode}_set_vreg_f
50
51.LDOUBLE_TO_INT_max:
52 .dword 0x41dfffffffc00000
53.LDOUBLE_TO_INT_min:
54 .dword 0xc1e0000000000000 # minint, as a double (high word)
55.LDOUBLE_TO_INT_maxret:
56 .word 0x7fffffff
57.LDOUBLE_TO_INT_minret:
58 .word 0x80000000