110d565efSmrg@ libgcc routines for ARM cpu.
210d565efSmrg@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
310d565efSmrg
4*ec02198aSmrg/* Copyright (C) 1995-2020 Free Software Foundation, Inc.
510d565efSmrg
610d565efSmrgThis file is free software; you can redistribute it and/or modify it
710d565efSmrgunder the terms of the GNU General Public License as published by the
810d565efSmrgFree Software Foundation; either version 3, or (at your option) any
910d565efSmrglater version.
1010d565efSmrg
1110d565efSmrgThis file is distributed in the hope that it will be useful, but
1210d565efSmrgWITHOUT ANY WARRANTY; without even the implied warranty of
1310d565efSmrgMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1410d565efSmrgGeneral Public License for more details.
1510d565efSmrg
1610d565efSmrgUnder Section 7 of GPL version 3, you are granted additional
1710d565efSmrgpermissions described in the GCC Runtime Library Exception, version
1810d565efSmrg3.1, as published by the Free Software Foundation.
1910d565efSmrg
2010d565efSmrgYou should have received a copy of the GNU General Public License and
2110d565efSmrga copy of the GCC Runtime Library Exception along with this program;
2210d565efSmrgsee the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2310d565efSmrg<http://www.gnu.org/licenses/>.  */
2410d565efSmrg
25*ec02198aSmrg/* Everything in this file should now use unified syntax.  */
26*ec02198aSmrg
27*ec02198aSmrg	.syntax unified
28*ec02198aSmrg
2910d565efSmrg/* An executable stack is *not* required for these functions.  */
3010d565efSmrg#if defined(__ELF__) && defined(__linux__)
3110d565efSmrg.section .note.GNU-stack,"",%progbits
3210d565efSmrg.previous
3310d565efSmrg#endif  /* __ELF__ and __linux__ */
3410d565efSmrg
3510d565efSmrg#ifdef __ARM_EABI__
3610d565efSmrg/* Some attributes that are common to all routines in this file.  */
3710d565efSmrg	/* Tag_ABI_align_needed: This code does not require 8-byte
3810d565efSmrg	   alignment from the caller.  */
3910d565efSmrg	/* .eabi_attribute 24, 0  -- default setting.  */
4010d565efSmrg	/* Tag_ABI_align_preserved: This code preserves 8-byte
4110d565efSmrg	   alignment in any callee.  */
4210d565efSmrg	.eabi_attribute 25, 1
4310d565efSmrg#endif /* __ARM_EABI__ */
4410d565efSmrg/* ------------------------------------------------------------------------ */
4510d565efSmrg
4610d565efSmrg/* We need to know what prefix to add to function names.  */
4710d565efSmrg
4810d565efSmrg#ifndef __USER_LABEL_PREFIX__
4910d565efSmrg#error  __USER_LABEL_PREFIX__ not defined
5010d565efSmrg#endif
5110d565efSmrg
5210d565efSmrg/* ANSI concatenation macros.  */
5310d565efSmrg
5410d565efSmrg#define CONCAT1(a, b) CONCAT2(a, b)
5510d565efSmrg#define CONCAT2(a, b) a ## b
5610d565efSmrg
5710d565efSmrg/* Use the right prefix for global labels.  */
5810d565efSmrg
5910d565efSmrg#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
6010d565efSmrg
6110d565efSmrg#ifdef __ELF__
6210d565efSmrg#ifdef __thumb__
6310d565efSmrg#define __PLT__  /* Not supported in Thumb assembler (for now).  */
6410d565efSmrg#elif defined __vxworks && !defined __PIC__
6510d565efSmrg#define __PLT__ /* Not supported by the kernel loader.  */
6610d565efSmrg#else
6710d565efSmrg#define __PLT__ (PLT)
6810d565efSmrg#endif
6910d565efSmrg#define TYPE(x) .type SYM(x),function
7010d565efSmrg#define SIZE(x) .size SYM(x), . - SYM(x)
7110d565efSmrg#define LSYM(x) .x
7210d565efSmrg#else
7310d565efSmrg#define __PLT__
7410d565efSmrg#define TYPE(x)
7510d565efSmrg#define SIZE(x)
7610d565efSmrg#define LSYM(x) x
7710d565efSmrg#endif
7810d565efSmrg
7910d565efSmrg/* Function end macros.  Variants for interworking.  */
8010d565efSmrg
8110d565efSmrg/* There are times when we might prefer Thumb1 code even if ARM code is
8210d565efSmrg   permitted, for example, the code might be smaller, or there might be
8310d565efSmrg   interworking problems with switching to ARM state if interworking is
8410d565efSmrg   disabled.  */
8510d565efSmrg#if (defined(__thumb__)			\
8610d565efSmrg     && !defined(__thumb2__)		\
8710d565efSmrg     && (!defined(__THUMB_INTERWORK__)	\
8810d565efSmrg	 || defined (__OPTIMIZE_SIZE__)	\
8910d565efSmrg	 || !__ARM_ARCH_ISA_ARM))
9010d565efSmrg# define __prefer_thumb__
9110d565efSmrg#endif
9210d565efSmrg
9310d565efSmrg#if !__ARM_ARCH_ISA_ARM && __ARM_ARCH_ISA_THUMB == 1
9410d565efSmrg#define NOT_ISA_TARGET_32BIT 1
9510d565efSmrg#endif
9610d565efSmrg
9710d565efSmrg/* How to return from a function call depends on the architecture variant.  */
9810d565efSmrg
990fc04c29Smrg#if (__ARM_ARCH > 4) || defined(__ARM_ARCH_4T__)
10010d565efSmrg
10110d565efSmrg# define RET		bx	lr
10210d565efSmrg# define RETc(x)	bx##x	lr
10310d565efSmrg
10410d565efSmrg/* Special precautions for interworking on armv4t.  */
1050fc04c29Smrg# if (__ARM_ARCH == 4)
10610d565efSmrg
10710d565efSmrg/* Always use bx, not ldr pc.  */
10810d565efSmrg#  if (defined(__thumb__) || defined(__THUMB_INTERWORK__))
10910d565efSmrg#    define __INTERWORKING__
11010d565efSmrg#   endif /* __THUMB__ || __THUMB_INTERWORK__ */
11110d565efSmrg
11210d565efSmrg/* Include thumb stub before arm mode code.  */
11310d565efSmrg#  if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
11410d565efSmrg#   define __INTERWORKING_STUBS__
11510d565efSmrg#  endif /* __thumb__ && !__THUMB_INTERWORK__ */
11610d565efSmrg
11710d565efSmrg#endif /* __ARM_ARCH == 4 */
11810d565efSmrg
11910d565efSmrg#else
12010d565efSmrg
12110d565efSmrg# define RET		mov	pc, lr
12210d565efSmrg# define RETc(x)	mov##x	pc, lr
12310d565efSmrg
12410d565efSmrg#endif
12510d565efSmrg
12610d565efSmrg.macro	cfi_pop		advance, reg, cfa_offset
12710d565efSmrg#ifdef __ELF__
12810d565efSmrg	.pushsection	.debug_frame
12910d565efSmrg	.byte	0x4		/* DW_CFA_advance_loc4 */
13010d565efSmrg	.4byte	\advance
13110d565efSmrg	.byte	(0xc0 | \reg)	/* DW_CFA_restore */
13210d565efSmrg	.byte	0xe		/* DW_CFA_def_cfa_offset */
13310d565efSmrg	.uleb128 \cfa_offset
13410d565efSmrg	.popsection
13510d565efSmrg#endif
13610d565efSmrg.endm
13710d565efSmrg.macro	cfi_push	advance, reg, offset, cfa_offset
13810d565efSmrg#ifdef __ELF__
13910d565efSmrg	.pushsection	.debug_frame
14010d565efSmrg	.byte	0x4		/* DW_CFA_advance_loc4 */
14110d565efSmrg	.4byte	\advance
14210d565efSmrg	.byte	(0x80 | \reg)	/* DW_CFA_offset */
14310d565efSmrg	.uleb128 (\offset / -4)
14410d565efSmrg	.byte	0xe		/* DW_CFA_def_cfa_offset */
14510d565efSmrg	.uleb128 \cfa_offset
14610d565efSmrg	.popsection
14710d565efSmrg#endif
14810d565efSmrg.endm
14910d565efSmrg.macro cfi_start	start_label, end_label
15010d565efSmrg#ifdef __ELF__
15110d565efSmrg	.pushsection	.debug_frame
15210d565efSmrgLSYM(Lstart_frame):
15310d565efSmrg	.4byte	LSYM(Lend_cie) - LSYM(Lstart_cie) @ Length of CIE
15410d565efSmrgLSYM(Lstart_cie):
15510d565efSmrg        .4byte	0xffffffff	@ CIE Identifier Tag
15610d565efSmrg        .byte	0x1	@ CIE Version
15710d565efSmrg        .ascii	"\0"	@ CIE Augmentation
15810d565efSmrg        .uleb128 0x1	@ CIE Code Alignment Factor
15910d565efSmrg        .sleb128 -4	@ CIE Data Alignment Factor
16010d565efSmrg        .byte	0xe	@ CIE RA Column
16110d565efSmrg        .byte	0xc	@ DW_CFA_def_cfa
16210d565efSmrg        .uleb128 0xd
16310d565efSmrg        .uleb128 0x0
16410d565efSmrg
16510d565efSmrg	.align 2
16610d565efSmrgLSYM(Lend_cie):
16710d565efSmrg	.4byte	LSYM(Lend_fde)-LSYM(Lstart_fde)	@ FDE Length
16810d565efSmrgLSYM(Lstart_fde):
16910d565efSmrg	.4byte	LSYM(Lstart_frame)	@ FDE CIE offset
17010d565efSmrg	.4byte	\start_label	@ FDE initial location
17110d565efSmrg	.4byte	\end_label-\start_label	@ FDE address range
17210d565efSmrg	.popsection
17310d565efSmrg#endif
17410d565efSmrg.endm
17510d565efSmrg.macro cfi_end	end_label
17610d565efSmrg#ifdef __ELF__
17710d565efSmrg	.pushsection	.debug_frame
17810d565efSmrg	.align	2
17910d565efSmrgLSYM(Lend_fde):
18010d565efSmrg	.popsection
18110d565efSmrg\end_label:
18210d565efSmrg#endif
18310d565efSmrg.endm
18410d565efSmrg
18510d565efSmrg/* Don't pass dirn, it's there just to get token pasting right.  */
18610d565efSmrg
18710d565efSmrg.macro	RETLDM	regs=, cond=, unwind=, dirn=ia
18810d565efSmrg#if defined (__INTERWORKING__)
18910d565efSmrg	.ifc "\regs",""
19010d565efSmrg	ldr\cond	lr, [sp], #8
19110d565efSmrg	.else
19210d565efSmrg# if defined(__thumb2__)
19310d565efSmrg	pop\cond	{\regs, lr}
19410d565efSmrg# else
19510d565efSmrg	ldm\cond\dirn	sp!, {\regs, lr}
19610d565efSmrg# endif
19710d565efSmrg	.endif
19810d565efSmrg	.ifnc "\unwind", ""
19910d565efSmrg	/* Mark LR as restored.  */
20010d565efSmrg97:	cfi_pop 97b - \unwind, 0xe, 0x0
20110d565efSmrg	.endif
20210d565efSmrg	bx\cond	lr
20310d565efSmrg#else
20410d565efSmrg	/* Caller is responsible for providing IT instruction.  */
20510d565efSmrg	.ifc "\regs",""
20610d565efSmrg	ldr\cond	pc, [sp], #8
20710d565efSmrg	.else
20810d565efSmrg# if defined(__thumb2__)
20910d565efSmrg	pop\cond	{\regs, pc}
21010d565efSmrg# else
21110d565efSmrg	ldm\cond\dirn	sp!, {\regs, pc}
21210d565efSmrg# endif
21310d565efSmrg	.endif
21410d565efSmrg#endif
21510d565efSmrg.endm
21610d565efSmrg
21710d565efSmrg/* The Unified assembly syntax allows the same code to be assembled for both
21810d565efSmrg   ARM and Thumb-2.  However this is only supported by recent gas, so define
21910d565efSmrg   a set of macros to allow ARM code on older assemblers.  */
22010d565efSmrg#if defined(__thumb2__)
22110d565efSmrg.macro do_it cond, suffix=""
22210d565efSmrg	it\suffix	\cond
22310d565efSmrg.endm
22410d565efSmrg.macro shift1 op, arg0, arg1, arg2
22510d565efSmrg	\op	\arg0, \arg1, \arg2
22610d565efSmrg.endm
22710d565efSmrg#define do_push	push
22810d565efSmrg#define do_pop	pop
22910d565efSmrg/* Perform an arithmetic operation with a variable shift operand.  This
23010d565efSmrg   requires two instructions and a scratch register on Thumb-2.  */
23110d565efSmrg.macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
23210d565efSmrg	\shiftop \tmp, \src2, \shiftreg
23310d565efSmrg	\name \dest, \src1, \tmp
23410d565efSmrg.endm
23510d565efSmrg#else
23610d565efSmrg.macro do_it cond, suffix=""
23710d565efSmrg.endm
23810d565efSmrg.macro shift1 op, arg0, arg1, arg2
23910d565efSmrg	mov	\arg0, \arg1, \op \arg2
24010d565efSmrg.endm
24110d565efSmrg#define do_push	stmfd sp!,
24210d565efSmrg#define do_pop	ldmfd sp!,
24310d565efSmrg.macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
24410d565efSmrg	\name \dest, \src1, \src2, \shiftop \shiftreg
24510d565efSmrg.endm
24610d565efSmrg#endif
24710d565efSmrg
248*ec02198aSmrg#define COND(op1, op2, cond) op1 ## op2 ## cond
249*ec02198aSmrg
25010d565efSmrg#ifdef __ARM_EABI__
25110d565efSmrg.macro ARM_LDIV0 name signed
25210d565efSmrg	cmp	r0, #0
25310d565efSmrg	.ifc	\signed, unsigned
25410d565efSmrg	movne	r0, #0xffffffff
25510d565efSmrg	.else
25610d565efSmrg	movgt	r0, #0x7fffffff
25710d565efSmrg	movlt	r0, #0x80000000
25810d565efSmrg	.endif
25910d565efSmrg	b	SYM (__aeabi_idiv0) __PLT__
26010d565efSmrg.endm
26110d565efSmrg#else
26210d565efSmrg.macro ARM_LDIV0 name signed
26310d565efSmrg	str	lr, [sp, #-8]!
26410d565efSmrg98:	cfi_push 98b - __\name, 0xe, -0x8, 0x8
26510d565efSmrg	bl	SYM (__div0) __PLT__
26610d565efSmrg	mov	r0, #0			@ About as wrong as it could be.
26710d565efSmrg	RETLDM	unwind=98b
26810d565efSmrg.endm
26910d565efSmrg#endif
27010d565efSmrg
27110d565efSmrg
27210d565efSmrg#ifdef __ARM_EABI__
27310d565efSmrg.macro THUMB_LDIV0 name signed
27410d565efSmrg#ifdef NOT_ISA_TARGET_32BIT
27510d565efSmrg
27610d565efSmrg	push	{r0, lr}
277*ec02198aSmrg	movs	r0, #0
27810d565efSmrg	bl	SYM(__aeabi_idiv0)
27910d565efSmrg	@ We know we are not on armv4t, so pop pc is safe.
28010d565efSmrg	pop	{r1, pc}
28110d565efSmrg
28210d565efSmrg#elif defined(__thumb2__)
28310d565efSmrg	.syntax unified
28410d565efSmrg	.ifc \signed, unsigned
28510d565efSmrg	cbz	r0, 1f
28610d565efSmrg	mov	r0, #0xffffffff
28710d565efSmrg1:
28810d565efSmrg	.else
28910d565efSmrg	cmp	r0, #0
29010d565efSmrg	do_it	gt
29110d565efSmrg	movgt	r0, #0x7fffffff
29210d565efSmrg	do_it	lt
29310d565efSmrg	movlt	r0, #0x80000000
29410d565efSmrg	.endif
29510d565efSmrg	b.w	SYM(__aeabi_idiv0) __PLT__
29610d565efSmrg#else
29710d565efSmrg	.align	2
29810d565efSmrg	bx	pc
29910d565efSmrg	nop
30010d565efSmrg	.arm
30110d565efSmrg	cmp	r0, #0
30210d565efSmrg	.ifc	\signed, unsigned
30310d565efSmrg	movne	r0, #0xffffffff
30410d565efSmrg	.else
30510d565efSmrg	movgt	r0, #0x7fffffff
30610d565efSmrg	movlt	r0, #0x80000000
30710d565efSmrg	.endif
30810d565efSmrg	b	SYM(__aeabi_idiv0) __PLT__
30910d565efSmrg	.thumb
31010d565efSmrg#endif
31110d565efSmrg.endm
31210d565efSmrg#else
31310d565efSmrg.macro THUMB_LDIV0 name signed
31410d565efSmrg	push	{ r1, lr }
31510d565efSmrg98:	cfi_push 98b - __\name, 0xe, -0x4, 0x8
31610d565efSmrg	bl	SYM (__div0)
317*ec02198aSmrg	movs	r0, #0			@ About as wrong as it could be.
31810d565efSmrg#if defined (__INTERWORKING__)
31910d565efSmrg	pop	{ r1, r2 }
32010d565efSmrg	bx	r2
32110d565efSmrg#else
32210d565efSmrg	pop	{ r1, pc }
32310d565efSmrg#endif
32410d565efSmrg.endm
32510d565efSmrg#endif
32610d565efSmrg
32710d565efSmrg.macro FUNC_END name
32810d565efSmrg	SIZE (__\name)
32910d565efSmrg.endm
33010d565efSmrg
33110d565efSmrg.macro DIV_FUNC_END name signed
33210d565efSmrg	cfi_start	__\name, LSYM(Lend_div0)
33310d565efSmrgLSYM(Ldiv0):
33410d565efSmrg#ifdef __thumb__
33510d565efSmrg	THUMB_LDIV0 \name \signed
33610d565efSmrg#else
33710d565efSmrg	ARM_LDIV0 \name \signed
33810d565efSmrg#endif
33910d565efSmrg	cfi_end	LSYM(Lend_div0)
34010d565efSmrg	FUNC_END \name
34110d565efSmrg.endm
34210d565efSmrg
34310d565efSmrg.macro THUMB_FUNC_START name
34410d565efSmrg	.globl	SYM (\name)
34510d565efSmrg	TYPE	(\name)
34610d565efSmrg	.thumb_func
34710d565efSmrgSYM (\name):
34810d565efSmrg.endm
34910d565efSmrg
35010d565efSmrg/* Function start macros.  Variants for ARM and Thumb.  */
35110d565efSmrg
35210d565efSmrg#ifdef __thumb__
35310d565efSmrg#define THUMB_FUNC .thumb_func
35410d565efSmrg#define THUMB_CODE .force_thumb
35510d565efSmrg# if defined(__thumb2__)
356*ec02198aSmrg#define THUMB_SYNTAX
35710d565efSmrg# else
35810d565efSmrg#define THUMB_SYNTAX
35910d565efSmrg# endif
36010d565efSmrg#else
36110d565efSmrg#define THUMB_FUNC
36210d565efSmrg#define THUMB_CODE
36310d565efSmrg#define THUMB_SYNTAX
36410d565efSmrg#endif
36510d565efSmrg
3660fc04c29Smrg.macro FUNC_START name
36710d565efSmrg	.text
36810d565efSmrg	.globl SYM (__\name)
36910d565efSmrg	TYPE (__\name)
37010d565efSmrg	.align 0
37110d565efSmrg	THUMB_CODE
37210d565efSmrg	THUMB_FUNC
37310d565efSmrg	THUMB_SYNTAX
37410d565efSmrgSYM (__\name):
37510d565efSmrg.endm
37610d565efSmrg
37710d565efSmrg.macro ARM_SYM_START name
37810d565efSmrg       TYPE (\name)
37910d565efSmrg       .align 0
38010d565efSmrgSYM (\name):
38110d565efSmrg.endm
38210d565efSmrg
38310d565efSmrg.macro SYM_END name
38410d565efSmrg       SIZE (\name)
38510d565efSmrg.endm
38610d565efSmrg
38710d565efSmrg/* Special function that will always be coded in ARM assembly, even if
38810d565efSmrg   in Thumb-only compilation.  */
38910d565efSmrg
39010d565efSmrg#if defined(__thumb2__)
39110d565efSmrg
39210d565efSmrg/* For Thumb-2 we build everything in thumb mode.  */
3930fc04c29Smrg.macro ARM_FUNC_START name
3940fc04c29Smrg       FUNC_START \name
39510d565efSmrg       .syntax unified
39610d565efSmrg.endm
39710d565efSmrg#define EQUIV .thumb_set
39810d565efSmrg.macro  ARM_CALL name
39910d565efSmrg	bl	__\name
40010d565efSmrg.endm
40110d565efSmrg
40210d565efSmrg#elif defined(__INTERWORKING_STUBS__)
40310d565efSmrg
40410d565efSmrg.macro	ARM_FUNC_START name
40510d565efSmrg	FUNC_START \name
40610d565efSmrg	bx	pc
40710d565efSmrg	nop
40810d565efSmrg	.arm
40910d565efSmrg/* A hook to tell gdb that we've switched to ARM mode.  Also used to call
41010d565efSmrg   directly from other local arm routines.  */
41110d565efSmrg_L__\name:
41210d565efSmrg.endm
41310d565efSmrg#define EQUIV .thumb_set
41410d565efSmrg/* Branch directly to a function declared with ARM_FUNC_START.
41510d565efSmrg   Must be called in arm mode.  */
41610d565efSmrg.macro  ARM_CALL name
41710d565efSmrg	bl	_L__\name
41810d565efSmrg.endm
41910d565efSmrg
42010d565efSmrg#else /* !(__INTERWORKING_STUBS__ || __thumb2__) */
42110d565efSmrg
42210d565efSmrg#ifdef NOT_ISA_TARGET_32BIT
42310d565efSmrg#define EQUIV .thumb_set
42410d565efSmrg#else
4250fc04c29Smrg.macro	ARM_FUNC_START name
42610d565efSmrg	.text
42710d565efSmrg	.globl SYM (__\name)
42810d565efSmrg	TYPE (__\name)
42910d565efSmrg	.align 0
43010d565efSmrg	.arm
43110d565efSmrgSYM (__\name):
43210d565efSmrg.endm
43310d565efSmrg#define EQUIV .set
43410d565efSmrg.macro  ARM_CALL name
43510d565efSmrg	bl	__\name
43610d565efSmrg.endm
43710d565efSmrg#endif
43810d565efSmrg
43910d565efSmrg#endif
44010d565efSmrg
44110d565efSmrg.macro	FUNC_ALIAS new old
44210d565efSmrg	.globl	SYM (__\new)
44310d565efSmrg#if defined (__thumb__)
44410d565efSmrg	.thumb_set	SYM (__\new), SYM (__\old)
44510d565efSmrg#else
44610d565efSmrg	.set	SYM (__\new), SYM (__\old)
44710d565efSmrg#endif
44810d565efSmrg.endm
44910d565efSmrg
45010d565efSmrg#ifndef NOT_ISA_TARGET_32BIT
45110d565efSmrg.macro	ARM_FUNC_ALIAS new old
45210d565efSmrg	.globl	SYM (__\new)
45310d565efSmrg	EQUIV	SYM (__\new), SYM (__\old)
45410d565efSmrg#if defined(__INTERWORKING_STUBS__)
45510d565efSmrg	.set	SYM (_L__\new), SYM (_L__\old)
45610d565efSmrg#endif
45710d565efSmrg.endm
45810d565efSmrg#endif
45910d565efSmrg
46010d565efSmrg#ifdef __ARMEB__
46110d565efSmrg#define xxh r0
46210d565efSmrg#define xxl r1
46310d565efSmrg#define yyh r2
46410d565efSmrg#define yyl r3
46510d565efSmrg#else
46610d565efSmrg#define xxh r1
46710d565efSmrg#define xxl r0
46810d565efSmrg#define yyh r3
46910d565efSmrg#define yyl r2
47010d565efSmrg#endif
47110d565efSmrg
47210d565efSmrg#ifdef __ARM_EABI__
47310d565efSmrg.macro	WEAK name
47410d565efSmrg	.weak SYM (__\name)
47510d565efSmrg.endm
47610d565efSmrg#endif
47710d565efSmrg
47810d565efSmrg#ifdef __thumb__
47910d565efSmrg/* Register aliases.  */
48010d565efSmrg
48110d565efSmrgwork		.req	r4	@ XXXX is this safe ?
48210d565efSmrgdividend	.req	r0
48310d565efSmrgdivisor		.req	r1
48410d565efSmrgoverdone	.req	r2
48510d565efSmrgresult		.req	r2
48610d565efSmrgcurbit		.req	r3
48710d565efSmrg#endif
48810d565efSmrg#if 0
48910d565efSmrgip		.req	r12
49010d565efSmrgsp		.req	r13
49110d565efSmrglr		.req	r14
49210d565efSmrgpc		.req	r15
49310d565efSmrg#endif
49410d565efSmrg
49510d565efSmrg/* ------------------------------------------------------------------------ */
49610d565efSmrg/*		Bodies of the division and modulo routines.		    */
49710d565efSmrg/* ------------------------------------------------------------------------ */
498*ec02198aSmrg
49910d565efSmrg.macro ARM_DIV_BODY dividend, divisor, result, curbit
50010d565efSmrg
5010fc04c29Smrg#if defined (__ARM_FEATURE_CLZ) && ! defined (__OPTIMIZE_SIZE__)
50210d565efSmrg
50310d565efSmrg#if defined (__thumb2__)
50410d565efSmrg	clz	\curbit, \dividend
50510d565efSmrg	clz	\result, \divisor
50610d565efSmrg	sub	\curbit, \result, \curbit
50710d565efSmrg	rsb	\curbit, \curbit, #31
50810d565efSmrg	adr	\result, 1f
50910d565efSmrg	add	\curbit, \result, \curbit, lsl #4
51010d565efSmrg	mov	\result, #0
51110d565efSmrg	mov	pc, \curbit
51210d565efSmrg.p2align 3
51310d565efSmrg1:
51410d565efSmrg	.set	shift, 32
51510d565efSmrg	.rept	32
51610d565efSmrg	.set	shift, shift - 1
51710d565efSmrg	cmp.w	\dividend, \divisor, lsl #shift
51810d565efSmrg	nop.n
51910d565efSmrg	adc.w	\result, \result, \result
52010d565efSmrg	it	cs
52110d565efSmrg	subcs.w	\dividend, \dividend, \divisor, lsl #shift
52210d565efSmrg	.endr
52310d565efSmrg#else
52410d565efSmrg	clz	\curbit, \dividend
52510d565efSmrg	clz	\result, \divisor
52610d565efSmrg	sub	\curbit, \result, \curbit
52710d565efSmrg	rsbs	\curbit, \curbit, #31
52810d565efSmrg	addne	\curbit, \curbit, \curbit, lsl #1
52910d565efSmrg	mov	\result, #0
53010d565efSmrg	addne	pc, pc, \curbit, lsl #2
53110d565efSmrg	nop
53210d565efSmrg	.set	shift, 32
53310d565efSmrg	.rept	32
53410d565efSmrg	.set	shift, shift - 1
53510d565efSmrg	cmp	\dividend, \divisor, lsl #shift
53610d565efSmrg	adc	\result, \result, \result
53710d565efSmrg	subcs	\dividend, \dividend, \divisor, lsl #shift
53810d565efSmrg	.endr
53910d565efSmrg#endif
54010d565efSmrg
5410fc04c29Smrg#else /* !defined (__ARM_FEATURE_CLZ) || defined (__OPTIMIZE_SIZE__) */
5420fc04c29Smrg#if defined (__ARM_FEATURE_CLZ)
54310d565efSmrg
54410d565efSmrg	clz	\curbit, \divisor
54510d565efSmrg	clz	\result, \dividend
54610d565efSmrg	sub	\result, \curbit, \result
54710d565efSmrg	mov	\curbit, #1
54810d565efSmrg	mov	\divisor, \divisor, lsl \result
54910d565efSmrg	mov	\curbit, \curbit, lsl \result
55010d565efSmrg	mov	\result, #0
55110d565efSmrg
5520fc04c29Smrg#else /* !defined (__ARM_FEATURE_CLZ) */
55310d565efSmrg
55410d565efSmrg	@ Initially shift the divisor left 3 bits if possible,
55510d565efSmrg	@ set curbit accordingly.  This allows for curbit to be located
55610d565efSmrg	@ at the left end of each 4-bit nibbles in the division loop
55710d565efSmrg	@ to save one loop in most cases.
55810d565efSmrg	tst	\divisor, #0xe0000000
55910d565efSmrg	moveq	\divisor, \divisor, lsl #3
56010d565efSmrg	moveq	\curbit, #8
56110d565efSmrg	movne	\curbit, #1
56210d565efSmrg
56310d565efSmrg	@ Unless the divisor is very big, shift it up in multiples of
56410d565efSmrg	@ four bits, since this is the amount of unwinding in the main
56510d565efSmrg	@ division loop.  Continue shifting until the divisor is
56610d565efSmrg	@ larger than the dividend.
56710d565efSmrg1:	cmp	\divisor, #0x10000000
56810d565efSmrg	cmplo	\divisor, \dividend
56910d565efSmrg	movlo	\divisor, \divisor, lsl #4
57010d565efSmrg	movlo	\curbit, \curbit, lsl #4
57110d565efSmrg	blo	1b
57210d565efSmrg
57310d565efSmrg	@ For very big divisors, we must shift it a bit at a time, or
57410d565efSmrg	@ we will be in danger of overflowing.
57510d565efSmrg1:	cmp	\divisor, #0x80000000
57610d565efSmrg	cmplo	\divisor, \dividend
57710d565efSmrg	movlo	\divisor, \divisor, lsl #1
57810d565efSmrg	movlo	\curbit, \curbit, lsl #1
57910d565efSmrg	blo	1b
58010d565efSmrg
58110d565efSmrg	mov	\result, #0
58210d565efSmrg
5830fc04c29Smrg#endif /* !defined (__ARM_FEATURE_CLZ) */
58410d565efSmrg
58510d565efSmrg	@ Division loop
58610d565efSmrg1:	cmp	\dividend, \divisor
58710d565efSmrg	do_it	hs, t
58810d565efSmrg	subhs	\dividend, \dividend, \divisor
58910d565efSmrg	orrhs	\result,   \result,   \curbit
59010d565efSmrg	cmp	\dividend, \divisor,  lsr #1
59110d565efSmrg	do_it	hs, t
59210d565efSmrg	subhs	\dividend, \dividend, \divisor, lsr #1
59310d565efSmrg	orrhs	\result,   \result,   \curbit,  lsr #1
59410d565efSmrg	cmp	\dividend, \divisor,  lsr #2
59510d565efSmrg	do_it	hs, t
59610d565efSmrg	subhs	\dividend, \dividend, \divisor, lsr #2
59710d565efSmrg	orrhs	\result,   \result,   \curbit,  lsr #2
59810d565efSmrg	cmp	\dividend, \divisor,  lsr #3
59910d565efSmrg	do_it	hs, t
60010d565efSmrg	subhs	\dividend, \dividend, \divisor, lsr #3
60110d565efSmrg	orrhs	\result,   \result,   \curbit,  lsr #3
60210d565efSmrg	cmp	\dividend, #0			@ Early termination?
60310d565efSmrg	do_it	ne, t
60410d565efSmrg	movnes	\curbit,   \curbit,  lsr #4	@ No, any more bits to do?
60510d565efSmrg	movne	\divisor,  \divisor, lsr #4
60610d565efSmrg	bne	1b
60710d565efSmrg
6080fc04c29Smrg#endif /* !defined (__ARM_FEATURE_CLZ) || defined (__OPTIMIZE_SIZE__) */
60910d565efSmrg
61010d565efSmrg.endm
61110d565efSmrg/* ------------------------------------------------------------------------ */
61210d565efSmrg.macro ARM_DIV2_ORDER divisor, order
61310d565efSmrg
6140fc04c29Smrg#if defined (__ARM_FEATURE_CLZ)
61510d565efSmrg
61610d565efSmrg	clz	\order, \divisor
61710d565efSmrg	rsb	\order, \order, #31
61810d565efSmrg
61910d565efSmrg#else
62010d565efSmrg
62110d565efSmrg	cmp	\divisor, #(1 << 16)
62210d565efSmrg	movhs	\divisor, \divisor, lsr #16
62310d565efSmrg	movhs	\order, #16
62410d565efSmrg	movlo	\order, #0
62510d565efSmrg
62610d565efSmrg	cmp	\divisor, #(1 << 8)
62710d565efSmrg	movhs	\divisor, \divisor, lsr #8
62810d565efSmrg	addhs	\order, \order, #8
62910d565efSmrg
63010d565efSmrg	cmp	\divisor, #(1 << 4)
63110d565efSmrg	movhs	\divisor, \divisor, lsr #4
63210d565efSmrg	addhs	\order, \order, #4
63310d565efSmrg
63410d565efSmrg	cmp	\divisor, #(1 << 2)
63510d565efSmrg	addhi	\order, \order, #3
63610d565efSmrg	addls	\order, \order, \divisor, lsr #1
63710d565efSmrg
63810d565efSmrg#endif
63910d565efSmrg
64010d565efSmrg.endm
64110d565efSmrg/* ------------------------------------------------------------------------ */
64210d565efSmrg.macro ARM_MOD_BODY dividend, divisor, order, spare
64310d565efSmrg
6440fc04c29Smrg#if defined(__ARM_FEATURE_CLZ) && ! defined (__OPTIMIZE_SIZE__)
64510d565efSmrg
64610d565efSmrg	clz	\order, \divisor
64710d565efSmrg	clz	\spare, \dividend
64810d565efSmrg	sub	\order, \order, \spare
64910d565efSmrg	rsbs	\order, \order, #31
65010d565efSmrg	addne	pc, pc, \order, lsl #3
65110d565efSmrg	nop
65210d565efSmrg	.set	shift, 32
65310d565efSmrg	.rept	32
65410d565efSmrg	.set	shift, shift - 1
65510d565efSmrg	cmp	\dividend, \divisor, lsl #shift
65610d565efSmrg	subcs	\dividend, \dividend, \divisor, lsl #shift
65710d565efSmrg	.endr
65810d565efSmrg
6590fc04c29Smrg#else /* !defined (__ARM_FEATURE_CLZ) || defined (__OPTIMIZE_SIZE__) */
6600fc04c29Smrg#if defined (__ARM_FEATURE_CLZ)
66110d565efSmrg
66210d565efSmrg	clz	\order, \divisor
66310d565efSmrg	clz	\spare, \dividend
66410d565efSmrg	sub	\order, \order, \spare
66510d565efSmrg	mov	\divisor, \divisor, lsl \order
66610d565efSmrg
6670fc04c29Smrg#else /* !defined (__ARM_FEATURE_CLZ) */
66810d565efSmrg
66910d565efSmrg	mov	\order, #0
67010d565efSmrg
67110d565efSmrg	@ Unless the divisor is very big, shift it up in multiples of
67210d565efSmrg	@ four bits, since this is the amount of unwinding in the main
67310d565efSmrg	@ division loop.  Continue shifting until the divisor is
67410d565efSmrg	@ larger than the dividend.
67510d565efSmrg1:	cmp	\divisor, #0x10000000
67610d565efSmrg	cmplo	\divisor, \dividend
67710d565efSmrg	movlo	\divisor, \divisor, lsl #4
67810d565efSmrg	addlo	\order, \order, #4
67910d565efSmrg	blo	1b
68010d565efSmrg
68110d565efSmrg	@ For very big divisors, we must shift it a bit at a time, or
68210d565efSmrg	@ we will be in danger of overflowing.
68310d565efSmrg1:	cmp	\divisor, #0x80000000
68410d565efSmrg	cmplo	\divisor, \dividend
68510d565efSmrg	movlo	\divisor, \divisor, lsl #1
68610d565efSmrg	addlo	\order, \order, #1
68710d565efSmrg	blo	1b
68810d565efSmrg
6890fc04c29Smrg#endif /* !defined (__ARM_FEATURE_CLZ) */
69010d565efSmrg
69110d565efSmrg	@ Perform all needed substractions to keep only the reminder.
69210d565efSmrg	@ Do comparisons in batch of 4 first.
69310d565efSmrg	subs	\order, \order, #3		@ yes, 3 is intended here
69410d565efSmrg	blt	2f
69510d565efSmrg
69610d565efSmrg1:	cmp	\dividend, \divisor
69710d565efSmrg	subhs	\dividend, \dividend, \divisor
69810d565efSmrg	cmp	\dividend, \divisor,  lsr #1
69910d565efSmrg	subhs	\dividend, \dividend, \divisor, lsr #1
70010d565efSmrg	cmp	\dividend, \divisor,  lsr #2
70110d565efSmrg	subhs	\dividend, \dividend, \divisor, lsr #2
70210d565efSmrg	cmp	\dividend, \divisor,  lsr #3
70310d565efSmrg	subhs	\dividend, \dividend, \divisor, lsr #3
70410d565efSmrg	cmp	\dividend, #1
70510d565efSmrg	mov	\divisor, \divisor, lsr #4
70610d565efSmrg	subges	\order, \order, #4
70710d565efSmrg	bge	1b
70810d565efSmrg
70910d565efSmrg	tst	\order, #3
71010d565efSmrg	teqne	\dividend, #0
71110d565efSmrg	beq	5f
71210d565efSmrg
71310d565efSmrg	@ Either 1, 2 or 3 comparison/substractions are left.
71410d565efSmrg2:	cmn	\order, #2
71510d565efSmrg	blt	4f
71610d565efSmrg	beq	3f
71710d565efSmrg	cmp	\dividend, \divisor
71810d565efSmrg	subhs	\dividend, \dividend, \divisor
71910d565efSmrg	mov	\divisor,  \divisor,  lsr #1
72010d565efSmrg3:	cmp	\dividend, \divisor
72110d565efSmrg	subhs	\dividend, \dividend, \divisor
72210d565efSmrg	mov	\divisor,  \divisor,  lsr #1
72310d565efSmrg4:	cmp	\dividend, \divisor
72410d565efSmrg	subhs	\dividend, \dividend, \divisor
72510d565efSmrg5:
72610d565efSmrg
7270fc04c29Smrg#endif /* !defined (__ARM_FEATURE_CLZ) || defined (__OPTIMIZE_SIZE__) */
72810d565efSmrg
72910d565efSmrg.endm
73010d565efSmrg/* ------------------------------------------------------------------------ */
73110d565efSmrg.macro THUMB_DIV_MOD_BODY modulo
73210d565efSmrg	@ Load the constant 0x10000000 into our work register.
733*ec02198aSmrg	movs	work, #1
734*ec02198aSmrg	lsls	work, #28
73510d565efSmrgLSYM(Loop1):
73610d565efSmrg	@ Unless the divisor is very big, shift it up in multiples of
73710d565efSmrg	@ four bits, since this is the amount of unwinding in the main
73810d565efSmrg	@ division loop.  Continue shifting until the divisor is
73910d565efSmrg	@ larger than the dividend.
74010d565efSmrg	cmp	divisor, work
74110d565efSmrg	bhs	LSYM(Lbignum)
74210d565efSmrg	cmp	divisor, dividend
74310d565efSmrg	bhs	LSYM(Lbignum)
744*ec02198aSmrg	lsls	divisor, #4
745*ec02198aSmrg	lsls	curbit,  #4
74610d565efSmrg	b	LSYM(Loop1)
74710d565efSmrgLSYM(Lbignum):
74810d565efSmrg	@ Set work to 0x80000000
749*ec02198aSmrg	lsls	work, #3
75010d565efSmrgLSYM(Loop2):
75110d565efSmrg	@ For very big divisors, we must shift it a bit at a time, or
75210d565efSmrg	@ we will be in danger of overflowing.
75310d565efSmrg	cmp	divisor, work
75410d565efSmrg	bhs	LSYM(Loop3)
75510d565efSmrg	cmp	divisor, dividend
75610d565efSmrg	bhs	LSYM(Loop3)
757*ec02198aSmrg	lsls	divisor, #1
758*ec02198aSmrg	lsls	curbit,  #1
75910d565efSmrg	b	LSYM(Loop2)
76010d565efSmrgLSYM(Loop3):
76110d565efSmrg	@ Test for possible subtractions ...
76210d565efSmrg  .if \modulo
76310d565efSmrg	@ ... On the final pass, this may subtract too much from the dividend,
76410d565efSmrg	@ so keep track of which subtractions are done, we can fix them up
76510d565efSmrg	@ afterwards.
766*ec02198aSmrg	movs	overdone, #0
76710d565efSmrg	cmp	dividend, divisor
76810d565efSmrg	blo	LSYM(Lover1)
769*ec02198aSmrg	subs	dividend, dividend, divisor
77010d565efSmrgLSYM(Lover1):
771*ec02198aSmrg	lsrs	work, divisor, #1
77210d565efSmrg	cmp	dividend, work
77310d565efSmrg	blo	LSYM(Lover2)
774*ec02198aSmrg	subs	dividend, dividend, work
77510d565efSmrg	mov	ip, curbit
776*ec02198aSmrg	movs	work, #1
777*ec02198aSmrg	rors	curbit, work
778*ec02198aSmrg	orrs	overdone, curbit
77910d565efSmrg	mov	curbit, ip
78010d565efSmrgLSYM(Lover2):
781*ec02198aSmrg	lsrs	work, divisor, #2
78210d565efSmrg	cmp	dividend, work
78310d565efSmrg	blo	LSYM(Lover3)
784*ec02198aSmrg	subs	dividend, dividend, work
78510d565efSmrg	mov	ip, curbit
786*ec02198aSmrg	movs	work, #2
787*ec02198aSmrg	rors	curbit, work
788*ec02198aSmrg	orrs	overdone, curbit
78910d565efSmrg	mov	curbit, ip
79010d565efSmrgLSYM(Lover3):
791*ec02198aSmrg	lsrs	work, divisor, #3
79210d565efSmrg	cmp	dividend, work
79310d565efSmrg	blo	LSYM(Lover4)
794*ec02198aSmrg	subs	dividend, dividend, work
79510d565efSmrg	mov	ip, curbit
796*ec02198aSmrg	movs	work, #3
797*ec02198aSmrg	rors	curbit, work
798*ec02198aSmrg	orrs	overdone, curbit
79910d565efSmrg	mov	curbit, ip
80010d565efSmrgLSYM(Lover4):
80110d565efSmrg	mov	ip, curbit
80210d565efSmrg  .else
80310d565efSmrg	@ ... and note which bits are done in the result.  On the final pass,
80410d565efSmrg	@ this may subtract too much from the dividend, but the result will be ok,
80510d565efSmrg	@ since the "bit" will have been shifted out at the bottom.
80610d565efSmrg	cmp	dividend, divisor
80710d565efSmrg	blo	LSYM(Lover1)
808*ec02198aSmrg	subs	dividend, dividend, divisor
809*ec02198aSmrg	orrs	result, result, curbit
81010d565efSmrgLSYM(Lover1):
811*ec02198aSmrg	lsrs	work, divisor, #1
81210d565efSmrg	cmp	dividend, work
81310d565efSmrg	blo	LSYM(Lover2)
814*ec02198aSmrg	subs	dividend, dividend, work
815*ec02198aSmrg	lsrs	work, curbit, #1
816*ec02198aSmrg	orrs	result, work
81710d565efSmrgLSYM(Lover2):
818*ec02198aSmrg	lsrs	work, divisor, #2
81910d565efSmrg	cmp	dividend, work
82010d565efSmrg	blo	LSYM(Lover3)
821*ec02198aSmrg	subs	dividend, dividend, work
822*ec02198aSmrg	lsrs	work, curbit, #2
823*ec02198aSmrg	orrs	result, work
82410d565efSmrgLSYM(Lover3):
825*ec02198aSmrg	lsrs	work, divisor, #3
82610d565efSmrg	cmp	dividend, work
82710d565efSmrg	blo	LSYM(Lover4)
828*ec02198aSmrg	subs	dividend, dividend, work
829*ec02198aSmrg	lsrs	work, curbit, #3
830*ec02198aSmrg	orrs	result, work
83110d565efSmrgLSYM(Lover4):
83210d565efSmrg  .endif
83310d565efSmrg
83410d565efSmrg	cmp	dividend, #0			@ Early termination?
83510d565efSmrg	beq	LSYM(Lover5)
836*ec02198aSmrg	lsrs	curbit,  #4			@ No, any more bits to do?
83710d565efSmrg	beq	LSYM(Lover5)
838*ec02198aSmrg	lsrs	divisor, #4
83910d565efSmrg	b	LSYM(Loop3)
84010d565efSmrgLSYM(Lover5):
84110d565efSmrg  .if \modulo
84210d565efSmrg	@ Any subtractions that we should not have done will be recorded in
84310d565efSmrg	@ the top three bits of "overdone".  Exactly which were not needed
84410d565efSmrg	@ are governed by the position of the bit, stored in ip.
845*ec02198aSmrg	movs	work, #0xe
846*ec02198aSmrg	lsls	work, #28
847*ec02198aSmrg	ands	overdone, work
84810d565efSmrg	beq	LSYM(Lgot_result)
84910d565efSmrg
85010d565efSmrg	@ If we terminated early, because dividend became zero, then the
85110d565efSmrg	@ bit in ip will not be in the bottom nibble, and we should not
85210d565efSmrg	@ perform the additions below.  We must test for this though
85310d565efSmrg	@ (rather relying upon the TSTs to prevent the additions) since
85410d565efSmrg	@ the bit in ip could be in the top two bits which might then match
85510d565efSmrg	@ with one of the smaller RORs.
85610d565efSmrg	mov	curbit, ip
857*ec02198aSmrg	movs	work, #0x7
85810d565efSmrg	tst	curbit, work
85910d565efSmrg	beq	LSYM(Lgot_result)
86010d565efSmrg
86110d565efSmrg	mov	curbit, ip
862*ec02198aSmrg	movs	work, #3
863*ec02198aSmrg	rors	curbit, work
86410d565efSmrg	tst	overdone, curbit
86510d565efSmrg	beq	LSYM(Lover6)
866*ec02198aSmrg	lsrs	work, divisor, #3
867*ec02198aSmrg	adds	dividend, work
86810d565efSmrgLSYM(Lover6):
86910d565efSmrg	mov	curbit, ip
870*ec02198aSmrg	movs	work, #2
871*ec02198aSmrg	rors	curbit, work
87210d565efSmrg	tst	overdone, curbit
87310d565efSmrg	beq	LSYM(Lover7)
874*ec02198aSmrg	lsrs	work, divisor, #2
875*ec02198aSmrg	adds	dividend, work
87610d565efSmrgLSYM(Lover7):
87710d565efSmrg	mov	curbit, ip
878*ec02198aSmrg	movs	work, #1
879*ec02198aSmrg	rors	curbit, work
88010d565efSmrg	tst	overdone, curbit
88110d565efSmrg	beq	LSYM(Lgot_result)
882*ec02198aSmrg	lsrs	work, divisor, #1
883*ec02198aSmrg	adds	dividend, work
88410d565efSmrg  .endif
88510d565efSmrgLSYM(Lgot_result):
88610d565efSmrg.endm
88710d565efSmrg
88810d565efSmrg/* If performance is preferred, the following functions are provided.  */
88910d565efSmrg#if defined(__prefer_thumb__) && !defined(__OPTIMIZE_SIZE__)
89010d565efSmrg
89110d565efSmrg/* Branch to div(n), and jump to label if curbit is lo than divisior.  */
89210d565efSmrg.macro BranchToDiv n, label
893*ec02198aSmrg	lsrs	curbit, dividend, \n
89410d565efSmrg	cmp	curbit, divisor
89510d565efSmrg	blo	\label
89610d565efSmrg.endm
89710d565efSmrg
89810d565efSmrg/* Body of div(n).  Shift the divisor in n bits and compare the divisor
89910d565efSmrg   and dividend.  Update the dividend as the substruction result.  */
90010d565efSmrg.macro DoDiv n
901*ec02198aSmrg	lsrs	curbit, dividend, \n
90210d565efSmrg	cmp	curbit, divisor
90310d565efSmrg	bcc	1f
904*ec02198aSmrg	lsls	curbit, divisor, \n
905*ec02198aSmrg	subs	dividend, dividend, curbit
90610d565efSmrg
907*ec02198aSmrg1:	adcs	result, result
90810d565efSmrg.endm
90910d565efSmrg
91010d565efSmrg/* The body of division with positive divisor.  Unless the divisor is very
91110d565efSmrg   big, shift it up in multiples of four bits, since this is the amount of
91210d565efSmrg   unwinding in the main division loop.  Continue shifting until the divisor
91310d565efSmrg   is larger than the dividend.  */
91410d565efSmrg.macro THUMB1_Div_Positive
915*ec02198aSmrg	movs	result, #0
91610d565efSmrg	BranchToDiv #1, LSYM(Lthumb1_div1)
91710d565efSmrg	BranchToDiv #4, LSYM(Lthumb1_div4)
91810d565efSmrg	BranchToDiv #8, LSYM(Lthumb1_div8)
91910d565efSmrg	BranchToDiv #12, LSYM(Lthumb1_div12)
92010d565efSmrg	BranchToDiv #16, LSYM(Lthumb1_div16)
92110d565efSmrgLSYM(Lthumb1_div_large_positive):
922*ec02198aSmrg	movs	result, #0xff
923*ec02198aSmrg	lsls	divisor, divisor, #8
92410d565efSmrg	rev	result, result
925*ec02198aSmrg	lsrs	curbit, dividend, #16
92610d565efSmrg	cmp	curbit, divisor
92710d565efSmrg	blo	1f
928*ec02198aSmrg	asrs	result, #8
929*ec02198aSmrg	lsls	divisor, divisor, #8
93010d565efSmrg	beq	LSYM(Ldivbyzero_waypoint)
93110d565efSmrg
932*ec02198aSmrg1:	lsrs	curbit, dividend, #12
93310d565efSmrg	cmp	curbit, divisor
93410d565efSmrg	blo	LSYM(Lthumb1_div12)
93510d565efSmrg	b	LSYM(Lthumb1_div16)
93610d565efSmrgLSYM(Lthumb1_div_loop):
937*ec02198aSmrg	lsrs	divisor, divisor, #8
93810d565efSmrgLSYM(Lthumb1_div16):
93910d565efSmrg	Dodiv	#15
94010d565efSmrg	Dodiv	#14
94110d565efSmrg	Dodiv	#13
94210d565efSmrg	Dodiv	#12
94310d565efSmrgLSYM(Lthumb1_div12):
94410d565efSmrg	Dodiv	#11
94510d565efSmrg	Dodiv	#10
94610d565efSmrg	Dodiv	#9
94710d565efSmrg	Dodiv	#8
94810d565efSmrg	bcs	LSYM(Lthumb1_div_loop)
94910d565efSmrgLSYM(Lthumb1_div8):
95010d565efSmrg	Dodiv	#7
95110d565efSmrg	Dodiv	#6
95210d565efSmrg	Dodiv	#5
95310d565efSmrgLSYM(Lthumb1_div5):
95410d565efSmrg	Dodiv	#4
95510d565efSmrgLSYM(Lthumb1_div4):
95610d565efSmrg	Dodiv	#3
95710d565efSmrgLSYM(Lthumb1_div3):
95810d565efSmrg	Dodiv	#2
95910d565efSmrgLSYM(Lthumb1_div2):
96010d565efSmrg	Dodiv	#1
96110d565efSmrgLSYM(Lthumb1_div1):
962*ec02198aSmrg	subs	divisor, dividend, divisor
96310d565efSmrg	bcs	1f
96410d565efSmrg	cpy	divisor, dividend
96510d565efSmrg
966*ec02198aSmrg1:	adcs	result, result
96710d565efSmrg	cpy	dividend, result
96810d565efSmrg	RET
96910d565efSmrg
97010d565efSmrgLSYM(Ldivbyzero_waypoint):
97110d565efSmrg	b	LSYM(Ldiv0)
97210d565efSmrg.endm
97310d565efSmrg
97410d565efSmrg/* The body of division with negative divisor.  Similar with
97510d565efSmrg   THUMB1_Div_Positive except that the shift steps are in multiples
97610d565efSmrg   of six bits.  */
97710d565efSmrg.macro THUMB1_Div_Negative
978*ec02198aSmrg	lsrs	result, divisor, #31
97910d565efSmrg	beq	1f
980*ec02198aSmrg	negs	divisor, divisor
98110d565efSmrg
982*ec02198aSmrg1:	asrs	curbit, dividend, #32
98310d565efSmrg	bcc	2f
984*ec02198aSmrg	negs	dividend, dividend
98510d565efSmrg
986*ec02198aSmrg2:	eors	curbit, result
987*ec02198aSmrg	movs	result, #0
98810d565efSmrg	cpy	ip, curbit
98910d565efSmrg	BranchToDiv #4, LSYM(Lthumb1_div_negative4)
99010d565efSmrg	BranchToDiv #8, LSYM(Lthumb1_div_negative8)
99110d565efSmrgLSYM(Lthumb1_div_large):
992*ec02198aSmrg	movs	result, #0xfc
993*ec02198aSmrg	lsls	divisor, divisor, #6
99410d565efSmrg	rev	result, result
995*ec02198aSmrg	lsrs	curbit, dividend, #8
99610d565efSmrg	cmp	curbit, divisor
99710d565efSmrg	blo	LSYM(Lthumb1_div_negative8)
99810d565efSmrg
999*ec02198aSmrg	lsls	divisor, divisor, #6
1000*ec02198aSmrg	asrs	result, result, #6
100110d565efSmrg	cmp	curbit, divisor
100210d565efSmrg	blo	LSYM(Lthumb1_div_negative8)
100310d565efSmrg
1004*ec02198aSmrg	lsls	divisor, divisor, #6
1005*ec02198aSmrg	asrs	result, result, #6
100610d565efSmrg	cmp	curbit, divisor
100710d565efSmrg	blo	LSYM(Lthumb1_div_negative8)
100810d565efSmrg
1009*ec02198aSmrg	lsls	divisor, divisor, #6
101010d565efSmrg	beq	LSYM(Ldivbyzero_negative)
1011*ec02198aSmrg	asrs	result, result, #6
101210d565efSmrg	b	LSYM(Lthumb1_div_negative8)
101310d565efSmrgLSYM(Lthumb1_div_negative_loop):
1014*ec02198aSmrg	lsrs	divisor, divisor, #6
101510d565efSmrgLSYM(Lthumb1_div_negative8):
101610d565efSmrg	DoDiv	#7
101710d565efSmrg	DoDiv	#6
101810d565efSmrg	DoDiv	#5
101910d565efSmrg	DoDiv	#4
102010d565efSmrgLSYM(Lthumb1_div_negative4):
102110d565efSmrg	DoDiv	#3
102210d565efSmrg	DoDiv	#2
102310d565efSmrg	bcs	LSYM(Lthumb1_div_negative_loop)
102410d565efSmrg	DoDiv	#1
1025*ec02198aSmrg	subs	divisor, dividend, divisor
102610d565efSmrg	bcs	1f
102710d565efSmrg	cpy	divisor, dividend
102810d565efSmrg
102910d565efSmrg1:	cpy	curbit, ip
1030*ec02198aSmrg	adcs	result, result
1031*ec02198aSmrg	asrs	curbit, curbit, #1
103210d565efSmrg	cpy	dividend, result
103310d565efSmrg	bcc	2f
1034*ec02198aSmrg	negs	dividend, dividend
103510d565efSmrg	cmp	curbit, #0
103610d565efSmrg
103710d565efSmrg2:	bpl	3f
1038*ec02198aSmrg	negs	divisor, divisor
103910d565efSmrg
104010d565efSmrg3:	RET
104110d565efSmrg
104210d565efSmrgLSYM(Ldivbyzero_negative):
104310d565efSmrg	cpy	curbit, ip
1044*ec02198aSmrg	asrs	curbit, curbit, #1
104510d565efSmrg	bcc	LSYM(Ldiv0)
1046*ec02198aSmrg	negs	dividend, dividend
104710d565efSmrg.endm
104810d565efSmrg#endif /* ARM Thumb version.  */
104910d565efSmrg
105010d565efSmrg/* ------------------------------------------------------------------------ */
105110d565efSmrg/*		Start of the Real Functions				    */
105210d565efSmrg/* ------------------------------------------------------------------------ */
105310d565efSmrg#ifdef L_udivsi3
105410d565efSmrg
105510d565efSmrg#if defined(__prefer_thumb__)
105610d565efSmrg
105710d565efSmrg	FUNC_START udivsi3
105810d565efSmrg	FUNC_ALIAS aeabi_uidiv udivsi3
105910d565efSmrg#if defined(__OPTIMIZE_SIZE__)
106010d565efSmrg
106110d565efSmrg	cmp	divisor, #0
106210d565efSmrg	beq	LSYM(Ldiv0)
106310d565efSmrgLSYM(udivsi3_skip_div0_test):
1064*ec02198aSmrg	movs	curbit, #1
1065*ec02198aSmrg	movs	result, #0
106610d565efSmrg
106710d565efSmrg	push	{ work }
106810d565efSmrg	cmp	dividend, divisor
106910d565efSmrg	blo	LSYM(Lgot_result)
107010d565efSmrg
107110d565efSmrg	THUMB_DIV_MOD_BODY 0
107210d565efSmrg
1073*ec02198aSmrg	movs	r0, result
107410d565efSmrg	pop	{ work }
107510d565efSmrg	RET
107610d565efSmrg
107710d565efSmrg/* Implementation of aeabi_uidiv for ARMv6m.  This version is only
107810d565efSmrg   used in ARMv6-M when we need an efficient implementation.  */
107910d565efSmrg#else
108010d565efSmrgLSYM(udivsi3_skip_div0_test):
108110d565efSmrg	THUMB1_Div_Positive
108210d565efSmrg
108310d565efSmrg#endif /* __OPTIMIZE_SIZE__ */
108410d565efSmrg
108510d565efSmrg#elif defined(__ARM_ARCH_EXT_IDIV__)
108610d565efSmrg
108710d565efSmrg	ARM_FUNC_START udivsi3
108810d565efSmrg	ARM_FUNC_ALIAS aeabi_uidiv udivsi3
108910d565efSmrg
109010d565efSmrg	cmp	r1, #0
109110d565efSmrg	beq	LSYM(Ldiv0)
109210d565efSmrg
109310d565efSmrg	udiv	r0, r0, r1
109410d565efSmrg	RET
109510d565efSmrg
109610d565efSmrg#else /* ARM version/Thumb-2.  */
109710d565efSmrg
109810d565efSmrg	ARM_FUNC_START udivsi3
109910d565efSmrg	ARM_FUNC_ALIAS aeabi_uidiv udivsi3
110010d565efSmrg
110110d565efSmrg	/* Note: if called via udivsi3_skip_div0_test, this will unnecessarily
110210d565efSmrg	   check for division-by-zero a second time.  */
110310d565efSmrgLSYM(udivsi3_skip_div0_test):
110410d565efSmrg	subs	r2, r1, #1
110510d565efSmrg	do_it	eq
110610d565efSmrg	RETc(eq)
110710d565efSmrg	bcc	LSYM(Ldiv0)
110810d565efSmrg	cmp	r0, r1
110910d565efSmrg	bls	11f
111010d565efSmrg	tst	r1, r2
111110d565efSmrg	beq	12f
111210d565efSmrg
111310d565efSmrg	ARM_DIV_BODY r0, r1, r2, r3
111410d565efSmrg
111510d565efSmrg	mov	r0, r2
111610d565efSmrg	RET
111710d565efSmrg
111810d565efSmrg11:	do_it	eq, e
111910d565efSmrg	moveq	r0, #1
112010d565efSmrg	movne	r0, #0
112110d565efSmrg	RET
112210d565efSmrg
112310d565efSmrg12:	ARM_DIV2_ORDER r1, r2
112410d565efSmrg
112510d565efSmrg	mov	r0, r0, lsr r2
112610d565efSmrg	RET
112710d565efSmrg
112810d565efSmrg#endif /* ARM version */
112910d565efSmrg
113010d565efSmrg	DIV_FUNC_END udivsi3 unsigned
113110d565efSmrg
113210d565efSmrg#if defined(__prefer_thumb__)
113310d565efSmrgFUNC_START aeabi_uidivmod
113410d565efSmrg	cmp	r1, #0
113510d565efSmrg	beq	LSYM(Ldiv0)
113610d565efSmrg# if defined(__OPTIMIZE_SIZE__)
113710d565efSmrg	push	{r0, r1, lr}
113810d565efSmrg	bl	LSYM(udivsi3_skip_div0_test)
113910d565efSmrg	POP	{r1, r2, r3}
1140*ec02198aSmrg	muls	r2, r0
1141*ec02198aSmrg	subs	r1, r1, r2
114210d565efSmrg	bx	r3
114310d565efSmrg# else
114410d565efSmrg	/* Both the quotient and remainder are calculated simultaneously
114510d565efSmrg	   in THUMB1_Div_Positive.  There is no need to calculate the
114610d565efSmrg	   remainder again here.  */
114710d565efSmrg	b	LSYM(udivsi3_skip_div0_test)
114810d565efSmrg	RET
114910d565efSmrg# endif /* __OPTIMIZE_SIZE__ */
115010d565efSmrg
115110d565efSmrg#elif defined(__ARM_ARCH_EXT_IDIV__)
115210d565efSmrgARM_FUNC_START aeabi_uidivmod
115310d565efSmrg	cmp	r1, #0
115410d565efSmrg	beq	LSYM(Ldiv0)
115510d565efSmrg	mov     r2, r0
115610d565efSmrg	udiv	r0, r0, r1
115710d565efSmrg	mls     r1, r0, r1, r2
115810d565efSmrg	RET
115910d565efSmrg#else
116010d565efSmrgARM_FUNC_START aeabi_uidivmod
116110d565efSmrg	cmp	r1, #0
116210d565efSmrg	beq	LSYM(Ldiv0)
116310d565efSmrg	stmfd	sp!, { r0, r1, lr }
116410d565efSmrg	bl	LSYM(udivsi3_skip_div0_test)
116510d565efSmrg	ldmfd	sp!, { r1, r2, lr }
116610d565efSmrg	mul	r3, r2, r0
116710d565efSmrg	sub	r1, r1, r3
116810d565efSmrg	RET
116910d565efSmrg#endif
117010d565efSmrg	FUNC_END aeabi_uidivmod
117110d565efSmrg
117210d565efSmrg#endif /* L_udivsi3 */
117310d565efSmrg/* ------------------------------------------------------------------------ */
117410d565efSmrg#ifdef L_umodsi3
117510d565efSmrg
117610d565efSmrg#if defined(__ARM_ARCH_EXT_IDIV__) && __ARM_ARCH_ISA_THUMB != 1
117710d565efSmrg
117810d565efSmrg	ARM_FUNC_START umodsi3
117910d565efSmrg
118010d565efSmrg	cmp	r1, #0
118110d565efSmrg	beq	LSYM(Ldiv0)
118210d565efSmrg	udiv	r2, r0, r1
118310d565efSmrg	mls     r0, r1, r2, r0
118410d565efSmrg	RET
118510d565efSmrg
118610d565efSmrg#elif defined(__thumb__)
118710d565efSmrg
118810d565efSmrg	FUNC_START umodsi3
118910d565efSmrg
119010d565efSmrg	cmp	divisor, #0
119110d565efSmrg	beq	LSYM(Ldiv0)
1192*ec02198aSmrg	movs	curbit, #1
119310d565efSmrg	cmp	dividend, divisor
119410d565efSmrg	bhs	LSYM(Lover10)
119510d565efSmrg	RET
119610d565efSmrg
119710d565efSmrgLSYM(Lover10):
119810d565efSmrg	push	{ work }
119910d565efSmrg
120010d565efSmrg	THUMB_DIV_MOD_BODY 1
120110d565efSmrg
120210d565efSmrg	pop	{ work }
120310d565efSmrg	RET
120410d565efSmrg
120510d565efSmrg#else  /* ARM version.  */
120610d565efSmrg
120710d565efSmrg	FUNC_START umodsi3
120810d565efSmrg
120910d565efSmrg	subs	r2, r1, #1			@ compare divisor with 1
121010d565efSmrg	bcc	LSYM(Ldiv0)
121110d565efSmrg	cmpne	r0, r1				@ compare dividend with divisor
121210d565efSmrg	moveq   r0, #0
121310d565efSmrg	tsthi	r1, r2				@ see if divisor is power of 2
121410d565efSmrg	andeq	r0, r0, r2
121510d565efSmrg	RETc(ls)
121610d565efSmrg
121710d565efSmrg	ARM_MOD_BODY r0, r1, r2, r3
121810d565efSmrg
121910d565efSmrg	RET
122010d565efSmrg
122110d565efSmrg#endif /* ARM version.  */
122210d565efSmrg
122310d565efSmrg	DIV_FUNC_END umodsi3 unsigned
122410d565efSmrg
122510d565efSmrg#endif /* L_umodsi3 */
122610d565efSmrg/* ------------------------------------------------------------------------ */
122710d565efSmrg#ifdef L_divsi3
122810d565efSmrg
122910d565efSmrg#if defined(__prefer_thumb__)
123010d565efSmrg
123110d565efSmrg	FUNC_START divsi3
123210d565efSmrg	FUNC_ALIAS aeabi_idiv divsi3
123310d565efSmrg#if defined(__OPTIMIZE_SIZE__)
123410d565efSmrg
123510d565efSmrg	cmp	divisor, #0
123610d565efSmrg	beq	LSYM(Ldiv0)
123710d565efSmrgLSYM(divsi3_skip_div0_test):
123810d565efSmrg	push	{ work }
1239*ec02198aSmrg	movs	work, dividend
1240*ec02198aSmrg	eors	work, divisor		@ Save the sign of the result.
124110d565efSmrg	mov	ip, work
1242*ec02198aSmrg	movs	curbit, #1
1243*ec02198aSmrg	movs	result, #0
124410d565efSmrg	cmp	divisor, #0
124510d565efSmrg	bpl	LSYM(Lover10)
1246*ec02198aSmrg	negs	divisor, divisor	@ Loops below use unsigned.
124710d565efSmrgLSYM(Lover10):
124810d565efSmrg	cmp	dividend, #0
124910d565efSmrg	bpl	LSYM(Lover11)
1250*ec02198aSmrg	negs	dividend, dividend
125110d565efSmrgLSYM(Lover11):
125210d565efSmrg	cmp	dividend, divisor
125310d565efSmrg	blo	LSYM(Lgot_result)
125410d565efSmrg
125510d565efSmrg	THUMB_DIV_MOD_BODY 0
125610d565efSmrg
1257*ec02198aSmrg	movs	r0, result
125810d565efSmrg	mov	work, ip
125910d565efSmrg	cmp	work, #0
126010d565efSmrg	bpl	LSYM(Lover12)
1261*ec02198aSmrg	negs	r0, r0
126210d565efSmrgLSYM(Lover12):
126310d565efSmrg	pop	{ work }
126410d565efSmrg	RET
126510d565efSmrg
126610d565efSmrg/* Implementation of aeabi_idiv for ARMv6m.  This version is only
126710d565efSmrg   used in ARMv6-M when we need an efficient implementation.  */
126810d565efSmrg#else
126910d565efSmrgLSYM(divsi3_skip_div0_test):
127010d565efSmrg	cpy	curbit, dividend
1271*ec02198aSmrg	orrs	curbit, divisor
127210d565efSmrg	bmi	LSYM(Lthumb1_div_negative)
127310d565efSmrg
127410d565efSmrgLSYM(Lthumb1_div_positive):
127510d565efSmrg	THUMB1_Div_Positive
127610d565efSmrg
127710d565efSmrgLSYM(Lthumb1_div_negative):
127810d565efSmrg	THUMB1_Div_Negative
127910d565efSmrg
128010d565efSmrg#endif /* __OPTIMIZE_SIZE__ */
128110d565efSmrg
128210d565efSmrg#elif defined(__ARM_ARCH_EXT_IDIV__)
128310d565efSmrg
128410d565efSmrg	ARM_FUNC_START divsi3
128510d565efSmrg	ARM_FUNC_ALIAS aeabi_idiv divsi3
128610d565efSmrg
128710d565efSmrg	cmp 	r1, #0
128810d565efSmrg	beq	LSYM(Ldiv0)
128910d565efSmrg	sdiv	r0, r0, r1
129010d565efSmrg	RET
129110d565efSmrg
129210d565efSmrg#else /* ARM/Thumb-2 version.  */
129310d565efSmrg
129410d565efSmrg	ARM_FUNC_START divsi3
129510d565efSmrg	ARM_FUNC_ALIAS aeabi_idiv divsi3
129610d565efSmrg
129710d565efSmrg	cmp	r1, #0
129810d565efSmrg	beq	LSYM(Ldiv0)
129910d565efSmrgLSYM(divsi3_skip_div0_test):
130010d565efSmrg	eor	ip, r0, r1			@ save the sign of the result.
130110d565efSmrg	do_it	mi
130210d565efSmrg	rsbmi	r1, r1, #0			@ loops below use unsigned.
130310d565efSmrg	subs	r2, r1, #1			@ division by 1 or -1 ?
130410d565efSmrg	beq	10f
130510d565efSmrg	movs	r3, r0
130610d565efSmrg	do_it	mi
130710d565efSmrg	rsbmi	r3, r0, #0			@ positive dividend value
130810d565efSmrg	cmp	r3, r1
130910d565efSmrg	bls	11f
131010d565efSmrg	tst	r1, r2				@ divisor is power of 2 ?
131110d565efSmrg	beq	12f
131210d565efSmrg
131310d565efSmrg	ARM_DIV_BODY r3, r1, r0, r2
131410d565efSmrg
131510d565efSmrg	cmp	ip, #0
131610d565efSmrg	do_it	mi
131710d565efSmrg	rsbmi	r0, r0, #0
131810d565efSmrg	RET
131910d565efSmrg
132010d565efSmrg10:	teq	ip, r0				@ same sign ?
132110d565efSmrg	do_it	mi
132210d565efSmrg	rsbmi	r0, r0, #0
132310d565efSmrg	RET
132410d565efSmrg
132510d565efSmrg11:	do_it	lo
132610d565efSmrg	movlo	r0, #0
132710d565efSmrg	do_it	eq,t
132810d565efSmrg	moveq	r0, ip, asr #31
132910d565efSmrg	orreq	r0, r0, #1
133010d565efSmrg	RET
133110d565efSmrg
133210d565efSmrg12:	ARM_DIV2_ORDER r1, r2
133310d565efSmrg
133410d565efSmrg	cmp	ip, #0
133510d565efSmrg	mov	r0, r3, lsr r2
133610d565efSmrg	do_it	mi
133710d565efSmrg	rsbmi	r0, r0, #0
133810d565efSmrg	RET
133910d565efSmrg
134010d565efSmrg#endif /* ARM version */
134110d565efSmrg
134210d565efSmrg	DIV_FUNC_END divsi3 signed
134310d565efSmrg
134410d565efSmrg#if defined(__prefer_thumb__)
134510d565efSmrgFUNC_START aeabi_idivmod
134610d565efSmrg	cmp	r1, #0
134710d565efSmrg	beq	LSYM(Ldiv0)
134810d565efSmrg# if defined(__OPTIMIZE_SIZE__)
134910d565efSmrg	push	{r0, r1, lr}
135010d565efSmrg	bl	LSYM(divsi3_skip_div0_test)
135110d565efSmrg	POP	{r1, r2, r3}
1352*ec02198aSmrg	muls	r2, r0
1353*ec02198aSmrg	subs	r1, r1, r2
135410d565efSmrg	bx	r3
135510d565efSmrg# else
135610d565efSmrg	/* Both the quotient and remainder are calculated simultaneously
135710d565efSmrg	   in THUMB1_Div_Positive and THUMB1_Div_Negative.  There is no
135810d565efSmrg	   need to calculate the remainder again here.  */
135910d565efSmrg	b	LSYM(divsi3_skip_div0_test)
136010d565efSmrg	RET
136110d565efSmrg# endif /* __OPTIMIZE_SIZE__ */
136210d565efSmrg
136310d565efSmrg#elif defined(__ARM_ARCH_EXT_IDIV__)
136410d565efSmrgARM_FUNC_START aeabi_idivmod
136510d565efSmrg	cmp 	r1, #0
136610d565efSmrg	beq	LSYM(Ldiv0)
136710d565efSmrg	mov     r2, r0
136810d565efSmrg	sdiv	r0, r0, r1
136910d565efSmrg	mls     r1, r0, r1, r2
137010d565efSmrg	RET
137110d565efSmrg#else
137210d565efSmrgARM_FUNC_START aeabi_idivmod
137310d565efSmrg	cmp	r1, #0
137410d565efSmrg	beq	LSYM(Ldiv0)
137510d565efSmrg	stmfd	sp!, { r0, r1, lr }
137610d565efSmrg	bl	LSYM(divsi3_skip_div0_test)
137710d565efSmrg	ldmfd	sp!, { r1, r2, lr }
137810d565efSmrg	mul	r3, r2, r0
137910d565efSmrg	sub	r1, r1, r3
138010d565efSmrg	RET
138110d565efSmrg#endif
138210d565efSmrg	FUNC_END aeabi_idivmod
138310d565efSmrg
138410d565efSmrg#endif /* L_divsi3 */
138510d565efSmrg/* ------------------------------------------------------------------------ */
138610d565efSmrg#ifdef L_modsi3
138710d565efSmrg
138810d565efSmrg#if defined(__ARM_ARCH_EXT_IDIV__) && __ARM_ARCH_ISA_THUMB != 1
138910d565efSmrg
139010d565efSmrg	ARM_FUNC_START modsi3
139110d565efSmrg
139210d565efSmrg	cmp	r1, #0
139310d565efSmrg	beq	LSYM(Ldiv0)
139410d565efSmrg
139510d565efSmrg	sdiv	r2, r0, r1
139610d565efSmrg	mls     r0, r1, r2, r0
139710d565efSmrg	RET
139810d565efSmrg
139910d565efSmrg#elif defined(__thumb__)
140010d565efSmrg
140110d565efSmrg	FUNC_START modsi3
140210d565efSmrg
1403*ec02198aSmrg	movs	curbit, #1
140410d565efSmrg	cmp	divisor, #0
140510d565efSmrg	beq	LSYM(Ldiv0)
140610d565efSmrg	bpl	LSYM(Lover10)
1407*ec02198aSmrg	negs	divisor, divisor		@ Loops below use unsigned.
140810d565efSmrgLSYM(Lover10):
140910d565efSmrg	push	{ work }
141010d565efSmrg	@ Need to save the sign of the dividend, unfortunately, we need
141110d565efSmrg	@ work later on.  Must do this after saving the original value of
141210d565efSmrg	@ the work register, because we will pop this value off first.
141310d565efSmrg	push	{ dividend }
141410d565efSmrg	cmp	dividend, #0
141510d565efSmrg	bpl	LSYM(Lover11)
1416*ec02198aSmrg	negs	dividend, dividend
141710d565efSmrgLSYM(Lover11):
141810d565efSmrg	cmp	dividend, divisor
141910d565efSmrg	blo	LSYM(Lgot_result)
142010d565efSmrg
142110d565efSmrg	THUMB_DIV_MOD_BODY 1
142210d565efSmrg
142310d565efSmrg	pop	{ work }
142410d565efSmrg	cmp	work, #0
142510d565efSmrg	bpl	LSYM(Lover12)
1426*ec02198aSmrg	negs	dividend, dividend
142710d565efSmrgLSYM(Lover12):
142810d565efSmrg	pop	{ work }
142910d565efSmrg	RET
143010d565efSmrg
143110d565efSmrg#else /* ARM version.  */
143210d565efSmrg
143310d565efSmrg	FUNC_START modsi3
143410d565efSmrg
143510d565efSmrg	cmp	r1, #0
143610d565efSmrg	beq	LSYM(Ldiv0)
143710d565efSmrg	rsbmi	r1, r1, #0			@ loops below use unsigned.
143810d565efSmrg	movs	ip, r0				@ preserve sign of dividend
143910d565efSmrg	rsbmi	r0, r0, #0			@ if negative make positive
144010d565efSmrg	subs	r2, r1, #1			@ compare divisor with 1
144110d565efSmrg	cmpne	r0, r1				@ compare dividend with divisor
144210d565efSmrg	moveq	r0, #0
144310d565efSmrg	tsthi	r1, r2				@ see if divisor is power of 2
144410d565efSmrg	andeq	r0, r0, r2
144510d565efSmrg	bls	10f
144610d565efSmrg
144710d565efSmrg	ARM_MOD_BODY r0, r1, r2, r3
144810d565efSmrg
144910d565efSmrg10:	cmp	ip, #0
145010d565efSmrg	rsbmi	r0, r0, #0
145110d565efSmrg	RET
145210d565efSmrg
145310d565efSmrg#endif /* ARM version */
145410d565efSmrg
145510d565efSmrg	DIV_FUNC_END modsi3 signed
145610d565efSmrg
145710d565efSmrg#endif /* L_modsi3 */
145810d565efSmrg/* ------------------------------------------------------------------------ */
145910d565efSmrg#ifdef L_dvmd_tls
146010d565efSmrg
146110d565efSmrg#ifdef __ARM_EABI__
146210d565efSmrg	WEAK aeabi_idiv0
146310d565efSmrg	WEAK aeabi_ldiv0
146410d565efSmrg	FUNC_START aeabi_idiv0
146510d565efSmrg	FUNC_START aeabi_ldiv0
146610d565efSmrg	RET
146710d565efSmrg	FUNC_END aeabi_ldiv0
146810d565efSmrg	FUNC_END aeabi_idiv0
146910d565efSmrg#else
147010d565efSmrg	FUNC_START div0
147110d565efSmrg	RET
147210d565efSmrg	FUNC_END div0
147310d565efSmrg#endif
147410d565efSmrg
147510d565efSmrg#endif /* L_divmodsi_tools */
147610d565efSmrg/* ------------------------------------------------------------------------ */
147710d565efSmrg#ifdef L_dvmd_lnx
147810d565efSmrg@ GNU/Linux division-by zero handler.  Used in place of L_dvmd_tls
147910d565efSmrg
148010d565efSmrg/* Constant taken from <asm/signal.h>.  */
148110d565efSmrg#define SIGFPE	8
148210d565efSmrg
148310d565efSmrg#ifdef __ARM_EABI__
148410d565efSmrg	cfi_start	__aeabi_ldiv0, LSYM(Lend_aeabi_ldiv0)
148510d565efSmrg	WEAK aeabi_idiv0
148610d565efSmrg	WEAK aeabi_ldiv0
148710d565efSmrg	ARM_FUNC_START aeabi_idiv0
148810d565efSmrg	ARM_FUNC_START aeabi_ldiv0
148910d565efSmrg	do_push	{r1, lr}
149010d565efSmrg98:	cfi_push 98b - __aeabi_ldiv0, 0xe, -0x4, 0x8
149110d565efSmrg#else
149210d565efSmrg	cfi_start	__div0, LSYM(Lend_div0)
149310d565efSmrg	ARM_FUNC_START div0
149410d565efSmrg	do_push	{r1, lr}
149510d565efSmrg98:	cfi_push 98b - __div0, 0xe, -0x4, 0x8
149610d565efSmrg#endif
149710d565efSmrg
149810d565efSmrg	mov	r0, #SIGFPE
149910d565efSmrg	bl	SYM(raise) __PLT__
150010d565efSmrg	RETLDM	r1 unwind=98b
150110d565efSmrg
150210d565efSmrg#ifdef __ARM_EABI__
150310d565efSmrg	cfi_end	LSYM(Lend_aeabi_ldiv0)
150410d565efSmrg	FUNC_END aeabi_ldiv0
150510d565efSmrg	FUNC_END aeabi_idiv0
150610d565efSmrg#else
150710d565efSmrg	cfi_end	LSYM(Lend_div0)
150810d565efSmrg	FUNC_END div0
150910d565efSmrg#endif
151010d565efSmrg
151110d565efSmrg#endif /* L_dvmd_lnx */
151210d565efSmrg#ifdef L_clear_cache
151310d565efSmrg#if defined __ARM_EABI__ && defined __linux__
151410d565efSmrg@ EABI GNU/Linux call to cacheflush syscall.
151510d565efSmrg	ARM_FUNC_START clear_cache
151610d565efSmrg	do_push	{r7}
15170fc04c29Smrg#if __ARM_ARCH >= 7 || defined(__ARM_ARCH_6T2__)
151810d565efSmrg	movw	r7, #2
151910d565efSmrg	movt	r7, #0xf
152010d565efSmrg#else
152110d565efSmrg	mov	r7, #0xf0000
152210d565efSmrg	add	r7, r7, #2
152310d565efSmrg#endif
152410d565efSmrg	mov	r2, #0
152510d565efSmrg	swi	0
152610d565efSmrg	do_pop	{r7}
152710d565efSmrg	RET
152810d565efSmrg	FUNC_END clear_cache
152910d565efSmrg#else
153010d565efSmrg#error "This is only for ARM EABI GNU/Linux"
153110d565efSmrg#endif
153210d565efSmrg#endif /* L_clear_cache */
15330fc04c29Smrg
15340fc04c29Smrg#ifdef L_speculation_barrier
15350fc04c29Smrg	FUNC_START speculation_barrier
15360fc04c29Smrg#if __ARM_ARCH >= 7
15370fc04c29Smrg	isb
15380fc04c29Smrg	dsb sy
15390fc04c29Smrg#elif defined __ARM_EABI__ && defined __linux__
15400fc04c29Smrg	/* We don't have a speculation barrier directly for this
15410fc04c29Smrg	   platform/architecture variant.  But we can use a kernel
15420fc04c29Smrg	   clear_cache service routine which will emit such instructions
15430fc04c29Smrg	   if run on a later version of the architecture.  We don't
15440fc04c29Smrg	   really want to flush the cache, but we must give it a valid
15450fc04c29Smrg	   address, so just clear pc..pc+1.  */
15460fc04c29Smrg#if defined __thumb__ && !defined __thumb2__
15470fc04c29Smrg	push	{r7}
1548*ec02198aSmrg	movs	r7, #0xf
1549*ec02198aSmrg	lsls	r7, #16
1550*ec02198aSmrg	adds	r7, #2
15510fc04c29Smrg	adr	r0, . + 4
1552*ec02198aSmrg	adds	r1, r0, #1
1553*ec02198aSmrg	movs	r2, #0
15540fc04c29Smrg	svc	0
15550fc04c29Smrg	pop	{r7}
15560fc04c29Smrg#else
15570fc04c29Smrg	do_push	{r7}
15580fc04c29Smrg#ifdef __ARM_ARCH_6T2__
15590fc04c29Smrg	movw	r7, #2
15600fc04c29Smrg	movt	r7, #0xf
15610fc04c29Smrg#else
15620fc04c29Smrg	mov	r7, #0xf0000
15630fc04c29Smrg	add	r7, r7, #2
15640fc04c29Smrg#endif
15650fc04c29Smrg	add	r0, pc, #0	/* ADR.  */
15660fc04c29Smrg	add	r1, r0, #1
15670fc04c29Smrg	mov	r2, #0
15680fc04c29Smrg	svc	0
15690fc04c29Smrg	do_pop	{r7}
15700fc04c29Smrg#endif /* Thumb1 only */
15710fc04c29Smrg#else
15720fc04c29Smrg#warning "No speculation barrier defined for this platform"
15730fc04c29Smrg#endif
15740fc04c29Smrg	RET
15750fc04c29Smrg	FUNC_END speculation_barrier
15760fc04c29Smrg#endif
157710d565efSmrg/* ------------------------------------------------------------------------ */
157810d565efSmrg/* Dword shift operations.  */
157910d565efSmrg/* All the following Dword shift variants rely on the fact that
158010d565efSmrg	shft xxx, Reg
158110d565efSmrg   is in fact done as
158210d565efSmrg	shft xxx, (Reg & 255)
158310d565efSmrg   so for Reg value in (32...63) and (-1...-31) we will get zero (in the
158410d565efSmrg   case of logical shifts) or the sign (for asr).  */
158510d565efSmrg
158610d565efSmrg#ifdef __ARMEB__
158710d565efSmrg#define al	r1
158810d565efSmrg#define ah	r0
158910d565efSmrg#else
159010d565efSmrg#define al	r0
159110d565efSmrg#define ah	r1
159210d565efSmrg#endif
159310d565efSmrg
159410d565efSmrg/* Prevent __aeabi double-word shifts from being produced on SymbianOS.  */
159510d565efSmrg#ifndef __symbian__
159610d565efSmrg
159710d565efSmrg#ifdef L_lshrdi3
159810d565efSmrg
159910d565efSmrg	FUNC_START lshrdi3
160010d565efSmrg	FUNC_ALIAS aeabi_llsr lshrdi3
160110d565efSmrg
160210d565efSmrg#ifdef __thumb__
1603*ec02198aSmrg	lsrs	al, r2
1604*ec02198aSmrg	movs	r3, ah
1605*ec02198aSmrg	lsrs	ah, r2
160610d565efSmrg	mov	ip, r3
1607*ec02198aSmrg	subs	r2, #32
1608*ec02198aSmrg	lsrs	r3, r2
1609*ec02198aSmrg	orrs	al, r3
1610*ec02198aSmrg	negs	r2, r2
161110d565efSmrg	mov	r3, ip
1612*ec02198aSmrg	lsls	r3, r2
1613*ec02198aSmrg	orrs	al, r3
161410d565efSmrg	RET
161510d565efSmrg#else
161610d565efSmrg	subs	r3, r2, #32
161710d565efSmrg	rsb	ip, r2, #32
161810d565efSmrg	movmi	al, al, lsr r2
161910d565efSmrg	movpl	al, ah, lsr r3
162010d565efSmrg	orrmi	al, al, ah, lsl ip
162110d565efSmrg	mov	ah, ah, lsr r2
162210d565efSmrg	RET
162310d565efSmrg#endif
162410d565efSmrg	FUNC_END aeabi_llsr
162510d565efSmrg	FUNC_END lshrdi3
162610d565efSmrg
162710d565efSmrg#endif
162810d565efSmrg
162910d565efSmrg#ifdef L_ashrdi3
163010d565efSmrg
163110d565efSmrg	FUNC_START ashrdi3
163210d565efSmrg	FUNC_ALIAS aeabi_lasr ashrdi3
163310d565efSmrg
163410d565efSmrg#ifdef __thumb__
1635*ec02198aSmrg	lsrs	al, r2
1636*ec02198aSmrg	movs	r3, ah
1637*ec02198aSmrg	asrs	ah, r2
1638*ec02198aSmrg	subs	r2, #32
163910d565efSmrg	@ If r2 is negative at this point the following step would OR
164010d565efSmrg	@ the sign bit into all of AL.  That's not what we want...
164110d565efSmrg	bmi	1f
164210d565efSmrg	mov	ip, r3
1643*ec02198aSmrg	asrs	r3, r2
1644*ec02198aSmrg	orrs	al, r3
164510d565efSmrg	mov	r3, ip
164610d565efSmrg1:
1647*ec02198aSmrg	negs	r2, r2
1648*ec02198aSmrg	lsls	r3, r2
1649*ec02198aSmrg	orrs	al, r3
165010d565efSmrg	RET
165110d565efSmrg#else
165210d565efSmrg	subs	r3, r2, #32
165310d565efSmrg	rsb	ip, r2, #32
165410d565efSmrg	movmi	al, al, lsr r2
165510d565efSmrg	movpl	al, ah, asr r3
165610d565efSmrg	orrmi	al, al, ah, lsl ip
165710d565efSmrg	mov	ah, ah, asr r2
165810d565efSmrg	RET
165910d565efSmrg#endif
166010d565efSmrg
166110d565efSmrg	FUNC_END aeabi_lasr
166210d565efSmrg	FUNC_END ashrdi3
166310d565efSmrg
166410d565efSmrg#endif
166510d565efSmrg
166610d565efSmrg#ifdef L_ashldi3
166710d565efSmrg
166810d565efSmrg	FUNC_START ashldi3
166910d565efSmrg	FUNC_ALIAS aeabi_llsl ashldi3
167010d565efSmrg
167110d565efSmrg#ifdef __thumb__
1672*ec02198aSmrg	lsls	ah, r2
1673*ec02198aSmrg	movs	r3, al
1674*ec02198aSmrg	lsls	al, r2
167510d565efSmrg	mov	ip, r3
1676*ec02198aSmrg	subs	r2, #32
1677*ec02198aSmrg	lsls	r3, r2
1678*ec02198aSmrg	orrs	ah, r3
1679*ec02198aSmrg	negs	r2, r2
168010d565efSmrg	mov	r3, ip
1681*ec02198aSmrg	lsrs	r3, r2
1682*ec02198aSmrg	orrs	ah, r3
168310d565efSmrg	RET
168410d565efSmrg#else
168510d565efSmrg	subs	r3, r2, #32
168610d565efSmrg	rsb	ip, r2, #32
168710d565efSmrg	movmi	ah, ah, lsl r2
168810d565efSmrg	movpl	ah, al, lsl r3
168910d565efSmrg	orrmi	ah, ah, al, lsr ip
169010d565efSmrg	mov	al, al, lsl r2
169110d565efSmrg	RET
169210d565efSmrg#endif
169310d565efSmrg	FUNC_END aeabi_llsl
169410d565efSmrg	FUNC_END ashldi3
169510d565efSmrg
169610d565efSmrg#endif
169710d565efSmrg
169810d565efSmrg#endif /* __symbian__ */
169910d565efSmrg
170010d565efSmrg#ifdef L_clzsi2
170110d565efSmrg#ifdef NOT_ISA_TARGET_32BIT
170210d565efSmrgFUNC_START clzsi2
1703*ec02198aSmrg	movs	r1, #28
1704*ec02198aSmrg	movs	r3, #1
1705*ec02198aSmrg	lsls	r3, r3, #16
170610d565efSmrg	cmp	r0, r3 /* 0x10000 */
170710d565efSmrg	bcc	2f
1708*ec02198aSmrg	lsrs	r0, r0, #16
1709*ec02198aSmrg	subs	r1, r1, #16
1710*ec02198aSmrg2:	lsrs	r3, r3, #8
171110d565efSmrg	cmp	r0, r3 /* #0x100 */
171210d565efSmrg	bcc	2f
1713*ec02198aSmrg	lsrs	r0, r0, #8
1714*ec02198aSmrg	subs	r1, r1, #8
1715*ec02198aSmrg2:	lsrs	r3, r3, #4
171610d565efSmrg	cmp	r0, r3 /* #0x10 */
171710d565efSmrg	bcc	2f
1718*ec02198aSmrg	lsrs	r0, r0, #4
1719*ec02198aSmrg	subs	r1, r1, #4
172010d565efSmrg2:	adr	r2, 1f
172110d565efSmrg	ldrb	r0, [r2, r0]
1722*ec02198aSmrg	adds	r0, r0, r1
172310d565efSmrg	bx lr
172410d565efSmrg.align 2
172510d565efSmrg1:
172610d565efSmrg.byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
172710d565efSmrg	FUNC_END clzsi2
172810d565efSmrg#else
172910d565efSmrgARM_FUNC_START clzsi2
17300fc04c29Smrg# if defined (__ARM_FEATURE_CLZ)
173110d565efSmrg	clz	r0, r0
173210d565efSmrg	RET
173310d565efSmrg# else
173410d565efSmrg	mov	r1, #28
173510d565efSmrg	cmp	r0, #0x10000
173610d565efSmrg	do_it	cs, t
173710d565efSmrg	movcs	r0, r0, lsr #16
173810d565efSmrg	subcs	r1, r1, #16
173910d565efSmrg	cmp	r0, #0x100
174010d565efSmrg	do_it	cs, t
174110d565efSmrg	movcs	r0, r0, lsr #8
174210d565efSmrg	subcs	r1, r1, #8
174310d565efSmrg	cmp	r0, #0x10
174410d565efSmrg	do_it	cs, t
174510d565efSmrg	movcs	r0, r0, lsr #4
174610d565efSmrg	subcs	r1, r1, #4
174710d565efSmrg	adr	r2, 1f
174810d565efSmrg	ldrb	r0, [r2, r0]
174910d565efSmrg	add	r0, r0, r1
175010d565efSmrg	RET
175110d565efSmrg.align 2
175210d565efSmrg1:
175310d565efSmrg.byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
17540fc04c29Smrg# endif /* !defined (__ARM_FEATURE_CLZ) */
175510d565efSmrg	FUNC_END clzsi2
175610d565efSmrg#endif
175710d565efSmrg#endif /* L_clzsi2 */
175810d565efSmrg
175910d565efSmrg#ifdef L_clzdi2
17600fc04c29Smrg#if !defined (__ARM_FEATURE_CLZ)
176110d565efSmrg
176210d565efSmrg# ifdef NOT_ISA_TARGET_32BIT
176310d565efSmrgFUNC_START clzdi2
176410d565efSmrg	push	{r4, lr}
1765*ec02198aSmrg	cmp	xxh, #0
1766*ec02198aSmrg	bne	1f
1767*ec02198aSmrg#  ifdef __ARMEB__
1768*ec02198aSmrg	movs	r0, xxl
1769*ec02198aSmrg	bl	__clzsi2
1770*ec02198aSmrg	adds	r0, r0, #32
1771*ec02198aSmrg	b 2f
1772*ec02198aSmrg1:
1773*ec02198aSmrg	bl	__clzsi2
177410d565efSmrg#  else
1775*ec02198aSmrg	bl	__clzsi2
1776*ec02198aSmrg	adds	r0, r0, #32
1777*ec02198aSmrg	b 2f
1778*ec02198aSmrg1:
1779*ec02198aSmrg	movs	r0, xxh
1780*ec02198aSmrg	bl	__clzsi2
1781*ec02198aSmrg#  endif
1782*ec02198aSmrg2:
1783*ec02198aSmrg	pop	{r4, pc}
1784*ec02198aSmrg# else /* NOT_ISA_TARGET_32BIT */
178510d565efSmrgARM_FUNC_START clzdi2
178610d565efSmrg	do_push	{r4, lr}
178710d565efSmrg	cmp	xxh, #0
178810d565efSmrg	bne	1f
178910d565efSmrg#  ifdef __ARMEB__
179010d565efSmrg	mov	r0, xxl
179110d565efSmrg	bl	__clzsi2
179210d565efSmrg	add	r0, r0, #32
179310d565efSmrg	b 2f
179410d565efSmrg1:
179510d565efSmrg	bl	__clzsi2
179610d565efSmrg#  else
179710d565efSmrg	bl	__clzsi2
179810d565efSmrg	add	r0, r0, #32
179910d565efSmrg	b 2f
180010d565efSmrg1:
180110d565efSmrg	mov	r0, xxh
180210d565efSmrg	bl	__clzsi2
180310d565efSmrg#  endif
180410d565efSmrg2:
180510d565efSmrg	RETLDM	r4
180610d565efSmrg	FUNC_END clzdi2
1807*ec02198aSmrg# endif /* NOT_ISA_TARGET_32BIT */
180810d565efSmrg
18090fc04c29Smrg#else /* defined (__ARM_FEATURE_CLZ) */
181010d565efSmrg
181110d565efSmrgARM_FUNC_START clzdi2
181210d565efSmrg	cmp	xxh, #0
181310d565efSmrg	do_it	eq, et
181410d565efSmrg	clzeq	r0, xxl
181510d565efSmrg	clzne	r0, xxh
181610d565efSmrg	addeq	r0, r0, #32
181710d565efSmrg	RET
181810d565efSmrg	FUNC_END clzdi2
181910d565efSmrg
182010d565efSmrg#endif
182110d565efSmrg#endif /* L_clzdi2 */
182210d565efSmrg
182310d565efSmrg#ifdef L_ctzsi2
182410d565efSmrg#ifdef NOT_ISA_TARGET_32BIT
182510d565efSmrgFUNC_START ctzsi2
1826*ec02198aSmrg	negs	r1, r0
1827*ec02198aSmrg	ands	r0, r0, r1
1828*ec02198aSmrg	movs	r1, #28
1829*ec02198aSmrg	movs	r3, #1
1830*ec02198aSmrg	lsls	r3, r3, #16
183110d565efSmrg	cmp	r0, r3 /* 0x10000 */
183210d565efSmrg	bcc	2f
1833*ec02198aSmrg	lsrs	r0, r0, #16
1834*ec02198aSmrg	subs	r1, r1, #16
1835*ec02198aSmrg2:	lsrs	r3, r3, #8
183610d565efSmrg	cmp	r0, r3 /* #0x100 */
183710d565efSmrg	bcc	2f
1838*ec02198aSmrg	lsrs	r0, r0, #8
1839*ec02198aSmrg	subs	r1, r1, #8
1840*ec02198aSmrg2:	lsrs	r3, r3, #4
184110d565efSmrg	cmp	r0, r3 /* #0x10 */
184210d565efSmrg	bcc	2f
1843*ec02198aSmrg	lsrs	r0, r0, #4
1844*ec02198aSmrg	subs	r1, r1, #4
184510d565efSmrg2:	adr	r2, 1f
184610d565efSmrg	ldrb	r0, [r2, r0]
1847*ec02198aSmrg	subs	r0, r0, r1
184810d565efSmrg	bx lr
184910d565efSmrg.align 2
185010d565efSmrg1:
185110d565efSmrg.byte	27, 28, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31
185210d565efSmrg	FUNC_END ctzsi2
185310d565efSmrg#else
185410d565efSmrgARM_FUNC_START ctzsi2
185510d565efSmrg	rsb	r1, r0, #0
185610d565efSmrg	and	r0, r0, r1
18570fc04c29Smrg# if defined (__ARM_FEATURE_CLZ)
185810d565efSmrg	clz	r0, r0
185910d565efSmrg	rsb	r0, r0, #31
186010d565efSmrg	RET
186110d565efSmrg# else
186210d565efSmrg	mov	r1, #28
186310d565efSmrg	cmp	r0, #0x10000
186410d565efSmrg	do_it	cs, t
186510d565efSmrg	movcs	r0, r0, lsr #16
186610d565efSmrg	subcs	r1, r1, #16
186710d565efSmrg	cmp	r0, #0x100
186810d565efSmrg	do_it	cs, t
186910d565efSmrg	movcs	r0, r0, lsr #8
187010d565efSmrg	subcs	r1, r1, #8
187110d565efSmrg	cmp	r0, #0x10
187210d565efSmrg	do_it	cs, t
187310d565efSmrg	movcs	r0, r0, lsr #4
187410d565efSmrg	subcs	r1, r1, #4
187510d565efSmrg	adr	r2, 1f
187610d565efSmrg	ldrb	r0, [r2, r0]
187710d565efSmrg	sub	r0, r0, r1
187810d565efSmrg	RET
187910d565efSmrg.align 2
188010d565efSmrg1:
188110d565efSmrg.byte	27, 28, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31
18820fc04c29Smrg# endif /* !defined (__ARM_FEATURE_CLZ) */
188310d565efSmrg	FUNC_END ctzsi2
188410d565efSmrg#endif
188510d565efSmrg#endif /* L_clzsi2 */
188610d565efSmrg
188710d565efSmrg/* ------------------------------------------------------------------------ */
188810d565efSmrg/* These next two sections are here despite the fact that they contain Thumb
188910d565efSmrg   assembler because their presence allows interworked code to be linked even
189010d565efSmrg   when the GCC library is this one.  */
189110d565efSmrg
189210d565efSmrg/* Do not build the interworking functions when the target architecture does
189310d565efSmrg   not support Thumb instructions.  (This can be a multilib option).  */
189410d565efSmrg#if defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__\
189510d565efSmrg      || defined __ARM_ARCH_5TE__ || defined __ARM_ARCH_5TEJ__ \
18960fc04c29Smrg      || __ARM_ARCH >= 6
189710d565efSmrg
189810d565efSmrg#if defined L_call_via_rX
189910d565efSmrg
190010d565efSmrg/* These labels & instructions are used by the Arm/Thumb interworking code.
190110d565efSmrg   The address of function to be called is loaded into a register and then
190210d565efSmrg   one of these labels is called via a BL instruction.  This puts the
190310d565efSmrg   return address into the link register with the bottom bit set, and the
190410d565efSmrg   code here switches to the correct mode before executing the function.  */
190510d565efSmrg
190610d565efSmrg	.text
190710d565efSmrg	.align 0
190810d565efSmrg        .force_thumb
190910d565efSmrg
191010d565efSmrg.macro call_via register
191110d565efSmrg	THUMB_FUNC_START _call_via_\register
191210d565efSmrg
191310d565efSmrg	bx	\register
191410d565efSmrg	nop
191510d565efSmrg
191610d565efSmrg	SIZE	(_call_via_\register)
191710d565efSmrg.endm
191810d565efSmrg
191910d565efSmrg	call_via r0
192010d565efSmrg	call_via r1
192110d565efSmrg	call_via r2
192210d565efSmrg	call_via r3
192310d565efSmrg	call_via r4
192410d565efSmrg	call_via r5
192510d565efSmrg	call_via r6
192610d565efSmrg	call_via r7
192710d565efSmrg	call_via r8
192810d565efSmrg	call_via r9
192910d565efSmrg	call_via sl
193010d565efSmrg	call_via fp
193110d565efSmrg	call_via ip
193210d565efSmrg	call_via sp
193310d565efSmrg	call_via lr
193410d565efSmrg
193510d565efSmrg#endif /* L_call_via_rX */
193610d565efSmrg
193710d565efSmrg/* Don't bother with the old interworking routines for Thumb-2.  */
193810d565efSmrg/* ??? Maybe only omit these on "m" variants.  */
193910d565efSmrg#if !defined(__thumb2__) && __ARM_ARCH_ISA_ARM
194010d565efSmrg
194110d565efSmrg#if defined L_interwork_call_via_rX
194210d565efSmrg
194310d565efSmrg/* These labels & instructions are used by the Arm/Thumb interworking code,
194410d565efSmrg   when the target address is in an unknown instruction set.  The address
194510d565efSmrg   of function to be called is loaded into a register and then one of these
194610d565efSmrg   labels is called via a BL instruction.  This puts the return address
194710d565efSmrg   into the link register with the bottom bit set, and the code here
194810d565efSmrg   switches to the correct mode before executing the function.  Unfortunately
194910d565efSmrg   the target code cannot be relied upon to return via a BX instruction, so
195010d565efSmrg   instead we have to store the resturn address on the stack and allow the
195110d565efSmrg   called function to return here instead.  Upon return we recover the real
195210d565efSmrg   return address and use a BX to get back to Thumb mode.
195310d565efSmrg
195410d565efSmrg   There are three variations of this code.  The first,
195510d565efSmrg   _interwork_call_via_rN(), will push the return address onto the
195610d565efSmrg   stack and pop it in _arm_return().  It should only be used if all
195710d565efSmrg   arguments are passed in registers.
195810d565efSmrg
195910d565efSmrg   The second, _interwork_r7_call_via_rN(), instead stores the return
196010d565efSmrg   address at [r7, #-4].  It is the caller's responsibility to ensure
196110d565efSmrg   that this address is valid and contains no useful data.
196210d565efSmrg
196310d565efSmrg   The third, _interwork_r11_call_via_rN(), works in the same way but
196410d565efSmrg   uses r11 instead of r7.  It is useful if the caller does not really
196510d565efSmrg   need a frame pointer.  */
196610d565efSmrg
196710d565efSmrg	.text
196810d565efSmrg	.align 0
196910d565efSmrg
197010d565efSmrg	.code   32
197110d565efSmrg	.globl _arm_return
197210d565efSmrgLSYM(Lstart_arm_return):
197310d565efSmrg	cfi_start	LSYM(Lstart_arm_return) LSYM(Lend_arm_return)
197410d565efSmrg	cfi_push	0, 0xe, -0x8, 0x8
197510d565efSmrg	nop	@ This nop is for the benefit of debuggers, so that
197610d565efSmrg		@ backtraces will use the correct unwind information.
197710d565efSmrg_arm_return:
197810d565efSmrg	RETLDM	unwind=LSYM(Lstart_arm_return)
197910d565efSmrg	cfi_end	LSYM(Lend_arm_return)
198010d565efSmrg
198110d565efSmrg	.globl _arm_return_r7
198210d565efSmrg_arm_return_r7:
198310d565efSmrg	ldr	lr, [r7, #-4]
198410d565efSmrg	bx	lr
198510d565efSmrg
198610d565efSmrg	.globl _arm_return_r11
198710d565efSmrg_arm_return_r11:
198810d565efSmrg	ldr	lr, [r11, #-4]
198910d565efSmrg	bx	lr
199010d565efSmrg
199110d565efSmrg.macro interwork_with_frame frame, register, name, return
199210d565efSmrg	.code	16
199310d565efSmrg
199410d565efSmrg	THUMB_FUNC_START \name
199510d565efSmrg
199610d565efSmrg	bx	pc
199710d565efSmrg	nop
199810d565efSmrg
199910d565efSmrg	.code	32
200010d565efSmrg	tst	\register, #1
200110d565efSmrg	streq	lr, [\frame, #-4]
200210d565efSmrg	adreq	lr, _arm_return_\frame
200310d565efSmrg	bx	\register
200410d565efSmrg
200510d565efSmrg	SIZE	(\name)
200610d565efSmrg.endm
200710d565efSmrg
200810d565efSmrg.macro interwork register
200910d565efSmrg	.code	16
201010d565efSmrg
201110d565efSmrg	THUMB_FUNC_START _interwork_call_via_\register
201210d565efSmrg
201310d565efSmrg	bx	pc
201410d565efSmrg	nop
201510d565efSmrg
201610d565efSmrg	.code	32
201710d565efSmrg	.globl LSYM(Lchange_\register)
201810d565efSmrgLSYM(Lchange_\register):
201910d565efSmrg	tst	\register, #1
202010d565efSmrg	streq	lr, [sp, #-8]!
202110d565efSmrg	adreq	lr, _arm_return
202210d565efSmrg	bx	\register
202310d565efSmrg
202410d565efSmrg	SIZE	(_interwork_call_via_\register)
202510d565efSmrg
202610d565efSmrg	interwork_with_frame r7,\register,_interwork_r7_call_via_\register
202710d565efSmrg	interwork_with_frame r11,\register,_interwork_r11_call_via_\register
202810d565efSmrg.endm
202910d565efSmrg
203010d565efSmrg	interwork r0
203110d565efSmrg	interwork r1
203210d565efSmrg	interwork r2
203310d565efSmrg	interwork r3
203410d565efSmrg	interwork r4
203510d565efSmrg	interwork r5
203610d565efSmrg	interwork r6
203710d565efSmrg	interwork r7
203810d565efSmrg	interwork r8
203910d565efSmrg	interwork r9
204010d565efSmrg	interwork sl
204110d565efSmrg	interwork fp
204210d565efSmrg	interwork ip
204310d565efSmrg	interwork sp
204410d565efSmrg
204510d565efSmrg	/* The LR case has to be handled a little differently...  */
204610d565efSmrg	.code 16
204710d565efSmrg
204810d565efSmrg	THUMB_FUNC_START _interwork_call_via_lr
204910d565efSmrg
205010d565efSmrg	bx 	pc
205110d565efSmrg	nop
205210d565efSmrg
205310d565efSmrg	.code 32
205410d565efSmrg	.globl .Lchange_lr
205510d565efSmrg.Lchange_lr:
205610d565efSmrg	tst	lr, #1
205710d565efSmrg	stmeqdb	r13!, {lr, pc}
205810d565efSmrg	mov	ip, lr
205910d565efSmrg	adreq	lr, _arm_return
206010d565efSmrg	bx	ip
206110d565efSmrg
206210d565efSmrg	SIZE	(_interwork_call_via_lr)
206310d565efSmrg
206410d565efSmrg#endif /* L_interwork_call_via_rX */
206510d565efSmrg#endif /* !__thumb2__ */
206610d565efSmrg
206710d565efSmrg/* Functions to support compact pic switch tables in thumb1 state.
206810d565efSmrg   All these routines take an index into the table in r0.  The
206910d565efSmrg   table is at LR & ~1 (but this must be rounded up in the case
207010d565efSmrg   of 32-bit entires).  They are only permitted to clobber r12
207110d565efSmrg   and r14 and r0 must be preserved on exit.  */
207210d565efSmrg#ifdef L_thumb1_case_sqi
207310d565efSmrg
207410d565efSmrg	.text
207510d565efSmrg	.align 0
207610d565efSmrg        .force_thumb
207710d565efSmrg	.syntax unified
207810d565efSmrg	THUMB_FUNC_START __gnu_thumb1_case_sqi
207910d565efSmrg	push	{r1}
208010d565efSmrg	mov	r1, lr
208110d565efSmrg	lsrs	r1, r1, #1
208210d565efSmrg	lsls	r1, r1, #1
208310d565efSmrg	ldrsb	r1, [r1, r0]
208410d565efSmrg	lsls	r1, r1, #1
208510d565efSmrg	add	lr, lr, r1
208610d565efSmrg	pop	{r1}
208710d565efSmrg	bx	lr
208810d565efSmrg	SIZE (__gnu_thumb1_case_sqi)
208910d565efSmrg#endif
209010d565efSmrg
209110d565efSmrg#ifdef L_thumb1_case_uqi
209210d565efSmrg
209310d565efSmrg	.text
209410d565efSmrg	.align 0
209510d565efSmrg        .force_thumb
209610d565efSmrg	.syntax unified
209710d565efSmrg	THUMB_FUNC_START __gnu_thumb1_case_uqi
209810d565efSmrg	push	{r1}
209910d565efSmrg	mov	r1, lr
210010d565efSmrg	lsrs	r1, r1, #1
210110d565efSmrg	lsls	r1, r1, #1
210210d565efSmrg	ldrb	r1, [r1, r0]
210310d565efSmrg	lsls	r1, r1, #1
210410d565efSmrg	add	lr, lr, r1
210510d565efSmrg	pop	{r1}
210610d565efSmrg	bx	lr
210710d565efSmrg	SIZE (__gnu_thumb1_case_uqi)
210810d565efSmrg#endif
210910d565efSmrg
211010d565efSmrg#ifdef L_thumb1_case_shi
211110d565efSmrg
211210d565efSmrg	.text
211310d565efSmrg	.align 0
211410d565efSmrg        .force_thumb
211510d565efSmrg	.syntax unified
211610d565efSmrg	THUMB_FUNC_START __gnu_thumb1_case_shi
211710d565efSmrg	push	{r0, r1}
211810d565efSmrg	mov	r1, lr
211910d565efSmrg	lsrs	r1, r1, #1
212010d565efSmrg	lsls	r0, r0, #1
212110d565efSmrg	lsls	r1, r1, #1
212210d565efSmrg	ldrsh	r1, [r1, r0]
212310d565efSmrg	lsls	r1, r1, #1
212410d565efSmrg	add	lr, lr, r1
212510d565efSmrg	pop	{r0, r1}
212610d565efSmrg	bx	lr
212710d565efSmrg	SIZE (__gnu_thumb1_case_shi)
212810d565efSmrg#endif
212910d565efSmrg
213010d565efSmrg#ifdef L_thumb1_case_uhi
213110d565efSmrg
213210d565efSmrg	.text
213310d565efSmrg	.align 0
213410d565efSmrg        .force_thumb
213510d565efSmrg	.syntax unified
213610d565efSmrg	THUMB_FUNC_START __gnu_thumb1_case_uhi
213710d565efSmrg	push	{r0, r1}
213810d565efSmrg	mov	r1, lr
213910d565efSmrg	lsrs	r1, r1, #1
214010d565efSmrg	lsls	r0, r0, #1
214110d565efSmrg	lsls	r1, r1, #1
214210d565efSmrg	ldrh	r1, [r1, r0]
214310d565efSmrg	lsls	r1, r1, #1
214410d565efSmrg	add	lr, lr, r1
214510d565efSmrg	pop	{r0, r1}
214610d565efSmrg	bx	lr
214710d565efSmrg	SIZE (__gnu_thumb1_case_uhi)
214810d565efSmrg#endif
214910d565efSmrg
215010d565efSmrg#ifdef L_thumb1_case_si
215110d565efSmrg
215210d565efSmrg	.text
215310d565efSmrg	.align 0
215410d565efSmrg        .force_thumb
215510d565efSmrg	.syntax unified
215610d565efSmrg	THUMB_FUNC_START __gnu_thumb1_case_si
215710d565efSmrg	push	{r0, r1}
215810d565efSmrg	mov	r1, lr
215910d565efSmrg	adds.n	r1, r1, #2	/* Align to word.  */
216010d565efSmrg	lsrs	r1, r1, #2
216110d565efSmrg	lsls	r0, r0, #2
216210d565efSmrg	lsls	r1, r1, #2
216310d565efSmrg	ldr	r0, [r1, r0]
216410d565efSmrg	adds	r0, r0, r1
216510d565efSmrg	mov	lr, r0
216610d565efSmrg	pop	{r0, r1}
216710d565efSmrg	mov	pc, lr		/* We know we were called from thumb code.  */
216810d565efSmrg	SIZE (__gnu_thumb1_case_si)
216910d565efSmrg#endif
217010d565efSmrg
217110d565efSmrg#endif /* Arch supports thumb.  */
217210d565efSmrg
217310d565efSmrg.macro CFI_START_FUNCTION
217410d565efSmrg	.cfi_startproc
217510d565efSmrg	.cfi_remember_state
217610d565efSmrg.endm
217710d565efSmrg
217810d565efSmrg.macro CFI_END_FUNCTION
217910d565efSmrg	.cfi_restore_state
218010d565efSmrg	.cfi_endproc
218110d565efSmrg.endm
218210d565efSmrg
218310d565efSmrg#ifndef __symbian__
21840fc04c29Smrg/* The condition here must match the one in gcc/config/arm/elf.h and
21850fc04c29Smrg   libgcc/config/arm/t-elf.  */
218610d565efSmrg#ifndef NOT_ISA_TARGET_32BIT
218710d565efSmrg#include "ieee754-df.S"
218810d565efSmrg#include "ieee754-sf.S"
218910d565efSmrg#include "bpabi.S"
219010d565efSmrg#else /* NOT_ISA_TARGET_32BIT */
219110d565efSmrg#include "bpabi-v6m.S"
219210d565efSmrg#endif /* NOT_ISA_TARGET_32BIT */
219310d565efSmrg#endif /* !__symbian__ */
2194