1 %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 11 d2i_doconv: 12 #ifdef MIPS32REVGE6 13 la t0, .LDOUBLE_TO_INT_max 14 LOAD64_F(fa1, fa1f, t0) 15 cmp.ule.d ft2, fa1, fa0 16 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) 21 cmp.ule.d ft2, fa0, fa1 22 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 59