1 %verify "executed" 2 @include "armv6t2/unopWider.S" {"instr":"bl __aeabi_f2lz"} 3 %include "armv6t2/unopWider.S" {"instr":"bl f2l_doconv"} 4 5 %break 6 /* 7 * Convert the float in r0 to a long in r0/r1. 8 * 9 * We have to clip values to long min/max per the specification. The 10 * expected common case is a "reasonable" value that converts directly 11 * to modest integer. The EABI convert function isn't doing this for us. 12 */ 13 f2l_doconv: 14 stmfd sp!, {r4, lr} 15 mov r1, #0x5f000000 @ (float)maxlong 16 mov r4, r0 17 bl __aeabi_fcmpge @ is arg >= maxlong? 18 cmp r0, #0 @ nonzero == yes 19 mvnne r0, #0 @ return maxlong (7fffffff) 20 mvnne r1, #0x80000000 21 ldmnefd sp!, {r4, pc} 22 23 mov r0, r4 @ recover arg 24 mov r1, #0xdf000000 @ (float)minlong 25 bl __aeabi_fcmple @ is arg <= minlong? 26 cmp r0, #0 @ nonzero == yes 27 movne r0, #0 @ return minlong (80000000) 28 movne r1, #0x80000000 29 ldmnefd sp!, {r4, pc} 30 31 mov r0, r4 @ recover arg 32 mov r1, r4 33 bl __aeabi_fcmpeq @ is arg == self? 34 cmp r0, #0 @ zero == no 35 moveq r1, #0 @ return zero for NaN 36 ldmeqfd sp!, {r4, pc} 37 38 mov r0, r4 @ recover arg 39 bl __aeabi_f2lz @ convert float to long 40 ldmfd sp!, {r4, pc} 41