This patch makes the BPF backend to use the new V4 bswap{16,32,64} instructions in order to implement the __builtin_bswap{16,32,64} built-ins. It also adds support for -mcpu=v4 and -m[no]bswap command-line options. Tests and doc updates are includes.
Tested in bpf-unknown-none. gcc/ChangeLog PR target/110786 * config/bpf/bpf.opt (mcpu): Add ISA_V4 and make it the default. (mbswap): New option. * config/bpf/bpf-opts.h (enum bpf_isa_version): New value ISA_V4. * config/bpf/bpf.cc (bpf_option_override): Set bpf_has_bswap. * config/bpf/bpf.md: Use bswap instructions if available for bswap* insn, and fix constraint. * doc/invoke.texi (eBPF Options): Document -mcpu=v4 and -mbswap. gcc/testsuite/ChangeLog PR target/110786 * gcc.target/bpf/bswap-1.c: Pass -mcpu=v3 to build test. * gcc.target/bpf/bswap-2.c: New test. --- gcc/config/bpf/bpf-opts.h | 1 + gcc/config/bpf/bpf.cc | 3 +++ gcc/config/bpf/bpf.md | 17 +++++++++++------ gcc/config/bpf/bpf.opt | 9 ++++++++- gcc/doc/invoke.texi | 11 ++++++++++- gcc/testsuite/gcc.target/bpf/bswap-1.c | 2 +- gcc/testsuite/gcc.target/bpf/bswap-2.c | 23 +++++++++++++++++++++++ 7 files changed, 57 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.target/bpf/bswap-2.c diff --git a/gcc/config/bpf/bpf-opts.h b/gcc/config/bpf/bpf-opts.h index 92db01ec4d5..e0be591b479 100644 --- a/gcc/config/bpf/bpf-opts.h +++ b/gcc/config/bpf/bpf-opts.h @@ -58,6 +58,7 @@ enum bpf_isa_version ISA_V1, ISA_V2, ISA_V3, + ISA_V4 }; enum bpf_asm_dialect diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc index 1d3936871d6..6bc715429dc 100644 --- a/gcc/config/bpf/bpf.cc +++ b/gcc/config/bpf/bpf.cc @@ -253,6 +253,9 @@ bpf_option_override (void) if (bpf_has_jmp32 == -1) bpf_has_jmp32 = (bpf_isa >= ISA_V3); + if (bpf_has_bswap == -1) + bpf_has_bswap = (bpf_isa >= ISA_V4); + /* Disable -fstack-protector as it is not supported in BPF. */ if (flag_stack_protect) { diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md index 80220f2ef37..81e2268c400 100644 --- a/gcc/config/bpf/bpf.md +++ b/gcc/config/bpf/bpf.md @@ -60,7 +60,7 @@ (define_constants ;; Instruction classes. ;; alu 64-bit arithmetic. ;; alu32 32-bit arithmetic. -;; end endianness conversion instructions. +;; end endianness conversion or byte swap instructions. ;; ld load instructions. ;; lddx load 64-bit immediate instruction. ;; ldx generic load instructions. @@ -354,20 +354,25 @@ (define_insn "lshr<SIM:mode>3" "{rsh<msuffix>\t%0,%2|%w0 >>= %w2}" [(set_attr "type" "<mtype>")]) -;;;; Endianness conversion +;;;; Byte swapping (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")))] + (bswap:BSM (match_operand:BSM 1 "register_operand" " 0")))] "" { - if (TARGET_BIG_ENDIAN) - return "{endle\t%0, <endmode>|%0 = le<endmode> %0}"; + if (bpf_has_bswap) + return "{bswap\t%0, <endmode>|%0 = bswap<endmode> %1}"; else - return "{endbe\t%0, <endmode>|%0 = be<endmode> %0}"; + { + if (TARGET_BIG_ENDIAN) + return "{endle\t%0, <endmode>|%0 = le<endmode> %1}"; + else + return "{endbe\t%0, <endmode>|%0 = be<endmode> %1}"; + } } [(set_attr "type" "end")]) diff --git a/gcc/config/bpf/bpf.opt b/gcc/config/bpf/bpf.opt index ff805f9e083..1e4dcc871d7 100644 --- a/gcc/config/bpf/bpf.opt +++ b/gcc/config/bpf/bpf.opt @@ -146,8 +146,12 @@ mjmp32 Target Var(bpf_has_jmp32) Init(-1) Enable 32-bit jump instructions. +mbswap +Target Var(bpf_has_bswap) Init(-1) +Enable byte swap instructions. + mcpu= -Target RejectNegative Joined Var(bpf_isa) Enum(bpf_isa) Init(ISA_V3) +Target RejectNegative Joined Var(bpf_isa) Enum(bpf_isa) Init(ISA_V4) Enum Name(bpf_isa) Type(enum bpf_isa_version) @@ -161,6 +165,9 @@ Enum(bpf_isa) String(v2) Value(ISA_V2) EnumValue Enum(bpf_isa) String(v3) Value(ISA_V3) +EnumValue +Enum(bpf_isa) String(v4) Value(ISA_V4) + masm= Target RejectNegative Joined Var(asm_dialect) Enum(asm_dialect) Init(ASM_NORMAL) Use given assembler dialect. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index efd356e7ef6..a977a34db42 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -24707,10 +24707,14 @@ Enable 32-bit jump instructions. Enabled for CPU v3 and above. @item -malu32 Enable 32-bit ALU instructions. Enabled for CPU v3 and above. +@opindex mbswap +@item -mbswap +Enable byte swap instructions. Enabled for CPU v4 and above. + @opindex mcpu @item -mcpu=@var{version} This specifies which version of the eBPF ISA to target. Newer versions -may not be supported by all kernels. The default is @samp{v3}. +may not be supported by all kernels. The default is @samp{v4}. Supported values for @var{version} are: @@ -24728,6 +24732,11 @@ All features of v2, plus: @item 32-bit ALU operations, as in @option{-malu32} @end itemize +@item v4 +All features of v3, plus: +@itemize @minus +@item Byte swap instructions, as in @option{-mbswap} +@end itemize @end table @opindex mco-re diff --git a/gcc/testsuite/gcc.target/bpf/bswap-1.c b/gcc/testsuite/gcc.target/bpf/bswap-1.c index 4748143ada5..ba19eb60485 100644 --- a/gcc/testsuite/gcc.target/bpf/bswap-1.c +++ b/gcc/testsuite/gcc.target/bpf/bswap-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mlittle-endian" } */ +/* { dg-options "-mlittle-endian -mcpu=v3" } */ unsigned short in16 = 0x1234U; unsigned int in32 = 0x12345678U; diff --git a/gcc/testsuite/gcc.target/bpf/bswap-2.c b/gcc/testsuite/gcc.target/bpf/bswap-2.c new file mode 100644 index 00000000000..e5aef3845d0 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/bswap-2.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-mlittle-endian -mcpu=v4" } */ + +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 "bswap\t%r., 16" } } */ +/* { dg-final { scan-assembler "bswap\t%r., 32" } } */ +/* { dg-final { scan-assembler "bswap\t%r., 64" } } */ -- 2.30.2