arm/libgcc: Support signed 64-bit division
Add support for signed 64-bit division. The implementation mostly relies on __aeabi_uldivmod, which is already implemented. ldivmod.S was adapted from CrOS EC version of ldivmod.S: https://chromium.googlesource.com/chromiumos/platform/ec/+/main/third_party/libaeabi-cortexm0/core/cortex-m0/ldivmod.S The CrOS EC version was adapted from: https://github.com/bobbl/libaeabi-cortexm0/blob/master/ldivmod.S BUG=b:240316722 BRANCH=None TEST=Signed division works in PSP verstage (runs on ARM) Change-Id: I53785c732b0fa35a4809bc054f1482c5461ada7b Signed-off-by: Rob Barnes <robbarnes@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/66207 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Julius Werner <jwerner@chromium.org> Reviewed-by: Tim Van Patten <timvp@google.com>
This commit is contained in:
		
				
					committed by
					
						 Martin L Roth
						Martin L Roth
					
				
			
			
				
	
			
			
			
						parent
						
							b11f9f7e16
						
					
				
				
					commit
					f6bb293f1c
				
			| @@ -1,6 +1,6 @@ | ||||
| ## SPDX-License-Identifier: GPL-2.0-only | ||||
|  | ||||
| libgcc_files = ashldi3.S lib1funcs.S lshrdi3.S muldi3.S ucmpdi2.S uldivmod.S | ||||
| libgcc_files = ashldi3.S lib1funcs.S lshrdi3.S muldi3.S ucmpdi2.S uldivmod.S ldivmod.S | ||||
| libgcc_files += udivmoddi4.c umoddi3.c | ||||
|  | ||||
| ifeq ($(CONFIG_ARCH_BOOTBLOCK_ARM),y) | ||||
|   | ||||
							
								
								
									
										74
									
								
								src/arch/arm/libgcc/ldivmod.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								src/arch/arm/libgcc/ldivmod.S
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| /* SPDX-License-Identifier: ISC OR GPL-2.0-only */ | ||||
|  | ||||
| /* | ||||
|  * ldivmod.S: signed 64 bit division (quotient and remainder) | ||||
|  * | ||||
|  * Taken from CrOS EC: third_party/libaeabi-cortexm0/core/cortex-m0/ldivmod.S | ||||
|  */ | ||||
|  | ||||
| #include <arch/asm.h> | ||||
|  | ||||
|  | ||||
| @ {long long quotient, long long remainder} | ||||
| @ __aeabi_ldivmod(long long numerator, long long denominator) | ||||
| @ | ||||
| @ Divide r1:r0 by r3:r2 and return the quotient in r1:r0 and the remainder in | ||||
| @ r3:r2 (all signed) | ||||
| @ | ||||
|  | ||||
| ENTRY(__aeabi_ldivmod) | ||||
|  | ||||
| 	cmp	r1, #0 | ||||
| 	bge	L_num_pos | ||||
|  | ||||
| 	push	{r4, lr} | ||||
| 	movs	r4, #0			@ num = -num | ||||
| 	rsbs	r0, r0, #0 | ||||
| 	sbcs	r4, r1 | ||||
| 	mov	r1, r4 | ||||
|  | ||||
| 	cmp	r3, #0 | ||||
| 	bge	L_neg_both | ||||
|  | ||||
| 	movs	r4, #0			@ den = -den | ||||
| 	rsbs	r2, r2, #0 | ||||
| 	sbcs	r4, r3 | ||||
| 	mov	r3, r4 | ||||
| 	bl	__aeabi_uldivmod | ||||
| 	movs	r4, #0			@ rem = -rem | ||||
| 	rsbs	r2, r2, #0 | ||||
| 	sbcs	r4, r3 | ||||
| 	mov	r3, r4 | ||||
| 	pop	{r4, pc} | ||||
|  | ||||
| L_neg_both: | ||||
| 	bl	__aeabi_uldivmod | ||||
| 	movs	r4, #0			@ quot = -quot | ||||
| 	rsbs	r0, r0, #0 | ||||
| 	sbcs	r4, r1 | ||||
| 	mov	r1, r4 | ||||
| 	movs	r4, #0			@ rem = -rem | ||||
| 	rsbs	r2, r2, #0 | ||||
| 	sbcs	r4, r3 | ||||
| 	mov	r3, r4 | ||||
| 	pop	{r4, pc} | ||||
|  | ||||
| L_num_pos: | ||||
| 	cmp	r3, #0 | ||||
| 	blt	L_den_neg | ||||
| 	push	{r4, lr} | ||||
| 	bl	__aeabi_uldivmod	@ offset too big for b / bge | ||||
| 	pop	{r4, pc} | ||||
|  | ||||
| L_den_neg: | ||||
| 	push	{r4, lr} | ||||
| 	movs	r4, #0			@ den = -den | ||||
| 	rsbs	r2, r2, #0 | ||||
| 	sbcs	r4, r3 | ||||
| 	mov	r3, r4 | ||||
| 	bl	__aeabi_uldivmod | ||||
| 	movs	r4, #0			@ quot = -quot | ||||
| 	rsbs	r0, r0, #0 | ||||
| 	sbcs	r4, r1 | ||||
| 	mov	r1, r4 | ||||
| 	pop	{r4, pc} | ||||
		Reference in New Issue
	
	Block a user