[Patch ARM] implement bswap16

Richard Earnshaw rearnsha@arm.com
Tue Sep 11 10:52:00 GMT 2012


On 11/09/12 11:25, Christophe Lyon wrote:
> On 10 September 2012 19:30, Richard Earnshaw <rearnsha@arm.com> wrote:
>> On 10/09/12 16:40, Christophe Lyon wrote:
>>> Why do we have to keep room for the predicate here? (%?) Doesn't this
>>> pattern match only in unconditional cases?
>>>
>>
>> Because the ARM back-end has a very late conditionalizer pass that can
>> also generate conditional execution.  It very rarely kicks in these
>> days, but if the predication rules are in there you could end up with an
>> instruction that the compiler thought was conditionally executed being
>> always run.  That would be bad^TM.
>>
> 
> Thanks for the clarification.
> 
>>> BTW, I didn't manage to have GCC generate conditional revsh. I merely
>>> added an "if (y)" guard before calling builtin_bswap16, but this
>>> didn't turn into a conditional revsh.
>>>
> On this topic, could you suggest a way to generate conditional revsh?
> 
> I would like to augment the testsuite for this, and I tried:
> 
> int y;
> short swaps16(short x) {
>   if (y)
>   return __builtin_bswap16(x);
> }
> but it generates:
> swaps16:
> 	@ args = 0, pretend = 0, frame = 0
> 	@ frame_needed = 0, uses_anonymous_args = 0
> 	@ link register save eliminated.
> 	movw	r3, #:lower16:y	@ 50	*arm_movsi_vfp/4	[length = 4]
> 	movt	r3, #:upper16:y	@ 51	*arm_movt	[length = 4]
> 	ldr	r3, [r3]	@ 7	*arm_movsi_vfp/5	[length = 4]
> 	cmp	r3, #0	@ 8	*arm_cmpsi_insn/3	[length = 4]
> 	beq	.L3	@ 9	arm_cond_branch	[length = 4]
> 	revsh	r0, r0	@ 13	*arm_revsh/3	[length = 4]
> 	bx	lr	@ 56	*arm_return	[length = 12]
> .L3:
> 	bx	lr	@ 58	*arm_return	[length = 12]
> 
> ie unconditional revsh.
> 
> 
> Another question regarding the *arm_revsh pattern you wrote: why is
> the "arch" set to "t1,t2,32" ?  Shouldn't it be "t1,t2,a" ?
> (IIUC, "32" matches both "a" and "t2" as per the definition of TARGET_32BIT)
> 
> Thanks
> 
> Christophe.
> 

Try something like:

short foo(int);

short swaps (short x, int y)
{
  int z = x;
  if (y)
	z = __builtin_bswap16(x);
  return foo (z);
}

If that's not enough, try adding 1 to z before calling foo.

R.




More information about the Gcc-patches mailing list