1 %verify "executed" 2 /* EABI appears to have Java-style conversions of +inf/-inf/NaN */ 3 %include "armv6t2/unopNarrower.S" {"instr":"bl __aeabi_d2iz"} 4 5 #if 0 6 @include "armv5te/unopNarrower.S" {"instr":"bl d2i_doconv"} 7 @break 8 /* 9 * Convert the double in r0/r1 to an int in r0. 10 * 11 * We have to clip values to int min/max per the specification. The 12 * expected common case is a "reasonable" value that converts directly 13 * to modest integer. The EABI convert function isn't doing this for us. 14 */ 15 d2i_doconv: 16 stmfd sp!, {r4, r5, lr} @ save regs 17 mov r2, #0x80000000 @ maxint, as a double (low word) 18 mov r2, r2, asr #9 @ 0xffc00000 19 sub sp, sp, #4 @ align for EABI 20 mvn r3, #0xbe000000 @ maxint, as a double (high word) 21 sub r3, r3, #0x00200000 @ 0x41dfffff 22 mov r4, r0 @ save a copy of r0 23 mov r5, r1 @ and r1 24 bl __aeabi_dcmpge @ is arg >= maxint? 25 cmp r0, #0 @ nonzero == yes 26 mvnne r0, #0x80000000 @ return maxint (0x7fffffff) 27 bne 1f 28 29 mov r0, r4 @ recover arg 30 mov r1, r5 31 mov r3, #0xc1000000 @ minint, as a double (high word) 32 add r3, r3, #0x00e00000 @ 0xc1e00000 33 mov r2, #0 @ minint, as a double (low word) 34 bl __aeabi_dcmple @ is arg <= minint? 35 cmp r0, #0 @ nonzero == yes 36 movne r0, #0x80000000 @ return minint (80000000) 37 bne 1f 38 39 mov r0, r4 @ recover arg 40 mov r1, r5 41 mov r2, r4 @ compare against self 42 mov r3, r5 43 bl __aeabi_dcmpeq @ is arg == self? 44 cmp r0, #0 @ zero == no 45 beq 1f @ return zero for NaN 46 47 mov r0, r4 @ recover arg 48 mov r1, r5 49 bl __aeabi_d2iz @ convert double to int 50 51 1: 52 add sp, sp, #4 53 ldmfd sp!, {r4, r5, pc} 54 #endif 55