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