2 %include "mips/funopNarrower.S" {"instr":"b d2i_doconv","instr_f":"b d2i_doconv"}
5 * Convert the double in a0/a1 to an int in a0.
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)
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?
22 li v0, ~0x80000000 # return maxint (7fffffff)
23 bgez t0, .L${opcode}_set_vreg # nonzero == yes
25 move rARG0, rBIX # recover arg
27 la t0, .LDOUBLE_TO_INT_min
28 LOAD64(rARG2, rARG3, t0)
29 JAL(__ledf2) # is arg <= minint?
32 li v0, 0x80000000 # return minint (80000000)
33 blez t0, .L${opcode}_set_vreg # nonzero == yes
35 move rARG0, rBIX # recover arg
37 move rARG2, rBIX # compare against self
39 JAL(__nedf2) # is arg == self?
41 move t0, v0 # zero == no
43 bnez t0, .L${opcode}_set_vreg # return zero for NaN
45 move rARG0, rBIX # recover arg
47 JAL(__fixdfsi) # convert double to int
48 b .L${opcode}_set_vreg
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
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
65 bc1t .L${opcode}_set_vreg_f
68 b .L${opcode}_set_vreg_f
73 .dword 0x41dfffffffc00000
75 .dword 0xc1e0000000000000 # minint, as a double (high word)
76 .LDOUBLE_TO_INT_maxret:
78 .LDOUBLE_TO_INT_minret: