This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] ARM add hand-coded implementations of DImode shift ops
- From: Richard Earnshaw <rearnsha at buzzard dot freeserve dot co dot uk>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Richard dot Earnshaw at buzzard dot freeserve dot co dot uk
- Date: Sat, 15 May 2004 18:35:25 +0100
- Subject: [PATCH] ARM add hand-coded implementations of DImode shift ops
- Reply-to: Richard dot Earnshaw at buzzard dot freeserve dot co dot uk
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