diff mbox

[RFA/ARM] Make libgcc use UDIV/SDIV instructions when they are available.

Message ID 4EC290A7.5030909@arm.com
State New
Headers show

Commit Message

Matthew Gretton-Dann Nov. 15, 2011, 4:17 p.m. UTC
All,

The attached patch causes libgcc to use the UDIV and SDIV instructions 
when possible in the implementation of the ARM div/mod functions in libgcc.

This will benefit Cortex-M3, Cortex-M4, all Cortex-R* CPUs, Cortex-A7, 
and Cortex-A15.

The special case of some Cortex-R* CPUs where the UDIV/SDIV instructions 
are only available in Thumb mode, making it beneficial to force these 
library functions into Thumb mode to make use of those instructions, is 
not handled.

This was tested by configuring GCC --with-cpu cortex-a15, and then 
running the testsuite with -mcpu=cortex-a9.  I've also manually 
inspected libgcc to make sure the functions are being built as expected.

Please can someone review?

Thanks,

Matt

libgcc/ChangeLog:

2011-11-15  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>

	* config/arm/lib1funcs.asm (udivsi3): Add support for divide
	functions.
	(aeabi_uidivmod): Likewise.	
	(umodsi3): Likewise.
	(divsi3): Likewise.
	(aeabi_idivmod): Likewise.
	(modsi3): Likewise.

Thanks,

Matt

Comments

Richard Earnshaw Nov. 16, 2011, 12:34 p.m. UTC | #1
On 15/11/11 16:17, Matthew Gretton-Dann wrote:
> All,
> 
> The attached patch causes libgcc to use the UDIV and SDIV instructions 
> when possible in the implementation of the ARM div/mod functions in libgcc.
> 
> This will benefit Cortex-M3, Cortex-M4, all Cortex-R* CPUs, Cortex-A7, 
> and Cortex-A15.
> 
> The special case of some Cortex-R* CPUs where the UDIV/SDIV instructions 
> are only available in Thumb mode, making it beneficial to force these 
> library functions into Thumb mode to make use of those instructions, is 
> not handled.
> 
> This was tested by configuring GCC --with-cpu cortex-a15, and then 
> running the testsuite with -mcpu=cortex-a9.  I've also manually 
> inspected libgcc to make sure the functions are being built as expected.
> 
> Please can someone review?
> 
> Thanks,
> 
> Matt
> 
> libgcc/ChangeLog:
> 
> 2011-11-15  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>
> 
> 	* config/arm/lib1funcs.asm (udivsi3): Add support for divide
> 	functions.
> 	(aeabi_uidivmod): Likewise.	
> 	(umodsi3): Likewise.
> 	(divsi3): Likewise.
> 	(aeabi_idivmod): Likewise.
> 	(modsi3): Likewise.
> 

OK.

R.
diff mbox

Patch

diff --git a/libgcc/config/arm/lib1funcs.S b/libgcc/config/arm/lib1funcs.S
index 2e76c01..094d79a 100644
--- a/libgcc/config/arm/lib1funcs.S
+++ b/libgcc/config/arm/lib1funcs.S
@@ -951,6 +951,17 @@  LSYM(udivsi3_skip_div0_test):
 	pop	{ work }
 	RET
 
+#elif defined(__ARM_ARCH_EXT_IDIV__)
+
+	ARM_FUNC_START udivsi3
+	ARM_FUNC_ALIAS aeabi_uidiv udivsi3
+
+	cmp	r1, #0
+	beq	LSYM(Ldiv0)
+
+	udiv	r0, r0, r1
+	RET
+
 #else /* ARM version/Thumb-2.  */
 
 	ARM_FUNC_START udivsi3
@@ -997,6 +1008,14 @@  FUNC_START aeabi_uidivmod
 	mul	r2, r0
 	sub	r1, r1, r2
 	bx	r3
+#elif defined(__ARM_ARCH_EXT_IDIV__)
+ARM_FUNC_START aeabi_uidivmod
+	cmp	r1, #0
+	beq	LSYM(Ldiv0)
+	mov     r2, r0 
+	udiv	r0, r0, r1
+	mls     r1, r0, r1, r2
+	RET
 #else
 ARM_FUNC_START aeabi_uidivmod
 	cmp	r1, #0
@@ -1014,9 +1033,19 @@  ARM_FUNC_START aeabi_uidivmod
 /* ------------------------------------------------------------------------ */
 #ifdef L_umodsi3
 
-	FUNC_START umodsi3
+#ifdef __ARM_ARCH_EXT_IDIV__
 
-#ifdef __thumb__
+	ARM_FUNC_START umodsi3
+
+	cmp	r1, #0
+	beq	LSYM(Ldiv0)
+	udiv	r2, r0, r1
+	mls     r0, r1, r2, r0
+	RET
+
+#elif defined(__thumb__)
+
+	FUNC_START umodsi3
 
 	cmp	divisor, #0
 	beq	LSYM(Ldiv0)
@@ -1035,6 +1064,8 @@  LSYM(Lover10):
 	
 #else  /* ARM version.  */
 	
+	FUNC_START umodsi3
+
 	subs	r2, r1, #1			@ compare divisor with 1
 	bcc	LSYM(Ldiv0)
 	cmpne	r0, r1				@ compare dividend with divisor
@@ -1091,6 +1122,16 @@  LSYM(Lover12):
 	pop	{ work }
 	RET
 
+#elif defined(__ARM_ARCH_EXT_IDIV__)
+
+	ARM_FUNC_START divsi3
+	ARM_FUNC_ALIAS aeabi_idiv divsi3
+
+	cmp 	r1, #0
+	beq	LSYM(Ldiv0)
+	sdiv	r0, r0, r1
+	RET
+
 #else /* ARM/Thumb-2 version.  */
 	
 	ARM_FUNC_START divsi3	
@@ -1153,6 +1194,14 @@  FUNC_START aeabi_idivmod
 	mul	r2, r0
 	sub	r1, r1, r2
 	bx	r3
+#elif defined(__ARM_ARCH_EXT_IDIV__)
+ARM_FUNC_START aeabi_idivmod
+	cmp 	r1, #0
+	beq	LSYM(Ldiv0)
+	mov     r2, r0
+	sdiv	r0, r0, r1
+	mls     r1, r0, r1, r2
+	RET
 #else
 ARM_FUNC_START aeabi_idivmod
 	cmp	r1, #0
@@ -1170,9 +1219,20 @@  ARM_FUNC_START aeabi_idivmod
 /* ------------------------------------------------------------------------ */
 #ifdef L_modsi3
 
-	FUNC_START modsi3
+#if defined(__ARM_ARCH_EXT_IDIV__)
 
-#ifdef __thumb__
+	ARM_FUNC_START modsi3
+
+	cmp	r1, #0
+	beq	LSYM(Ldiv0)
+
+	sdiv	r2, r0, r1
+	mls     r0, r1, r2, r0
+	RET
+
+#elif defined(__thumb__)
+
+	FUNC_START modsi3
 
 	mov	curbit, #1
 	cmp	divisor, #0
@@ -1204,6 +1264,8 @@  LSYM(Lover12):
 
 #else /* ARM version.  */
 	
+	FUNC_START modsi3
+
 	cmp	r1, #0
 	beq	LSYM(Ldiv0)
 	rsbmi	r1, r1, #0			@ loops below use unsigned.