1/* ieee754-df.S double-precision floating point support for ARM 2 3 Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. 4 Contributed by Nicolas Pitre (nico@cam.org) 5 6 This file is free software; you can redistribute it and/or modify it 7 under the terms of the GNU General Public License as published by the 8 Free Software Foundation; either version 3, or (at your option) any 9 later version. 10 11 This file is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 Under Section 7 of GPL version 3, you are granted additional 17 permissions described in the GCC Runtime Library Exception, version 18 3.1, as published by the Free Software Foundation. 19 20 You should have received a copy of the GNU General Public License and 21 a copy of the GCC Runtime Library Exception along with this program; 22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 <http://www.gnu.org/licenses/>. */ 24 25/* 26 * Notes: 27 * 28 * The goal of this code is to be as fast as possible. This is 29 * not meant to be easy to understand for the casual reader. 30 * For slightly simpler code please see the single precision version 31 * of this file. 32 * 33 * Only the default rounding mode is intended for best performances. 34 * Exceptions aren't supported yet, but that can be added quite easily 35 * if necessary without impacting performances. 36 */ 37 38 39@ For FPA, float words are always big-endian. 40@ For VFP, floats words follow the memory system mode. 41#if defined(__VFP_FP__) && !defined(__ARMEB__) 42#define xl r0 43#define xh r1 44#define yl r2 45#define yh r3 46#else 47#define xh r0 48#define xl r1 49#define yh r2 50#define yl r3 51#endif 52 53 54#ifdef L_arm_negdf2 55 56ARM_FUNC_START negdf2 57ARM_FUNC_ALIAS aeabi_dneg negdf2 58 59 @ flip sign bit 60 eor xh, xh, #0x80000000 61 RET 62 63 FUNC_END aeabi_dneg 64 FUNC_END negdf2 65 66#endif 67 68#ifdef L_arm_addsubdf3 69 70ARM_FUNC_START aeabi_drsub 71 72 eor xh, xh, #0x80000000 @ flip sign bit of first arg 73 b 1f 74 75ARM_FUNC_START subdf3 76ARM_FUNC_ALIAS aeabi_dsub subdf3 77 78 eor yh, yh, #0x80000000 @ flip sign bit of second arg 79#if defined(__INTERWORKING_STUBS__) 80 b 1f @ Skip Thumb-code prologue 81#endif 82 83ARM_FUNC_START adddf3 84ARM_FUNC_ALIAS aeabi_dadd adddf3 85 861: do_push {r4, r5, lr} 87 88 @ Look for zeroes, equal values, INF, or NAN. 89 shift1 lsl, r4, xh, #1 90 shift1 lsl, r5, yh, #1 91 teq r4, r5 92 do_it eq 93 teqeq xl, yl 94 do_it ne, ttt 95 COND(orr,s,ne) ip, r4, xl 96 COND(orr,s,ne) ip, r5, yl 97 COND(mvn,s,ne) ip, r4, asr #21 98 COND(mvn,s,ne) ip, r5, asr #21 99 beq LSYM(Lad_s) 100 101 @ Compute exponent difference. Make largest exponent in r4, 102 @ corresponding arg in xh-xl, and positive exponent difference in r5. 103 shift1 lsr, r4, r4, #21 104 rsbs r5, r4, r5, lsr #21 105 do_it lt 106 rsblt r5, r5, #0 107 ble 1f 108 add r4, r4, r5 109 eor yl, xl, yl 110 eor yh, xh, yh 111 eor xl, yl, xl 112 eor xh, yh, xh 113 eor yl, xl, yl 114 eor yh, xh, yh 1151: 116 @ If exponent difference is too large, return largest argument 117 @ already in xh-xl. We need up to 54 bit to handle proper rounding 118 @ of 0x1p54 - 1.1. 119 cmp r5, #54 120 do_it hi 121 RETLDM "r4, r5" hi 122 123 @ Convert mantissa to signed integer. 124 tst xh, #0x80000000 125 mov xh, xh, lsl #12 126 mov ip, #0x00100000 127 orr xh, ip, xh, lsr #12 128 beq 1f 129#if defined(__thumb2__) 130 negs xl, xl 131 sbc xh, xh, xh, lsl #1 132#else 133 rsbs xl, xl, #0 134 rsc xh, xh, #0 135#endif 1361: 137 tst yh, #0x80000000 138 mov yh, yh, lsl #12 139 orr yh, ip, yh, lsr #12 140 beq 1f 141#if defined(__thumb2__) 142 negs yl, yl 143 sbc yh, yh, yh, lsl #1 144#else 145 rsbs yl, yl, #0 146 rsc yh, yh, #0 147#endif 1481: 149 @ If exponent == difference, one or both args were denormalized. 150 @ Since this is not common case, rescale them off line. 151 teq r4, r5 152 beq LSYM(Lad_d) 153LSYM(Lad_x): 154 155 @ Compensate for the exponent overlapping the mantissa MSB added later 156 sub r4, r4, #1 157 158 @ Shift yh-yl right per r5, add to xh-xl, keep leftover bits into ip. 159 rsbs lr, r5, #32 160 blt 1f 161 shift1 lsl, ip, yl, lr 162 shiftop adds xl xl yl lsr r5 yl 163 adc xh, xh, #0 164 shiftop adds xl xl yh lsl lr yl 165 shiftop adcs xh xh yh asr r5 yh 166 b 2f 1671: sub r5, r5, #32 168 add lr, lr, #32 169 cmp yl, #1 170 shift1 lsl,ip, yh, lr 171 do_it cs 172 orrcs ip, ip, #2 @ 2 not 1, to allow lsr #1 later 173 shiftop adds xl xl yh asr r5 yh 174 adcs xh, xh, yh, asr #31 1752: 176 @ We now have a result in xh-xl-ip. 177 @ Keep absolute value in xh-xl-ip, sign in r5 (the n bit was set above) 178 and r5, xh, #0x80000000 179 bpl LSYM(Lad_p) 180#if defined(__thumb2__) 181 mov lr, #0 182 negs ip, ip 183 sbcs xl, lr, xl 184 sbc xh, lr, xh 185#else 186 rsbs ip, ip, #0 187 rscs xl, xl, #0 188 rsc xh, xh, #0 189#endif 190 191 @ Determine how to normalize the result. 192LSYM(Lad_p): 193 cmp xh, #0x00100000 194 bcc LSYM(Lad_a) 195 cmp xh, #0x00200000 196 bcc LSYM(Lad_e) 197 198 @ Result needs to be shifted right. 199 movs xh, xh, lsr #1 200 movs xl, xl, rrx 201 mov ip, ip, rrx 202 add r4, r4, #1 203 204 @ Make sure we did not bust our exponent. 205 mov r2, r4, lsl #21 206 cmn r2, #(2 << 21) 207 bcs LSYM(Lad_o) 208 209 @ Our result is now properly aligned into xh-xl, remaining bits in ip. 210 @ Round with MSB of ip. If halfway between two numbers, round towards 211 @ LSB of xl = 0. 212 @ Pack final result together. 213LSYM(Lad_e): 214 cmp ip, #0x80000000 215 do_it eq 216 COND(mov,s,eq) ip, xl, lsr #1 217 adcs xl, xl, #0 218 adc xh, xh, r4, lsl #20 219 orr xh, xh, r5 220 RETLDM "r4, r5" 221 222 @ Result must be shifted left and exponent adjusted. 223LSYM(Lad_a): 224 movs ip, ip, lsl #1 225 adcs xl, xl, xl 226 adc xh, xh, xh 227 tst xh, #0x00100000 228 sub r4, r4, #1 229 bne LSYM(Lad_e) 230 231 @ No rounding necessary since ip will always be 0 at this point. 232LSYM(Lad_l): 233 234#if __ARM_ARCH__ < 5 235 236 teq xh, #0 237 movne r3, #20 238 moveq r3, #52 239 moveq xh, xl 240 moveq xl, #0 241 mov r2, xh 242 cmp r2, #(1 << 16) 243 movhs r2, r2, lsr #16 244 subhs r3, r3, #16 245 cmp r2, #(1 << 8) 246 movhs r2, r2, lsr #8 247 subhs r3, r3, #8 248 cmp r2, #(1 << 4) 249 movhs r2, r2, lsr #4 250 subhs r3, r3, #4 251 cmp r2, #(1 << 2) 252 subhs r3, r3, #2 253 sublo r3, r3, r2, lsr #1 254 sub r3, r3, r2, lsr #3 255 256#else 257 258 teq xh, #0 259 do_it eq, t 260 moveq xh, xl 261 moveq xl, #0 262 clz r3, xh 263 do_it eq 264 addeq r3, r3, #32 265 sub r3, r3, #11 266 267#endif 268 269 @ determine how to shift the value. 270 subs r2, r3, #32 271 bge 2f 272 adds r2, r2, #12 273 ble 1f 274 275 @ shift value left 21 to 31 bits, or actually right 11 to 1 bits 276 @ since a register switch happened above. 277 add ip, r2, #20 278 rsb r2, r2, #12 279 shift1 lsl, xl, xh, ip 280 shift1 lsr, xh, xh, r2 281 b 3f 282 283 @ actually shift value left 1 to 20 bits, which might also represent 284 @ 32 to 52 bits if counting the register switch that happened earlier. 2851: add r2, r2, #20 2862: do_it le 287 rsble ip, r2, #32 288 shift1 lsl, xh, xh, r2 289#if defined(__thumb2__) 290 lsr ip, xl, ip 291 itt le 292 orrle xh, xh, ip 293 lslle xl, xl, r2 294#else 295 orrle xh, xh, xl, lsr ip 296 movle xl, xl, lsl r2 297#endif 298 299 @ adjust exponent accordingly. 3003: subs r4, r4, r3 301 do_it ge, tt 302 addge xh, xh, r4, lsl #20 303 orrge xh, xh, r5 304 RETLDM "r4, r5" ge 305 306 @ Exponent too small, denormalize result. 307 @ Find out proper shift value. 308 mvn r4, r4 309 subs r4, r4, #31 310 bge 2f 311 adds r4, r4, #12 312 bgt 1f 313 314 @ shift result right of 1 to 20 bits, sign is in r5. 315 add r4, r4, #20 316 rsb r2, r4, #32 317 shift1 lsr, xl, xl, r4 318 shiftop orr xl xl xh lsl r2 yh 319 shiftop orr xh r5 xh lsr r4 yh 320 RETLDM "r4, r5" 321 322 @ shift result right of 21 to 31 bits, or left 11 to 1 bits after 323 @ a register switch from xh to xl. 3241: rsb r4, r4, #12 325 rsb r2, r4, #32 326 shift1 lsr, xl, xl, r2 327 shiftop orr xl xl xh lsl r4 yh 328 mov xh, r5 329 RETLDM "r4, r5" 330 331 @ Shift value right of 32 to 64 bits, or 0 to 32 bits after a switch 332 @ from xh to xl. 3332: shift1 lsr, xl, xh, r4 334 mov xh, r5 335 RETLDM "r4, r5" 336 337 @ Adjust exponents for denormalized arguments. 338 @ Note that r4 must not remain equal to 0. 339LSYM(Lad_d): 340 teq r4, #0 341 eor yh, yh, #0x00100000 342 do_it eq, te 343 eoreq xh, xh, #0x00100000 344 addeq r4, r4, #1 345 subne r5, r5, #1 346 b LSYM(Lad_x) 347 348 349LSYM(Lad_s): 350 mvns ip, r4, asr #21 351 do_it ne 352 COND(mvn,s,ne) ip, r5, asr #21 353 beq LSYM(Lad_i) 354 355 teq r4, r5 356 do_it eq 357 teqeq xl, yl 358 beq 1f 359 360 @ Result is x + 0.0 = x or 0.0 + y = y. 361 orrs ip, r4, xl 362 do_it eq, t 363 moveq xh, yh 364 moveq xl, yl 365 RETLDM "r4, r5" 366 3671: teq xh, yh 368 369 @ Result is x - x = 0. 370 do_it ne, tt 371 movne xh, #0 372 movne xl, #0 373 RETLDM "r4, r5" ne 374 375 @ Result is x + x = 2x. 376 movs ip, r4, lsr #21 377 bne 2f 378 movs xl, xl, lsl #1 379 adcs xh, xh, xh 380 do_it cs 381 orrcs xh, xh, #0x80000000 382 RETLDM "r4, r5" 3832: adds r4, r4, #(2 << 21) 384 do_it cc, t 385 addcc xh, xh, #(1 << 20) 386 RETLDM "r4, r5" cc 387 and r5, xh, #0x80000000 388 389 @ Overflow: return INF. 390LSYM(Lad_o): 391 orr xh, r5, #0x7f000000 392 orr xh, xh, #0x00f00000 393 mov xl, #0 394 RETLDM "r4, r5" 395 396 @ At least one of x or y is INF/NAN. 397 @ if xh-xl != INF/NAN: return yh-yl (which is INF/NAN) 398 @ if yh-yl != INF/NAN: return xh-xl (which is INF/NAN) 399 @ if either is NAN: return NAN 400 @ if opposite sign: return NAN 401 @ otherwise return xh-xl (which is INF or -INF) 402LSYM(Lad_i): 403 mvns ip, r4, asr #21 404 do_it ne, te 405 movne xh, yh 406 movne xl, yl 407 COND(mvn,s,eq) ip, r5, asr #21 408 do_it ne, t 409 movne yh, xh 410 movne yl, xl 411 orrs r4, xl, xh, lsl #12 412 do_it eq, te 413 COND(orr,s,eq) r5, yl, yh, lsl #12 414 teqeq xh, yh 415 orrne xh, xh, #0x00080000 @ quiet NAN 416 RETLDM "r4, r5" 417 418 FUNC_END aeabi_dsub 419 FUNC_END subdf3 420 FUNC_END aeabi_dadd 421 FUNC_END adddf3 422 423ARM_FUNC_START floatunsidf 424ARM_FUNC_ALIAS aeabi_ui2d floatunsidf 425 426 teq r0, #0 427 do_it eq, t 428 moveq r1, #0 429 RETc(eq) 430 do_push {r4, r5, lr} 431 mov r4, #0x400 @ initial exponent 432 add r4, r4, #(52-1 - 1) 433 mov r5, #0 @ sign bit is 0 434 .ifnc xl, r0 435 mov xl, r0 436 .endif 437 mov xh, #0 438 b LSYM(Lad_l) 439 440 FUNC_END aeabi_ui2d 441 FUNC_END floatunsidf 442 443ARM_FUNC_START floatsidf 444ARM_FUNC_ALIAS aeabi_i2d floatsidf 445 446 teq r0, #0 447 do_it eq, t 448 moveq r1, #0 449 RETc(eq) 450 do_push {r4, r5, lr} 451 mov r4, #0x400 @ initial exponent 452 add r4, r4, #(52-1 - 1) 453 ands r5, r0, #0x80000000 @ sign bit in r5 454 do_it mi 455 rsbmi r0, r0, #0 @ absolute value 456 .ifnc xl, r0 457 mov xl, r0 458 .endif 459 mov xh, #0 460 b LSYM(Lad_l) 461 462 FUNC_END aeabi_i2d 463 FUNC_END floatsidf 464 465ARM_FUNC_START extendsfdf2 466ARM_FUNC_ALIAS aeabi_f2d extendsfdf2 467 468 movs r2, r0, lsl #1 @ toss sign bit 469 mov xh, r2, asr #3 @ stretch exponent 470 mov xh, xh, rrx @ retrieve sign bit 471 mov xl, r2, lsl #28 @ retrieve remaining bits 472 do_it ne, ttt 473 COND(and,s,ne) r3, r2, #0xff000000 @ isolate exponent 474 teqne r3, #0xff000000 @ if not 0, check if INF or NAN 475 eorne xh, xh, #0x38000000 @ fixup exponent otherwise. 476 RETc(ne) @ and return it. 477 478 teq r2, #0 @ if actually 0 479 do_it ne, e 480 teqne r3, #0xff000000 @ or INF or NAN 481 RETc(eq) @ we are done already. 482 483 @ value was denormalized. We can normalize it now. 484 do_push {r4, r5, lr} 485 mov r4, #0x380 @ setup corresponding exponent 486 and r5, xh, #0x80000000 @ move sign bit in r5 487 bic xh, xh, #0x80000000 488 b LSYM(Lad_l) 489 490 FUNC_END aeabi_f2d 491 FUNC_END extendsfdf2 492 493ARM_FUNC_START floatundidf 494ARM_FUNC_ALIAS aeabi_ul2d floatundidf 495 496 orrs r2, r0, r1 497#if !defined (__VFP_FP__) && !defined(__SOFTFP__) 498 do_it eq, t 499 mvfeqd f0, #0.0 500#else 501 do_it eq 502#endif 503 RETc(eq) 504 505#if !defined (__VFP_FP__) && !defined(__SOFTFP__) 506 @ For hard FPA code we want to return via the tail below so that 507 @ we can return the result in f0 as well as in r0/r1 for backwards 508 @ compatibility. 509 adr ip, LSYM(f0_ret) 510 @ Push pc as well so that RETLDM works correctly. 511 do_push {r4, r5, ip, lr, pc} 512#else 513 do_push {r4, r5, lr} 514#endif 515 516 mov r5, #0 517 b 2f 518 519ARM_FUNC_START floatdidf 520ARM_FUNC_ALIAS aeabi_l2d floatdidf 521 522 orrs r2, r0, r1 523#if !defined (__VFP_FP__) && !defined(__SOFTFP__) 524 do_it eq, t 525 mvfeqd f0, #0.0 526#else 527 do_it eq 528#endif 529 RETc(eq) 530 531#if !defined (__VFP_FP__) && !defined(__SOFTFP__) 532 @ For hard FPA code we want to return via the tail below so that 533 @ we can return the result in f0 as well as in r0/r1 for backwards 534 @ compatibility. 535 adr ip, LSYM(f0_ret) 536 @ Push pc as well so that RETLDM works correctly. 537 do_push {r4, r5, ip, lr, pc} 538#else 539 do_push {r4, r5, lr} 540#endif 541 542 ands r5, ah, #0x80000000 @ sign bit in r5 543 bpl 2f 544#if defined(__thumb2__) 545 negs al, al 546 sbc ah, ah, ah, lsl #1 547#else 548 rsbs al, al, #0 549 rsc ah, ah, #0 550#endif 5512: 552 mov r4, #0x400 @ initial exponent 553 add r4, r4, #(52-1 - 1) 554 555 @ FPA little-endian: must swap the word order. 556 .ifnc xh, ah 557 mov ip, al 558 mov xh, ah 559 mov xl, ip 560 .endif 561 562 movs ip, xh, lsr #22 563 beq LSYM(Lad_p) 564 565 @ The value is too big. Scale it down a bit... 566 mov r2, #3 567 movs ip, ip, lsr #3 568 do_it ne 569 addne r2, r2, #3 570 movs ip, ip, lsr #3 571 do_it ne 572 addne r2, r2, #3 573 add r2, r2, ip, lsr #3 574 575 rsb r3, r2, #32 576 shift1 lsl, ip, xl, r3 577 shift1 lsr, xl, xl, r2 578 shiftop orr xl xl xh lsl r3 lr 579 shift1 lsr, xh, xh, r2 580 add r4, r4, r2 581 b LSYM(Lad_p) 582 583#if !defined (__VFP_FP__) && !defined(__SOFTFP__) 584 585 @ Legacy code expects the result to be returned in f0. Copy it 586 @ there as well. 587LSYM(f0_ret): 588 do_push {r0, r1} 589 ldfd f0, [sp], #8 590 RETLDM 591 592#endif 593 594 FUNC_END floatdidf 595 FUNC_END aeabi_l2d 596 FUNC_END floatundidf 597 FUNC_END aeabi_ul2d 598 599#endif /* L_addsubdf3 */ 600 601#ifdef L_arm_muldivdf3 602 603ARM_FUNC_START muldf3 604ARM_FUNC_ALIAS aeabi_dmul muldf3 605 do_push {r4, r5, r6, lr} 606 607 @ Mask out exponents, trap any zero/denormal/INF/NAN. 608 mov ip, #0xff 609 orr ip, ip, #0x700 610 ands r4, ip, xh, lsr #20 611 do_it ne, tte 612 COND(and,s,ne) r5, ip, yh, lsr #20 613 teqne r4, ip 614 teqne r5, ip 615 bleq LSYM(Lml_s) 616 617 @ Add exponents together 618 add r4, r4, r5 619 620 @ Determine final sign. 621 eor r6, xh, yh 622 623 @ Convert mantissa to unsigned integer. 624 @ If power of two, branch to a separate path. 625 bic xh, xh, ip, lsl #21 626 bic yh, yh, ip, lsl #21 627 orrs r5, xl, xh, lsl #12 628 do_it ne 629 COND(orr,s,ne) r5, yl, yh, lsl #12 630 orr xh, xh, #0x00100000 631 orr yh, yh, #0x00100000 632 beq LSYM(Lml_1) 633 634#if __ARM_ARCH__ < 4 635 636 @ Put sign bit in r6, which will be restored in yl later. 637 and r6, r6, #0x80000000 638 639 @ Well, no way to make it shorter without the umull instruction. 640 stmfd sp!, {r6, r7, r8, r9, sl, fp} 641 mov r7, xl, lsr #16 642 mov r8, yl, lsr #16 643 mov r9, xh, lsr #16 644 mov sl, yh, lsr #16 645 bic xl, xl, r7, lsl #16 646 bic yl, yl, r8, lsl #16 647 bic xh, xh, r9, lsl #16 648 bic yh, yh, sl, lsl #16 649 mul ip, xl, yl 650 mul fp, xl, r8 651 mov lr, #0 652 adds ip, ip, fp, lsl #16 653 adc lr, lr, fp, lsr #16 654 mul fp, r7, yl 655 adds ip, ip, fp, lsl #16 656 adc lr, lr, fp, lsr #16 657 mul fp, xl, sl 658 mov r5, #0 659 adds lr, lr, fp, lsl #16 660 adc r5, r5, fp, lsr #16 661 mul fp, r7, yh 662 adds lr, lr, fp, lsl #16 663 adc r5, r5, fp, lsr #16 664 mul fp, xh, r8 665 adds lr, lr, fp, lsl #16 666 adc r5, r5, fp, lsr #16 667 mul fp, r9, yl 668 adds lr, lr, fp, lsl #16 669 adc r5, r5, fp, lsr #16 670 mul fp, xh, sl 671 mul r6, r9, sl 672 adds r5, r5, fp, lsl #16 673 adc r6, r6, fp, lsr #16 674 mul fp, r9, yh 675 adds r5, r5, fp, lsl #16 676 adc r6, r6, fp, lsr #16 677 mul fp, xl, yh 678 adds lr, lr, fp 679 mul fp, r7, sl 680 adcs r5, r5, fp 681 mul fp, xh, yl 682 adc r6, r6, #0 683 adds lr, lr, fp 684 mul fp, r9, r8 685 adcs r5, r5, fp 686 mul fp, r7, r8 687 adc r6, r6, #0 688 adds lr, lr, fp 689 mul fp, xh, yh 690 adcs r5, r5, fp 691 adc r6, r6, #0 692 ldmfd sp!, {yl, r7, r8, r9, sl, fp} 693 694#else 695 696 @ Here is the actual multiplication. 697 umull ip, lr, xl, yl 698 mov r5, #0 699 umlal lr, r5, xh, yl 700 and yl, r6, #0x80000000 701 umlal lr, r5, xl, yh 702 mov r6, #0 703 umlal r5, r6, xh, yh 704 705#endif 706 707 @ The LSBs in ip are only significant for the final rounding. 708 @ Fold them into lr. 709 teq ip, #0 710 do_it ne 711 orrne lr, lr, #1 712 713 @ Adjust result upon the MSB position. 714 sub r4, r4, #0xff 715 cmp r6, #(1 << (20-11)) 716 sbc r4, r4, #0x300 717 bcs 1f 718 movs lr, lr, lsl #1 719 adcs r5, r5, r5 720 adc r6, r6, r6 7211: 722 @ Shift to final position, add sign to result. 723 orr xh, yl, r6, lsl #11 724 orr xh, xh, r5, lsr #21 725 mov xl, r5, lsl #11 726 orr xl, xl, lr, lsr #21 727 mov lr, lr, lsl #11 728 729 @ Check exponent range for under/overflow. 730 subs ip, r4, #(254 - 1) 731 do_it hi 732 cmphi ip, #0x700 733 bhi LSYM(Lml_u) 734 735 @ Round the result, merge final exponent. 736 cmp lr, #0x80000000 737 do_it eq 738 COND(mov,s,eq) lr, xl, lsr #1 739 adcs xl, xl, #0 740 adc xh, xh, r4, lsl #20 741 RETLDM "r4, r5, r6" 742 743 @ Multiplication by 0x1p*: let''s shortcut a lot of code. 744LSYM(Lml_1): 745 and r6, r6, #0x80000000 746 orr xh, r6, xh 747 orr xl, xl, yl 748 eor xh, xh, yh 749 subs r4, r4, ip, lsr #1 750 do_it gt, tt 751 COND(rsb,s,gt) r5, r4, ip 752 orrgt xh, xh, r4, lsl #20 753 RETLDM "r4, r5, r6" gt 754 755 @ Under/overflow: fix things up for the code below. 756 orr xh, xh, #0x00100000 757 mov lr, #0 758 subs r4, r4, #1 759 760LSYM(Lml_u): 761 @ Overflow? 762 bgt LSYM(Lml_o) 763 764 @ Check if denormalized result is possible, otherwise return signed 0. 765 cmn r4, #(53 + 1) 766 do_it le, tt 767 movle xl, #0 768 bicle xh, xh, #0x7fffffff 769 RETLDM "r4, r5, r6" le 770 771 @ Find out proper shift value. 772 rsb r4, r4, #0 773 subs r4, r4, #32 774 bge 2f 775 adds r4, r4, #12 776 bgt 1f 777 778 @ shift result right of 1 to 20 bits, preserve sign bit, round, etc. 779 add r4, r4, #20 780 rsb r5, r4, #32 781 shift1 lsl, r3, xl, r5 782 shift1 lsr, xl, xl, r4 783 shiftop orr xl xl xh lsl r5 r2 784 and r2, xh, #0x80000000 785 bic xh, xh, #0x80000000 786 adds xl, xl, r3, lsr #31 787 shiftop adc xh r2 xh lsr r4 r6 788 orrs lr, lr, r3, lsl #1 789 do_it eq 790 biceq xl, xl, r3, lsr #31 791 RETLDM "r4, r5, r6" 792 793 @ shift result right of 21 to 31 bits, or left 11 to 1 bits after 794 @ a register switch from xh to xl. Then round. 7951: rsb r4, r4, #12 796 rsb r5, r4, #32 797 shift1 lsl, r3, xl, r4 798 shift1 lsr, xl, xl, r5 799 shiftop orr xl xl xh lsl r4 r2 800 bic xh, xh, #0x7fffffff 801 adds xl, xl, r3, lsr #31 802 adc xh, xh, #0 803 orrs lr, lr, r3, lsl #1 804 do_it eq 805 biceq xl, xl, r3, lsr #31 806 RETLDM "r4, r5, r6" 807 808 @ Shift value right of 32 to 64 bits, or 0 to 32 bits after a switch 809 @ from xh to xl. Leftover bits are in r3-r6-lr for rounding. 8102: rsb r5, r4, #32 811 shiftop orr lr lr xl lsl r5 r2 812 shift1 lsr, r3, xl, r4 813 shiftop orr r3 r3 xh lsl r5 r2 814 shift1 lsr, xl, xh, r4 815 bic xh, xh, #0x7fffffff 816 shiftop bic xl xl xh lsr r4 r2 817 add xl, xl, r3, lsr #31 818 orrs lr, lr, r3, lsl #1 819 do_it eq 820 biceq xl, xl, r3, lsr #31 821 RETLDM "r4, r5, r6" 822 823 @ One or both arguments are denormalized. 824 @ Scale them leftwards and preserve sign bit. 825LSYM(Lml_d): 826 teq r4, #0 827 bne 2f 828 and r6, xh, #0x80000000 8291: movs xl, xl, lsl #1 830 adc xh, xh, xh 831 tst xh, #0x00100000 832 do_it eq 833 subeq r4, r4, #1 834 beq 1b 835 orr xh, xh, r6 836 teq r5, #0 837 do_it ne 838 RETc(ne) 8392: and r6, yh, #0x80000000 8403: movs yl, yl, lsl #1 841 adc yh, yh, yh 842 tst yh, #0x00100000 843 do_it eq 844 subeq r5, r5, #1 845 beq 3b 846 orr yh, yh, r6 847 RET 848 849LSYM(Lml_s): 850 @ Isolate the INF and NAN cases away 851 teq r4, ip 852 and r5, ip, yh, lsr #20 853 do_it ne 854 teqne r5, ip 855 beq 1f 856 857 @ Here, one or more arguments are either denormalized or zero. 858 orrs r6, xl, xh, lsl #1 859 do_it ne 860 COND(orr,s,ne) r6, yl, yh, lsl #1 861 bne LSYM(Lml_d) 862 863 @ Result is 0, but determine sign anyway. 864LSYM(Lml_z): 865 eor xh, xh, yh 866 and xh, xh, #0x80000000 867 mov xl, #0 868 RETLDM "r4, r5, r6" 869 8701: @ One or both args are INF or NAN. 871 orrs r6, xl, xh, lsl #1 872 do_it eq, te 873 moveq xl, yl 874 moveq xh, yh 875 COND(orr,s,ne) r6, yl, yh, lsl #1 876 beq LSYM(Lml_n) @ 0 * INF or INF * 0 -> NAN 877 teq r4, ip 878 bne 1f 879 orrs r6, xl, xh, lsl #12 880 bne LSYM(Lml_n) @ NAN * <anything> -> NAN 8811: teq r5, ip 882 bne LSYM(Lml_i) 883 orrs r6, yl, yh, lsl #12 884 do_it ne, t 885 movne xl, yl 886 movne xh, yh 887 bne LSYM(Lml_n) @ <anything> * NAN -> NAN 888 889 @ Result is INF, but we need to determine its sign. 890LSYM(Lml_i): 891 eor xh, xh, yh 892 893 @ Overflow: return INF (sign already in xh). 894LSYM(Lml_o): 895 and xh, xh, #0x80000000 896 orr xh, xh, #0x7f000000 897 orr xh, xh, #0x00f00000 898 mov xl, #0 899 RETLDM "r4, r5, r6" 900 901 @ Return a quiet NAN. 902LSYM(Lml_n): 903 orr xh, xh, #0x7f000000 904 orr xh, xh, #0x00f80000 905 RETLDM "r4, r5, r6" 906 907 FUNC_END aeabi_dmul 908 FUNC_END muldf3 909 910ARM_FUNC_START divdf3 911ARM_FUNC_ALIAS aeabi_ddiv divdf3 912 913 do_push {r4, r5, r6, lr} 914 915 @ Mask out exponents, trap any zero/denormal/INF/NAN. 916 mov ip, #0xff 917 orr ip, ip, #0x700 918 ands r4, ip, xh, lsr #20 919 do_it ne, tte 920 COND(and,s,ne) r5, ip, yh, lsr #20 921 teqne r4, ip 922 teqne r5, ip 923 bleq LSYM(Ldv_s) 924 925 @ Substract divisor exponent from dividend''s. 926 sub r4, r4, r5 927 928 @ Preserve final sign into lr. 929 eor lr, xh, yh 930 931 @ Convert mantissa to unsigned integer. 932 @ Dividend -> r5-r6, divisor -> yh-yl. 933 orrs r5, yl, yh, lsl #12 934 mov xh, xh, lsl #12 935 beq LSYM(Ldv_1) 936 mov yh, yh, lsl #12 937 mov r5, #0x10000000 938 orr yh, r5, yh, lsr #4 939 orr yh, yh, yl, lsr #24 940 mov yl, yl, lsl #8 941 orr r5, r5, xh, lsr #4 942 orr r5, r5, xl, lsr #24 943 mov r6, xl, lsl #8 944 945 @ Initialize xh with final sign bit. 946 and xh, lr, #0x80000000 947 948 @ Ensure result will land to known bit position. 949 @ Apply exponent bias accordingly. 950 cmp r5, yh 951 do_it eq 952 cmpeq r6, yl 953 adc r4, r4, #(255 - 2) 954 add r4, r4, #0x300 955 bcs 1f 956 movs yh, yh, lsr #1 957 mov yl, yl, rrx 9581: 959 @ Perform first substraction to align result to a nibble. 960 subs r6, r6, yl 961 sbc r5, r5, yh 962 movs yh, yh, lsr #1 963 mov yl, yl, rrx 964 mov xl, #0x00100000 965 mov ip, #0x00080000 966 967 @ The actual division loop. 9681: subs lr, r6, yl 969 sbcs lr, r5, yh 970 do_it cs, tt 971 subcs r6, r6, yl 972 movcs r5, lr 973 orrcs xl, xl, ip 974 movs yh, yh, lsr #1 975 mov yl, yl, rrx 976 subs lr, r6, yl 977 sbcs lr, r5, yh 978 do_it cs, tt 979 subcs r6, r6, yl 980 movcs r5, lr 981 orrcs xl, xl, ip, lsr #1 982 movs yh, yh, lsr #1 983 mov yl, yl, rrx 984 subs lr, r6, yl 985 sbcs lr, r5, yh 986 do_it cs, tt 987 subcs r6, r6, yl 988 movcs r5, lr 989 orrcs xl, xl, ip, lsr #2 990 movs yh, yh, lsr #1 991 mov yl, yl, rrx 992 subs lr, r6, yl 993 sbcs lr, r5, yh 994 do_it cs, tt 995 subcs r6, r6, yl 996 movcs r5, lr 997 orrcs xl, xl, ip, lsr #3 998 999 orrs lr, r5, r6 1000 beq 2f 1001 mov r5, r5, lsl #4 1002 orr r5, r5, r6, lsr #28 1003 mov r6, r6, lsl #4 1004 mov yh, yh, lsl #3 1005 orr yh, yh, yl, lsr #29 1006 mov yl, yl, lsl #3 1007 movs ip, ip, lsr #4 1008 bne 1b 1009 1010 @ We are done with a word of the result. 1011 @ Loop again for the low word if this pass was for the high word. 1012 tst xh, #0x00100000 1013 bne 3f 1014 orr xh, xh, xl 1015 mov xl, #0 1016 mov ip, #0x80000000 1017 b 1b 10182: 1019 @ Be sure result starts in the high word. 1020 tst xh, #0x00100000 1021 do_it eq, t 1022 orreq xh, xh, xl 1023 moveq xl, #0 10243: 1025 @ Check exponent range for under/overflow. 1026 subs ip, r4, #(254 - 1) 1027 do_it hi 1028 cmphi ip, #0x700 1029 bhi LSYM(Lml_u) 1030 1031 @ Round the result, merge final exponent. 1032 subs ip, r5, yh 1033 do_it eq, t 1034 COND(sub,s,eq) ip, r6, yl 1035 COND(mov,s,eq) ip, xl, lsr #1 1036 adcs xl, xl, #0 1037 adc xh, xh, r4, lsl #20 1038 RETLDM "r4, r5, r6" 1039 1040 @ Division by 0x1p*: shortcut a lot of code. 1041LSYM(Ldv_1): 1042 and lr, lr, #0x80000000 1043 orr xh, lr, xh, lsr #12 1044 adds r4, r4, ip, lsr #1 1045 do_it gt, tt 1046 COND(rsb,s,gt) r5, r4, ip 1047 orrgt xh, xh, r4, lsl #20 1048 RETLDM "r4, r5, r6" gt 1049 1050 orr xh, xh, #0x00100000 1051 mov lr, #0 1052 subs r4, r4, #1 1053 b LSYM(Lml_u) 1054 1055 @ Result mightt need to be denormalized: put remainder bits 1056 @ in lr for rounding considerations. 1057LSYM(Ldv_u): 1058 orr lr, r5, r6 1059 b LSYM(Lml_u) 1060 1061 @ One or both arguments is either INF, NAN or zero. 1062LSYM(Ldv_s): 1063 and r5, ip, yh, lsr #20 1064 teq r4, ip 1065 do_it eq 1066 teqeq r5, ip 1067 beq LSYM(Lml_n) @ INF/NAN / INF/NAN -> NAN 1068 teq r4, ip 1069 bne 1f 1070 orrs r4, xl, xh, lsl #12 1071 bne LSYM(Lml_n) @ NAN / <anything> -> NAN 1072 teq r5, ip 1073 bne LSYM(Lml_i) @ INF / <anything> -> INF 1074 mov xl, yl 1075 mov xh, yh 1076 b LSYM(Lml_n) @ INF / (INF or NAN) -> NAN 10771: teq r5, ip 1078 bne 2f 1079 orrs r5, yl, yh, lsl #12 1080 beq LSYM(Lml_z) @ <anything> / INF -> 0 1081 mov xl, yl 1082 mov xh, yh 1083 b LSYM(Lml_n) @ <anything> / NAN -> NAN 10842: @ If both are nonzero, we need to normalize and resume above. 1085 orrs r6, xl, xh, lsl #1 1086 do_it ne 1087 COND(orr,s,ne) r6, yl, yh, lsl #1 1088 bne LSYM(Lml_d) 1089 @ One or both arguments are 0. 1090 orrs r4, xl, xh, lsl #1 1091 bne LSYM(Lml_i) @ <non_zero> / 0 -> INF 1092 orrs r5, yl, yh, lsl #1 1093 bne LSYM(Lml_z) @ 0 / <non_zero> -> 0 1094 b LSYM(Lml_n) @ 0 / 0 -> NAN 1095 1096 FUNC_END aeabi_ddiv 1097 FUNC_END divdf3 1098 1099#endif /* L_muldivdf3 */ 1100 1101#ifdef L_arm_cmpdf2 1102 1103@ Note: only r0 (return value) and ip are clobbered here. 1104 1105ARM_FUNC_START gtdf2 1106ARM_FUNC_ALIAS gedf2 gtdf2 1107 mov ip, #-1 1108 b 1f 1109 1110ARM_FUNC_START ltdf2 1111ARM_FUNC_ALIAS ledf2 ltdf2 1112 mov ip, #1 1113 b 1f 1114 1115ARM_FUNC_START cmpdf2 1116ARM_FUNC_ALIAS nedf2 cmpdf2 1117ARM_FUNC_ALIAS eqdf2 cmpdf2 1118 mov ip, #1 @ how should we specify unordered here? 1119 11201: str ip, [sp, #-4]! 1121 1122 @ Trap any INF/NAN first. 1123 mov ip, xh, lsl #1 1124 mvns ip, ip, asr #21 1125 mov ip, yh, lsl #1 1126 do_it ne 1127 COND(mvn,s,ne) ip, ip, asr #21 1128 beq 3f 1129 1130 @ Test for equality. 1131 @ Note that 0.0 is equal to -0.0. 11322: add sp, sp, #4 1133 orrs ip, xl, xh, lsl #1 @ if x == 0.0 or -0.0 1134 do_it eq, e 1135 COND(orr,s,eq) ip, yl, yh, lsl #1 @ and y == 0.0 or -0.0 1136 teqne xh, yh @ or xh == yh 1137 do_it eq, tt 1138 teqeq xl, yl @ and xl == yl 1139 moveq r0, #0 @ then equal. 1140 RETc(eq) 1141 1142 @ Clear C flag 1143 cmn r0, #0 1144 1145 @ Compare sign, 1146 teq xh, yh 1147 1148 @ Compare values if same sign 1149 do_it pl 1150 cmppl xh, yh 1151 do_it eq 1152 cmpeq xl, yl 1153 1154 @ Result: 1155 do_it cs, e 1156 movcs r0, yh, asr #31 1157 mvncc r0, yh, asr #31 1158 orr r0, r0, #1 1159 RET 1160 1161 @ Look for a NAN. 11623: mov ip, xh, lsl #1 1163 mvns ip, ip, asr #21 1164 bne 4f 1165 orrs ip, xl, xh, lsl #12 1166 bne 5f @ x is NAN 11674: mov ip, yh, lsl #1 1168 mvns ip, ip, asr #21 1169 bne 2b 1170 orrs ip, yl, yh, lsl #12 1171 beq 2b @ y is not NAN 11725: ldr r0, [sp], #4 @ unordered return code 1173 RET 1174 1175 FUNC_END gedf2 1176 FUNC_END gtdf2 1177 FUNC_END ledf2 1178 FUNC_END ltdf2 1179 FUNC_END nedf2 1180 FUNC_END eqdf2 1181 FUNC_END cmpdf2 1182 1183ARM_FUNC_START aeabi_cdrcmple 1184 1185 mov ip, r0 1186 mov r0, r2 1187 mov r2, ip 1188 mov ip, r1 1189 mov r1, r3 1190 mov r3, ip 1191 b 6f 1192 1193ARM_FUNC_START aeabi_cdcmpeq 1194ARM_FUNC_ALIAS aeabi_cdcmple aeabi_cdcmpeq 1195 1196 @ The status-returning routines are required to preserve all 1197 @ registers except ip, lr, and cpsr. 11986: do_push {r0, lr} 1199 ARM_CALL cmpdf2 1200 @ Set the Z flag correctly, and the C flag unconditionally. 1201 cmp r0, #0 1202 @ Clear the C flag if the return value was -1, indicating 1203 @ that the first operand was smaller than the second. 1204 do_it mi 1205 cmnmi r0, #0 1206 RETLDM "r0" 1207 1208 FUNC_END aeabi_cdcmple 1209 FUNC_END aeabi_cdcmpeq 1210 FUNC_END aeabi_cdrcmple 1211 1212ARM_FUNC_START aeabi_dcmpeq 1213 1214 str lr, [sp, #-8]! 1215 ARM_CALL aeabi_cdcmple 1216 do_it eq, e 1217 moveq r0, #1 @ Equal to. 1218 movne r0, #0 @ Less than, greater than, or unordered. 1219 RETLDM 1220 1221 FUNC_END aeabi_dcmpeq 1222 1223ARM_FUNC_START aeabi_dcmplt 1224 1225 str lr, [sp, #-8]! 1226 ARM_CALL aeabi_cdcmple 1227 do_it cc, e 1228 movcc r0, #1 @ Less than. 1229 movcs r0, #0 @ Equal to, greater than, or unordered. 1230 RETLDM 1231 1232 FUNC_END aeabi_dcmplt 1233 1234ARM_FUNC_START aeabi_dcmple 1235 1236 str lr, [sp, #-8]! 1237 ARM_CALL aeabi_cdcmple 1238 do_it ls, e 1239 movls r0, #1 @ Less than or equal to. 1240 movhi r0, #0 @ Greater than or unordered. 1241 RETLDM 1242 1243 FUNC_END aeabi_dcmple 1244 1245ARM_FUNC_START aeabi_dcmpge 1246 1247 str lr, [sp, #-8]! 1248 ARM_CALL aeabi_cdrcmple 1249 do_it ls, e 1250 movls r0, #1 @ Operand 2 is less than or equal to operand 1. 1251 movhi r0, #0 @ Operand 2 greater than operand 1, or unordered. 1252 RETLDM 1253 1254 FUNC_END aeabi_dcmpge 1255 1256ARM_FUNC_START aeabi_dcmpgt 1257 1258 str lr, [sp, #-8]! 1259 ARM_CALL aeabi_cdrcmple 1260 do_it cc, e 1261 movcc r0, #1 @ Operand 2 is less than operand 1. 1262 movcs r0, #0 @ Operand 2 is greater than or equal to operand 1, 1263 @ or they are unordered. 1264 RETLDM 1265 1266 FUNC_END aeabi_dcmpgt 1267 1268#endif /* L_cmpdf2 */ 1269 1270#ifdef L_arm_unorddf2 1271 1272ARM_FUNC_START unorddf2 1273ARM_FUNC_ALIAS aeabi_dcmpun unorddf2 1274 1275 mov ip, xh, lsl #1 1276 mvns ip, ip, asr #21 1277 bne 1f 1278 orrs ip, xl, xh, lsl #12 1279 bne 3f @ x is NAN 12801: mov ip, yh, lsl #1 1281 mvns ip, ip, asr #21 1282 bne 2f 1283 orrs ip, yl, yh, lsl #12 1284 bne 3f @ y is NAN 12852: mov r0, #0 @ arguments are ordered. 1286 RET 1287 12883: mov r0, #1 @ arguments are unordered. 1289 RET 1290 1291 FUNC_END aeabi_dcmpun 1292 FUNC_END unorddf2 1293 1294#endif /* L_unorddf2 */ 1295 1296#ifdef L_arm_fixdfsi 1297 1298ARM_FUNC_START fixdfsi 1299ARM_FUNC_ALIAS aeabi_d2iz fixdfsi 1300 1301 @ check exponent range. 1302 mov r2, xh, lsl #1 1303 adds r2, r2, #(1 << 21) 1304 bcs 2f @ value is INF or NAN 1305 bpl 1f @ value is too small 1306 mov r3, #(0xfffffc00 + 31) 1307 subs r2, r3, r2, asr #21 1308 bls 3f @ value is too large 1309 1310 @ scale value 1311 mov r3, xh, lsl #11 1312 orr r3, r3, #0x80000000 1313 orr r3, r3, xl, lsr #21 1314 tst xh, #0x80000000 @ the sign bit 1315 shift1 lsr, r0, r3, r2 1316 do_it ne 1317 rsbne r0, r0, #0 1318 RET 1319 13201: mov r0, #0 1321 RET 1322 13232: orrs xl, xl, xh, lsl #12 1324 bne 4f @ x is NAN. 13253: ands r0, xh, #0x80000000 @ the sign bit 1326 do_it eq 1327 moveq r0, #0x7fffffff @ maximum signed positive si 1328 RET 1329 13304: mov r0, #0 @ How should we convert NAN? 1331 RET 1332 1333 FUNC_END aeabi_d2iz 1334 FUNC_END fixdfsi 1335 1336#endif /* L_fixdfsi */ 1337 1338#ifdef L_arm_fixunsdfsi 1339 1340ARM_FUNC_START fixunsdfsi 1341ARM_FUNC_ALIAS aeabi_d2uiz fixunsdfsi 1342 1343 @ check exponent range. 1344 movs r2, xh, lsl #1 1345 bcs 1f @ value is negative 1346 adds r2, r2, #(1 << 21) 1347 bcs 2f @ value is INF or NAN 1348 bpl 1f @ value is too small 1349 mov r3, #(0xfffffc00 + 31) 1350 subs r2, r3, r2, asr #21 1351 bmi 3f @ value is too large 1352 1353 @ scale value 1354 mov r3, xh, lsl #11 1355 orr r3, r3, #0x80000000 1356 orr r3, r3, xl, lsr #21 1357 shift1 lsr, r0, r3, r2 1358 RET 1359 13601: mov r0, #0 1361 RET 1362 13632: orrs xl, xl, xh, lsl #12 1364 bne 4f @ value is NAN. 13653: mov r0, #0xffffffff @ maximum unsigned si 1366 RET 1367 13684: mov r0, #0 @ How should we convert NAN? 1369 RET 1370 1371 FUNC_END aeabi_d2uiz 1372 FUNC_END fixunsdfsi 1373 1374#endif /* L_fixunsdfsi */ 1375 1376#ifdef L_arm_truncdfsf2 1377 1378ARM_FUNC_START truncdfsf2 1379ARM_FUNC_ALIAS aeabi_d2f truncdfsf2 1380 1381 @ check exponent range. 1382 mov r2, xh, lsl #1 1383 subs r3, r2, #((1023 - 127) << 21) 1384 do_it cs, t 1385 COND(sub,s,cs) ip, r3, #(1 << 21) 1386 COND(rsb,s,cs) ip, ip, #(254 << 21) 1387 bls 2f @ value is out of range 1388 13891: @ shift and round mantissa 1390 and ip, xh, #0x80000000 1391 mov r2, xl, lsl #3 1392 orr xl, ip, xl, lsr #29 1393 cmp r2, #0x80000000 1394 adc r0, xl, r3, lsl #2 1395 do_it eq 1396 biceq r0, r0, #1 1397 RET 1398 13992: @ either overflow or underflow 1400 tst xh, #0x40000000 1401 bne 3f @ overflow 1402 1403 @ check if denormalized value is possible 1404 adds r2, r3, #(23 << 21) 1405 do_it lt, t 1406 andlt r0, xh, #0x80000000 @ too small, return signed 0. 1407 RETc(lt) 1408 1409 @ denormalize value so we can resume with the code above afterwards. 1410 orr xh, xh, #0x00100000 1411 mov r2, r2, lsr #21 1412 rsb r2, r2, #24 1413 rsb ip, r2, #32 1414#if defined(__thumb2__) 1415 lsls r3, xl, ip 1416#else 1417 movs r3, xl, lsl ip 1418#endif 1419 shift1 lsr, xl, xl, r2 1420 do_it ne 1421 orrne xl, xl, #1 @ fold r3 for rounding considerations. 1422 mov r3, xh, lsl #11 1423 mov r3, r3, lsr #11 1424 shiftop orr xl xl r3 lsl ip ip 1425 shift1 lsr, r3, r3, r2 1426 mov r3, r3, lsl #1 1427 b 1b 1428 14293: @ chech for NAN 1430 mvns r3, r2, asr #21 1431 bne 5f @ simple overflow 1432 orrs r3, xl, xh, lsl #12 1433 do_it ne, tt 1434 movne r0, #0x7f000000 1435 orrne r0, r0, #0x00c00000 1436 RETc(ne) @ return NAN 1437 14385: @ return INF with sign 1439 and r0, xh, #0x80000000 1440 orr r0, r0, #0x7f000000 1441 orr r0, r0, #0x00800000 1442 RET 1443 1444 FUNC_END aeabi_d2f 1445 FUNC_END truncdfsf2 1446 1447#endif /* L_truncdfsf2 */ 1448