Hi David.
> The eBPF architecture provides 'end[be,le]' instructions for endianness > swapping. Add a define_insn for bswap<mode>2 to use them instaed of > falling back on a libcall. > > Tested on bpf-unknown-none, no known regressions. > > OK to commit? > Thanks OK for master. Thanks! > gcc/ > > * config/bpf/bpf.md (bswap<mode>2): New define_insn. > > gcc/testsuite/ > > * gcc.target/bpf/bswap-1.c: New test. > --- > gcc/config/bpf/bpf.md | 17 +++++++++++++++++ > gcc/testsuite/gcc.target/bpf/bswap-1.c | 23 +++++++++++++++++++++++ > 2 files changed, 40 insertions(+) > create mode 100644 gcc/testsuite/gcc.target/bpf/bswap-1.c > > diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md > index a28021aef26..22a133f1c79 100644 > --- a/gcc/config/bpf/bpf.md > +++ b/gcc/config/bpf/bpf.md > @@ -341,6 +341,23 @@ (define_insn "lshr<SIM:mode>3" > "rsh<msuffix>\t%0,%2" > [(set_attr "type" "<mtype>")]) > > +;;;; Endianness conversion > + > +(define_mode_iterator BSM [HI SI DI]) > +(define_mode_attr endmode [(HI "16") (SI "32") (DI "64")]) > + > +(define_insn "bswap<BSM:mode>2" > + [(set (match_operand:BSM 0 "register_operand" "=r") > + (bswap:BSM (match_operand:BSM 1 "register_operand" " r")))] > + "" > +{ > + if (TARGET_BIG_ENDIAN) > + return "endle\t%0, <endmode>"; > + else > + return "endbe\t%0, <endmode>"; > +} > + [(set_attr "type" "end")]) > + > ;;;; Conditional branches > > ;; The eBPF jump instructions use 64-bit arithmetic when evaluating > diff --git a/gcc/testsuite/gcc.target/bpf/bswap-1.c > b/gcc/testsuite/gcc.target/bpf/bswap-1.c > new file mode 100644 > index 00000000000..4748143ada5 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/bpf/bswap-1.c > @@ -0,0 +1,23 @@ > +/* { dg-do compile } */ > +/* { dg-options "-mlittle-endian" } */ > + > +unsigned short in16 = 0x1234U; > +unsigned int in32 = 0x12345678U; > +unsigned long in64 = 0x123456789abcdef0ULL; > + > +unsigned short out16 = 0; > +unsigned int out32 = 0; > +unsigned long out64 = 0; > + > +int foo (void) > +{ > + out16 = __builtin_bswap16 (in16); > + out32 = __builtin_bswap32 (in32); > + out64 = __builtin_bswap64 (in64); > + > + return 0; > +} > + > +/* { dg-final { scan-assembler "endbe\t%r., 16" } } */ > +/* { dg-final { scan-assembler "endbe\t%r., 32" } } */ > +/* { dg-final { scan-assembler "endbe\t%r., 64" } } */