This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] ARM add hand-coded implementations of DImode shift ops


This patch adds hand-coded implementations of _lshrdi3, _ashrdi3 and 
_ashldi3 for ARM and thumb, and enables them in the arm-unknown-elf 
configurations.  These implementations are less than half the size of the 
C implementations that come from libgcc2.c.

An interesting observation is that because of the way the shifter works on 
the ARM, the Thumb implementaions of logical shifts can be done without 
any branches.

Tested on arm-elf and installed on the mainline.

2004-05-15  Richard Earnshaw  <reanrsha@arm.com>

	* arm/lib1funcs.asm (_lshrdi3, _ashrdi3, _ashldi3): Add ASM 
	implementations for ARM and Thumb.
	* arm/t-arm-elf (LIB1ASMFUNCS): Use them.


Index: lib1funcs.asm
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/lib1funcs.asm,v
retrieving revision 1.30
diff -p -p -r1.30 lib1funcs.asm
*** lib1funcs.asm	15 May 2004 12:41:33 -0000	1.30
--- lib1funcs.asm	15 May 2004 17:26:05 -0000
*************** LSYM(Lover12):
*** 865,870 ****
--- 865,980 ----
  	
  #endif /* L_dvmd_lnx */
  /* ------------------------------------------------------------------------ */
+ /* Dword shift operations.  */
+ /* All the following Dword shift variants rely on the fact that
+ 	shft xxx, Reg
+    is in fact done as
+ 	shft xxx, (Reg & 255)
+    so for Reg value in (32...63) and (-1...-31) we will get zero (in the
+    case of logical shifts) or the sign (for asr).  */
+ 
+ #ifdef __ARMEB__
+ #define al	r1
+ #define ah	r0
+ #else
+ #define al	r0
+ #define ah	r1
+ #endif
+ 
+ #ifdef L_lshrdi3
+ 
+ 	FUNC_START lshrdi3
+ 
+ #ifdef __thumb__
+ 	lsr	al, r2
+ 	mov	r3, ah
+ 	lsr	ah, r2
+ 	mov	ip, r3
+ 	sub	r2, #32
+ 	lsr	r3, r2
+ 	orr	al, r3
+ 	neg	r2, r2
+ 	mov	r3, ip
+ 	lsl	r3, r2
+ 	orr	al, r3
+ 	RET
+ #else
+ 	subs	r3, r2, #32
+ 	rsb	ip, r2, #32
+ 	movmi	al, al, lsr r2
+ 	movpl	al, ah, lsr r3
+ 	orrmi	al, al, ah, lsl ip
+ 	mov	ah, ah, lsr r2
+ 	RET
+ #endif
+ 	FUNC_END lshrdi3
+ 
+ #endif
+ 	
+ #ifdef L_ashrdi3
+ 	
+ 	FUNC_START ashrdi3
+ #ifdef __thumb__
+ 	lsr	al, r2
+ 	mov	r3, ah
+ 	asr	ah, r2
+ 	sub	r2, #32
+ 	@ If r2 is negative at this point the following step would OR
+ 	@ the sign bit into all of AL.  That's not what we want...
+ 	bmi	1f
+ 	mov	ip, r3
+ 	asr	r3, r2
+ 	orr	al, r3
+ 	mov	r3, ip
+ 1:
+ 	neg	r2, r2
+ 	lsl	r3, r2
+ 	orr	al, r3
+ 	RET
+ #else
+ 	subs	r3, r2, #32
+ 	rsb	ip, r2, #32
+ 	movmi	al, al, lsr r2
+ 	movpl	al, ah, asr r3
+ 	orrmi	al, al, ah, lsl ip
+ 	mov	ah, ah, asr r2
+ 	RET
+ #endif
+ 
+ 	FUNC_END ashrdi3
+ 
+ #endif
+ 
+ #ifdef L_ashldi3
+ 
+ 	FUNC_START ashldi3
+ #ifdef __thumb__
+ 	lsl	ah, r2
+ 	mov	r3, al
+ 	lsl	al, r2
+ 	mov	ip, r3
+ 	sub	r2, #32
+ 	lsl	r3, r2
+ 	orr	ah, r3
+ 	neg	r2, r2
+ 	mov	r3, ip
+ 	lsr	r3, r2
+ 	orr	ah, r3
+ 	RET
+ #else
+ 	subs	r3, r2, #32
+ 	rsb	ip, r2, #32
+ 	movmi	ah, ah, lsl r2
+ 	movpl	ah, al, lsl r3
+ 	orrmi	ah, ah, al, lsr ip
+ 	mov	al, al, lsl r2
+ 	RET
+ #endif
+ 	FUNC_END ashldi3
+ 
+ #endif
+ 
+ /* ------------------------------------------------------------------------ */
  /* These next two sections are here despite the fact that they contain Thumb 
     assembler because their presence allows interworked code to be linked even
     when the GCC library is this one.  */
Index: t-arm-elf
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/t-arm-elf,v
retrieving revision 1.21
diff -p -p -r1.21 t-arm-elf
*** t-arm-elf	15 May 2004 12:41:35 -0000	1.21
--- t-arm-elf	15 May 2004 17:26:05 -0000
***************
*** 1,6 ****
--- 1,7 ----
  LIB1ASMSRC = arm/lib1funcs.asm
  LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _bb_init_func \
  	_call_via_rX _interwork_call_via_rX \
+ 	_lshrdi3 _ashrdi3 _ashldi3 \
  	_negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi _fixunsdfsi \
  	_truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \
  	_fixsfsi _fixunssfsi

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]