RFC: ARM 64-bit shifts in NEON

Andrew Stubbs andrew_stubbs@mentor.com
Mon Dec 12 16:29:00 GMT 2011


On 07/12/11 13:42, Richard Earnshaw wrote:
> So it looks like the code generated for core registers with thumb2 is
> pretty rubbish (no real surprise there -- to get the best code you need
> to make use of the fact that on ARM a shift by a small negative number
> (<  -128) will give zero.  This gives us sequences like:
>
> For ARM state it's something like (untested)
>
> 					@ shft<  32			, shft>= 32
> __ashldi3_v3:
> 	sub	r3, r2, #32		@ -ve            		, shft - 32
> 	lsl	ah, ah, r2		@ ah<<  shft     		, 0
> 	rsb	ip, r2, #32		@ 32 - shft      		, -ve
> 	orr	ah, ah, al, lsl r3	@ ah<<  shft     		, al<<  shft - 32
> 	orr	ah, ah, al, lsr ip	@ ah<<  shft | al>>  32 - shft	, al<<  shft - 32
> 	lsl	al, al, r2		@ al<<  shft     		, 0
>
> For Thumb2 (where there is no orr with register shift)
>
> 	lsls	ah, ah, r2		@ ah<<  shft     		, 0
> 	sub	r3, r2, #32		@ -ve            		, shft - 32
> 	lsl	ip, al, r3		@ 0              		, al<<  shft - 32
> 	negs	r3, r3			@ 32 - shft      		, -ve
> 	orr	ah, ah, ip		@ ah<<  shft     		, al<<  shft - 32
> 	lsr	r3, al, r3		@ al>>  32 - shft		, 0
> 	orrs	ah, ah, r3		@ ah<<  shft | al>>  32 - shft	, al<<  shft - 32
> 	lsls	al, al, r2		@ al<<  shft     		, 0
>
> Neither of which needs the condition flags during execution (and indeed
> is probably better in both cases than the code currently in lib1funcs.asm
> for a modern core).  The flag clobbering behaviour in the thumb2 variant
> is only for code size saving; that would normally be added by a late
> optimization pass.
>
> None of this directly helps with your neon usage, but it does show that we
> really don't need to clobber the condition code register to get an
> efficient sequence.

Unfortunately, both these sequences use two scratch registers, as shown, 
and that's worse than clobbering CC.

Now, I can implement this for non-Neon easily enough, I think, and that 
would be a win, but I'm trying to figure out how best to do it for both 
that case and the case where neon is available but the compiler chooses 
not to do it.

The problem is that when there is no neon available, this can be 
converted at expand or split1 time, but when neon *is* available we have 
to wait until a post-reload split, and then we'd be forced to expand 
this in early-clobber mode, which is far less optimal.

Any suggestions now to do this without pessimizing the code in the case 
that neon is available but not used?

In fact, is the general shift operation sufficiently expensive that I 
should I just abandon the fall back alternatives and *always* use Neon 
when available? In this case, what about A8 vs. A9?

Thanks

Andrew



More information about the Gcc-patches mailing list