1@ libgcc routines for ARM cpu. 2@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk) 3 4/* Copyright (C) 1995-2022 Free Software Foundation, Inc. 5 6This file is free software; you can redistribute it and/or modify it 7under the terms of the GNU General Public License as published by the 8Free Software Foundation; either version 3, or (at your option) any 9later version. 10 11This file is distributed in the hope that it will be useful, but 12WITHOUT ANY WARRANTY; without even the implied warranty of 13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14General Public License for more details. 15 16Under Section 7 of GPL version 3, you are granted additional 17permissions described in the GCC Runtime Library Exception, version 183.1, as published by the Free Software Foundation. 19 20You should have received a copy of the GNU General Public License and 21a copy of the GCC Runtime Library Exception along with this program; 22see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23<http://www.gnu.org/licenses/>. */ 24 25/* Everything in this file should now use unified syntax. */ 26 27 .syntax unified 28 29/* An executable stack is *not* required for these functions. */ 30#if defined(__ELF__) && defined(__linux__) 31.section .note.GNU-stack,"",%progbits 32.previous 33#endif /* __ELF__ and __linux__ */ 34 35#ifdef __ARM_EABI__ 36/* Some attributes that are common to all routines in this file. */ 37 /* Tag_ABI_align_needed: This code does not require 8-byte 38 alignment from the caller. */ 39 /* .eabi_attribute 24, 0 -- default setting. */ 40 /* Tag_ABI_align_preserved: This code preserves 8-byte 41 alignment in any callee. */ 42 .eabi_attribute 25, 1 43#endif /* __ARM_EABI__ */ 44/* ------------------------------------------------------------------------ */ 45 46/* We need to know what prefix to add to function names. */ 47 48#ifndef __USER_LABEL_PREFIX__ 49#error __USER_LABEL_PREFIX__ not defined 50#endif 51 52/* ANSI concatenation macros. */ 53 54#define CONCAT1(a, b) CONCAT2(a, b) 55#define CONCAT2(a, b) a ## b 56 57/* Use the right prefix for global labels. */ 58 59#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) 60 61#ifdef __ELF__ 62#ifdef __thumb__ 63#define __PLT__ /* Not supported in Thumb assembler (for now). */ 64#elif defined __vxworks && !defined __PIC__ 65#define __PLT__ /* Not supported by the kernel loader. */ 66#else 67#define __PLT__ (PLT) 68#endif 69#define TYPE(x) .type SYM(x),function 70#define SIZE(x) .size SYM(x), . - SYM(x) 71#define LSYM(x) .x 72#else 73#define __PLT__ 74#define TYPE(x) 75#define SIZE(x) 76#define LSYM(x) x 77#endif 78 79/* Function end macros. Variants for interworking. */ 80 81/* There are times when we might prefer Thumb1 code even if ARM code is 82 permitted, for example, the code might be smaller, or there might be 83 interworking problems with switching to ARM state if interworking is 84 disabled. */ 85#if (defined(__thumb__) \ 86 && !defined(__thumb2__) \ 87 && (!defined(__THUMB_INTERWORK__) \ 88 || defined (__OPTIMIZE_SIZE__) \ 89 || !__ARM_ARCH_ISA_ARM)) 90# define __prefer_thumb__ 91#endif 92 93#if !__ARM_ARCH_ISA_ARM && __ARM_ARCH_ISA_THUMB == 1 94#define NOT_ISA_TARGET_32BIT 1 95#endif 96 97/* How to return from a function call depends on the architecture variant. */ 98 99#if (__ARM_ARCH > 4) || defined(__ARM_ARCH_4T__) 100 101# define RET bx lr 102# define RETc(x) bx##x lr 103 104/* Special precautions for interworking on armv4t. */ 105# if (__ARM_ARCH == 4) 106 107/* Always use bx, not ldr pc. */ 108# if (defined(__thumb__) || defined(__THUMB_INTERWORK__)) 109# define __INTERWORKING__ 110# endif /* __THUMB__ || __THUMB_INTERWORK__ */ 111 112/* Include thumb stub before arm mode code. */ 113# if defined(__thumb__) && !defined(__THUMB_INTERWORK__) 114# define __INTERWORKING_STUBS__ 115# endif /* __thumb__ && !__THUMB_INTERWORK__ */ 116 117#endif /* __ARM_ARCH == 4 */ 118 119#else 120 121# define RET mov pc, lr 122# define RETc(x) mov##x pc, lr 123 124#endif 125 126.macro cfi_pop advance, reg, cfa_offset 127#ifdef __ELF__ 128 .pushsection .debug_frame 129 .byte 0x4 /* DW_CFA_advance_loc4 */ 130 .4byte \advance 131 .byte (0xc0 | \reg) /* DW_CFA_restore */ 132 .byte 0xe /* DW_CFA_def_cfa_offset */ 133 .uleb128 \cfa_offset 134 .popsection 135#endif 136.endm 137.macro cfi_push advance, reg, offset, cfa_offset 138#ifdef __ELF__ 139 .pushsection .debug_frame 140 .byte 0x4 /* DW_CFA_advance_loc4 */ 141 .4byte \advance 142 .byte (0x80 | \reg) /* DW_CFA_offset */ 143 .uleb128 (\offset / -4) 144 .byte 0xe /* DW_CFA_def_cfa_offset */ 145 .uleb128 \cfa_offset 146 .popsection 147#endif 148.endm 149.macro cfi_start start_label, end_label 150#ifdef __ELF__ 151 .pushsection .debug_frame 152LSYM(Lstart_frame): 153 .4byte LSYM(Lend_cie) - LSYM(Lstart_cie) @ Length of CIE 154LSYM(Lstart_cie): 155 .4byte 0xffffffff @ CIE Identifier Tag 156 .byte 0x1 @ CIE Version 157 .ascii "\0" @ CIE Augmentation 158 .uleb128 0x1 @ CIE Code Alignment Factor 159 .sleb128 -4 @ CIE Data Alignment Factor 160 .byte 0xe @ CIE RA Column 161 .byte 0xc @ DW_CFA_def_cfa 162 .uleb128 0xd 163 .uleb128 0x0 164 165 .align 2 166LSYM(Lend_cie): 167 .4byte LSYM(Lend_fde)-LSYM(Lstart_fde) @ FDE Length 168LSYM(Lstart_fde): 169 .4byte LSYM(Lstart_frame) @ FDE CIE offset 170 .4byte \start_label @ FDE initial location 171 .4byte \end_label-\start_label @ FDE address range 172 .popsection 173#endif 174.endm 175.macro cfi_end end_label 176#ifdef __ELF__ 177 .pushsection .debug_frame 178 .align 2 179LSYM(Lend_fde): 180 .popsection 181\end_label: 182#endif 183.endm 184 185/* Don't pass dirn, it's there just to get token pasting right. */ 186 187.macro RETLDM regs=, cond=, unwind=, dirn=ia 188#if defined (__INTERWORKING__) 189 .ifc "\regs","" 190 ldr\cond lr, [sp], #8 191 .else 192# if defined(__thumb2__) 193 pop\cond {\regs, lr} 194# else 195 ldm\cond\dirn sp!, {\regs, lr} 196# endif 197 .endif 198 .ifnc "\unwind", "" 199 /* Mark LR as restored. */ 20097: cfi_pop 97b - \unwind, 0xe, 0x0 201 .endif 202 bx\cond lr 203#else 204 /* Caller is responsible for providing IT instruction. */ 205 .ifc "\regs","" 206 ldr\cond pc, [sp], #8 207 .else 208# if defined(__thumb2__) 209 pop\cond {\regs, pc} 210# else 211 ldm\cond\dirn sp!, {\regs, pc} 212# endif 213 .endif 214#endif 215.endm 216 217/* The Unified assembly syntax allows the same code to be assembled for both 218 ARM and Thumb-2. However this is only supported by recent gas, so define 219 a set of macros to allow ARM code on older assemblers. */ 220#if defined(__thumb2__) 221.macro do_it cond, suffix="" 222 it\suffix \cond 223.endm 224.macro shift1 op, arg0, arg1, arg2 225 \op \arg0, \arg1, \arg2 226.endm 227#define do_push push 228#define do_pop pop 229/* Perform an arithmetic operation with a variable shift operand. This 230 requires two instructions and a scratch register on Thumb-2. */ 231.macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp 232 \shiftop \tmp, \src2, \shiftreg 233 \name \dest, \src1, \tmp 234.endm 235#else 236.macro do_it cond, suffix="" 237.endm 238.macro shift1 op, arg0, arg1, arg2 239 mov \arg0, \arg1, \op \arg2 240.endm 241#define do_push stmfd sp!, 242#define do_pop ldmfd sp!, 243.macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp 244 \name \dest, \src1, \src2, \shiftop \shiftreg 245.endm 246#endif 247 248#define COND(op1, op2, cond) op1 ## op2 ## cond 249 250#ifdef __ARM_EABI__ 251.macro ARM_LDIV0 name signed 252 cmp r0, #0 253 .ifc \signed, unsigned 254 movne r0, #0xffffffff 255 .else 256 movgt r0, #0x7fffffff 257 movlt r0, #0x80000000 258 .endif 259 b SYM (__aeabi_idiv0) __PLT__ 260.endm 261#else 262.macro ARM_LDIV0 name signed 263 str lr, [sp, #-8]! 26498: cfi_push 98b - __\name, 0xe, -0x8, 0x8 265 bl SYM (__div0) __PLT__ 266 mov r0, #0 @ About as wrong as it could be. 267 RETLDM unwind=98b 268.endm 269#endif 270 271 272#ifdef __ARM_EABI__ 273.macro THUMB_LDIV0 name signed 274#ifdef NOT_ISA_TARGET_32BIT 275 276 push {r0, lr} 277 movs r0, #0 278 bl SYM(__aeabi_idiv0) 279 @ We know we are not on armv4t, so pop pc is safe. 280 pop {r1, pc} 281 282#elif defined(__thumb2__) 283 .syntax unified 284 .ifc \signed, unsigned 285 cbz r0, 1f 286 mov r0, #0xffffffff 2871: 288 .else 289 cmp r0, #0 290 do_it gt 291 movgt r0, #0x7fffffff 292 do_it lt 293 movlt r0, #0x80000000 294 .endif 295 b.w SYM(__aeabi_idiv0) __PLT__ 296#else 297 .align 2 298 bx pc 299 nop 300 .arm 301 cmp r0, #0 302 .ifc \signed, unsigned 303 movne r0, #0xffffffff 304 .else 305 movgt r0, #0x7fffffff 306 movlt r0, #0x80000000 307 .endif 308 b SYM(__aeabi_idiv0) __PLT__ 309 .thumb 310#endif 311.endm 312#else 313.macro THUMB_LDIV0 name signed 314 push { r1, lr } 31598: cfi_push 98b - __\name, 0xe, -0x4, 0x8 316 bl SYM (__div0) 317 movs r0, #0 @ About as wrong as it could be. 318#if defined (__INTERWORKING__) 319 pop { r1, r2 } 320 bx r2 321#else 322 pop { r1, pc } 323#endif 324.endm 325#endif 326 327.macro FUNC_END name 328 SIZE (__\name) 329.endm 330 331.macro DIV_FUNC_END name signed 332 cfi_start __\name, LSYM(Lend_div0) 333LSYM(Ldiv0): 334#ifdef __thumb__ 335 THUMB_LDIV0 \name \signed 336#else 337 ARM_LDIV0 \name \signed 338#endif 339 cfi_end LSYM(Lend_div0) 340 FUNC_END \name 341.endm 342 343.macro THUMB_FUNC_START name 344 .globl SYM (\name) 345 TYPE (\name) 346 .thumb_func 347SYM (\name): 348.endm 349 350/* Function start macros. Variants for ARM and Thumb. */ 351 352#ifdef __thumb__ 353#define THUMB_FUNC .thumb_func 354#define THUMB_CODE .force_thumb 355# if defined(__thumb2__) 356#define THUMB_SYNTAX 357# else 358#define THUMB_SYNTAX 359# endif 360#else 361#define THUMB_FUNC 362#define THUMB_CODE 363#define THUMB_SYNTAX 364#endif 365 366.macro FUNC_START name 367 .text 368 .globl SYM (__\name) 369 TYPE (__\name) 370 .align 0 371 THUMB_CODE 372 THUMB_FUNC 373 THUMB_SYNTAX 374SYM (__\name): 375.endm 376 377.macro ARM_SYM_START name 378 TYPE (\name) 379 .align 0 380SYM (\name): 381.endm 382 383.macro SYM_END name 384 SIZE (\name) 385.endm 386 387/* Special function that will always be coded in ARM assembly, even if 388 in Thumb-only compilation. */ 389 390#if defined(__thumb2__) 391 392/* For Thumb-2 we build everything in thumb mode. */ 393.macro ARM_FUNC_START name 394 FUNC_START \name 395 .syntax unified 396.endm 397#define EQUIV .thumb_set 398.macro ARM_CALL name 399 bl __\name 400.endm 401 402#elif defined(__INTERWORKING_STUBS__) 403 404.macro ARM_FUNC_START name 405 FUNC_START \name 406 bx pc 407 nop 408 .arm 409/* A hook to tell gdb that we've switched to ARM mode. Also used to call 410 directly from other local arm routines. */ 411_L__\name: 412.endm 413#define EQUIV .thumb_set 414/* Branch directly to a function declared with ARM_FUNC_START. 415 Must be called in arm mode. */ 416.macro ARM_CALL name 417 bl _L__\name 418.endm 419 420#else /* !(__INTERWORKING_STUBS__ || __thumb2__) */ 421 422#ifdef NOT_ISA_TARGET_32BIT 423#define EQUIV .thumb_set 424#else 425.macro ARM_FUNC_START name 426 .text 427 .globl SYM (__\name) 428 TYPE (__\name) 429 .align 0 430 .arm 431SYM (__\name): 432.endm 433#define EQUIV .set 434.macro ARM_CALL name 435 bl __\name 436.endm 437#endif 438 439#endif 440 441.macro FUNC_ALIAS new old 442 .globl SYM (__\new) 443#if defined (__thumb__) 444 .thumb_set SYM (__\new), SYM (__\old) 445#else 446 .set SYM (__\new), SYM (__\old) 447#endif 448.endm 449 450#ifndef NOT_ISA_TARGET_32BIT 451.macro ARM_FUNC_ALIAS new old 452 .globl SYM (__\new) 453 EQUIV SYM (__\new), SYM (__\old) 454#if defined(__INTERWORKING_STUBS__) 455 .set SYM (_L__\new), SYM (_L__\old) 456#endif 457.endm 458#endif 459 460#ifdef __ARMEB__ 461#define xxh r0 462#define xxl r1 463#define yyh r2 464#define yyl r3 465#else 466#define xxh r1 467#define xxl r0 468#define yyh r3 469#define yyl r2 470#endif 471 472#ifdef __ARM_EABI__ 473.macro WEAK name 474 .weak SYM (__\name) 475.endm 476#endif 477 478#ifdef __thumb__ 479/* Register aliases. */ 480 481work .req r4 @ XXXX is this safe ? 482dividend .req r0 483divisor .req r1 484overdone .req r2 485result .req r2 486curbit .req r3 487#endif 488#if 0 489ip .req r12 490sp .req r13 491lr .req r14 492pc .req r15 493#endif 494 495/* ------------------------------------------------------------------------ */ 496/* Bodies of the division and modulo routines. */ 497/* ------------------------------------------------------------------------ */ 498 499.macro ARM_DIV_BODY dividend, divisor, result, curbit 500 501#if defined (__ARM_FEATURE_CLZ) && ! defined (__OPTIMIZE_SIZE__) 502 503#if defined (__thumb2__) 504 clz \curbit, \dividend 505 clz \result, \divisor 506 sub \curbit, \result, \curbit 507 rsb \curbit, \curbit, #31 508 adr \result, 1f 509 add \curbit, \result, \curbit, lsl #4 510 mov \result, #0 511 mov pc, \curbit 512.p2align 3 5131: 514 .set shift, 32 515 .rept 32 516 .set shift, shift - 1 517 cmp.w \dividend, \divisor, lsl #shift 518 nop.n 519 adc.w \result, \result, \result 520 it cs 521 subcs.w \dividend, \dividend, \divisor, lsl #shift 522 .endr 523#else 524 clz \curbit, \dividend 525 clz \result, \divisor 526 sub \curbit, \result, \curbit 527 rsbs \curbit, \curbit, #31 528 addne \curbit, \curbit, \curbit, lsl #1 529 mov \result, #0 530 addne pc, pc, \curbit, lsl #2 531 nop 532 .set shift, 32 533 .rept 32 534 .set shift, shift - 1 535 cmp \dividend, \divisor, lsl #shift 536 adc \result, \result, \result 537 subcs \dividend, \dividend, \divisor, lsl #shift 538 .endr 539#endif 540 541#else /* !defined (__ARM_FEATURE_CLZ) || defined (__OPTIMIZE_SIZE__) */ 542#if defined (__ARM_FEATURE_CLZ) 543 544 clz \curbit, \divisor 545 clz \result, \dividend 546 sub \result, \curbit, \result 547 mov \curbit, #1 548 mov \divisor, \divisor, lsl \result 549 mov \curbit, \curbit, lsl \result 550 mov \result, #0 551 552#else /* !defined (__ARM_FEATURE_CLZ) */ 553 554 @ Initially shift the divisor left 3 bits if possible, 555 @ set curbit accordingly. This allows for curbit to be located 556 @ at the left end of each 4-bit nibbles in the division loop 557 @ to save one loop in most cases. 558 tst \divisor, #0xe0000000 559 moveq \divisor, \divisor, lsl #3 560 moveq \curbit, #8 561 movne \curbit, #1 562 563 @ Unless the divisor is very big, shift it up in multiples of 564 @ four bits, since this is the amount of unwinding in the main 565 @ division loop. Continue shifting until the divisor is 566 @ larger than the dividend. 5671: cmp \divisor, #0x10000000 568 cmplo \divisor, \dividend 569 movlo \divisor, \divisor, lsl #4 570 movlo \curbit, \curbit, lsl #4 571 blo 1b 572 573 @ For very big divisors, we must shift it a bit at a time, or 574 @ we will be in danger of overflowing. 5751: cmp \divisor, #0x80000000 576 cmplo \divisor, \dividend 577 movlo \divisor, \divisor, lsl #1 578 movlo \curbit, \curbit, lsl #1 579 blo 1b 580 581 mov \result, #0 582 583#endif /* !defined (__ARM_FEATURE_CLZ) */ 584 585 @ Division loop 5861: cmp \dividend, \divisor 587 do_it hs, t 588 subhs \dividend, \dividend, \divisor 589 orrhs \result, \result, \curbit 590 cmp \dividend, \divisor, lsr #1 591 do_it hs, t 592 subhs \dividend, \dividend, \divisor, lsr #1 593 orrhs \result, \result, \curbit, lsr #1 594 cmp \dividend, \divisor, lsr #2 595 do_it hs, t 596 subhs \dividend, \dividend, \divisor, lsr #2 597 orrhs \result, \result, \curbit, lsr #2 598 cmp \dividend, \divisor, lsr #3 599 do_it hs, t 600 subhs \dividend, \dividend, \divisor, lsr #3 601 orrhs \result, \result, \curbit, lsr #3 602 cmp \dividend, #0 @ Early termination? 603 do_it ne, t 604 movnes \curbit, \curbit, lsr #4 @ No, any more bits to do? 605 movne \divisor, \divisor, lsr #4 606 bne 1b 607 608#endif /* !defined (__ARM_FEATURE_CLZ) || defined (__OPTIMIZE_SIZE__) */ 609 610.endm 611/* ------------------------------------------------------------------------ */ 612.macro ARM_DIV2_ORDER divisor, order 613 614#if defined (__ARM_FEATURE_CLZ) 615 616 clz \order, \divisor 617 rsb \order, \order, #31 618 619#else 620 621 cmp \divisor, #(1 << 16) 622 movhs \divisor, \divisor, lsr #16 623 movhs \order, #16 624 movlo \order, #0 625 626 cmp \divisor, #(1 << 8) 627 movhs \divisor, \divisor, lsr #8 628 addhs \order, \order, #8 629 630 cmp \divisor, #(1 << 4) 631 movhs \divisor, \divisor, lsr #4 632 addhs \order, \order, #4 633 634 cmp \divisor, #(1 << 2) 635 addhi \order, \order, #3 636 addls \order, \order, \divisor, lsr #1 637 638#endif 639 640.endm 641/* ------------------------------------------------------------------------ */ 642.macro ARM_MOD_BODY dividend, divisor, order, spare 643 644#if defined(__ARM_FEATURE_CLZ) && ! defined (__OPTIMIZE_SIZE__) 645 646 clz \order, \divisor 647 clz \spare, \dividend 648 sub \order, \order, \spare 649 rsbs \order, \order, #31 650 addne pc, pc, \order, lsl #3 651 nop 652 .set shift, 32 653 .rept 32 654 .set shift, shift - 1 655 cmp \dividend, \divisor, lsl #shift 656 subcs \dividend, \dividend, \divisor, lsl #shift 657 .endr 658 659#else /* !defined (__ARM_FEATURE_CLZ) || defined (__OPTIMIZE_SIZE__) */ 660#if defined (__ARM_FEATURE_CLZ) 661 662 clz \order, \divisor 663 clz \spare, \dividend 664 sub \order, \order, \spare 665 mov \divisor, \divisor, lsl \order 666 667#else /* !defined (__ARM_FEATURE_CLZ) */ 668 669 mov \order, #0 670 671 @ Unless the divisor is very big, shift it up in multiples of 672 @ four bits, since this is the amount of unwinding in the main 673 @ division loop. Continue shifting until the divisor is 674 @ larger than the dividend. 6751: cmp \divisor, #0x10000000 676 cmplo \divisor, \dividend 677 movlo \divisor, \divisor, lsl #4 678 addlo \order, \order, #4 679 blo 1b 680 681 @ For very big divisors, we must shift it a bit at a time, or 682 @ we will be in danger of overflowing. 6831: cmp \divisor, #0x80000000 684 cmplo \divisor, \dividend 685 movlo \divisor, \divisor, lsl #1 686 addlo \order, \order, #1 687 blo 1b 688 689#endif /* !defined (__ARM_FEATURE_CLZ) */ 690 691 @ Perform all needed substractions to keep only the reminder. 692 @ Do comparisons in batch of 4 first. 693 subs \order, \order, #3 @ yes, 3 is intended here 694 blt 2f 695 6961: cmp \dividend, \divisor 697 subhs \dividend, \dividend, \divisor 698 cmp \dividend, \divisor, lsr #1 699 subhs \dividend, \dividend, \divisor, lsr #1 700 cmp \dividend, \divisor, lsr #2 701 subhs \dividend, \dividend, \divisor, lsr #2 702 cmp \dividend, \divisor, lsr #3 703 subhs \dividend, \dividend, \divisor, lsr #3 704 cmp \dividend, #1 705 mov \divisor, \divisor, lsr #4 706 subges \order, \order, #4 707 bge 1b 708 709 tst \order, #3 710 teqne \dividend, #0 711 beq 5f 712 713 @ Either 1, 2 or 3 comparison/substractions are left. 7142: cmn \order, #2 715 blt 4f 716 beq 3f 717 cmp \dividend, \divisor 718 subhs \dividend, \dividend, \divisor 719 mov \divisor, \divisor, lsr #1 7203: cmp \dividend, \divisor 721 subhs \dividend, \dividend, \divisor 722 mov \divisor, \divisor, lsr #1 7234: cmp \dividend, \divisor 724 subhs \dividend, \dividend, \divisor 7255: 726 727#endif /* !defined (__ARM_FEATURE_CLZ) || defined (__OPTIMIZE_SIZE__) */ 728 729.endm 730/* ------------------------------------------------------------------------ */ 731.macro THUMB_DIV_MOD_BODY modulo 732 @ Load the constant 0x10000000 into our work register. 733 movs work, #1 734 lsls work, #28 735LSYM(Loop1): 736 @ Unless the divisor is very big, shift it up in multiples of 737 @ four bits, since this is the amount of unwinding in the main 738 @ division loop. Continue shifting until the divisor is 739 @ larger than the dividend. 740 cmp divisor, work 741 bhs LSYM(Lbignum) 742 cmp divisor, dividend 743 bhs LSYM(Lbignum) 744 lsls divisor, #4 745 lsls curbit, #4 746 b LSYM(Loop1) 747LSYM(Lbignum): 748 @ Set work to 0x80000000 749 lsls work, #3 750LSYM(Loop2): 751 @ For very big divisors, we must shift it a bit at a time, or 752 @ we will be in danger of overflowing. 753 cmp divisor, work 754 bhs LSYM(Loop3) 755 cmp divisor, dividend 756 bhs LSYM(Loop3) 757 lsls divisor, #1 758 lsls curbit, #1 759 b LSYM(Loop2) 760LSYM(Loop3): 761 @ Test for possible subtractions ... 762 .if \modulo 763 @ ... On the final pass, this may subtract too much from the dividend, 764 @ so keep track of which subtractions are done, we can fix them up 765 @ afterwards. 766 movs overdone, #0 767 cmp dividend, divisor 768 blo LSYM(Lover1) 769 subs dividend, dividend, divisor 770LSYM(Lover1): 771 lsrs work, divisor, #1 772 cmp dividend, work 773 blo LSYM(Lover2) 774 subs dividend, dividend, work 775 mov ip, curbit 776 movs work, #1 777 rors curbit, work 778 orrs overdone, curbit 779 mov curbit, ip 780LSYM(Lover2): 781 lsrs work, divisor, #2 782 cmp dividend, work 783 blo LSYM(Lover3) 784 subs dividend, dividend, work 785 mov ip, curbit 786 movs work, #2 787 rors curbit, work 788 orrs overdone, curbit 789 mov curbit, ip 790LSYM(Lover3): 791 lsrs work, divisor, #3 792 cmp dividend, work 793 blo LSYM(Lover4) 794 subs dividend, dividend, work 795 mov ip, curbit 796 movs work, #3 797 rors curbit, work 798 orrs overdone, curbit 799 mov curbit, ip 800LSYM(Lover4): 801 mov ip, curbit 802 .else 803 @ ... and note which bits are done in the result. On the final pass, 804 @ this may subtract too much from the dividend, but the result will be ok, 805 @ since the "bit" will have been shifted out at the bottom. 806 cmp dividend, divisor 807 blo LSYM(Lover1) 808 subs dividend, dividend, divisor 809 orrs result, result, curbit 810LSYM(Lover1): 811 lsrs work, divisor, #1 812 cmp dividend, work 813 blo LSYM(Lover2) 814 subs dividend, dividend, work 815 lsrs work, curbit, #1 816 orrs result, work 817LSYM(Lover2): 818 lsrs work, divisor, #2 819 cmp dividend, work 820 blo LSYM(Lover3) 821 subs dividend, dividend, work 822 lsrs work, curbit, #2 823 orrs result, work 824LSYM(Lover3): 825 lsrs work, divisor, #3 826 cmp dividend, work 827 blo LSYM(Lover4) 828 subs dividend, dividend, work 829 lsrs work, curbit, #3 830 orrs result, work 831LSYM(Lover4): 832 .endif 833 834 cmp dividend, #0 @ Early termination? 835 beq LSYM(Lover5) 836 lsrs curbit, #4 @ No, any more bits to do? 837 beq LSYM(Lover5) 838 lsrs divisor, #4 839 b LSYM(Loop3) 840LSYM(Lover5): 841 .if \modulo 842 @ Any subtractions that we should not have done will be recorded in 843 @ the top three bits of "overdone". Exactly which were not needed 844 @ are governed by the position of the bit, stored in ip. 845 movs work, #0xe 846 lsls work, #28 847 ands overdone, work 848 beq LSYM(Lgot_result) 849 850 @ If we terminated early, because dividend became zero, then the 851 @ bit in ip will not be in the bottom nibble, and we should not 852 @ perform the additions below. We must test for this though 853 @ (rather relying upon the TSTs to prevent the additions) since 854 @ the bit in ip could be in the top two bits which might then match 855 @ with one of the smaller RORs. 856 mov curbit, ip 857 movs work, #0x7 858 tst curbit, work 859 beq LSYM(Lgot_result) 860 861 mov curbit, ip 862 movs work, #3 863 rors curbit, work 864 tst overdone, curbit 865 beq LSYM(Lover6) 866 lsrs work, divisor, #3 867 adds dividend, work 868LSYM(Lover6): 869 mov curbit, ip 870 movs work, #2 871 rors curbit, work 872 tst overdone, curbit 873 beq LSYM(Lover7) 874 lsrs work, divisor, #2 875 adds dividend, work 876LSYM(Lover7): 877 mov curbit, ip 878 movs work, #1 879 rors curbit, work 880 tst overdone, curbit 881 beq LSYM(Lgot_result) 882 lsrs work, divisor, #1 883 adds dividend, work 884 .endif 885LSYM(Lgot_result): 886.endm 887 888/* If performance is preferred, the following functions are provided. */ 889#if defined(__prefer_thumb__) && !defined(__OPTIMIZE_SIZE__) 890 891/* Branch to div(n), and jump to label if curbit is lo than divisior. */ 892.macro BranchToDiv n, label 893 lsrs curbit, dividend, \n 894 cmp curbit, divisor 895 blo \label 896.endm 897 898/* Body of div(n). Shift the divisor in n bits and compare the divisor 899 and dividend. Update the dividend as the substruction result. */ 900.macro DoDiv n 901 lsrs curbit, dividend, \n 902 cmp curbit, divisor 903 bcc 1f 904 lsls curbit, divisor, \n 905 subs dividend, dividend, curbit 906 9071: adcs result, result 908.endm 909 910/* The body of division with positive divisor. Unless the divisor is very 911 big, shift it up in multiples of four bits, since this is the amount of 912 unwinding in the main division loop. Continue shifting until the divisor 913 is larger than the dividend. */ 914.macro THUMB1_Div_Positive 915 movs result, #0 916 BranchToDiv #1, LSYM(Lthumb1_div1) 917 BranchToDiv #4, LSYM(Lthumb1_div4) 918 BranchToDiv #8, LSYM(Lthumb1_div8) 919 BranchToDiv #12, LSYM(Lthumb1_div12) 920 BranchToDiv #16, LSYM(Lthumb1_div16) 921LSYM(Lthumb1_div_large_positive): 922 movs result, #0xff 923 lsls divisor, divisor, #8 924 rev result, result 925 lsrs curbit, dividend, #16 926 cmp curbit, divisor 927 blo 1f 928 asrs result, #8 929 lsls divisor, divisor, #8 930 beq LSYM(Ldivbyzero_waypoint) 931 9321: lsrs curbit, dividend, #12 933 cmp curbit, divisor 934 blo LSYM(Lthumb1_div12) 935 b LSYM(Lthumb1_div16) 936LSYM(Lthumb1_div_loop): 937 lsrs divisor, divisor, #8 938LSYM(Lthumb1_div16): 939 Dodiv #15 940 Dodiv #14 941 Dodiv #13 942 Dodiv #12 943LSYM(Lthumb1_div12): 944 Dodiv #11 945 Dodiv #10 946 Dodiv #9 947 Dodiv #8 948 bcs LSYM(Lthumb1_div_loop) 949LSYM(Lthumb1_div8): 950 Dodiv #7 951 Dodiv #6 952 Dodiv #5 953LSYM(Lthumb1_div5): 954 Dodiv #4 955LSYM(Lthumb1_div4): 956 Dodiv #3 957LSYM(Lthumb1_div3): 958 Dodiv #2 959LSYM(Lthumb1_div2): 960 Dodiv #1 961LSYM(Lthumb1_div1): 962 subs divisor, dividend, divisor 963 bcs 1f 964 cpy divisor, dividend 965 9661: adcs result, result 967 cpy dividend, result 968 RET 969 970LSYM(Ldivbyzero_waypoint): 971 b LSYM(Ldiv0) 972.endm 973 974/* The body of division with negative divisor. Similar with 975 THUMB1_Div_Positive except that the shift steps are in multiples 976 of six bits. */ 977.macro THUMB1_Div_Negative 978 lsrs result, divisor, #31 979 beq 1f 980 negs divisor, divisor 981 9821: asrs curbit, dividend, #32 983 bcc 2f 984 negs dividend, dividend 985 9862: eors curbit, result 987 movs result, #0 988 cpy ip, curbit 989 BranchToDiv #4, LSYM(Lthumb1_div_negative4) 990 BranchToDiv #8, LSYM(Lthumb1_div_negative8) 991LSYM(Lthumb1_div_large): 992 movs result, #0xfc 993 lsls divisor, divisor, #6 994 rev result, result 995 lsrs curbit, dividend, #8 996 cmp curbit, divisor 997 blo LSYM(Lthumb1_div_negative8) 998 999 lsls divisor, divisor, #6 1000 asrs result, result, #6 1001 cmp curbit, divisor 1002 blo LSYM(Lthumb1_div_negative8) 1003 1004 lsls divisor, divisor, #6 1005 asrs result, result, #6 1006 cmp curbit, divisor 1007 blo LSYM(Lthumb1_div_negative8) 1008 1009 lsls divisor, divisor, #6 1010 beq LSYM(Ldivbyzero_negative) 1011 asrs result, result, #6 1012 b LSYM(Lthumb1_div_negative8) 1013LSYM(Lthumb1_div_negative_loop): 1014 lsrs divisor, divisor, #6 1015LSYM(Lthumb1_div_negative8): 1016 DoDiv #7 1017 DoDiv #6 1018 DoDiv #5 1019 DoDiv #4 1020LSYM(Lthumb1_div_negative4): 1021 DoDiv #3 1022 DoDiv #2 1023 bcs LSYM(Lthumb1_div_negative_loop) 1024 DoDiv #1 1025 subs divisor, dividend, divisor 1026 bcs 1f 1027 cpy divisor, dividend 1028 10291: cpy curbit, ip 1030 adcs result, result 1031 asrs curbit, curbit, #1 1032 cpy dividend, result 1033 bcc 2f 1034 negs dividend, dividend 1035 cmp curbit, #0 1036 10372: bpl 3f 1038 negs divisor, divisor 1039 10403: RET 1041 1042LSYM(Ldivbyzero_negative): 1043 cpy curbit, ip 1044 asrs curbit, curbit, #1 1045 bcc LSYM(Ldiv0) 1046 negs dividend, dividend 1047.endm 1048#endif /* ARM Thumb version. */ 1049 1050/* ------------------------------------------------------------------------ */ 1051/* Start of the Real Functions */ 1052/* ------------------------------------------------------------------------ */ 1053#ifdef L_udivsi3 1054 1055#if defined(__prefer_thumb__) 1056 1057 FUNC_START udivsi3 1058 FUNC_ALIAS aeabi_uidiv udivsi3 1059#if defined(__OPTIMIZE_SIZE__) 1060 1061 cmp divisor, #0 1062 beq LSYM(Ldiv0) 1063LSYM(udivsi3_skip_div0_test): 1064 movs curbit, #1 1065 movs result, #0 1066 1067 push { work } 1068 cmp dividend, divisor 1069 blo LSYM(Lgot_result) 1070 1071 THUMB_DIV_MOD_BODY 0 1072 1073 movs r0, result 1074 pop { work } 1075 RET 1076 1077/* Implementation of aeabi_uidiv for ARMv6m. This version is only 1078 used in ARMv6-M when we need an efficient implementation. */ 1079#else 1080LSYM(udivsi3_skip_div0_test): 1081 THUMB1_Div_Positive 1082 1083#endif /* __OPTIMIZE_SIZE__ */ 1084 1085#elif defined(__ARM_ARCH_EXT_IDIV__) 1086 1087 ARM_FUNC_START udivsi3 1088 ARM_FUNC_ALIAS aeabi_uidiv udivsi3 1089 1090 cmp r1, #0 1091 beq LSYM(Ldiv0) 1092 1093 udiv r0, r0, r1 1094 RET 1095 1096#else /* ARM version/Thumb-2. */ 1097 1098 ARM_FUNC_START udivsi3 1099 ARM_FUNC_ALIAS aeabi_uidiv udivsi3 1100 1101 /* Note: if called via udivsi3_skip_div0_test, this will unnecessarily 1102 check for division-by-zero a second time. */ 1103LSYM(udivsi3_skip_div0_test): 1104 subs r2, r1, #1 1105 do_it eq 1106 RETc(eq) 1107 bcc LSYM(Ldiv0) 1108 cmp r0, r1 1109 bls 11f 1110 tst r1, r2 1111 beq 12f 1112 1113 ARM_DIV_BODY r0, r1, r2, r3 1114 1115 mov r0, r2 1116 RET 1117 111811: do_it eq, e 1119 moveq r0, #1 1120 movne r0, #0 1121 RET 1122 112312: ARM_DIV2_ORDER r1, r2 1124 1125 mov r0, r0, lsr r2 1126 RET 1127 1128#endif /* ARM version */ 1129 1130 DIV_FUNC_END udivsi3 unsigned 1131 1132#if defined(__prefer_thumb__) 1133FUNC_START aeabi_uidivmod 1134 cmp r1, #0 1135 beq LSYM(Ldiv0) 1136# if defined(__OPTIMIZE_SIZE__) 1137 push {r0, r1, lr} 1138 bl LSYM(udivsi3_skip_div0_test) 1139 POP {r1, r2, r3} 1140 muls r2, r0 1141 subs r1, r1, r2 1142 bx r3 1143# else 1144 /* Both the quotient and remainder are calculated simultaneously 1145 in THUMB1_Div_Positive. There is no need to calculate the 1146 remainder again here. */ 1147 b LSYM(udivsi3_skip_div0_test) 1148 RET 1149# endif /* __OPTIMIZE_SIZE__ */ 1150 1151#elif defined(__ARM_ARCH_EXT_IDIV__) 1152ARM_FUNC_START aeabi_uidivmod 1153 cmp r1, #0 1154 beq LSYM(Ldiv0) 1155 mov r2, r0 1156 udiv r0, r0, r1 1157 mls r1, r0, r1, r2 1158 RET 1159#else 1160ARM_FUNC_START aeabi_uidivmod 1161 cmp r1, #0 1162 beq LSYM(Ldiv0) 1163 stmfd sp!, { r0, r1, lr } 1164 bl LSYM(udivsi3_skip_div0_test) 1165 ldmfd sp!, { r1, r2, lr } 1166 mul r3, r2, r0 1167 sub r1, r1, r3 1168 RET 1169#endif 1170 FUNC_END aeabi_uidivmod 1171 1172#endif /* L_udivsi3 */ 1173/* ------------------------------------------------------------------------ */ 1174#ifdef L_umodsi3 1175 1176#if defined(__ARM_ARCH_EXT_IDIV__) && __ARM_ARCH_ISA_THUMB != 1 1177 1178 ARM_FUNC_START umodsi3 1179 1180 cmp r1, #0 1181 beq LSYM(Ldiv0) 1182 udiv r2, r0, r1 1183 mls r0, r1, r2, r0 1184 RET 1185 1186#elif defined(__thumb__) 1187 1188 FUNC_START umodsi3 1189 1190 cmp divisor, #0 1191 beq LSYM(Ldiv0) 1192 movs curbit, #1 1193 cmp dividend, divisor 1194 bhs LSYM(Lover10) 1195 RET 1196 1197LSYM(Lover10): 1198 push { work } 1199 1200 THUMB_DIV_MOD_BODY 1 1201 1202 pop { work } 1203 RET 1204 1205#else /* ARM version. */ 1206 1207 FUNC_START umodsi3 1208 1209 subs r2, r1, #1 @ compare divisor with 1 1210 bcc LSYM(Ldiv0) 1211 cmpne r0, r1 @ compare dividend with divisor 1212 moveq r0, #0 1213 tsthi r1, r2 @ see if divisor is power of 2 1214 andeq r0, r0, r2 1215 RETc(ls) 1216 1217 ARM_MOD_BODY r0, r1, r2, r3 1218 1219 RET 1220 1221#endif /* ARM version. */ 1222 1223 DIV_FUNC_END umodsi3 unsigned 1224 1225#endif /* L_umodsi3 */ 1226/* ------------------------------------------------------------------------ */ 1227#ifdef L_divsi3 1228 1229#if defined(__prefer_thumb__) 1230 1231 FUNC_START divsi3 1232 FUNC_ALIAS aeabi_idiv divsi3 1233#if defined(__OPTIMIZE_SIZE__) 1234 1235 cmp divisor, #0 1236 beq LSYM(Ldiv0) 1237LSYM(divsi3_skip_div0_test): 1238 push { work } 1239 movs work, dividend 1240 eors work, divisor @ Save the sign of the result. 1241 mov ip, work 1242 movs curbit, #1 1243 movs result, #0 1244 cmp divisor, #0 1245 bpl LSYM(Lover10) 1246 negs divisor, divisor @ Loops below use unsigned. 1247LSYM(Lover10): 1248 cmp dividend, #0 1249 bpl LSYM(Lover11) 1250 negs dividend, dividend 1251LSYM(Lover11): 1252 cmp dividend, divisor 1253 blo LSYM(Lgot_result) 1254 1255 THUMB_DIV_MOD_BODY 0 1256 1257 movs r0, result 1258 mov work, ip 1259 cmp work, #0 1260 bpl LSYM(Lover12) 1261 negs r0, r0 1262LSYM(Lover12): 1263 pop { work } 1264 RET 1265 1266/* Implementation of aeabi_idiv for ARMv6m. This version is only 1267 used in ARMv6-M when we need an efficient implementation. */ 1268#else 1269LSYM(divsi3_skip_div0_test): 1270 cpy curbit, dividend 1271 orrs curbit, divisor 1272 bmi LSYM(Lthumb1_div_negative) 1273 1274LSYM(Lthumb1_div_positive): 1275 THUMB1_Div_Positive 1276 1277LSYM(Lthumb1_div_negative): 1278 THUMB1_Div_Negative 1279 1280#endif /* __OPTIMIZE_SIZE__ */ 1281 1282#elif defined(__ARM_ARCH_EXT_IDIV__) 1283 1284 ARM_FUNC_START divsi3 1285 ARM_FUNC_ALIAS aeabi_idiv divsi3 1286 1287 cmp r1, #0 1288 beq LSYM(Ldiv0) 1289 sdiv r0, r0, r1 1290 RET 1291 1292#else /* ARM/Thumb-2 version. */ 1293 1294 ARM_FUNC_START divsi3 1295 ARM_FUNC_ALIAS aeabi_idiv divsi3 1296 1297 cmp r1, #0 1298 beq LSYM(Ldiv0) 1299LSYM(divsi3_skip_div0_test): 1300 eor ip, r0, r1 @ save the sign of the result. 1301 do_it mi 1302 rsbmi r1, r1, #0 @ loops below use unsigned. 1303 subs r2, r1, #1 @ division by 1 or -1 ? 1304 beq 10f 1305 movs r3, r0 1306 do_it mi 1307 rsbmi r3, r0, #0 @ positive dividend value 1308 cmp r3, r1 1309 bls 11f 1310 tst r1, r2 @ divisor is power of 2 ? 1311 beq 12f 1312 1313 ARM_DIV_BODY r3, r1, r0, r2 1314 1315 cmp ip, #0 1316 do_it mi 1317 rsbmi r0, r0, #0 1318 RET 1319 132010: teq ip, r0 @ same sign ? 1321 do_it mi 1322 rsbmi r0, r0, #0 1323 RET 1324 132511: do_it lo 1326 movlo r0, #0 1327 do_it eq,t 1328 moveq r0, ip, asr #31 1329 orreq r0, r0, #1 1330 RET 1331 133212: ARM_DIV2_ORDER r1, r2 1333 1334 cmp ip, #0 1335 mov r0, r3, lsr r2 1336 do_it mi 1337 rsbmi r0, r0, #0 1338 RET 1339 1340#endif /* ARM version */ 1341 1342 DIV_FUNC_END divsi3 signed 1343 1344#if defined(__prefer_thumb__) 1345FUNC_START aeabi_idivmod 1346 cmp r1, #0 1347 beq LSYM(Ldiv0) 1348# if defined(__OPTIMIZE_SIZE__) 1349 push {r0, r1, lr} 1350 bl LSYM(divsi3_skip_div0_test) 1351 POP {r1, r2, r3} 1352 muls r2, r0 1353 subs r1, r1, r2 1354 bx r3 1355# else 1356 /* Both the quotient and remainder are calculated simultaneously 1357 in THUMB1_Div_Positive and THUMB1_Div_Negative. There is no 1358 need to calculate the remainder again here. */ 1359 b LSYM(divsi3_skip_div0_test) 1360 RET 1361# endif /* __OPTIMIZE_SIZE__ */ 1362 1363#elif defined(__ARM_ARCH_EXT_IDIV__) 1364ARM_FUNC_START aeabi_idivmod 1365 cmp r1, #0 1366 beq LSYM(Ldiv0) 1367 mov r2, r0 1368 sdiv r0, r0, r1 1369 mls r1, r0, r1, r2 1370 RET 1371#else 1372ARM_FUNC_START aeabi_idivmod 1373 cmp r1, #0 1374 beq LSYM(Ldiv0) 1375 stmfd sp!, { r0, r1, lr } 1376 bl LSYM(divsi3_skip_div0_test) 1377 ldmfd sp!, { r1, r2, lr } 1378 mul r3, r2, r0 1379 sub r1, r1, r3 1380 RET 1381#endif 1382 FUNC_END aeabi_idivmod 1383 1384#endif /* L_divsi3 */ 1385/* ------------------------------------------------------------------------ */ 1386#ifdef L_modsi3 1387 1388#if defined(__ARM_ARCH_EXT_IDIV__) && __ARM_ARCH_ISA_THUMB != 1 1389 1390 ARM_FUNC_START modsi3 1391 1392 cmp r1, #0 1393 beq LSYM(Ldiv0) 1394 1395 sdiv r2, r0, r1 1396 mls r0, r1, r2, r0 1397 RET 1398 1399#elif defined(__thumb__) 1400 1401 FUNC_START modsi3 1402 1403 movs curbit, #1 1404 cmp divisor, #0 1405 beq LSYM(Ldiv0) 1406 bpl LSYM(Lover10) 1407 negs divisor, divisor @ Loops below use unsigned. 1408LSYM(Lover10): 1409 push { work } 1410 @ Need to save the sign of the dividend, unfortunately, we need 1411 @ work later on. Must do this after saving the original value of 1412 @ the work register, because we will pop this value off first. 1413 push { dividend } 1414 cmp dividend, #0 1415 bpl LSYM(Lover11) 1416 negs dividend, dividend 1417LSYM(Lover11): 1418 cmp dividend, divisor 1419 blo LSYM(Lgot_result) 1420 1421 THUMB_DIV_MOD_BODY 1 1422 1423 pop { work } 1424 cmp work, #0 1425 bpl LSYM(Lover12) 1426 negs dividend, dividend 1427LSYM(Lover12): 1428 pop { work } 1429 RET 1430 1431#else /* ARM version. */ 1432 1433 FUNC_START modsi3 1434 1435 cmp r1, #0 1436 beq LSYM(Ldiv0) 1437 rsbmi r1, r1, #0 @ loops below use unsigned. 1438 movs ip, r0 @ preserve sign of dividend 1439 rsbmi r0, r0, #0 @ if negative make positive 1440 subs r2, r1, #1 @ compare divisor with 1 1441 cmpne r0, r1 @ compare dividend with divisor 1442 moveq r0, #0 1443 tsthi r1, r2 @ see if divisor is power of 2 1444 andeq r0, r0, r2 1445 bls 10f 1446 1447 ARM_MOD_BODY r0, r1, r2, r3 1448 144910: cmp ip, #0 1450 rsbmi r0, r0, #0 1451 RET 1452 1453#endif /* ARM version */ 1454 1455 DIV_FUNC_END modsi3 signed 1456 1457#endif /* L_modsi3 */ 1458/* ------------------------------------------------------------------------ */ 1459#ifdef L_dvmd_tls 1460 1461#ifdef __ARM_EABI__ 1462 WEAK aeabi_idiv0 1463 WEAK aeabi_ldiv0 1464 FUNC_START aeabi_idiv0 1465 FUNC_START aeabi_ldiv0 1466 RET 1467 FUNC_END aeabi_ldiv0 1468 FUNC_END aeabi_idiv0 1469#else 1470 FUNC_START div0 1471 RET 1472 FUNC_END div0 1473#endif 1474 1475#endif /* L_divmodsi_tools */ 1476/* ------------------------------------------------------------------------ */ 1477#ifdef L_dvmd_lnx 1478@ GNU/Linux division-by zero handler. Used in place of L_dvmd_tls 1479 1480/* Constant taken from <asm/signal.h>. */ 1481#define SIGFPE 8 1482 1483#ifdef __ARM_EABI__ 1484 cfi_start __aeabi_ldiv0, LSYM(Lend_aeabi_ldiv0) 1485 WEAK aeabi_idiv0 1486 WEAK aeabi_ldiv0 1487 ARM_FUNC_START aeabi_idiv0 1488 ARM_FUNC_START aeabi_ldiv0 1489 do_push {r1, lr} 149098: cfi_push 98b - __aeabi_ldiv0, 0xe, -0x4, 0x8 1491#else 1492 cfi_start __div0, LSYM(Lend_div0) 1493 ARM_FUNC_START div0 1494 do_push {r1, lr} 149598: cfi_push 98b - __div0, 0xe, -0x4, 0x8 1496#endif 1497 1498 mov r0, #SIGFPE 1499 bl SYM(raise) __PLT__ 1500 RETLDM r1 unwind=98b 1501 1502#ifdef __ARM_EABI__ 1503 cfi_end LSYM(Lend_aeabi_ldiv0) 1504 FUNC_END aeabi_ldiv0 1505 FUNC_END aeabi_idiv0 1506#else 1507 cfi_end LSYM(Lend_div0) 1508 FUNC_END div0 1509#endif 1510 1511#endif /* L_dvmd_lnx */ 1512#ifdef L_clear_cache 1513#if defined __ARM_EABI__ && defined __linux__ 1514@ EABI GNU/Linux call to cacheflush syscall. 1515 ARM_FUNC_START clear_cache 1516 do_push {r7} 1517#if __ARM_ARCH >= 7 || defined(__ARM_ARCH_6T2__) 1518 movw r7, #2 1519 movt r7, #0xf 1520#else 1521 mov r7, #0xf0000 1522 add r7, r7, #2 1523#endif 1524 mov r2, #0 1525 swi 0 1526 do_pop {r7} 1527 RET 1528 FUNC_END clear_cache 1529#else 1530#error "This is only for ARM EABI GNU/Linux" 1531#endif 1532#endif /* L_clear_cache */ 1533 1534#ifdef L_speculation_barrier 1535 FUNC_START speculation_barrier 1536#if __ARM_ARCH >= 7 1537 isb 1538 dsb sy 1539#elif defined __ARM_EABI__ && defined __linux__ 1540 /* We don't have a speculation barrier directly for this 1541 platform/architecture variant. But we can use a kernel 1542 clear_cache service routine which will emit such instructions 1543 if run on a later version of the architecture. We don't 1544 really want to flush the cache, but we must give it a valid 1545 address, so just clear pc..pc+1. */ 1546#if defined __thumb__ && !defined __thumb2__ 1547 push {r7} 1548 movs r7, #0xf 1549 lsls r7, #16 1550 adds r7, #2 1551 adr r0, . + 4 1552 adds r1, r0, #1 1553 movs r2, #0 1554 svc 0 1555 pop {r7} 1556#else 1557 do_push {r7} 1558#ifdef __ARM_ARCH_6T2__ 1559 movw r7, #2 1560 movt r7, #0xf 1561#else 1562 mov r7, #0xf0000 1563 add r7, r7, #2 1564#endif 1565 add r0, pc, #0 /* ADR. */ 1566 add r1, r0, #1 1567 mov r2, #0 1568 svc 0 1569 do_pop {r7} 1570#endif /* Thumb1 only */ 1571#else 1572#warning "No speculation barrier defined for this platform" 1573#endif 1574 RET 1575 FUNC_END speculation_barrier 1576#endif 1577/* ------------------------------------------------------------------------ */ 1578/* Dword shift operations. */ 1579/* All the following Dword shift variants rely on the fact that 1580 shft xxx, Reg 1581 is in fact done as 1582 shft xxx, (Reg & 255) 1583 so for Reg value in (32...63) and (-1...-31) we will get zero (in the 1584 case of logical shifts) or the sign (for asr). */ 1585 1586#ifdef __ARMEB__ 1587#define al r1 1588#define ah r0 1589#else 1590#define al r0 1591#define ah r1 1592#endif 1593 1594/* Prevent __aeabi double-word shifts from being produced on SymbianOS. */ 1595#ifndef __symbian__ 1596 1597#ifdef L_lshrdi3 1598 1599 FUNC_START lshrdi3 1600 FUNC_ALIAS aeabi_llsr lshrdi3 1601 1602#ifdef __thumb__ 1603 lsrs al, r2 1604 movs r3, ah 1605 lsrs ah, r2 1606 mov ip, r3 1607 subs r2, #32 1608 lsrs r3, r2 1609 orrs al, r3 1610 negs r2, r2 1611 mov r3, ip 1612 lsls r3, r2 1613 orrs al, r3 1614 RET 1615#else 1616 subs r3, r2, #32 1617 rsb ip, r2, #32 1618 movmi al, al, lsr r2 1619 movpl al, ah, lsr r3 1620 orrmi al, al, ah, lsl ip 1621 mov ah, ah, lsr r2 1622 RET 1623#endif 1624 FUNC_END aeabi_llsr 1625 FUNC_END lshrdi3 1626 1627#endif 1628 1629#ifdef L_ashrdi3 1630 1631 FUNC_START ashrdi3 1632 FUNC_ALIAS aeabi_lasr ashrdi3 1633 1634#ifdef __thumb__ 1635 lsrs al, r2 1636 movs r3, ah 1637 asrs ah, r2 1638 subs r2, #32 1639 @ If r2 is negative at this point the following step would OR 1640 @ the sign bit into all of AL. That's not what we want... 1641 bmi 1f 1642 mov ip, r3 1643 asrs r3, r2 1644 orrs al, r3 1645 mov r3, ip 16461: 1647 negs r2, r2 1648 lsls r3, r2 1649 orrs al, r3 1650 RET 1651#else 1652 subs r3, r2, #32 1653 rsb ip, r2, #32 1654 movmi al, al, lsr r2 1655 movpl al, ah, asr r3 1656 orrmi al, al, ah, lsl ip 1657 mov ah, ah, asr r2 1658 RET 1659#endif 1660 1661 FUNC_END aeabi_lasr 1662 FUNC_END ashrdi3 1663 1664#endif 1665 1666#ifdef L_ashldi3 1667 1668 FUNC_START ashldi3 1669 FUNC_ALIAS aeabi_llsl ashldi3 1670 1671#ifdef __thumb__ 1672 lsls ah, r2 1673 movs r3, al 1674 lsls al, r2 1675 mov ip, r3 1676 subs r2, #32 1677 lsls r3, r2 1678 orrs ah, r3 1679 negs r2, r2 1680 mov r3, ip 1681 lsrs r3, r2 1682 orrs ah, r3 1683 RET 1684#else 1685 subs r3, r2, #32 1686 rsb ip, r2, #32 1687 movmi ah, ah, lsl r2 1688 movpl ah, al, lsl r3 1689 orrmi ah, ah, al, lsr ip 1690 mov al, al, lsl r2 1691 RET 1692#endif 1693 FUNC_END aeabi_llsl 1694 FUNC_END ashldi3 1695 1696#endif 1697 1698#endif /* __symbian__ */ 1699 1700#ifdef L_clzsi2 1701#ifdef NOT_ISA_TARGET_32BIT 1702FUNC_START clzsi2 1703 movs r1, #28 1704 movs r3, #1 1705 lsls r3, r3, #16 1706 cmp r0, r3 /* 0x10000 */ 1707 bcc 2f 1708 lsrs r0, r0, #16 1709 subs r1, r1, #16 17102: lsrs r3, r3, #8 1711 cmp r0, r3 /* #0x100 */ 1712 bcc 2f 1713 lsrs r0, r0, #8 1714 subs r1, r1, #8 17152: lsrs r3, r3, #4 1716 cmp r0, r3 /* #0x10 */ 1717 bcc 2f 1718 lsrs r0, r0, #4 1719 subs r1, r1, #4 17202: adr r2, 1f 1721 ldrb r0, [r2, r0] 1722 adds r0, r0, r1 1723 bx lr 1724.align 2 17251: 1726.byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 1727 FUNC_END clzsi2 1728#else 1729ARM_FUNC_START clzsi2 1730# if defined (__ARM_FEATURE_CLZ) 1731 clz r0, r0 1732 RET 1733# else 1734 mov r1, #28 1735 cmp r0, #0x10000 1736 do_it cs, t 1737 movcs r0, r0, lsr #16 1738 subcs r1, r1, #16 1739 cmp r0, #0x100 1740 do_it cs, t 1741 movcs r0, r0, lsr #8 1742 subcs r1, r1, #8 1743 cmp r0, #0x10 1744 do_it cs, t 1745 movcs r0, r0, lsr #4 1746 subcs r1, r1, #4 1747 adr r2, 1f 1748 ldrb r0, [r2, r0] 1749 add r0, r0, r1 1750 RET 1751.align 2 17521: 1753.byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 1754# endif /* !defined (__ARM_FEATURE_CLZ) */ 1755 FUNC_END clzsi2 1756#endif 1757#endif /* L_clzsi2 */ 1758 1759#ifdef L_clzdi2 1760#if !defined (__ARM_FEATURE_CLZ) 1761 1762# ifdef NOT_ISA_TARGET_32BIT 1763FUNC_START clzdi2 1764 push {r4, lr} 1765 cmp xxh, #0 1766 bne 1f 1767# ifdef __ARMEB__ 1768 movs r0, xxl 1769 bl __clzsi2 1770 adds r0, r0, #32 1771 b 2f 17721: 1773 bl __clzsi2 1774# else 1775 bl __clzsi2 1776 adds r0, r0, #32 1777 b 2f 17781: 1779 movs r0, xxh 1780 bl __clzsi2 1781# endif 17822: 1783 pop {r4, pc} 1784# else /* NOT_ISA_TARGET_32BIT */ 1785ARM_FUNC_START clzdi2 1786 do_push {r4, lr} 1787 cmp xxh, #0 1788 bne 1f 1789# ifdef __ARMEB__ 1790 mov r0, xxl 1791 bl __clzsi2 1792 add r0, r0, #32 1793 b 2f 17941: 1795 bl __clzsi2 1796# else 1797 bl __clzsi2 1798 add r0, r0, #32 1799 b 2f 18001: 1801 mov r0, xxh 1802 bl __clzsi2 1803# endif 18042: 1805 RETLDM r4 1806 FUNC_END clzdi2 1807# endif /* NOT_ISA_TARGET_32BIT */ 1808 1809#else /* defined (__ARM_FEATURE_CLZ) */ 1810 1811ARM_FUNC_START clzdi2 1812 cmp xxh, #0 1813 do_it eq, et 1814 clzeq r0, xxl 1815 clzne r0, xxh 1816 addeq r0, r0, #32 1817 RET 1818 FUNC_END clzdi2 1819 1820#endif 1821#endif /* L_clzdi2 */ 1822 1823#ifdef L_ctzsi2 1824#ifdef NOT_ISA_TARGET_32BIT 1825FUNC_START ctzsi2 1826 negs r1, r0 1827 ands r0, r0, r1 1828 movs r1, #28 1829 movs r3, #1 1830 lsls r3, r3, #16 1831 cmp r0, r3 /* 0x10000 */ 1832 bcc 2f 1833 lsrs r0, r0, #16 1834 subs r1, r1, #16 18352: lsrs r3, r3, #8 1836 cmp r0, r3 /* #0x100 */ 1837 bcc 2f 1838 lsrs r0, r0, #8 1839 subs r1, r1, #8 18402: lsrs r3, r3, #4 1841 cmp r0, r3 /* #0x10 */ 1842 bcc 2f 1843 lsrs r0, r0, #4 1844 subs r1, r1, #4 18452: adr r2, 1f 1846 ldrb r0, [r2, r0] 1847 subs r0, r0, r1 1848 bx lr 1849.align 2 18501: 1851.byte 27, 28, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31 1852 FUNC_END ctzsi2 1853#else 1854ARM_FUNC_START ctzsi2 1855 rsb r1, r0, #0 1856 and r0, r0, r1 1857# if defined (__ARM_FEATURE_CLZ) 1858 clz r0, r0 1859 rsb r0, r0, #31 1860 RET 1861# else 1862 mov r1, #28 1863 cmp r0, #0x10000 1864 do_it cs, t 1865 movcs r0, r0, lsr #16 1866 subcs r1, r1, #16 1867 cmp r0, #0x100 1868 do_it cs, t 1869 movcs r0, r0, lsr #8 1870 subcs r1, r1, #8 1871 cmp r0, #0x10 1872 do_it cs, t 1873 movcs r0, r0, lsr #4 1874 subcs r1, r1, #4 1875 adr r2, 1f 1876 ldrb r0, [r2, r0] 1877 sub r0, r0, r1 1878 RET 1879.align 2 18801: 1881.byte 27, 28, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31 1882# endif /* !defined (__ARM_FEATURE_CLZ) */ 1883 FUNC_END ctzsi2 1884#endif 1885#endif /* L_clzsi2 */ 1886 1887/* ------------------------------------------------------------------------ */ 1888/* These next two sections are here despite the fact that they contain Thumb 1889 assembler because their presence allows interworked code to be linked even 1890 when the GCC library is this one. */ 1891 1892/* Do not build the interworking functions when the target architecture does 1893 not support Thumb instructions. (This can be a multilib option). */ 1894#if defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__\ 1895 || defined __ARM_ARCH_5TE__ || defined __ARM_ARCH_5TEJ__ \ 1896 || __ARM_ARCH >= 6 1897 1898#if defined L_call_via_rX 1899 1900/* These labels & instructions are used by the Arm/Thumb interworking code. 1901 The address of function to be called is loaded into a register and then 1902 one of these labels is called via a BL instruction. This puts the 1903 return address into the link register with the bottom bit set, and the 1904 code here switches to the correct mode before executing the function. */ 1905 1906 .text 1907 .align 0 1908 .force_thumb 1909 1910.macro call_via register 1911 THUMB_FUNC_START _call_via_\register 1912 1913 bx \register 1914 nop 1915 1916 SIZE (_call_via_\register) 1917.endm 1918 1919 call_via r0 1920 call_via r1 1921 call_via r2 1922 call_via r3 1923 call_via r4 1924 call_via r5 1925 call_via r6 1926 call_via r7 1927 call_via r8 1928 call_via r9 1929 call_via sl 1930 call_via fp 1931 call_via ip 1932 call_via sp 1933 call_via lr 1934 1935#endif /* L_call_via_rX */ 1936 1937/* Don't bother with the old interworking routines for Thumb-2. */ 1938/* ??? Maybe only omit these on "m" variants. */ 1939#if !defined(__thumb2__) && __ARM_ARCH_ISA_ARM 1940 1941#if defined L_interwork_call_via_rX 1942 1943/* These labels & instructions are used by the Arm/Thumb interworking code, 1944 when the target address is in an unknown instruction set. The address 1945 of function to be called is loaded into a register and then one of these 1946 labels is called via a BL instruction. This puts the return address 1947 into the link register with the bottom bit set, and the code here 1948 switches to the correct mode before executing the function. Unfortunately 1949 the target code cannot be relied upon to return via a BX instruction, so 1950 instead we have to store the resturn address on the stack and allow the 1951 called function to return here instead. Upon return we recover the real 1952 return address and use a BX to get back to Thumb mode. 1953 1954 There are three variations of this code. The first, 1955 _interwork_call_via_rN(), will push the return address onto the 1956 stack and pop it in _arm_return(). It should only be used if all 1957 arguments are passed in registers. 1958 1959 The second, _interwork_r7_call_via_rN(), instead stores the return 1960 address at [r7, #-4]. It is the caller's responsibility to ensure 1961 that this address is valid and contains no useful data. 1962 1963 The third, _interwork_r11_call_via_rN(), works in the same way but 1964 uses r11 instead of r7. It is useful if the caller does not really 1965 need a frame pointer. */ 1966 1967 .text 1968 .align 0 1969 1970 .code 32 1971 .globl _arm_return 1972LSYM(Lstart_arm_return): 1973 cfi_start LSYM(Lstart_arm_return) LSYM(Lend_arm_return) 1974 cfi_push 0, 0xe, -0x8, 0x8 1975 nop @ This nop is for the benefit of debuggers, so that 1976 @ backtraces will use the correct unwind information. 1977_arm_return: 1978 RETLDM unwind=LSYM(Lstart_arm_return) 1979 cfi_end LSYM(Lend_arm_return) 1980 1981 .globl _arm_return_r7 1982_arm_return_r7: 1983 ldr lr, [r7, #-4] 1984 bx lr 1985 1986 .globl _arm_return_r11 1987_arm_return_r11: 1988 ldr lr, [r11, #-4] 1989 bx lr 1990 1991.macro interwork_with_frame frame, register, name, return 1992 .code 16 1993 1994 THUMB_FUNC_START \name 1995 1996 bx pc 1997 nop 1998 1999 .code 32 2000 tst \register, #1 2001 streq lr, [\frame, #-4] 2002 adreq lr, _arm_return_\frame 2003 bx \register 2004 2005 SIZE (\name) 2006.endm 2007 2008.macro interwork register 2009 .code 16 2010 2011 THUMB_FUNC_START _interwork_call_via_\register 2012 2013 bx pc 2014 nop 2015 2016 .code 32 2017 .globl LSYM(Lchange_\register) 2018LSYM(Lchange_\register): 2019 tst \register, #1 2020 streq lr, [sp, #-8]! 2021 adreq lr, _arm_return 2022 bx \register 2023 2024 SIZE (_interwork_call_via_\register) 2025 2026 interwork_with_frame r7,\register,_interwork_r7_call_via_\register 2027 interwork_with_frame r11,\register,_interwork_r11_call_via_\register 2028.endm 2029 2030 interwork r0 2031 interwork r1 2032 interwork r2 2033 interwork r3 2034 interwork r4 2035 interwork r5 2036 interwork r6 2037 interwork r7 2038 interwork r8 2039 interwork r9 2040 interwork sl 2041 interwork fp 2042 interwork ip 2043 interwork sp 2044 2045 /* The LR case has to be handled a little differently... */ 2046 .code 16 2047 2048 THUMB_FUNC_START _interwork_call_via_lr 2049 2050 bx pc 2051 nop 2052 2053 .code 32 2054 .globl .Lchange_lr 2055.Lchange_lr: 2056 tst lr, #1 2057 stmeqdb r13!, {lr, pc} 2058 mov ip, lr 2059 adreq lr, _arm_return 2060 bx ip 2061 2062 SIZE (_interwork_call_via_lr) 2063 2064#endif /* L_interwork_call_via_rX */ 2065#endif /* !__thumb2__ */ 2066 2067/* Functions to support compact pic switch tables in thumb1 state. 2068 All these routines take an index into the table in r0. The 2069 table is at LR & ~1 (but this must be rounded up in the case 2070 of 32-bit entires). They are only permitted to clobber r12 2071 and r14 and r0 must be preserved on exit. */ 2072#ifdef L_thumb1_case_sqi 2073 2074 .text 2075 .align 0 2076 .force_thumb 2077 .syntax unified 2078 THUMB_FUNC_START __gnu_thumb1_case_sqi 2079 push {r1} 2080 mov r1, lr 2081 lsrs r1, r1, #1 2082 lsls r1, r1, #1 2083 ldrsb r1, [r1, r0] 2084 lsls r1, r1, #1 2085 add lr, lr, r1 2086 pop {r1} 2087 bx lr 2088 SIZE (__gnu_thumb1_case_sqi) 2089#endif 2090 2091#ifdef L_thumb1_case_uqi 2092 2093 .text 2094 .align 0 2095 .force_thumb 2096 .syntax unified 2097 THUMB_FUNC_START __gnu_thumb1_case_uqi 2098 push {r1} 2099 mov r1, lr 2100 lsrs r1, r1, #1 2101 lsls r1, r1, #1 2102 ldrb r1, [r1, r0] 2103 lsls r1, r1, #1 2104 add lr, lr, r1 2105 pop {r1} 2106 bx lr 2107 SIZE (__gnu_thumb1_case_uqi) 2108#endif 2109 2110#ifdef L_thumb1_case_shi 2111 2112 .text 2113 .align 0 2114 .force_thumb 2115 .syntax unified 2116 THUMB_FUNC_START __gnu_thumb1_case_shi 2117 push {r0, r1} 2118 mov r1, lr 2119 lsrs r1, r1, #1 2120 lsls r0, r0, #1 2121 lsls r1, r1, #1 2122 ldrsh r1, [r1, r0] 2123 lsls r1, r1, #1 2124 add lr, lr, r1 2125 pop {r0, r1} 2126 bx lr 2127 SIZE (__gnu_thumb1_case_shi) 2128#endif 2129 2130#ifdef L_thumb1_case_uhi 2131 2132 .text 2133 .align 0 2134 .force_thumb 2135 .syntax unified 2136 THUMB_FUNC_START __gnu_thumb1_case_uhi 2137 push {r0, r1} 2138 mov r1, lr 2139 lsrs r1, r1, #1 2140 lsls r0, r0, #1 2141 lsls r1, r1, #1 2142 ldrh r1, [r1, r0] 2143 lsls r1, r1, #1 2144 add lr, lr, r1 2145 pop {r0, r1} 2146 bx lr 2147 SIZE (__gnu_thumb1_case_uhi) 2148#endif 2149 2150#ifdef L_thumb1_case_si 2151 2152 .text 2153 .align 0 2154 .force_thumb 2155 .syntax unified 2156 THUMB_FUNC_START __gnu_thumb1_case_si 2157 push {r0, r1} 2158 mov r1, lr 2159 adds.n r1, r1, #2 /* Align to word. */ 2160 lsrs r1, r1, #2 2161 lsls r0, r0, #2 2162 lsls r1, r1, #2 2163 ldr r0, [r1, r0] 2164 adds r0, r0, r1 2165 mov lr, r0 2166 pop {r0, r1} 2167 mov pc, lr /* We know we were called from thumb code. */ 2168 SIZE (__gnu_thumb1_case_si) 2169#endif 2170 2171#endif /* Arch supports thumb. */ 2172 2173.macro CFI_START_FUNCTION 2174 .cfi_startproc 2175 .cfi_remember_state 2176.endm 2177 2178.macro CFI_END_FUNCTION 2179 .cfi_restore_state 2180 .cfi_endproc 2181.endm 2182 2183#ifndef __symbian__ 2184/* The condition here must match the one in gcc/config/arm/elf.h and 2185 libgcc/config/arm/t-elf. */ 2186#ifndef NOT_ISA_TARGET_32BIT 2187#include "ieee754-df.S" 2188#include "ieee754-sf.S" 2189#include "bpabi.S" 2190#else /* NOT_ISA_TARGET_32BIT */ 2191#include "bpabi-v6m.S" 2192#endif /* NOT_ISA_TARGET_32BIT */ 2193#endif /* !__symbian__ */ 2194