mirror of
				https://source.denx.de/u-boot/u-boot.git
				synced 2025-10-26 05:51:29 +01:00 
			
		
		
		
	When CONFIG_SYS_THUMB_BUILD is defined these functions may be called from Thumb code. Add the required ENTRY and ENDPROC bracketing so that BLX is used to call these ARM functions, instead of plain BL, which will fail. Signed-off-by: Simon Glass <sjg@chromium.org> Reported-by: Pavel Machek <pavel@denx.de>
		
			
				
	
	
		
			144 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			144 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| #include <linux/linkage.h>
 | |
| 
 | |
| .macro ARM_DIV_BODY dividend, divisor, result, curbit
 | |
| 
 | |
| #if __LINUX_ARM_ARCH__ >= 5
 | |
| 
 | |
| 	clz	\curbit, \divisor
 | |
| 	clz	\result, \dividend
 | |
| 	sub	\result, \curbit, \result
 | |
| 	mov	\curbit, #1
 | |
| 	mov	\divisor, \divisor, lsl \result
 | |
| 	mov	\curbit, \curbit, lsl \result
 | |
| 	mov	\result, #0
 | |
| 
 | |
| #else
 | |
| 
 | |
| 	@ Initially shift the divisor left 3 bits if possible,
 | |
| 	@ set curbit accordingly.  This allows for curbit to be located
 | |
| 	@ at the left end of each 4 bit nibbles in the division loop
 | |
| 	@ to save one loop in most cases.
 | |
| 	tst	\divisor, #0xe0000000
 | |
| 	moveq	\divisor, \divisor, lsl #3
 | |
| 	moveq	\curbit, #8
 | |
| 	movne	\curbit, #1
 | |
| 
 | |
| 	@ Unless the divisor is very big, shift it up in multiples of
 | |
| 	@ four bits, since this is the amount of unwinding in the main
 | |
| 	@ division loop.  Continue shifting until the divisor is
 | |
| 	@ larger than the dividend.
 | |
| 1:	cmp	\divisor, #0x10000000
 | |
| 	cmplo	\divisor, \dividend
 | |
| 	movlo	\divisor, \divisor, lsl #4
 | |
| 	movlo	\curbit, \curbit, lsl #4
 | |
| 	blo	1b
 | |
| 
 | |
| 	@ For very big divisors, we must shift it a bit at a time, or
 | |
| 	@ we will be in danger of overflowing.
 | |
| 1:	cmp	\divisor, #0x80000000
 | |
| 	cmplo	\divisor, \dividend
 | |
| 	movlo	\divisor, \divisor, lsl #1
 | |
| 	movlo	\curbit, \curbit, lsl #1
 | |
| 	blo	1b
 | |
| 
 | |
| 	mov	\result, #0
 | |
| 
 | |
| #endif
 | |
| 
 | |
| 	@ Division loop
 | |
| 1:	cmp	\dividend, \divisor
 | |
| 	subhs	\dividend, \dividend, \divisor
 | |
| 	orrhs	\result,   \result,   \curbit
 | |
| 	cmp	\dividend, \divisor,  lsr #1
 | |
| 	subhs	\dividend, \dividend, \divisor, lsr #1
 | |
| 	orrhs	\result,   \result,   \curbit,  lsr #1
 | |
| 	cmp	\dividend, \divisor,  lsr #2
 | |
| 	subhs	\dividend, \dividend, \divisor, lsr #2
 | |
| 	orrhs	\result,   \result,   \curbit,  lsr #2
 | |
| 	cmp	\dividend, \divisor,  lsr #3
 | |
| 	subhs	\dividend, \dividend, \divisor, lsr #3
 | |
| 	orrhs	\result,   \result,   \curbit,  lsr #3
 | |
| 	cmp	\dividend, #0			@ Early termination?
 | |
| 	movnes	\curbit,   \curbit,  lsr #4	@ No, any more bits to do?
 | |
| 	movne	\divisor,  \divisor, lsr #4
 | |
| 	bne	1b
 | |
| 
 | |
| .endm
 | |
| 
 | |
| .macro ARM_DIV2_ORDER divisor, order
 | |
| 
 | |
| #if __LINUX_ARM_ARCH__ >= 5
 | |
| 
 | |
| 	clz	\order, \divisor
 | |
| 	rsb	\order, \order, #31
 | |
| 
 | |
| #else
 | |
| 
 | |
| 	cmp	\divisor, #(1 << 16)
 | |
| 	movhs	\divisor, \divisor, lsr #16
 | |
| 	movhs	\order, #16
 | |
| 	movlo	\order, #0
 | |
| 
 | |
| 	cmp	\divisor, #(1 << 8)
 | |
| 	movhs	\divisor, \divisor, lsr #8
 | |
| 	addhs	\order, \order, #8
 | |
| 
 | |
| 	cmp	\divisor, #(1 << 4)
 | |
| 	movhs	\divisor, \divisor, lsr #4
 | |
| 	addhs	\order, \order, #4
 | |
| 
 | |
| 	cmp	\divisor, #(1 << 2)
 | |
| 	addhi	\order, \order, #3
 | |
| 	addls	\order, \order, \divisor, lsr #1
 | |
| 
 | |
| #endif
 | |
| 
 | |
| .endm
 | |
| 
 | |
| 	.align	5
 | |
| .globl __divsi3
 | |
| __divsi3:
 | |
| ENTRY(__aeabi_idiv)
 | |
| 	cmp	r1, #0
 | |
| 	eor	ip, r0, r1			@ save the sign of the result.
 | |
| 	beq	Ldiv0
 | |
| 	rsbmi	r1, r1, #0			@ loops below use unsigned.
 | |
| 	subs	r2, r1, #1			@ division by 1 or -1 ?
 | |
| 	beq	10f
 | |
| 	movs	r3, r0
 | |
| 	rsbmi	r3, r0, #0			@ positive dividend value
 | |
| 	cmp	r3, r1
 | |
| 	bls	11f
 | |
| 	tst	r1, r2				@ divisor is power of 2 ?
 | |
| 	beq	12f
 | |
| 
 | |
| 	ARM_DIV_BODY r3, r1, r0, r2
 | |
| 
 | |
| 	cmp	ip, #0
 | |
| 	rsbmi	r0, r0, #0
 | |
| 	mov	pc, lr
 | |
| 
 | |
| 10:	teq	ip, r0				@ same sign ?
 | |
| 	rsbmi	r0, r0, #0
 | |
| 	mov	pc, lr
 | |
| 
 | |
| 11:	movlo	r0, #0
 | |
| 	moveq	r0, ip, asr #31
 | |
| 	orreq	r0, r0, #1
 | |
| 	mov	pc, lr
 | |
| 
 | |
| 12:	ARM_DIV2_ORDER r1, r2
 | |
| 
 | |
| 	cmp	ip, #0
 | |
| 	mov	r0, r3, lsr r2
 | |
| 	rsbmi	r0, r0, #0
 | |
| 	mov	pc, lr
 | |
| 
 | |
| Ldiv0:
 | |
| 
 | |
| 	str	lr, [sp, #-4]!
 | |
| 	bl	__div0
 | |
| 	mov	r0, #0			@ About as wrong as it could be.
 | |
| 	ldr	pc, [sp], #4
 | |
| ENDPROC(__aeabi_idiv)
 |