https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115102
--- Comment #4 from Uroš Bizjak <ubizjak at gmail dot com> ---
(In reply to Richard Biener from comment #1)
> though on x86 there's no high word preserving swap of the lower 2 bytes.
There is, please try:
asm ("xchgb %h0, %b0" : "+Q" (val));
like:
--cut here--
#include <stdint.h>
#include <stdio.h>
uint32_t __attribute__((noinline))
bswap8(uint32_t val)
{
return (val & 0xffff0000) | ((val & 0xff00) >> 8) | ((val & 0xff) << 8);
}
uint32_t __attribute__((noinline))
bswap8_new(uint32_t val)
{
asm ("xchgb %h0, %b0" : "+Q" (val));
return val;
}
int main ()
{
uint32_t a = 0x10325476;
printf ("%x %x\n", bswap8 (a), bswap8_new (a));
return 0;
}
--cut here--
we already have:
(define_insn "bswaphi_lowpart"
[(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
(bswap:HI (match_dup 0)))
(clobber (reg:CC FLAGS_REG))]
""
"@
xchg{b}\t{%h0, %b0|%b0, %h0}
rol{w}\t{$8, %0|%0, 8}"
but bswaphi2 named pattern is enabled only for TARGET_MOVBE.
Time to fix this ;)