1@ libgcc routines for ARM cpu. 2@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk) 3 4/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005 5 Free Software Foundation, Inc. 6 7This file is free software; you can redistribute it and/or modify it 8under the terms of the GNU General Public License as published by the 9Free Software Foundation; either version 2, or (at your option) any 10later version. 11 12In addition to the permissions in the GNU General Public License, the 13Free Software Foundation gives you unlimited permission to link the 14compiled version of this file into combinations with other programs, 15and to distribute those combinations without any restriction coming 16from the use of this file. (The General Public License restrictions 17do apply in other respects; for example, they cover modification of 18the file, and distribution when not linked into a combine 19executable.) 20 21This file is distributed in the hope that it will be useful, but 22WITHOUT ANY WARRANTY; without even the implied warranty of 23MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24General Public License for more details. 25 26You should have received a copy of the GNU General Public License 27along with this program; see the file COPYING. If not, write to 28the Free Software Foundation, 51 Franklin Street, Fifth Floor, 29Boston, MA 02110-1301, USA. */ 30/* ------------------------------------------------------------------------ */ 31 32/* We need to know what prefix to add to function names. */ 33 34#ifndef __USER_LABEL_PREFIX__ 35#error __USER_LABEL_PREFIX__ not defined 36#endif 37 38/* ANSI concatenation macros. */ 39 40#define CONCAT1(a, b) CONCAT2(a, b) 41#define CONCAT2(a, b) a ## b 42 43/* Use the right prefix for global labels. */ 44 45#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) 46 47#ifdef __ELF__ 48#ifdef __thumb__ 49#define __PLT__ /* Not supported in Thumb assembler (for now). */ 50#else 51#define __PLT__ (PLT) 52#endif 53#define TYPE(x) .type SYM(x),function 54#define SIZE(x) .size SYM(x), . - SYM(x) 55#define LSYM(x) .x 56#else 57#define __PLT__ 58#define TYPE(x) 59#define SIZE(x) 60#define LSYM(x) x 61#endif 62 63/* Function end macros. Variants for interworking. */ 64 65@ This selects the minimum architecture level required. 66#define __ARM_ARCH__ 3 67 68#if defined(__ARM_ARCH_3M__) || defined(__ARM_ARCH_4__) \ 69 || defined(__ARM_ARCH_4T__) 70/* We use __ARM_ARCH__ set to 4 here, but in reality it's any processor with 71 long multiply instructions. That includes v3M. */ 72# undef __ARM_ARCH__ 73# define __ARM_ARCH__ 4 74#endif 75 76#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \ 77 || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \ 78 || defined(__ARM_ARCH_5TEJ__) 79# undef __ARM_ARCH__ 80# define __ARM_ARCH__ 5 81#endif 82 83#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \ 84 || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \ 85 || defined(__ARM_ARCH_6ZK__) 86# undef __ARM_ARCH__ 87# define __ARM_ARCH__ 6 88#endif 89 90#ifndef __ARM_ARCH__ 91#error Unable to determine architecture. 92#endif 93 94/* How to return from a function call depends on the architecture variant. */ 95 96#if (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__) 97 98# define RET bx lr 99# define RETc(x) bx##x lr 100 101/* Special precautions for interworking on armv4t. */ 102# if (__ARM_ARCH__ == 4) 103 104/* Always use bx, not ldr pc. */ 105# if (defined(__thumb__) || defined(__THUMB_INTERWORK__)) 106# define __INTERWORKING__ 107# endif /* __THUMB__ || __THUMB_INTERWORK__ */ 108 109/* Include thumb stub before arm mode code. */ 110# if defined(__thumb__) && !defined(__THUMB_INTERWORK__) 111# define __INTERWORKING_STUBS__ 112# endif /* __thumb__ && !__THUMB_INTERWORK__ */ 113 114#endif /* __ARM_ARCH == 4 */ 115 116#else 117 118# define RET mov pc, lr 119# define RETc(x) mov##x pc, lr 120 121#endif 122 123.macro cfi_pop advance, reg, cfa_offset 124#ifdef __ELF__ 125 .pushsection .debug_frame 126 .byte 0x4 /* DW_CFA_advance_loc4 */ 127 .4byte \advance 128 .byte (0xc0 | \reg) /* DW_CFA_restore */ 129 .byte 0xe /* DW_CFA_def_cfa_offset */ 130 .uleb128 \cfa_offset 131 .popsection 132#endif 133.endm 134.macro cfi_push advance, reg, offset, cfa_offset 135#ifdef __ELF__ 136 .pushsection .debug_frame 137 .byte 0x4 /* DW_CFA_advance_loc4 */ 138 .4byte \advance 139 .byte (0x80 | \reg) /* DW_CFA_offset */ 140 .uleb128 (\offset / -4) 141 .byte 0xe /* DW_CFA_def_cfa_offset */ 142 .uleb128 \cfa_offset 143 .popsection 144#endif 145.endm 146.macro cfi_start start_label, end_label 147#ifdef __ELF__ 148 .pushsection .debug_frame 149LSYM(Lstart_frame): 150 .4byte LSYM(Lend_cie) - LSYM(Lstart_cie) @ Length of CIE 151LSYM(Lstart_cie): 152 .4byte 0xffffffff @ CIE Identifier Tag 153 .byte 0x1 @ CIE Version 154 .ascii "\0" @ CIE Augmentation 155 .uleb128 0x1 @ CIE Code Alignment Factor 156 .sleb128 -4 @ CIE Data Alignment Factor 157 .byte 0xe @ CIE RA Column 158 .byte 0xc @ DW_CFA_def_cfa 159 .uleb128 0xd 160 .uleb128 0x0 161 162 .align 2 163LSYM(Lend_cie): 164 .4byte LSYM(Lend_fde)-LSYM(Lstart_fde) @ FDE Length 165LSYM(Lstart_fde): 166 .4byte LSYM(Lstart_frame) @ FDE CIE offset 167 .4byte \start_label @ FDE initial location 168 .4byte \end_label-\start_label @ FDE address range 169 .popsection 170#endif 171.endm 172.macro cfi_end end_label 173#ifdef __ELF__ 174 .pushsection .debug_frame 175 .align 2 176LSYM(Lend_fde): 177 .popsection 178\end_label: 179#endif 180.endm 181 182/* Don't pass dirn, it's there just to get token pasting right. */ 183 184.macro RETLDM regs=, cond=, unwind=, dirn=ia 185#if defined (__INTERWORKING__) 186 .ifc "\regs","" 187 ldr\cond lr, [sp], #8 188 .else 189 ldm\cond\dirn sp!, {\regs, lr} 190 .endif 191 .ifnc "\unwind", "" 192 /* Mark LR as restored. */ 19397: cfi_pop 97b - \unwind, 0xe, 0x0 194 .endif 195 bx\cond lr 196#else 197 .ifc "\regs","" 198 ldr\cond pc, [sp], #8 199 .else 200 ldm\cond\dirn sp!, {\regs, pc} 201 .endif 202#endif 203.endm 204 205 206.macro ARM_LDIV0 name 207 str lr, [sp, #-8]! 20898: cfi_push 98b - __\name, 0xe, -0x8, 0x8 209 bl SYM (__div0) __PLT__ 210 mov r0, #0 @ About as wrong as it could be. 211 RETLDM unwind=98b 212.endm 213 214 215.macro THUMB_LDIV0 name 216 push { r1, lr } 21798: cfi_push 98b - __\name, 0xe, -0x4, 0x8 218 bl SYM (__div0) 219 mov r0, #0 @ About as wrong as it could be. 220#if defined (__INTERWORKING__) 221 pop { r1, r2 } 222 bx r2 223#else 224 pop { r1, pc } 225#endif 226.endm 227 228.macro FUNC_END name 229 SIZE (__\name) 230.endm 231 232.macro DIV_FUNC_END name 233 cfi_start __\name, LSYM(Lend_div0) 234LSYM(Ldiv0): 235#ifdef __thumb__ 236 THUMB_LDIV0 \name 237#else 238 ARM_LDIV0 \name 239#endif 240 cfi_end LSYM(Lend_div0) 241 FUNC_END \name 242.endm 243 244.macro THUMB_FUNC_START name 245 .globl SYM (\name) 246 TYPE (\name) 247 .thumb_func 248SYM (\name): 249.endm 250 251/* Function start macros. Variants for ARM and Thumb. */ 252 253#ifdef __thumb__ 254#define THUMB_FUNC .thumb_func 255#define THUMB_CODE .thumb 256#else 257#define THUMB_FUNC 258#define THUMB_CODE 259#endif 260 261.macro FUNC_START name 262 .text 263 .globl SYM (__\name) 264 TYPE (__\name) 265 .align 0 266 THUMB_CODE 267 THUMB_FUNC 268SYM (__\name): 269.endm 270 271/* Special function that will always be coded in ARM assembly, even if 272 in Thumb-only compilation. */ 273 274#if defined(__INTERWORKING_STUBS__) 275.macro ARM_FUNC_START name 276 FUNC_START \name 277 bx pc 278 nop 279 .arm 280/* A hook to tell gdb that we've switched to ARM mode. Also used to call 281 directly from other local arm routines. */ 282_L__\name: 283.endm 284#define EQUIV .thumb_set 285/* Branch directly to a function declared with ARM_FUNC_START. 286 Must be called in arm mode. */ 287.macro ARM_CALL name 288 bl _L__\name 289.endm 290#else 291.macro ARM_FUNC_START name 292 .text 293 .globl SYM (__\name) 294 TYPE (__\name) 295 .align 0 296 .arm 297SYM (__\name): 298.endm 299#define EQUIV .set 300.macro ARM_CALL name 301 bl __\name 302.endm 303#endif 304 305.macro FUNC_ALIAS new old 306 .globl SYM (__\new) 307#if defined (__thumb__) 308 .thumb_set SYM (__\new), SYM (__\old) 309#else 310 .set SYM (__\new), SYM (__\old) 311#endif 312.endm 313 314.macro ARM_FUNC_ALIAS new old 315 .globl SYM (__\new) 316 EQUIV SYM (__\new), SYM (__\old) 317#if defined(__INTERWORKING_STUBS__) 318 .set SYM (_L__\new), SYM (_L__\old) 319#endif 320.endm 321 322#ifdef __thumb__ 323/* Register aliases. */ 324 325work .req r4 @ XXXX is this safe ? 326dividend .req r0 327divisor .req r1 328overdone .req r2 329result .req r2 330curbit .req r3 331#endif 332#if 0 333ip .req r12 334sp .req r13 335lr .req r14 336pc .req r15 337#endif 338 339/* ------------------------------------------------------------------------ */ 340/* Bodies of the division and modulo routines. */ 341/* ------------------------------------------------------------------------ */ 342.macro ARM_DIV_BODY dividend, divisor, result, curbit 343 344#if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__) 345 346 clz \curbit, \dividend 347 clz \result, \divisor 348 sub \curbit, \result, \curbit 349 rsbs \curbit, \curbit, #31 350 addne \curbit, \curbit, \curbit, lsl #1 351 mov \result, #0 352 addne pc, pc, \curbit, lsl #2 353 nop 354 .set shift, 32 355 .rept 32 356 .set shift, shift - 1 357 cmp \dividend, \divisor, lsl #shift 358 adc \result, \result, \result 359 subcs \dividend, \dividend, \divisor, lsl #shift 360 .endr 361 362#else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */ 363#if __ARM_ARCH__ >= 5 364 365 clz \curbit, \divisor 366 clz \result, \dividend 367 sub \result, \curbit, \result 368 mov \curbit, #1 369 mov \divisor, \divisor, lsl \result 370 mov \curbit, \curbit, lsl \result 371 mov \result, #0 372 373#else /* __ARM_ARCH__ < 5 */ 374 375 @ Initially shift the divisor left 3 bits if possible, 376 @ set curbit accordingly. This allows for curbit to be located 377 @ at the left end of each 4 bit nibbles in the division loop 378 @ to save one loop in most cases. 379 tst \divisor, #0xe0000000 380 moveq \divisor, \divisor, lsl #3 381 moveq \curbit, #8 382 movne \curbit, #1 383 384 @ Unless the divisor is very big, shift it up in multiples of 385 @ four bits, since this is the amount of unwinding in the main 386 @ division loop. Continue shifting until the divisor is 387 @ larger than the dividend. 3881: cmp \divisor, #0x10000000 389 cmplo \divisor, \dividend 390 movlo \divisor, \divisor, lsl #4 391 movlo \curbit, \curbit, lsl #4 392 blo 1b 393 394 @ For very big divisors, we must shift it a bit at a time, or 395 @ we will be in danger of overflowing. 3961: cmp \divisor, #0x80000000 397 cmplo \divisor, \dividend 398 movlo \divisor, \divisor, lsl #1 399 movlo \curbit, \curbit, lsl #1 400 blo 1b 401 402 mov \result, #0 403 404#endif /* __ARM_ARCH__ < 5 */ 405 406 @ Division loop 4071: cmp \dividend, \divisor 408 subhs \dividend, \dividend, \divisor 409 orrhs \result, \result, \curbit 410 cmp \dividend, \divisor, lsr #1 411 subhs \dividend, \dividend, \divisor, lsr #1 412 orrhs \result, \result, \curbit, lsr #1 413 cmp \dividend, \divisor, lsr #2 414 subhs \dividend, \dividend, \divisor, lsr #2 415 orrhs \result, \result, \curbit, lsr #2 416 cmp \dividend, \divisor, lsr #3 417 subhs \dividend, \dividend, \divisor, lsr #3 418 orrhs \result, \result, \curbit, lsr #3 419 cmp \dividend, #0 @ Early termination? 420 movnes \curbit, \curbit, lsr #4 @ No, any more bits to do? 421 movne \divisor, \divisor, lsr #4 422 bne 1b 423 424#endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */ 425 426.endm 427/* ------------------------------------------------------------------------ */ 428.macro ARM_DIV2_ORDER divisor, order 429 430#if __ARM_ARCH__ >= 5 431 432 clz \order, \divisor 433 rsb \order, \order, #31 434 435#else 436 437 cmp \divisor, #(1 << 16) 438 movhs \divisor, \divisor, lsr #16 439 movhs \order, #16 440 movlo \order, #0 441 442 cmp \divisor, #(1 << 8) 443 movhs \divisor, \divisor, lsr #8 444 addhs \order, \order, #8 445 446 cmp \divisor, #(1 << 4) 447 movhs \divisor, \divisor, lsr #4 448 addhs \order, \order, #4 449 450 cmp \divisor, #(1 << 2) 451 addhi \order, \order, #3 452 addls \order, \order, \divisor, lsr #1 453 454#endif 455 456.endm 457/* ------------------------------------------------------------------------ */ 458.macro ARM_MOD_BODY dividend, divisor, order, spare 459 460#if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__) 461 462 clz \order, \divisor 463 clz \spare, \dividend 464 sub \order, \order, \spare 465 rsbs \order, \order, #31 466 addne pc, pc, \order, lsl #3 467 nop 468 .set shift, 32 469 .rept 32 470 .set shift, shift - 1 471 cmp \dividend, \divisor, lsl #shift 472 subcs \dividend, \dividend, \divisor, lsl #shift 473 .endr 474 475#else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */ 476#if __ARM_ARCH__ >= 5 477 478 clz \order, \divisor 479 clz \spare, \dividend 480 sub \order, \order, \spare 481 mov \divisor, \divisor, lsl \order 482 483#else /* __ARM_ARCH__ < 5 */ 484 485 mov \order, #0 486 487 @ Unless the divisor is very big, shift it up in multiples of 488 @ four bits, since this is the amount of unwinding in the main 489 @ division loop. Continue shifting until the divisor is 490 @ larger than the dividend. 4911: cmp \divisor, #0x10000000 492 cmplo \divisor, \dividend 493 movlo \divisor, \divisor, lsl #4 494 addlo \order, \order, #4 495 blo 1b 496 497 @ For very big divisors, we must shift it a bit at a time, or 498 @ we will be in danger of overflowing. 4991: cmp \divisor, #0x80000000 500 cmplo \divisor, \dividend 501 movlo \divisor, \divisor, lsl #1 502 addlo \order, \order, #1 503 blo 1b 504 505#endif /* __ARM_ARCH__ < 5 */ 506 507 @ Perform all needed substractions to keep only the reminder. 508 @ Do comparisons in batch of 4 first. 509 subs \order, \order, #3 @ yes, 3 is intended here 510 blt 2f 511 5121: cmp \dividend, \divisor 513 subhs \dividend, \dividend, \divisor 514 cmp \dividend, \divisor, lsr #1 515 subhs \dividend, \dividend, \divisor, lsr #1 516 cmp \dividend, \divisor, lsr #2 517 subhs \dividend, \dividend, \divisor, lsr #2 518 cmp \dividend, \divisor, lsr #3 519 subhs \dividend, \dividend, \divisor, lsr #3 520 cmp \dividend, #1 521 mov \divisor, \divisor, lsr #4 522 subges \order, \order, #4 523 bge 1b 524 525 tst \order, #3 526 teqne \dividend, #0 527 beq 5f 528 529 @ Either 1, 2 or 3 comparison/substractions are left. 5302: cmn \order, #2 531 blt 4f 532 beq 3f 533 cmp \dividend, \divisor 534 subhs \dividend, \dividend, \divisor 535 mov \divisor, \divisor, lsr #1 5363: cmp \dividend, \divisor 537 subhs \dividend, \dividend, \divisor 538 mov \divisor, \divisor, lsr #1 5394: cmp \dividend, \divisor 540 subhs \dividend, \dividend, \divisor 5415: 542 543#endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */ 544 545.endm 546/* ------------------------------------------------------------------------ */ 547.macro THUMB_DIV_MOD_BODY modulo 548 @ Load the constant 0x10000000 into our work register. 549 mov work, #1 550 lsl work, #28 551LSYM(Loop1): 552 @ Unless the divisor is very big, shift it up in multiples of 553 @ four bits, since this is the amount of unwinding in the main 554 @ division loop. Continue shifting until the divisor is 555 @ larger than the dividend. 556 cmp divisor, work 557 bhs LSYM(Lbignum) 558 cmp divisor, dividend 559 bhs LSYM(Lbignum) 560 lsl divisor, #4 561 lsl curbit, #4 562 b LSYM(Loop1) 563LSYM(Lbignum): 564 @ Set work to 0x80000000 565 lsl work, #3 566LSYM(Loop2): 567 @ For very big divisors, we must shift it a bit at a time, or 568 @ we will be in danger of overflowing. 569 cmp divisor, work 570 bhs LSYM(Loop3) 571 cmp divisor, dividend 572 bhs LSYM(Loop3) 573 lsl divisor, #1 574 lsl curbit, #1 575 b LSYM(Loop2) 576LSYM(Loop3): 577 @ Test for possible subtractions ... 578 .if \modulo 579 @ ... On the final pass, this may subtract too much from the dividend, 580 @ so keep track of which subtractions are done, we can fix them up 581 @ afterwards. 582 mov overdone, #0 583 cmp dividend, divisor 584 blo LSYM(Lover1) 585 sub dividend, dividend, divisor 586LSYM(Lover1): 587 lsr work, divisor, #1 588 cmp dividend, work 589 blo LSYM(Lover2) 590 sub dividend, dividend, work 591 mov ip, curbit 592 mov work, #1 593 ror curbit, work 594 orr overdone, curbit 595 mov curbit, ip 596LSYM(Lover2): 597 lsr work, divisor, #2 598 cmp dividend, work 599 blo LSYM(Lover3) 600 sub dividend, dividend, work 601 mov ip, curbit 602 mov work, #2 603 ror curbit, work 604 orr overdone, curbit 605 mov curbit, ip 606LSYM(Lover3): 607 lsr work, divisor, #3 608 cmp dividend, work 609 blo LSYM(Lover4) 610 sub dividend, dividend, work 611 mov ip, curbit 612 mov work, #3 613 ror curbit, work 614 orr overdone, curbit 615 mov curbit, ip 616LSYM(Lover4): 617 mov ip, curbit 618 .else 619 @ ... and note which bits are done in the result. On the final pass, 620 @ this may subtract too much from the dividend, but the result will be ok, 621 @ since the "bit" will have been shifted out at the bottom. 622 cmp dividend, divisor 623 blo LSYM(Lover1) 624 sub dividend, dividend, divisor 625 orr result, result, curbit 626LSYM(Lover1): 627 lsr work, divisor, #1 628 cmp dividend, work 629 blo LSYM(Lover2) 630 sub dividend, dividend, work 631 lsr work, curbit, #1 632 orr result, work 633LSYM(Lover2): 634 lsr work, divisor, #2 635 cmp dividend, work 636 blo LSYM(Lover3) 637 sub dividend, dividend, work 638 lsr work, curbit, #2 639 orr result, work 640LSYM(Lover3): 641 lsr work, divisor, #3 642 cmp dividend, work 643 blo LSYM(Lover4) 644 sub dividend, dividend, work 645 lsr work, curbit, #3 646 orr result, work 647LSYM(Lover4): 648 .endif 649 650 cmp dividend, #0 @ Early termination? 651 beq LSYM(Lover5) 652 lsr curbit, #4 @ No, any more bits to do? 653 beq LSYM(Lover5) 654 lsr divisor, #4 655 b LSYM(Loop3) 656LSYM(Lover5): 657 .if \modulo 658 @ Any subtractions that we should not have done will be recorded in 659 @ the top three bits of "overdone". Exactly which were not needed 660 @ are governed by the position of the bit, stored in ip. 661 mov work, #0xe 662 lsl work, #28 663 and overdone, work 664 beq LSYM(Lgot_result) 665 666 @ If we terminated early, because dividend became zero, then the 667 @ bit in ip will not be in the bottom nibble, and we should not 668 @ perform the additions below. We must test for this though 669 @ (rather relying upon the TSTs to prevent the additions) since 670 @ the bit in ip could be in the top two bits which might then match 671 @ with one of the smaller RORs. 672 mov curbit, ip 673 mov work, #0x7 674 tst curbit, work 675 beq LSYM(Lgot_result) 676 677 mov curbit, ip 678 mov work, #3 679 ror curbit, work 680 tst overdone, curbit 681 beq LSYM(Lover6) 682 lsr work, divisor, #3 683 add dividend, work 684LSYM(Lover6): 685 mov curbit, ip 686 mov work, #2 687 ror curbit, work 688 tst overdone, curbit 689 beq LSYM(Lover7) 690 lsr work, divisor, #2 691 add dividend, work 692LSYM(Lover7): 693 mov curbit, ip 694 mov work, #1 695 ror curbit, work 696 tst overdone, curbit 697 beq LSYM(Lgot_result) 698 lsr work, divisor, #1 699 add dividend, work 700 .endif 701LSYM(Lgot_result): 702.endm 703/* ------------------------------------------------------------------------ */ 704/* Start of the Real Functions */ 705/* ------------------------------------------------------------------------ */ 706#ifdef L_udivsi3 707 708 FUNC_START udivsi3 709 FUNC_ALIAS aeabi_uidiv udivsi3 710 711#ifdef __thumb__ 712 713 cmp divisor, #0 714 beq LSYM(Ldiv0) 715 mov curbit, #1 716 mov result, #0 717 718 push { work } 719 cmp dividend, divisor 720 blo LSYM(Lgot_result) 721 722 THUMB_DIV_MOD_BODY 0 723 724 mov r0, result 725 pop { work } 726 RET 727 728#else /* ARM version. */ 729 730 subs r2, r1, #1 731 RETc(eq) 732 bcc LSYM(Ldiv0) 733 cmp r0, r1 734 bls 11f 735 tst r1, r2 736 beq 12f 737 738 ARM_DIV_BODY r0, r1, r2, r3 739 740 mov r0, r2 741 RET 742 74311: moveq r0, #1 744 movne r0, #0 745 RET 746 74712: ARM_DIV2_ORDER r1, r2 748 749 mov r0, r0, lsr r2 750 RET 751 752#endif /* ARM version */ 753 754 DIV_FUNC_END udivsi3 755 756FUNC_START aeabi_uidivmod 757#ifdef __thumb__ 758 push {r0, r1, lr} 759 bl SYM(__udivsi3) 760 POP {r1, r2, r3} 761 mul r2, r0 762 sub r1, r1, r2 763 bx r3 764#else 765 stmfd sp!, { r0, r1, lr } 766 bl SYM(__udivsi3) 767 ldmfd sp!, { r1, r2, lr } 768 mul r3, r2, r0 769 sub r1, r1, r3 770 RET 771#endif 772 FUNC_END aeabi_uidivmod 773 774#endif /* L_udivsi3 */ 775/* ------------------------------------------------------------------------ */ 776#ifdef L_umodsi3 777 778 FUNC_START umodsi3 779 780#ifdef __thumb__ 781 782 cmp divisor, #0 783 beq LSYM(Ldiv0) 784 mov curbit, #1 785 cmp dividend, divisor 786 bhs LSYM(Lover10) 787 RET 788 789LSYM(Lover10): 790 push { work } 791 792 THUMB_DIV_MOD_BODY 1 793 794 pop { work } 795 RET 796 797#else /* ARM version. */ 798 799 subs r2, r1, #1 @ compare divisor with 1 800 bcc LSYM(Ldiv0) 801 cmpne r0, r1 @ compare dividend with divisor 802 moveq r0, #0 803 tsthi r1, r2 @ see if divisor is power of 2 804 andeq r0, r0, r2 805 RETc(ls) 806 807 ARM_MOD_BODY r0, r1, r2, r3 808 809 RET 810 811#endif /* ARM version. */ 812 813 DIV_FUNC_END umodsi3 814 815#endif /* L_umodsi3 */ 816/* ------------------------------------------------------------------------ */ 817#ifdef L_divsi3 818 819 FUNC_START divsi3 820 FUNC_ALIAS aeabi_idiv divsi3 821 822#ifdef __thumb__ 823 cmp divisor, #0 824 beq LSYM(Ldiv0) 825 826 push { work } 827 mov work, dividend 828 eor work, divisor @ Save the sign of the result. 829 mov ip, work 830 mov curbit, #1 831 mov result, #0 832 cmp divisor, #0 833 bpl LSYM(Lover10) 834 neg divisor, divisor @ Loops below use unsigned. 835LSYM(Lover10): 836 cmp dividend, #0 837 bpl LSYM(Lover11) 838 neg dividend, dividend 839LSYM(Lover11): 840 cmp dividend, divisor 841 blo LSYM(Lgot_result) 842 843 THUMB_DIV_MOD_BODY 0 844 845 mov r0, result 846 mov work, ip 847 cmp work, #0 848 bpl LSYM(Lover12) 849 neg r0, r0 850LSYM(Lover12): 851 pop { work } 852 RET 853 854#else /* ARM version. */ 855 856 cmp r1, #0 857 eor ip, r0, r1 @ save the sign of the result. 858 beq LSYM(Ldiv0) 859 rsbmi r1, r1, #0 @ loops below use unsigned. 860 subs r2, r1, #1 @ division by 1 or -1 ? 861 beq 10f 862 movs r3, r0 863 rsbmi r3, r0, #0 @ positive dividend value 864 cmp r3, r1 865 bls 11f 866 tst r1, r2 @ divisor is power of 2 ? 867 beq 12f 868 869 ARM_DIV_BODY r3, r1, r0, r2 870 871 cmp ip, #0 872 rsbmi r0, r0, #0 873 RET 874 87510: teq ip, r0 @ same sign ? 876 rsbmi r0, r0, #0 877 RET 878 87911: movlo r0, #0 880 moveq r0, ip, asr #31 881 orreq r0, r0, #1 882 RET 883 88412: ARM_DIV2_ORDER r1, r2 885 886 cmp ip, #0 887 mov r0, r3, lsr r2 888 rsbmi r0, r0, #0 889 RET 890 891#endif /* ARM version */ 892 893 DIV_FUNC_END divsi3 894 895FUNC_START aeabi_idivmod 896#ifdef __thumb__ 897 push {r0, r1, lr} 898 bl SYM(__divsi3) 899 POP {r1, r2, r3} 900 mul r2, r0 901 sub r1, r1, r2 902 bx r3 903#else 904 stmfd sp!, { r0, r1, lr } 905 bl SYM(__divsi3) 906 ldmfd sp!, { r1, r2, lr } 907 mul r3, r2, r0 908 sub r1, r1, r3 909 RET 910#endif 911 FUNC_END aeabi_idivmod 912 913#endif /* L_divsi3 */ 914/* ------------------------------------------------------------------------ */ 915#ifdef L_modsi3 916 917 FUNC_START modsi3 918 919#ifdef __thumb__ 920 921 mov curbit, #1 922 cmp divisor, #0 923 beq LSYM(Ldiv0) 924 bpl LSYM(Lover10) 925 neg divisor, divisor @ Loops below use unsigned. 926LSYM(Lover10): 927 push { work } 928 @ Need to save the sign of the dividend, unfortunately, we need 929 @ work later on. Must do this after saving the original value of 930 @ the work register, because we will pop this value off first. 931 push { dividend } 932 cmp dividend, #0 933 bpl LSYM(Lover11) 934 neg dividend, dividend 935LSYM(Lover11): 936 cmp dividend, divisor 937 blo LSYM(Lgot_result) 938 939 THUMB_DIV_MOD_BODY 1 940 941 pop { work } 942 cmp work, #0 943 bpl LSYM(Lover12) 944 neg dividend, dividend 945LSYM(Lover12): 946 pop { work } 947 RET 948 949#else /* ARM version. */ 950 951 cmp r1, #0 952 beq LSYM(Ldiv0) 953 rsbmi r1, r1, #0 @ loops below use unsigned. 954 movs ip, r0 @ preserve sign of dividend 955 rsbmi r0, r0, #0 @ if negative make positive 956 subs r2, r1, #1 @ compare divisor with 1 957 cmpne r0, r1 @ compare dividend with divisor 958 moveq r0, #0 959 tsthi r1, r2 @ see if divisor is power of 2 960 andeq r0, r0, r2 961 bls 10f 962 963 ARM_MOD_BODY r0, r1, r2, r3 964 96510: cmp ip, #0 966 rsbmi r0, r0, #0 967 RET 968 969#endif /* ARM version */ 970 971 DIV_FUNC_END modsi3 972 973#endif /* L_modsi3 */ 974/* ------------------------------------------------------------------------ */ 975#ifdef L_dvmd_tls 976 977 FUNC_START div0 978 FUNC_ALIAS aeabi_idiv0 div0 979 FUNC_ALIAS aeabi_ldiv0 div0 980 981 RET 982 983 FUNC_END div0 984 985#endif /* L_divmodsi_tools */ 986/* ------------------------------------------------------------------------ */ 987#ifdef L_dvmd_lnx 988@ GNU/Linux division-by zero handler. Used in place of L_dvmd_tls 989 990/* Constant taken from <asm/signal.h>. */ 991#define SIGFPE 8 992 993 .code 32 994 FUNC_START div0 995 996 stmfd sp!, {r1, lr} 997 mov r0, #SIGFPE 998 bl SYM(raise) __PLT__ 999 RETLDM r1 1000 1001 FUNC_END div0 1002 1003#endif /* L_dvmd_lnx */ 1004/* ------------------------------------------------------------------------ */ 1005/* Dword shift operations. */ 1006/* All the following Dword shift variants rely on the fact that 1007 shft xxx, Reg 1008 is in fact done as 1009 shft xxx, (Reg & 255) 1010 so for Reg value in (32...63) and (-1...-31) we will get zero (in the 1011 case of logical shifts) or the sign (for asr). */ 1012 1013#ifdef __ARMEB__ 1014#define al r1 1015#define ah r0 1016#else 1017#define al r0 1018#define ah r1 1019#endif 1020 1021/* Prevent __aeabi double-word shifts from being produced on SymbianOS. */ 1022#ifndef __symbian__ 1023 1024#ifdef L_lshrdi3 1025 1026 FUNC_START lshrdi3 1027 FUNC_ALIAS aeabi_llsr lshrdi3 1028 1029#ifdef __thumb__ 1030 lsr al, r2 1031 mov r3, ah 1032 lsr ah, r2 1033 mov ip, r3 1034 sub r2, #32 1035 lsr r3, r2 1036 orr al, r3 1037 neg r2, r2 1038 mov r3, ip 1039 lsl r3, r2 1040 orr al, r3 1041 RET 1042#else 1043 subs r3, r2, #32 1044 rsb ip, r2, #32 1045 movmi al, al, lsr r2 1046 movpl al, ah, lsr r3 1047 orrmi al, al, ah, lsl ip 1048 mov ah, ah, lsr r2 1049 RET 1050#endif 1051 FUNC_END aeabi_llsr 1052 FUNC_END lshrdi3 1053 1054#endif 1055 1056#ifdef L_ashrdi3 1057 1058 FUNC_START ashrdi3 1059 FUNC_ALIAS aeabi_lasr ashrdi3 1060 1061#ifdef __thumb__ 1062 lsr al, r2 1063 mov r3, ah 1064 asr ah, r2 1065 sub r2, #32 1066 @ If r2 is negative at this point the following step would OR 1067 @ the sign bit into all of AL. That's not what we want... 1068 bmi 1f 1069 mov ip, r3 1070 asr r3, r2 1071 orr al, r3 1072 mov r3, ip 10731: 1074 neg r2, r2 1075 lsl r3, r2 1076 orr al, r3 1077 RET 1078#else 1079 subs r3, r2, #32 1080 rsb ip, r2, #32 1081 movmi al, al, lsr r2 1082 movpl al, ah, asr r3 1083 orrmi al, al, ah, lsl ip 1084 mov ah, ah, asr r2 1085 RET 1086#endif 1087 1088 FUNC_END aeabi_lasr 1089 FUNC_END ashrdi3 1090 1091#endif 1092 1093#ifdef L_ashldi3 1094 1095 FUNC_START ashldi3 1096 FUNC_ALIAS aeabi_llsl ashldi3 1097 1098#ifdef __thumb__ 1099 lsl ah, r2 1100 mov r3, al 1101 lsl al, r2 1102 mov ip, r3 1103 sub r2, #32 1104 lsl r3, r2 1105 orr ah, r3 1106 neg r2, r2 1107 mov r3, ip 1108 lsr r3, r2 1109 orr ah, r3 1110 RET 1111#else 1112 subs r3, r2, #32 1113 rsb ip, r2, #32 1114 movmi ah, ah, lsl r2 1115 movpl ah, al, lsl r3 1116 orrmi ah, ah, al, lsr ip 1117 mov al, al, lsl r2 1118 RET 1119#endif 1120 FUNC_END aeabi_llsl 1121 FUNC_END ashldi3 1122 1123#endif 1124 1125#endif /* __symbian__ */ 1126 1127/* ------------------------------------------------------------------------ */ 1128/* These next two sections are here despite the fact that they contain Thumb 1129 assembler because their presence allows interworked code to be linked even 1130 when the GCC library is this one. */ 1131 1132/* Do not build the interworking functions when the target architecture does 1133 not support Thumb instructions. (This can be a multilib option). */ 1134#if defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__\ 1135 || defined __ARM_ARCH_5TE__ || defined __ARM_ARCH_5TEJ__ \ 1136 || __ARM_ARCH__ >= 6 1137 1138#if defined L_call_via_rX 1139 1140/* These labels & instructions are used by the Arm/Thumb interworking code. 1141 The address of function to be called is loaded into a register and then 1142 one of these labels is called via a BL instruction. This puts the 1143 return address into the link register with the bottom bit set, and the 1144 code here switches to the correct mode before executing the function. */ 1145 1146 .text 1147 .align 0 1148 .force_thumb 1149 1150.macro call_via register 1151 THUMB_FUNC_START _call_via_\register 1152 1153 bx \register 1154 nop 1155 1156 SIZE (_call_via_\register) 1157.endm 1158 1159 call_via r0 1160 call_via r1 1161 call_via r2 1162 call_via r3 1163 call_via r4 1164 call_via r5 1165 call_via r6 1166 call_via r7 1167 call_via r8 1168 call_via r9 1169 call_via sl 1170 call_via fp 1171 call_via ip 1172 call_via sp 1173 call_via lr 1174 1175#endif /* L_call_via_rX */ 1176 1177#if defined L_interwork_call_via_rX 1178 1179/* These labels & instructions are used by the Arm/Thumb interworking code, 1180 when the target address is in an unknown instruction set. The address 1181 of function to be called is loaded into a register and then one of these 1182 labels is called via a BL instruction. This puts the return address 1183 into the link register with the bottom bit set, and the code here 1184 switches to the correct mode before executing the function. Unfortunately 1185 the target code cannot be relied upon to return via a BX instruction, so 1186 instead we have to store the resturn address on the stack and allow the 1187 called function to return here instead. Upon return we recover the real 1188 return address and use a BX to get back to Thumb mode. 1189 1190 There are three variations of this code. The first, 1191 _interwork_call_via_rN(), will push the return address onto the 1192 stack and pop it in _arm_return(). It should only be used if all 1193 arguments are passed in registers. 1194 1195 The second, _interwork_r7_call_via_rN(), instead stores the return 1196 address at [r7, #-4]. It is the caller's responsibility to ensure 1197 that this address is valid and contains no useful data. 1198 1199 The third, _interwork_r11_call_via_rN(), works in the same way but 1200 uses r11 instead of r7. It is useful if the caller does not really 1201 need a frame pointer. */ 1202 1203 .text 1204 .align 0 1205 1206 .code 32 1207 .globl _arm_return 1208LSYM(Lstart_arm_return): 1209 cfi_start LSYM(Lstart_arm_return) LSYM(Lend_arm_return) 1210 cfi_push 0, 0xe, -0x8, 0x8 1211 nop @ This nop is for the benefit of debuggers, so that 1212 @ backtraces will use the correct unwind information. 1213_arm_return: 1214 RETLDM unwind=LSYM(Lstart_arm_return) 1215 cfi_end LSYM(Lend_arm_return) 1216 1217 .globl _arm_return_r7 1218_arm_return_r7: 1219 ldr lr, [r7, #-4] 1220 bx lr 1221 1222 .globl _arm_return_r11 1223_arm_return_r11: 1224 ldr lr, [r11, #-4] 1225 bx lr 1226 1227.macro interwork_with_frame frame, register, name, return 1228 .code 16 1229 1230 THUMB_FUNC_START \name 1231 1232 bx pc 1233 nop 1234 1235 .code 32 1236 tst \register, #1 1237 streq lr, [\frame, #-4] 1238 adreq lr, _arm_return_\frame 1239 bx \register 1240 1241 SIZE (\name) 1242.endm 1243 1244.macro interwork register 1245 .code 16 1246 1247 THUMB_FUNC_START _interwork_call_via_\register 1248 1249 bx pc 1250 nop 1251 1252 .code 32 1253 .globl LSYM(Lchange_\register) 1254LSYM(Lchange_\register): 1255 tst \register, #1 1256 streq lr, [sp, #-8]! 1257 adreq lr, _arm_return 1258 bx \register 1259 1260 SIZE (_interwork_call_via_\register) 1261 1262 interwork_with_frame r7,\register,_interwork_r7_call_via_\register 1263 interwork_with_frame r11,\register,_interwork_r11_call_via_\register 1264.endm 1265 1266 interwork r0 1267 interwork r1 1268 interwork r2 1269 interwork r3 1270 interwork r4 1271 interwork r5 1272 interwork r6 1273 interwork r7 1274 interwork r8 1275 interwork r9 1276 interwork sl 1277 interwork fp 1278 interwork ip 1279 interwork sp 1280 1281 /* The LR case has to be handled a little differently... */ 1282 .code 16 1283 1284 THUMB_FUNC_START _interwork_call_via_lr 1285 1286 bx pc 1287 nop 1288 1289 .code 32 1290 .globl .Lchange_lr 1291.Lchange_lr: 1292 tst lr, #1 1293 stmeqdb r13!, {lr, pc} 1294 mov ip, lr 1295 adreq lr, _arm_return 1296 bx ip 1297 1298 SIZE (_interwork_call_via_lr) 1299 1300#endif /* L_interwork_call_via_rX */ 1301#endif /* Arch supports thumb. */ 1302 1303#ifndef __symbian__ 1304#include "ieee754-df.S" 1305#include "ieee754-sf.S" 1306#include "bpabi.S" 1307#endif /* __symbian__ */ 1308 1309 .section .note.GNU-stack,"",%progbits 1310