1%verify "executed" 2@include "armv5te/unopWide.S" {"instr":"bl __aeabi_d2lz"} 3%include "armv5te/unopWide.S" {"instr":"bl d2l_doconv"} 4 5%break 6/* 7 * Convert the double in r0/r1 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 */ 13d2l_doconv: 14 stmfd sp!, {r4, r5, lr} @ save regs 15 ldr r3, .L${opcode}_max @ (double)maxlong, hi 16 sub sp, sp, #4 @ align for EABI 17 mov r2, #0 @ (double)maxlong, lo 18 mov r4, r0 @ save r0 19 mov r5, r1 @ and r1 20 bl __aeabi_dcmpge @ is arg >= maxlong? 21 cmp r0, #0 @ nonzero == yes 22 mvnne r0, #0 @ return maxlong (7fffffffffffffff) 23 mvnne r1, #0x80000000 24 bne 1f 25 26 mov r0, r4 @ recover arg 27 mov r1, r5 28 ldr r3, .L${opcode}_min @ (double)minlong, hi 29 mov r2, #0 @ (double)minlong, lo 30 bl __aeabi_dcmple @ is arg <= minlong? 31 cmp r0, #0 @ nonzero == yes 32 movne r0, #0 @ return minlong (8000000000000000) 33 movne r1, #0x80000000 34 bne 1f 35 36 mov r0, r4 @ recover arg 37 mov r1, r5 38 mov r2, r4 @ compare against self 39 mov r3, r5 40 bl __aeabi_dcmpeq @ is arg == self? 41 cmp r0, #0 @ zero == no 42 moveq r1, #0 @ return zero for NaN 43 beq 1f 44 45 mov r0, r4 @ recover arg 46 mov r1, r5 47 bl __aeabi_d2lz @ convert double to long 48 491: 50 add sp, sp, #4 51 ldmfd sp!, {r4, r5, pc} 52 53.L${opcode}_max: 54 .word 0x43e00000 @ maxlong, as a double (high word) 55.L${opcode}_min: 56 .word 0xc3e00000 @ minlong, as a double (high word) 57 58