Home | History | Annotate | Line # | Download | only in arm
      1   1.1.1.5  mrg /* Miscellaneous BPABI functions.  Thumb-1 implementation, suitable for ARMv4T,
      2   1.1.1.5  mrg    ARMv6-M and ARMv8-M Baseline like ISA variants.
      3       1.1  mrg 
      4  1.1.1.12  mrg    Copyright (C) 2006-2024 Free Software Foundation, Inc.
      5       1.1  mrg    Contributed by CodeSourcery.
      6       1.1  mrg 
      7       1.1  mrg    This file is free software; you can redistribute it and/or modify it
      8       1.1  mrg    under the terms of the GNU General Public License as published by the
      9       1.1  mrg    Free Software Foundation; either version 3, or (at your option) any
     10       1.1  mrg    later version.
     11       1.1  mrg 
     12       1.1  mrg    This file is distributed in the hope that it will be useful, but
     13       1.1  mrg    WITHOUT ANY WARRANTY; without even the implied warranty of
     14       1.1  mrg    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15       1.1  mrg    General Public License for more details.
     16       1.1  mrg 
     17       1.1  mrg    Under Section 7 of GPL version 3, you are granted additional
     18       1.1  mrg    permissions described in the GCC Runtime Library Exception, version
     19       1.1  mrg    3.1, as published by the Free Software Foundation.
     20       1.1  mrg 
     21       1.1  mrg    You should have received a copy of the GNU General Public License and
     22       1.1  mrg    a copy of the GCC Runtime Library Exception along with this program;
     23       1.1  mrg    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     24       1.1  mrg    <http://www.gnu.org/licenses/>.  */
     25       1.1  mrg 
     26       1.1  mrg #ifdef __ARM_EABI__
     27       1.1  mrg /* Some attributes that are common to all routines in this file.  */
     28       1.1  mrg 	/* Tag_ABI_align_needed: This code does not require 8-byte
     29       1.1  mrg 	   alignment from the caller.  */
     30       1.1  mrg 	/* .eabi_attribute 24, 0  -- default setting.  */
     31       1.1  mrg 	/* Tag_ABI_align_preserved: This code preserves 8-byte
     32       1.1  mrg 	   alignment in any callee.  */
     33       1.1  mrg 	.eabi_attribute 25, 1
     34       1.1  mrg #endif /* __ARM_EABI__ */
     35       1.1  mrg 
     36       1.1  mrg #ifdef L_aeabi_lcmp
     37       1.1  mrg 
     38       1.1  mrg FUNC_START aeabi_lcmp
     39       1.1  mrg 	cmp	xxh, yyh
     40       1.1  mrg 	beq	1f
     41       1.1  mrg 	bgt	2f
     42  1.1.1.10  mrg 	movs	r0, #1
     43  1.1.1.10  mrg 	negs	r0, r0
     44       1.1  mrg 	RET
     45       1.1  mrg 2:
     46  1.1.1.10  mrg 	movs	r0, #1
     47       1.1  mrg 	RET
     48       1.1  mrg 1:
     49  1.1.1.10  mrg 	subs	r0, xxl, yyl
     50       1.1  mrg 	beq	1f
     51       1.1  mrg 	bhi	2f
     52  1.1.1.10  mrg 	movs	r0, #1
     53  1.1.1.10  mrg 	negs	r0, r0
     54       1.1  mrg 	RET
     55       1.1  mrg 2:
     56  1.1.1.10  mrg 	movs	r0, #1
     57       1.1  mrg 1:
     58       1.1  mrg 	RET
     59       1.1  mrg 	FUNC_END aeabi_lcmp
     60       1.1  mrg 
     61       1.1  mrg #endif /* L_aeabi_lcmp */
     62       1.1  mrg 
     63       1.1  mrg #ifdef L_aeabi_ulcmp
     64       1.1  mrg 
     65       1.1  mrg FUNC_START aeabi_ulcmp
     66       1.1  mrg 	cmp	xxh, yyh
     67       1.1  mrg 	bne	1f
     68  1.1.1.10  mrg 	subs	r0, xxl, yyl
     69       1.1  mrg 	beq	2f
     70       1.1  mrg 1:
     71       1.1  mrg 	bcs	1f
     72  1.1.1.10  mrg 	movs	r0, #1
     73  1.1.1.10  mrg 	negs	r0, r0
     74       1.1  mrg 	RET
     75       1.1  mrg 1:
     76  1.1.1.10  mrg 	movs	r0, #1
     77       1.1  mrg 2:
     78       1.1  mrg 	RET
     79       1.1  mrg 	FUNC_END aeabi_ulcmp
     80       1.1  mrg 
     81       1.1  mrg #endif /* L_aeabi_ulcmp */
     82       1.1  mrg 
     83       1.1  mrg .macro test_div_by_zero signed
     84       1.1  mrg 	cmp	yyh, #0
     85       1.1  mrg 	bne	7f
     86       1.1  mrg 	cmp	yyl, #0
     87       1.1  mrg 	bne	7f
     88       1.1  mrg 	cmp	xxh, #0
     89   1.1.1.2  mrg 	.ifc	\signed, unsigned
     90       1.1  mrg 	bne	2f
     91       1.1  mrg 	cmp	xxl, #0
     92       1.1  mrg 2:
     93       1.1  mrg 	beq	3f
     94  1.1.1.10  mrg 	movs	xxh, #0
     95  1.1.1.10  mrg 	mvns	xxh, xxh		@ 0xffffffff
     96  1.1.1.10  mrg 	movs	xxl, xxh
     97       1.1  mrg 3:
     98       1.1  mrg 	.else
     99       1.1  mrg 	blt	6f
    100   1.1.1.2  mrg 	bgt	4f
    101   1.1.1.2  mrg 	cmp	xxl, #0
    102   1.1.1.2  mrg 	beq	5f
    103  1.1.1.10  mrg 4:	movs	xxl, #0
    104  1.1.1.10  mrg 	mvns	xxl, xxl		@ 0xffffffff
    105  1.1.1.10  mrg 	lsrs	xxh, xxl, #1		@ 0x7fffffff
    106       1.1  mrg 	b	5f
    107  1.1.1.10  mrg 6:	movs	xxh, #0x80
    108  1.1.1.10  mrg 	lsls	xxh, xxh, #24		@ 0x80000000
    109  1.1.1.10  mrg 	movs	xxl, #0
    110       1.1  mrg 5:
    111       1.1  mrg 	.endif
    112       1.1  mrg 	@ tailcalls are tricky on v6-m.
    113       1.1  mrg 	push	{r0, r1, r2}
    114       1.1  mrg 	ldr	r0, 1f
    115       1.1  mrg 	adr	r1, 1f
    116  1.1.1.10  mrg 	adds	r0, r1
    117       1.1  mrg 	str	r0, [sp, #8]
    118       1.1  mrg 	@ We know we are not on armv4t, so pop pc is safe.
    119       1.1  mrg 	pop	{r0, r1, pc}
    120       1.1  mrg 	.align	2
    121       1.1  mrg 1:
    122       1.1  mrg 	.word	__aeabi_ldiv0 - 1b
    123       1.1  mrg 7:
    124       1.1  mrg .endm
    125       1.1  mrg 
    126       1.1  mrg #ifdef L_aeabi_ldivmod
    127       1.1  mrg 
    128       1.1  mrg FUNC_START aeabi_ldivmod
    129       1.1  mrg 	test_div_by_zero signed
    130       1.1  mrg 
    131  1.1.1.10  mrg 	push	{r0, r1}
    132  1.1.1.10  mrg 	mov	r0, sp
    133  1.1.1.10  mrg 	push	{r0, lr}
    134  1.1.1.10  mrg 	ldr	r0, [sp, #8]
    135  1.1.1.10  mrg 	bl	SYM(__gnu_ldivmod_helper)
    136  1.1.1.10  mrg 	ldr	r3, [sp, #4]
    137  1.1.1.10  mrg 	mov	lr, r3
    138  1.1.1.10  mrg 	add	sp, sp, #8
    139  1.1.1.10  mrg 	pop	{r2, r3}
    140       1.1  mrg 	RET
    141       1.1  mrg 	FUNC_END aeabi_ldivmod
    142       1.1  mrg 
    143       1.1  mrg #endif /* L_aeabi_ldivmod */
    144       1.1  mrg 
    145       1.1  mrg #ifdef L_aeabi_uldivmod
    146       1.1  mrg 
    147       1.1  mrg FUNC_START aeabi_uldivmod
    148       1.1  mrg 	test_div_by_zero unsigned
    149       1.1  mrg 
    150  1.1.1.10  mrg 	push	{r0, r1}
    151  1.1.1.10  mrg 	mov	r0, sp
    152  1.1.1.10  mrg 	push	{r0, lr}
    153  1.1.1.10  mrg 	ldr	r0, [sp, #8]
    154  1.1.1.10  mrg 	bl	SYM(__udivmoddi4)
    155  1.1.1.10  mrg 	ldr	r3, [sp, #4]
    156  1.1.1.10  mrg 	mov	lr, r3
    157  1.1.1.10  mrg 	add	sp, sp, #8
    158  1.1.1.10  mrg 	pop	{r2, r3}
    159       1.1  mrg 	RET
    160       1.1  mrg 	FUNC_END aeabi_uldivmod
    161       1.1  mrg 
    162       1.1  mrg #endif /* L_aeabi_uldivmod */
    163       1.1  mrg 
    164       1.1  mrg #ifdef L_arm_addsubsf3
    165       1.1  mrg 
    166       1.1  mrg FUNC_START aeabi_frsub
    167       1.1  mrg 
    168       1.1  mrg       push	{r4, lr}
    169  1.1.1.10  mrg       movs	r4, #1
    170  1.1.1.10  mrg       lsls	r4, #31
    171  1.1.1.10  mrg       eors	r0, r0, r4
    172       1.1  mrg       bl	__aeabi_fadd
    173       1.1  mrg       pop	{r4, pc}
    174       1.1  mrg 
    175       1.1  mrg       FUNC_END aeabi_frsub
    176       1.1  mrg 
    177       1.1  mrg #endif /* L_arm_addsubsf3 */
    178       1.1  mrg 
    179       1.1  mrg #ifdef L_arm_cmpsf2
    180       1.1  mrg 
    181       1.1  mrg FUNC_START aeabi_cfrcmple
    182       1.1  mrg 
    183       1.1  mrg 	mov	ip, r0
    184  1.1.1.10  mrg 	movs	r0, r1
    185       1.1  mrg 	mov	r1, ip
    186       1.1  mrg 	b	6f
    187       1.1  mrg 
    188       1.1  mrg FUNC_START aeabi_cfcmpeq
    189       1.1  mrg FUNC_ALIAS aeabi_cfcmple aeabi_cfcmpeq
    190       1.1  mrg 
    191       1.1  mrg 	@ The status-returning routines are required to preserve all
    192       1.1  mrg 	@ registers except ip, lr, and cpsr.
    193       1.1  mrg 6:	push	{r0, r1, r2, r3, r4, lr}
    194       1.1  mrg 	bl	__lesf2
    195       1.1  mrg 	@ Set the Z flag correctly, and the C flag unconditionally.
    196       1.1  mrg 	cmp	r0, #0
    197       1.1  mrg 	@ Clear the C flag if the return value was -1, indicating
    198       1.1  mrg 	@ that the first operand was smaller than the second.
    199  1.1.1.10  mrg 	bmi	1f
    200  1.1.1.10  mrg 	movs	r1, #0
    201       1.1  mrg 	cmn	r0, r1
    202       1.1  mrg 1:
    203       1.1  mrg 	pop	{r0, r1, r2, r3, r4, pc}
    204       1.1  mrg 
    205       1.1  mrg 	FUNC_END aeabi_cfcmple
    206       1.1  mrg 	FUNC_END aeabi_cfcmpeq
    207       1.1  mrg 	FUNC_END aeabi_cfrcmple
    208       1.1  mrg 
    209       1.1  mrg FUNC_START	aeabi_fcmpeq
    210       1.1  mrg 
    211       1.1  mrg 	push	{r4, lr}
    212       1.1  mrg 	bl	__eqsf2
    213  1.1.1.10  mrg 	negs	r0, r0
    214  1.1.1.10  mrg 	adds	r0, r0, #1
    215       1.1  mrg 	pop	{r4, pc}
    216       1.1  mrg 
    217       1.1  mrg 	FUNC_END aeabi_fcmpeq
    218       1.1  mrg 
    219       1.1  mrg .macro COMPARISON cond, helper, mode=sf2
    220       1.1  mrg FUNC_START	aeabi_fcmp\cond
    221       1.1  mrg 
    222       1.1  mrg 	push	{r4, lr}
    223       1.1  mrg 	bl	__\helper\mode
    224       1.1  mrg 	cmp	r0, #0
    225       1.1  mrg 	b\cond	1f
    226  1.1.1.10  mrg 	movs	r0, #0
    227       1.1  mrg 	pop	{r4, pc}
    228       1.1  mrg 1:
    229  1.1.1.10  mrg 	movs	r0, #1
    230       1.1  mrg 	pop	{r4, pc}
    231       1.1  mrg 
    232       1.1  mrg 	FUNC_END aeabi_fcmp\cond
    233       1.1  mrg .endm
    234       1.1  mrg 
    235       1.1  mrg COMPARISON lt, le
    236       1.1  mrg COMPARISON le, le
    237       1.1  mrg COMPARISON gt, ge
    238       1.1  mrg COMPARISON ge, ge
    239       1.1  mrg 
    240       1.1  mrg #endif /* L_arm_cmpsf2 */
    241       1.1  mrg 
    242       1.1  mrg #ifdef L_arm_addsubdf3
    243       1.1  mrg 
    244       1.1  mrg FUNC_START aeabi_drsub
    245       1.1  mrg 
    246       1.1  mrg       push	{r4, lr}
    247  1.1.1.10  mrg       movs	r4, #1
    248  1.1.1.10  mrg       lsls	r4, #31
    249  1.1.1.10  mrg       eors	xxh, xxh, r4
    250       1.1  mrg       bl	__aeabi_dadd
    251       1.1  mrg       pop	{r4, pc}
    252       1.1  mrg 
    253       1.1  mrg       FUNC_END aeabi_drsub
    254       1.1  mrg 
    255       1.1  mrg #endif /* L_arm_addsubdf3 */
    256       1.1  mrg 
    257       1.1  mrg #ifdef L_arm_cmpdf2
    258       1.1  mrg 
    259       1.1  mrg FUNC_START aeabi_cdrcmple
    260       1.1  mrg 
    261       1.1  mrg 	mov	ip, r0
    262  1.1.1.10  mrg 	movs	r0, r2
    263       1.1  mrg 	mov	r2, ip
    264       1.1  mrg 	mov	ip, r1
    265  1.1.1.10  mrg 	movs	r1, r3
    266       1.1  mrg 	mov	r3, ip
    267       1.1  mrg 	b	6f
    268       1.1  mrg 
    269       1.1  mrg FUNC_START aeabi_cdcmpeq
    270       1.1  mrg FUNC_ALIAS aeabi_cdcmple aeabi_cdcmpeq
    271       1.1  mrg 
    272       1.1  mrg 	@ The status-returning routines are required to preserve all
    273       1.1  mrg 	@ registers except ip, lr, and cpsr.
    274       1.1  mrg 6:	push	{r0, r1, r2, r3, r4, lr}
    275       1.1  mrg 	bl	__ledf2
    276       1.1  mrg 	@ Set the Z flag correctly, and the C flag unconditionally.
    277       1.1  mrg 	cmp	r0, #0
    278       1.1  mrg 	@ Clear the C flag if the return value was -1, indicating
    279       1.1  mrg 	@ that the first operand was smaller than the second.
    280  1.1.1.10  mrg 	bmi	1f
    281  1.1.1.10  mrg 	movs	r1, #0
    282       1.1  mrg 	cmn	r0, r1
    283       1.1  mrg 1:
    284       1.1  mrg 	pop	{r0, r1, r2, r3, r4, pc}
    285       1.1  mrg 
    286       1.1  mrg 	FUNC_END aeabi_cdcmple
    287       1.1  mrg 	FUNC_END aeabi_cdcmpeq
    288       1.1  mrg 	FUNC_END aeabi_cdrcmple
    289       1.1  mrg 
    290       1.1  mrg FUNC_START	aeabi_dcmpeq
    291       1.1  mrg 
    292       1.1  mrg 	push	{r4, lr}
    293       1.1  mrg 	bl	__eqdf2
    294  1.1.1.10  mrg 	negs	r0, r0
    295  1.1.1.10  mrg 	adds	r0, r0, #1
    296       1.1  mrg 	pop	{r4, pc}
    297       1.1  mrg 
    298       1.1  mrg 	FUNC_END aeabi_dcmpeq
    299       1.1  mrg 
    300       1.1  mrg .macro COMPARISON cond, helper, mode=df2
    301       1.1  mrg FUNC_START	aeabi_dcmp\cond
    302       1.1  mrg 
    303       1.1  mrg 	push	{r4, lr}
    304       1.1  mrg 	bl	__\helper\mode
    305       1.1  mrg 	cmp	r0, #0
    306       1.1  mrg 	b\cond	1f
    307  1.1.1.10  mrg 	movs	r0, #0
    308       1.1  mrg 	pop	{r4, pc}
    309       1.1  mrg 1:
    310  1.1.1.10  mrg 	movs	r0, #1
    311       1.1  mrg 	pop	{r4, pc}
    312       1.1  mrg 
    313       1.1  mrg 	FUNC_END aeabi_dcmp\cond
    314       1.1  mrg .endm
    315       1.1  mrg 
    316       1.1  mrg COMPARISON lt, le
    317       1.1  mrg COMPARISON le, le
    318       1.1  mrg COMPARISON gt, ge
    319       1.1  mrg COMPARISON ge, ge
    320       1.1  mrg 
    321       1.1  mrg #endif /* L_arm_cmpdf2 */
    322